<?php
/**
 * SeekQuarry/Yioop --
 * Open Source Pure PHP Search Engine, Crawler, and Indexer
 *
 * Copyright (C) 2009 - 2026  Chris Pollett chris@pollett.org
 *
 * LICENSE:
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 * END LICENSE
 *
 * @author Chris Pollett chris@pollett.org
 * @license https://www.gnu.org/licenses/ GPL3
 * @link https://www.seekquarry.com/
 * @copyright 2009 - 2026
 * @filesource
 */
namespace seekquarry\yioop\tests;

use seekquarry\yioop\library\JavascriptUnitTest;

/**
 * Tests the parts of basic.js that decide whether a browser can turn
 * speech into words and how those words are made ready to travel inside
 * a message. A browser that cannot listen is not offered the button
 * that would ask it to, so knowing which browsers can matters.
 *
 * @author Chris Pollett
 */
class BasicJavascriptTest extends JavascriptUnitTest
{
    /**
     * Checks that a browser is said to listen when it offers either
     * name for the listener, and not when it offers neither.
     *
     * @return string html and Javascript that checks the answer in a
     *      browser or, from the command line, under node
     */
    public function listeningIsOfferedOnlyWhenTheBrowserCanTestCase()
    {
        ob_start();
        ?>
        <div id="basicListeningTest"></div>
        <script src="../scripts/basic.js" ></script>
        <script>
        var unit_test_results = [];
        window.SpeechRecognition = undefined;
        window.webkitSpeechRecognition = undefined;
        unit_test_results.push(
            {name: "a browser offering no listener cannot listen",
            pass: canListenForWords() === false});
        window.webkitSpeechRecognition = function () {};
        unit_test_results.push(
            {name: "a browser offering the older name can listen",
            pass: canListenForWords() === true});
        window.webkitSpeechRecognition = undefined;
        window.SpeechRecognition = function () {};
        unit_test_results.push(
            {name: "a browser offering the plain name can listen",
            pass: canListenForWords() === true});
        </script>
        <?php
        $out_data = ob_get_contents();
        ob_end_clean();
        return $out_data;
    }
    /**
     * Checks that a recorder is made for the first kind the browser can
     * actually build one for, taken from a list that puts the kinds
     * every browser plays ahead of the ones only some do. A kind is
     * tried by building with it, since a browser may say it cannot
     * write a kind it will in fact write.
     *
     * @return string html and Javascript that checks the choice in a
     *      browser or, from the command line, under node
     */
    public function recorderIsMadeOfTheWidestKindTestCase()
    {
        ob_start();
        ?>
        <div id="basicRecordingKindTest"></div>
        <script src="../scripts/basic.js" ></script>
        <script>
        var unit_test_results = [];
        var builder = function (allowed) {
            return function (sound, type) {
                if (allowed.indexOf(type) < 0) {
                    throw new Error("cannot write " + type);
                }
                return {made: type};
            };
        };
        var wide = makeRecorderOfWidestKind({}, null,
            builder(['audio/mp4', 'audio/webm']));
        unit_test_results.push(
            {name: "a browser writing several kinds is given the widest",
            pass: wide.type === 'audio/mp4' && wide.extension === 'mp4'});
        var narrow = makeRecorderOfWidestKind({}, null,
            builder(['audio/webm']));
        unit_test_results.push(
            {name: "a browser writing one kind alone is given that one",
            pass: narrow.type === 'audio/webm' &&
                narrow.extension === 'webm'});
        var aacish = makeRecorderOfWidestKind({}, null,
            builder(['audio/aac', 'audio/webm']));
        unit_test_results.push(
            {name: "a kind more browsers play comes before one fewer do",
            pass: aacish.type === 'audio/aac' &&
                aacish.extension === 'aac'});
        var mpegish = makeRecorderOfWidestKind({}, null,
            builder(['audio/mpeg', 'audio/webm']));
        unit_test_results.push(
            {name: "mp3 is taken ahead of the kind fewer browsers play",
            pass: mpegish.type === 'audio/mpeg' &&
                mpegish.extension === 'mp3'});
        unit_test_results.push(
            {name: "a browser writing none of them is given nothing",
            pass: makeRecorderOfWidestKind({}, null,
                builder([])) === null});
        unit_test_results.push(
            {name: "the recorder built is the one handed back",
            pass: wide.recorder.made === 'audio/mp4'});
        </script>
        <?php
        $out_data = ob_get_contents();
        ob_end_clean();
        return $out_data;
    }
    /**
     * Checks that words heard are made ready to sit inside a message:
     * the mark that separates a recording from its words is taken out,
     * a pair of closing brackets is split so it cannot end the message
     * early, and runs of space become one.
     *
     * @return string html and Javascript that checks the tidying in a
     *      browser or, from the command line, under node
     */
    public function heardWordsAreMadeReadyToTravelTestCase()
    {
        ob_start();
        ?>
        <div id="basicTidyTest"></div>
        <script src="../scripts/basic.js" ></script>
        <script>
        var unit_test_results = [];
        unit_test_results.push(
            {name: "the separating mark is taken out",
            pass: cleanTranscript("a|b") === "a b"});
        unit_test_results.push(
            {name: "closing brackets are split apart",
            pass: cleanTranscript("stop))now") === "stop) )now"});
        unit_test_results.push(
            {name: "runs of space become one",
            pass: cleanTranscript("  many   spaces ") === "many spaces"});
        unit_test_results.push(
            {name: "words with none of these are left as they are",
            pass: cleanTranscript("hello there") === "hello there"});
        </script>
        <?php
        $out_data = ob_get_contents();
        ob_end_clean();
        return $out_data;
    }
}
