spanish-quizzer

An app to quiz you on Spanish vocabulary and verb conjugations
git clone https://git.ashermorgan.net/spanish-quizzer/
Log | Files | Refs | README

commit e095a87cc7b17c01aedfcff2ddd7b5a7cb304dff
parent da409182a3d8961b353ee5fdf2212a6b006117a6
Author: AsherMorgan <59518073+AsherMorgan@users.noreply.github.com>
Date:   Thu,  3 Dec 2020 11:06:44 -0800

Merge pull request #25 from AsherMorgan/refactor

Refactor Spanish-Quizzer.
Diffstat:
Acss/app.css | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acss/filterInput.css | 69+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dcss/home.css | 30------------------------------
Dcss/settings.css | 117-------------------------------------------------------------------------------
Acss/settingsInput.css | 15+++++++++++++++
Mindex.html | 26++++++++++++++++++--------
Ajs/app.js | 209+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ajs/filterInput.js | 288+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ajs/filters.js | 371+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mjs/global.js | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
Djs/home.js | 161-------------------------------------------------------------------------------
Mjs/quizzer.js | 56++++++++------------------------------------------------
Djs/settings.js | 856-------------------------------------------------------------------------------
Ajs/settingsInput.js | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtests/index.html | 12++++++++----
Mtests/test.app.js | 36++++++++++--------------------------
Atests/test.filterInput.js | 378+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atests/test.filters.js | 893+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtests/test.global.js | 97++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Mtests/test.quizzer.js | 131+------------------------------------------------------------------------------
Dtests/test.settings.js | 1311-------------------------------------------------------------------------------
Atests/test.settingsInput.js | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
22 files changed, 2636 insertions(+), 2707 deletions(-)

diff --git a/css/app.css b/css/app.css @@ -0,0 +1,62 @@ +/* Header */ +#home > h1 { + font-size: 20px; + font-weight: bold; + margin-top: 15px; + margin-bottom: 5px; +} + +/* Vocab & Conjugation buttons*/ +#home button { + width: 150px; + height: 50px; + line-height: 50px; + margin: 10px; + font-size: 15px; +} + +/* Link to Reference Tables */ +#home a { + margin-top: 10px; +} + +/* Filters and Settings */ +#settings { + display: flex; + flex-direction: column; + align-items: center; +} +#settings[hidden] { + display: none; +} + +/* Start/Resume Buttons */ +.settingButtons { + margin-top: 20px; + margin-bottom: 10px; +} +.settingButtons button { + width: 100px; + height: 40px; + font-size: 18px; + margin: 0px 5px; +} +@media only screen and (max-width: 510px) { + /* Expand Start/Resume buttons */ + .settingButtons { + width: calc(100% - 10px); + } + .settingButtons button { + width: calc(50% - 15px); + height: 50px; + } +} + +/* Congrats message */ +#congrats p { + margin: 20px; +} +#congrats button { + width: 100px; + height: 35px; +} diff --git a/css/filterInput.css b/css/filterInput.css @@ -0,0 +1,69 @@ +/* FilterInput */ +.filtersInput h1 { + font-size: 16px; + font-weight: normal; + margin-bottom: 10px; +} +.filtersInput h2 { + font-size: 20px; + margin-bottom: 5px; +} +.filtersInput { + margin-left: 5px; + margin-right: 5px; + margin-top: 10px; +} +.filtersInput div h2 button { + padding: 3px; +} + +/* Filter */ +.filter { + width: max-content; + + background-color: var(--background-color); + border: 1px solid var(--border-color); + box-shadow: 0 0 15px var(--border-color); + + margin: 5px auto; + padding: 5px; + border-radius: 5px; +} +.filter button { + border: none; + background-color: var(--background-color); + color: var(--foreground-color); + cursor: pointer; +} + +/* Conjugation settings on mobile devices */ +@media only screen and (max-width: 510px) { + .verbSettings { + width: calc(100% - 20px); + } + .verbSettings .filter { + width: 100%; + margin: 10px auto; + } + .verbSettings .filter select, .verbSettings .filter button { + width: 100%; + height: 30px; + margin: 3px 0px; + } +} + +/* Vocab settings on mobile devices */ +@media only screen and (max-width: 350px) { + .vocabSettings { + width: calc(100% - 20px); + } + .vocabSettings .filter { + width: 100%; + margin: 10px auto; + } + .vocabSettings .filter select, .vocabSettings .filter button { + width: 100%; + height: 30px; + margin: 3px 0px; + } +} diff --git a/css/home.css b/css/home.css @@ -1,30 +0,0 @@ -/* Header */ -#home > h1 { - font-size: 20px; - font-weight: bold; - margin-top: 15px; - margin-bottom: 5px; -} - -/* Vocab & Conjugation buttons*/ -#home button { - width: 150px; - height: 50px; - line-height: 50px; - margin: 10px; - font-size: 15px; -} - -/* Link to Reference Tables */ -#home a { - margin-top: 10px; -} - -/* Congrats message */ -#congrats p { - margin: 20px; -} -#congrats button { - width: 100px; - height: 35px; -} diff --git a/css/settings.css b/css/settings.css @@ -1,117 +0,0 @@ -/* Settings */ -.settings { - display: flex; - flex-direction: column; - align-items: center; -} -.settings[hidden] { - display: none; -} -.settings h1 { - font-size: 16px; - font-weight: normal; - margin-bottom: 10px; -} -.settings h2 { - font-size: 20px; - margin-bottom: 5px; -} -.vocabSettings, .verbSettings, .quizzerSettings { - margin-left: 5px; - margin-right: 5px; - margin-top: 10px; -} - - - -/* Filters */ -.vocabSettings h2 button, .verbSettings h2 button { - padding: 3px; -} -.filter { - width: max-content; - - background-color: var(--background-color); - border: 1px solid var(--border-color); - box-shadow: 0 0 15px var(--border-color); - - margin: 5px auto; - padding: 5px; - border-radius: 5px; -} -.filter button { - border: none; - background-color: var(--background-color); - color: var(--foreground-color); - cursor: pointer; -} - - - -/* Quizzer Settings div */ -.quizzerSettings div { - text-align: left; -} -.quizzerSettings input[type=number] { - width: 50px; -} - - - -/* Start/Resume Buttons */ -.settingButtons { - margin-top: 20px; - margin-bottom: 10px; -} -.settingButtons button { - width: 100px; - height: 40px; - font-size: 18px; - margin: 0px 5px; -} -@media only screen and (max-width: 510px) { - /* Expand Start/Resume buttons */ - .settingButtons { - width: calc(100% - 10px); - } - .settingButtons button { - width: calc(50% - 15px); - height: 50px; - } -} - - - -/* Conjugation settings on mobile devices */ -@media only screen and (max-width: 510px) { - .verbSettings { - width: calc(100% - 20px); - } - .verbSettings .filter { - width: 100%; - margin: 10px auto; - } - .verbSettings .filter select, .verbSettings .filter button { - width: 100%; - height: 30px; - margin: 3px 0px; - } -} - - - -/* Vocab settings on mobile devices */ -@media only screen and (max-width: 350px) { - .vocabSettings { - width: calc(100% - 20px); - } - .vocabSettings .filter { - width: 100%; - margin: 10px auto; - } - .vocabSettings .filter select, .vocabSettings s.filter button { - width: 100%; - height: 30px; - margin: 3px 0px; - } -} diff --git a/css/settingsInput.css b/css/settingsInput.css @@ -0,0 +1,15 @@ +.settingsInput h2 { + font-size: 20px; + margin-bottom: 5px; +} +.settingsInput { + margin-left: 5px; + margin-right: 5px; + margin-top: 10px; +} +.settingsInput div { + text-align: left; +} +.settingsInput input[type=number] { + width: 50px; +} diff --git a/index.html b/index.html @@ -8,14 +8,17 @@ <link rel="icon" type="image/png" href="images/favicon-32.png"> <link rel="apple-touch-icon" sizes="180x180" href="images/apple-touch-icon.png"> <link rel="stylesheet" href="css/global.css"> - <link rel="stylesheet" href="css/home.css"> - <link rel="stylesheet" href="css/settings.css"> + <link rel="stylesheet" href="css/app.css"> + <link rel="stylesheet" href="css/filterInput.css"> + <link rel="stylesheet" href="css/settingsInput.css"> <link rel="stylesheet" href="css/quizzer.css"> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script> <script src="https://unpkg.com/papaparse@5.1.1/papaparse.min.js"></script> <script src="js/global.js"></script> - <script src="js/home.js"></script> - <script src="js/settings.js"></script> + <script src="js/app.js"></script> + <script src="js/filterInput.js"></script> + <script src="js/settingsInput.js"></script> + <script src="js/filters.js"></script> <script src="js/quizzer.js"></script> </head> @@ -43,11 +46,18 @@ </div> </div> - <settings id="settings" v-show="state === 'settings'" hidden - :category="category" @start-session="StartSession"> - </settings> + <div id="settings" v-show="state === 'settings'" hidden> + <filter-input :category="category" v-model="filters"></filter-input> - <quizzer id="quizzer" v-show="state === 'quizzer'" :active="state === 'quizzer'" hidden + <settings-input v-model="settings"></settings-input> + + <div class="settingButtons"> + <button class="settingsStart" @click="CreateSession();">Start</button> + <button class="settingsResume" @click="ResumeSession();">Resume</button> + </div> + </div> + + <quizzer id="quizzer" v-if="state === 'quizzer'" :starting-index="promptIndex" :starting-prompts="prompts" :settings="settings" @new-prompt="updateProgress" @finished-prompts="state = 'congrats';"> </quizzer> diff --git a/js/app.js b/js/app.js @@ -0,0 +1,209 @@ +// Declare global variables +let Sets; // List of parsed sets +let app; + + + +/** + * Initialize the Vue app + */ +function loadVue() { + app = new Vue({ + el: "#app", // Mount to app div + + data: { + state: "home", // Can be either "home", "settings", or "quizzer" + category: "verbs", // Can be either "verbs" or "vocab" + filters: [], + settings: getSettings(), + prompts: [], + promptIndex: 0, + }, + + methods: { + /** + * Return to the previous state. + */ + Back: function() { + switch (app.state) { + case "quizzer": + case "congrats": + app.state = "settings"; + break; + case "settings": + case "home": + default: + app.state = "home"; + break; + } + }, + + /** + * Update the user's progress in localStorage. + * @param {Array} prompts - The list of prompts. + * @param {Number} index - The index of the current prompt. + */ + updateProgress: function(prompts, index) { + // Get localStorage prefix + let prefix = app.category === "verbs" ? "verb-" : "vocab-"; + + // Save progress to local storage + localStorage.setItem(prefix + "prompts", JSON.stringify(prompts)); + localStorage.setItem(prefix + "prompt", JSON.stringify(index)); + }, + + /** + * Start a new quizzer session + */ + CreateSession: function() { + // Get prompts + if (this.category === "vocab") { + this.prompts = Shuffle(ApplyFilters(Sets, GetVocabFilters(this.filters), this.settings.multiplePrompts)); + } + else if (this.category === "verbs") { + // Get prompts + this.prompts = Shuffle(ApplyFilters(Sets, GetVerbFilters(this.filters), this.settings.multiplePrompts)); + } + + // Set progress + this.promptIndex = 0; + + // Start quizzer + this.StartSession(); + }, + + /** + * Resume the previous quizzer session. + */ + ResumeSession: function() { + // Get localStorage prefix + let prefix; + if (this.category === "vocab") { + prefix = "vocab-" + } + else if (this.category === "verbs") { + prefix = "verb-" + } + + // Load prompts and progress + this.prompts = JSON.parse(localStorage.getItem(prefix + "prompts")); + this.promptIndex = parseInt(localStorage.getItem(prefix + "prompt")); + + // Start quizzer + this.StartSession(); + }, + + /** + * Perform validation checks and then start the quizzer. + */ + StartSession: function() { + // Validate prompts and promptIndex + if (!this.prompts) { + alert("An error occured while resuming the previous session."); + return; + } + else if (this.prompts.length === 0) { + alert("Your custom vocabulary set must contain at least one term."); + return; + } + else if (isNaN(this.promptIndex) || this.promptIndex < 0 || this.promptIndex >= this.prompts.length) { + alert("An error occured while resuming the previous session."); + return; + } + + // Validate browser for voice input + if (this.settings.inputType !== "Text") { + if ((window.SpeechRecognition || window.webkitSpeechRecognition || window.mozSpeechRecognition || window.msSpeechRecognition) === undefined) { + alert("Your browser does not support voice input."); + return; + } + } + + // Give iOS devices ringer warning for prompt audio + if (this.settings.promptType !== "Text") { + if (!!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform)) { + alert("Please make sure your ringer is on in order to hear audio prompts."); + } + } + + // Show and hide elements (also enables the quizzer) + this.state = "quizzer"; + }, + }, + }); +} + + + +/** + * Load the document. + */ +function Load() { + // Call LoadPage method from global.js + LoadPage(); + + // Initialize the Vue app + loadVue(); + + // Unhide hidden divs + // Divs were hidden to improve interface for users with JS blocked + document.getElementById("home").hidden = false; + document.getElementById("settings").hidden = false; + document.getElementById("congrats").hidden = false; + document.querySelector("footer").hidden = false; + + // Add event Listeners + document.addEventListener("keydown", KeyDown); + + // Load CSVs + Sets = []; + let setNames = ["Verbs", "Adjectives", "Adverbs", "Prepositions", "Transitions", + "Colors", "Days", "Months", "Questions", "Weather", "Family", "Clothes", + "Nature", "House", "Vacation", "Childhood", "Professions", "Health"]; + for (let setName of setNames) { + Papa.parse(`vocab/${setName}.csv`, { + download: true, + complete: function(results) { + // Set verbs + Sets[setName] = results.data; + } + }); + } +} + + + +/** + * Handle a keyDown event (implements some keyboard shortcuts). + * @param {object} e - The event args. + */ +function KeyDown(e) { + if (e.key === "Escape") { + app.Back(); + } + + // Home shortcuts + if (app.state === "home") { + if (e.key === "c") { + app.category = "verbs"; + app.state = "settings"; + } + if (e.key === "v") { + app.category = "vocab"; + app.state = "settings"; + } + if (e.key === "r") { + window.location = "reference.html"; + } + } + + // Settings shortcuts + if (app.state === "settings") { + if (e.key === "s") { + app.CreateSession(); + } + if (e.key === "r") { + app.ResumeSession(); + } + } +} diff --git a/js/filterInput.js b/js/filterInput.js @@ -0,0 +1,288 @@ +let filterInput = Vue.component("filterInput", { + props: { + category: { + type: String, + default: "verbs", + }, + }, + + computed: { + value: function() { + if (this.category === "verbs") { + return this.verbFilters; + } + else if (this.category === "vocab") { + return this.vocabFilters; + } + } + }, + + data: function() { + return { + verbFilters: [], + vocabFilters: [], + }; + }, + + watch: { + value: { + handler: function(value) { + this.$emit("input", value); + }, + deep: true, + }, + }, + + methods: { + /** + * Add a filter to the settings page. + */ + AddFilter: function() { + if (this.category === "verbs") { + this.verbFilters.push({tense:"All Tenses", type:"All Types", subject:"All Subjects", direction:"Eng. → Conj."}); + } + else if (this.category === "vocab") { + this.vocabFilters.push({set:"All Sets", type:"All Types", direction:"Eng. ↔ Esp."}); + } + }, + + /** + * Remove a filter from the settings page. + * @param {Number} index - The index of the verb filter. + */ + RemoveFilter: function(index) { + if (this.category === "verbs") { + this.verbFilters.splice(index, 1); + } + else if (this.category === "vocab") { + this.vocabFilters.splice(index, 1); + } + }, + + /** + * Get the regularity filters available for a verb filter. + * @param {Number} index - The index of the verb filter. + * @returns {object} - An object with boolean properties for each regularity filter. + */ + getTenseTypes: function(index) { + // Get filter options + let filters = {"All Types":true, "Reflexive":true, "Regular":true, "Nonregular":true, "Stem Changing":true, "Orthographic":true, "Irregular":true} + switch(this.verbFilters[index].tense) + { + case "All Tenses": + break; + case "Present Participles": + filters["Reflexive"] = false; // Reflexive + filters["Orthographic"] = false; // Orthographic + break; + case "Present Tense": + filters["Orthographic"] = false; // Orthographic + break; + case "Preterite Tense": + break; + case "Imperfect Tense": + filters["Stem Changing"] = false; // Stem Changing + filters["Orthographic"] = false; // Orthographic + break; + case "Simple Future Tense": + filters["Stem Changing"] = false; // Stem Changing + filters["Orthographic"] = false; // Orthographic + break; + } + + // Reset type if needed + if (!filters[this.verbFilters[index].type]) { + this.verbFilters[index].type = "All Types"; + } + + // Return filters + return filters; + }, + + /** + * Get the subject filters available for a verb filter. + * @param {Number} index - The index of the verb filter. + * @returns {object} - An object with boolean properties for each subject filter. + */ + getTenseSubjects: function(index) { + // Set default filters + let filters = {"All Subjects":true, "Type":true, "Yo":true, "Tú":true, "Él":true, "Nosotros":true, "Ellos":true} + + if (this.verbFilters[index].tense === "Present Participles") { + // Override filters + filters["Yo"] = false; + filters["Tú"] = false; + filters["Él"] = false; + filters["Nosotros"] = false; + filters["Ellos"] = false; + } + + // Reset subject + if (this.verbFilters[index].tense === "Present Participles" && this.verbFilters[index].subject !== "Type") { + this.verbFilters[index].subject = "All Subjects"; + } + + // Return filters + return filters; + }, + + /** + * Get the filters available for a vocab Set. + * @param {Number} index - The index of the vocab filter. + * @returns {Array} - An array containing available filters. + */ + getSetFilters: function(index) { + // Get filter options + let filters = {"All Types":true, "Adjectives":true, "Nouns":true, "Verbs":true} + switch(this.vocabFilters[index].set) + { + case "Verbs": + filters["Adjectives"] = false; + filters["Nouns"] = false; + filters["Verbs"] = false; + break; + + case "Adjectives": + filters["Nouns"] = false; + filters["Verbs"] = false; + break; + + case "Adverbs": + filters["Adjectives"] = false; + filters["Nouns"] = false; + filters["Verbs"] = false; + break; + + case "Prepositions": + case "Transitions": + case "Questions": + filters["Adjectives"] = false; + filters["Nouns"] = false; + filters["Verbs"] = false; + break; + + case "Colors": + filters["Nouns"] = false; + filters["Verbs"] = false; + break; + + case "Days": + case "Months": + filters["Adjectives"] = false; + filters["Verbs"] = false; + break; + + case "Weather": + case "Professions": + filters["Adjectives"] = false; + break; + + case "Family": + case "Clothes": + filters["Verbs"] = false; + break; + + case "Nature": + case "House": + case "Vacation": + case "Childhood": + case "Health": + break; + } + + // Reset type if needed + if (!filters[this.vocabFilters[index].type]) { + this.vocabFilters[index].type = "All Types"; + } + + // Return filters + return filters; + } + }, + + template: ` + <div class="filtersInput" ref="container"> + <div class="verbSettings" v-show="category === 'verbs'"> + <h1>Choose your settings and then click start.</h1> + + <h2> + Verb Filters + <button @click="AddFilter();">Add Filter</button> + </h2> + + <div v-for="(filter, index) in verbFilters" class="filter"> + <select v-model="filter.tense"> + <option>All Tenses</option> + <option>Present Participles</option> + <option>Present Tense</option> + <option>Preterite Tense</option> + <option>Imperfect Tense</option> + <option>Simple Future Tense</option> + </select> + <select v-model="filter.type"> + <option v-for="(available, type) in getTenseTypes(index)" :disabled="!available">{{ type }}</option> + </select> + <select v-model="filter.subject"> + <option v-for="(available, subject) in getTenseSubjects(index)" :disabled="!available">{{ subject }}</option> + </select> + <select v-model="filter.direction"> + <option>Eng. → Conj.</option> + <option>Esp. → Conj.</option> + <option>Conj. → Eng.</option> + <option>Conj. → Esp.</option> + </select> + <button class="itemRemove" @click="RemoveFilter(index);">╳</button> + </div> + </div> + + + <div class="vocabSettings" v-show="category === 'vocab'"> + <h1>Choose your settings and then click start.</h1> + + <h2> + Vocabulary Sets + <button @click="AddFilter();">Add set</button> + </h2> + + <div v-for="(filter, index) in vocabFilters" class="filter"> + <select class="vocabSetName" v-model="filter.set"> + <option>All Sets</option> + <optgroup label="Common Words"> + <option>Adjectives</option> + <option>Adverbs</option> + <option>Prepositions</option> + <option>Transitions</option> + <option>Verbs</option> + </optgroup> + <optgroup label="Basic Words"> + <option>Colors</option> + <option>Days</option> + <option>Months</option> + <option>Questions</option> + </optgroup> + <optgroup label="Advanced Words"> + <option>Childhood</option> + <option>Clothes</option> + <option>Family</option> + <option>Health</option> + <option>House</option> + <option>Nature</option> + <option>Professions</option> + <option>Vacation</option> + <option>Weather</option> + </optgroup> + </select> + <select v-model="filter.type"> + <option v-for="(available, type) in getSetFilters(index)" :disabled="!available">{{ type }}</option> + </select> + <select v-model="filter.direction"> + <option>Eng. ↔ Esp.</option> + <option>Eng. → Esp.</option> + <option>Esp. → Eng.</option> + </select> + <button class="itemRemove" @click="RemoveFilter(index);">╳</button> + </div> + </div> + </div> + `, +}); diff --git a/js/filters.js b/js/filters.js @@ -0,0 +1,371 @@ +/** + * Create io-filters from an array of vocab filters. + * @param {Array} rawFilters The array of filters. + * @returns {Array} The io-filters. + */ +function GetVocabFilters(rawFilters) { + // Expand "All Sets" filters + let filters = []; // Format: [{set:"vocab set name", tense:"specific tense", subject:"specific subject", type:"regex"}] + for (let filter of rawFilters) { + if (filter.set === "All Sets") { + filters.push({set:"Verbs", type: filter.type, direction:filter.direction}); + filters.push({set:"Adjectives", type: filter.type, direction:filter.direction}); + filters.push({set:"Adverbs", type: filter.type, direction:filter.direction}); + filters.push({set:"Prepositions", type: filter.type, direction:filter.direction}); + filters.push({set:"Transitions", type: filter.type, direction:filter.direction}); + filters.push({set:"Colors", type: filter.type, direction:filter.direction}); + filters.push({set:"Days", type: filter.type, direction:filter.direction}); + filters.push({set:"Months", type: filter.type, direction:filter.direction}); + filters.push({set:"Questions", type: filter.type, direction:filter.direction}); + filters.push({set:"Weather", type: filter.type, direction:filter.direction}); + filters.push({set:"Family", type: filter.type, direction:filter.direction}); + filters.push({set:"Clothes", type: filter.type, direction:filter.direction}); + filters.push({set:"Nature", type: filter.type, direction:filter.direction}); + filters.push({set:"House", type: filter.type, direction:filter.direction}); + filters.push({set:"Vacation", type: filter.type, direction:filter.direction}); + filters.push({set:"Childhood", type: filter.type, direction:filter.direction}); + filters.push({set:"Professions", type: filter.type, direction:filter.direction}); + filters.push({set:"Health", type: filter.type, direction:filter.direction}); + } + else { + filters.push({set:filter.set, type: filter.type, direction:filter.direction}); + } + } + + // Expand "All directions" filters + for (let filter of filters) { + if (filter.direction === "Eng. ↔ Esp.") { + filter.direction = "Eng. → Esp."; + filters.push({set:filter.set, type: filter.type, direction:"Esp. → Eng."}); + } + } + + // Get type regex filter + for (let filter of filters) { + switch (filter.type.toLowerCase()) { + case "adjectives": + filter.type = "Adjective"; + break; + case "nouns": + filter.type = "Noun"; + break; + case "verbs": + filter.type = "Verb"; + break; + case "all types": + filter.type = ".*"; + break; + default: + throw `Unrecognized filter: ${type}.`; + } + } + + // Create io-filters + let ioFilters = []; // Format: [{set:"vocab set name", outputIndex:0, inputIndex:0, filterIndex:0, filterValue:"regex"}] + for (let filter of filters) { + // Create filter + if (filter.direction.toLowerCase().startsWith("eng")) { + ioFilters.push({set:filter.set, outputIndex:0, inputIndex:1, filterIndex:2, filterValue:filter.type}); + } + else { + ioFilters.push({set:filter.set, outputIndex:1, inputIndex:0, filterIndex:2, filterValue:filter.type}); + } + } + + // Return io-filters + return ioFilters; +} + + + +/** + * Create io-filters from an array of verb filters. + * @param {Array} rawFilters The array of filters. + * @returns {Array} The io-filters. + */ +function GetVerbFilters(rawFilters) { + // Expand "All Tenses" filters + let filters = []; // Format: [{set:"Verbs", tense:"specific tense", subject:"specific subject", type:"regex"}] + for (let filter of rawFilters) { + if (filter.tense.toLowerCase() === "all tenses") { + filters.push({ tense: "present participles", type: filter.type, subject: filter.subject, direction: filter.direction }); + filters.push({ tense: "present tense", type: filter.type, subject: filter.subject, direction: filter.direction }); + filters.push({ tense: "preterite tense", type: filter.type, subject: filter.subject, direction: filter.direction }); + filters.push({ tense: "imperfect tense", type: filter.type, subject: filter.subject, direction: filter.direction }); + filters.push({ tense: "simple future tense", type: filter.type, subject: filter.subject, direction: filter.direction }); + } + else { + filters.push({ tense: filter.tense.toLowerCase(), type: filter.type, subject: filter.subject, direction: filter.direction }); + } + } + + // Expand "All Subjects" filters + for (let filter of filters) { + if (filter.subject.toLowerCase() === "all subjects" && filter.tense !== "present participles") { + filter.subject = "yo"; + filters.push({ tense: filter.tense, type: filter.type, subject: "tú", direction: filter.direction }); + filters.push({ tense: filter.tense, type: filter.type, subject: "él", direction: filter.direction }); + filters.push({ tense: filter.tense, type: filter.type, subject: "nosotros", direction: filter.direction }); + filters.push({ tense: filter.tense, type: filter.type, subject: "ellos", direction: filter.direction }); + } + else { + filter.subject = filter.subject.toLowerCase(); + } + } + + // Replace regularities with regex filters + for (let filter of filters) { + switch (filter.type.toLowerCase()) { + case "regular": + filter.type = "Regular"; + break; + case "reflexive": + filter.type = "Reflexive"; + break; + case "irregular": + filter.type = "Irregular"; + break; + case "stem changing": + filter.type = "Stem.?Changing"; + break; + case "orthographic": + filter.type = "Orthographic"; + break; + case "nonregular": + filter.type = "Irregular|Stem.?Changing|Orthographic"; + break; + case "all types": + filter.type = ".*"; + break; + default: + throw `Unrecognized filter: ${filter.type}.`; + } + } + + // Create io-filters + let ioFilters = []; // Format: [{set:"Verbs", outputIndex:0, inputIndex:0, filterIndex:0, filterValue:"regex"}] + for (let filter of filters) { + // Get output index + let outputIndex; + if (filter.direction.toLowerCase().includes("eng")) { + outputIndex = 0; + } + else if (filter.direction.toLowerCase().includes("esp")) { + outputIndex = 1; + } + + // Get input index and filter index + let inputIndex; + let filterIndex; + switch (filter.tense) { + case "present participles": + filterIndex = 2; + switch (filter.subject) { + case "type": + inputIndex = filterIndex; + break; + default: + inputIndex = 3; + break; + } + break; + case "present tense": + filterIndex = 4; + switch (filter.subject) { + case "type": + inputIndex = filterIndex; + break; + case "yo": + inputIndex = 5; + break; + case "tú": + inputIndex = 6; + break; + case "él": + inputIndex = 7; + break; + case "nosotros": + inputIndex = 8; + break; + case "ellos": + inputIndex = 9; + break; + default: + throw `Unrecognized subject: ${filter.subject}.`; + } + break; + case "preterite tense": + filterIndex = 10; + switch (filter.subject) { + case "type": + inputIndex = filterIndex; + break; + case "yo": + inputIndex = 11; + break; + case "tú": + inputIndex = 12; + break; + case "él": + inputIndex = 13; + break; + case "nosotros": + inputIndex = 14; + break; + case "ellos": + inputIndex = 15; + break; + default: + throw `Unrecognized subject: ${filter.subject}.`; + } + break; + case "imperfect tense": + filterIndex = 16; + switch (filter.subject) { + case "type": + inputIndex = filterIndex; + break; + case "yo": + inputIndex = 17; + break; + case "tú": + inputIndex = 18; + break; + case "él": + inputIndex = 19; + break; + case "nosotros": + inputIndex = 20; + break; + case "ellos": + inputIndex = 21; + break; + default: + throw `Unrecognized subject: ${filter.subject}.`; + } + break; + case "simple future tense": + filterIndex = 22; + switch (filter.subject) { + case "type": + inputIndex = filterIndex; + break; + case "yo": + inputIndex = 23; + break; + case "tú": + inputIndex = 24; + break; + case "él": + inputIndex = 25; + break; + case "nosotros": + inputIndex = 26; + break; + case "ellos": + inputIndex = 27; + break; + default: + throw `Unrecognized subject: ${filter.subject}.`; + } + break; + + default: + throw `Unrecognized tense: ${filter.tense}.`; + } + + // Create filter + if (filter.direction.toLowerCase().startsWith("conj")) { + // Swap input and output + ioFilters.push({set:"Verbs", outputIndex:inputIndex, inputIndex:outputIndex, filterIndex:filterIndex, filterValue:filter.type}) + } + else { + ioFilters.push({set:"Verbs", outputIndex:outputIndex, inputIndex:inputIndex, filterIndex:filterIndex, filterValue:filter.type}) + } + } + + // Return io-filters + return ioFilters; +} + + + +/** + * Creates an array of prompts from an array of io-filters. + * @param {Object} terms The terms to filter. + * @param {Array} filters The io-filters. + * @returns {Array} The prompts. + */ +function ApplyFilters(terms, filters, multiplePrompts="Show together") { + // Filter terms + let results = []; // Format: [[<output label>, <output>, <input label>, <input>]] + for (let filter of filters) { + // Iterate over terms (minus headers) + for (let term of terms[filter.set].slice(1)) { + // Check against filters + if (term[filter.filterIndex].match(filter.filterValue)) { + results.push([terms[filter.set][0][filter.outputIndex], term[filter.outputIndex], terms[filter.set][0][filter.inputIndex], term[filter.inputIndex]]); + } + } + } + + // Iterate over prompts to enforce multiplePrompts setting + for (let result of results) { + // Get array of prompt outputs + let prompts = result[1].split(/\s*,\s*/); + + // Check if multiple outputs exist + if (prompts.length > 1) { + switch (multiplePrompts) { + case "Show one": + // Set current prompt's output to a random prompt + result[1] = prompts[Math.floor(Math.random() * (prompts.length - 1))] + break; + + case "Show separately": + result[1] = prompts[0]; // Set current prompt's output to 1st prompt + for (let prompt of prompts.splice(1)) { + // Add seperate prompts for extra outputs + results.push([result[0], prompt, result[2], result[3]]) + } + break; + + case "Show together": + default: + // Do nothing + break; + } + } + } + + // Return prompts + return results; +} + + + +/** + * Shuffles an array of items. + * @param {Array} items - The array. + */ +function Shuffle(items) { + // Initialize variables + var currentIndex = items.length; + var temp; + var randomIndex; + + // While there are more elements to shuffle + while (0 !== currentIndex) { + // Pick a remaining element + randomIndex = Math.floor(Math.random() * currentIndex); + currentIndex--; + + // Swap the two elements + temp = items[currentIndex]; + items[currentIndex] = items[randomIndex]; + items[randomIndex] = temp; + } + + // Return shuffled items + return items; +} diff --git a/js/global.js b/js/global.js @@ -3,20 +3,9 @@ * @param {Boolean} darkTheme - Whether to use the dark theme. If null, a theme will be automatically chosen. */ function SetTheme(darkTheme = null) { - // Get theme from localStorage if null + // Get theme if null if (darkTheme === null) { - try { - darkTheme = JSON.parse(localStorage.getItem("darkTheme")); - } - catch { } - } - - // Detect preferred color scheme if null - if (darkTheme === null) { - try { - darkTheme = (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) - } - catch { } + darkTheme = getSettings().darkTheme; } // Apply theme @@ -75,3 +64,76 @@ function Read(text, label) msg.lang = getLang(label); window.speechSynthesis.speak(msg); } + + + +/** + * Load settings from localStorage. + * @returns {Object} The settings. + */ +function getSettings() { + // Initialize settings + let settings = { + darkTheme: false, + promptType: "Text", + inputType: "Text", + onMissedPrompt: "Correct me", + repeatPrompts: "Never", + multiplePrompts: "Show together", + multipleAnswers: "Require all", + }; + + // Parse settings + let parsedSettings; + try { + parsedSettings = JSON.parse(localStorage.getItem("settings")); + } + catch { return settings; } + if (!parsedSettings) { return settings; } + + // Load settings + if ([true, false].includes(parsedSettings.darkTheme)) { + settings.darkTheme = parsedSettings.darkTheme; + } + else { + try { + settings.darkTheme = (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) + } + catch { } + } + if (["Text", "Audio", "Both"].includes(parsedSettings.promptType)) { + settings.promptType = parsedSettings.promptType; + } + if (["Text", "Voice", "Either"].includes(parsedSettings.inputType)) { + settings.inputType = parsedSettings.inputType; + } + if (["Correct me", "Tell me", "Ignore it"].includes(parsedSettings.onMissedPrompt)) { + settings.onMissedPrompt = parsedSettings.onMissedPrompt; + } + if (["Never", "Immediately", "5 prompts later", "At the end"].includes(parsedSettings.repeatPrompts)) { + settings.repeatPrompts = parsedSettings.repeatPrompts; + } + if (["Show together", "Show separately", "Show one"].includes(parsedSettings.multiplePrompts)) { + settings.multiplePrompts = parsedSettings.multiplePrompts; + } + if (["Require one", "Require any"].includes(parsedSettings.multipleAnswers)) { + settings.multipleAnswers = parsedSettings.multipleAnswers; + } + + // Return parsed settings + return settings; +} + + + +/** + * Save settings to localStorage. + * @param {Object} value The settings. + */ +function setSettings(value) { + // Update settings in localStorage + localStorage.setItem("settings", JSON.stringify(value)); + + // Apply theme + SetTheme(value.darkTheme); +} diff --git a/js/home.js b/js/home.js @@ -1,161 +0,0 @@ -// Declare global variables -let Sets; // List of parsed sets -let app; - - - -/** - * Initialize the Vue app - */ -function loadVue() { - app = new Vue({ - el: "#app", // Mount to app div - - data: { - state: "home", // Can be either "home", "settings", or "quizzer" - category: "verbs", // Can be either "verbs" or "vocab" - - settings: { - promptType: "Text", - inputType: "Text", - onMissedPrompt: "Correct me", - repeatPrompts: "Never", - multiplePrompts: "Show together", - multipleAnswers: "Require all", - }, - - prompts: [], - promptIndex: 0, - }, - - methods: { - /** - * Return to the previous state. - */ - Back: function() { - switch (app.state) { - case "quizzer": - case "congrats": - app.state = "settings"; - break; - case "settings": - case "home": - default: - app.state = "home"; - break; - } - }, - - /** - * Update the user's progress in localStorage. - * @param {Array} prompts - The list of prompts. - * @param {Number} index - The index of the current prompt. - */ - updateProgress: function(prompts, index) { - // Get localStorage prefix - let prefix = app.category === "verbs" ? "verb-" : "vocab-"; - - // Save progress to local storage - localStorage.setItem(prefix + "prompts", JSON.stringify(prompts)); - localStorage.setItem(prefix + "prompt", JSON.stringify(index)); - }, - - /** - * Perform validation checks and then start the quizzer. - * @param {Array} prompts - The list of prompts. - * @param {Number} promptIndex - The index of the current prompt. - * @param {Object} settings - The user's settings. - */ - StartSession: function(prompts, promptIndex, settings) { - // Validate browser for voice input - if (settings.inputType !== "Text") { - if ((window.SpeechRecognition || window.webkitSpeechRecognition || window.mozSpeechRecognition || window.msSpeechRecognition) === undefined) { - alert("Your browser does not support voice input."); - return; - } - } - - // Give iOS devices ringer warning for prompt audio - if (settings.promptType !== "Text") { - if (!!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform)) { - alert("Please make sure your ringer is on in order to hear audio prompts."); - } - } - - // Copy over parameters - this.prompts = prompts; - this.promptIndex = promptIndex; - this.settings = settings; - - // Show and hide elements (also enables the quizzer) - this.state = "quizzer"; - } - }, - }); -} - - - -/** - * Load the document. - */ -function Load() { - // Call LoadPage method from global.js - LoadPage(); - - // Initialize the Vue app - loadVue(); - - // Unhide hidden divs - // Divs were hidden to improve interface for users with JS blocked - document.getElementById("home").hidden = false; - document.getElementById("settings").hidden = false; - document.getElementById("quizzer").hidden = false; - document.getElementById("congrats").hidden = false; - document.querySelector("footer").hidden = false; - - // Add event Listeners - document.addEventListener("keydown", KeyDown); - - // Load CSVs - Sets = []; - let setNames = ["Verbs", "Adjectives", "Adverbs", "Prepositions", "Transitions", - "Colors", "Days", "Months", "Questions", "Weather", "Family", "Clothes", - "Nature", "House", "Vacation", "Childhood", "Professions", "Health"]; - for (let setName of setNames) { - Papa.parse(`vocab/${setName}.csv`, { - download: true, - complete: function(results) { - // Set verbs - Sets[setName] = results.data; - } - }); - } -} - - - -/** - * Handle a keyDown event (implements some keyboard shortcuts). - * @param {object} e - The event args. - */ -function KeyDown(e) { - if (e.key === "Escape") { - app.Back(); - } - - // Home shortcuts - if (app.state === "home") { - if (e.key === "c") { - app.category = "verbs"; - app.state = "settings"; - } - if (e.key === "v") { - app.category = "vocab"; - app.state = "settings"; - } - if (e.key === "r") { - window.location = "reference.html"; - } - } -} diff --git a/js/quizzer.js b/js/quizzer.js @@ -1,10 +1,5 @@ let quizzer = Vue.component("quizzer", { props: { - active: { - type: Boolean, - default: false, - }, - startingPrompts: { type: Array, default: function() { @@ -24,7 +19,7 @@ let quizzer = Vue.component("quizzer", { onMissedPrompt: "Correct me", repeatPrompts: "Never", multipleAnswers: "Require all", - } + }; }, }, }, @@ -38,33 +33,11 @@ let quizzer = Vue.component("quizzer", { }; }, - watch: { - /** - * Activates/deactivates the quizzer. - * @param {Boolean} value - The boolean value. - */ - active: function(value) { - if (value) { - // Update prompts - this.prompts = this.startingPrompts; - this.index = this.startingIndex - 1; - - // Reset quizzer - this.Reset(); - } - }, - }, - methods: { /** * Handles keyup events and implements quizzer keyboard shortcuts. */ keyup: function(e) { - // Check if Quizzer is active - if (!this.active) { - return; - } - if (e.keyCode === 13 && e.ctrlKey) { this.Reset(); } @@ -77,11 +50,6 @@ let quizzer = Vue.component("quizzer", { * Give the user the next prompt and reset the quizzer. */ Reset: function() { - // Check if Quizzer is active - if (!this.active) { - return; - } - // Show and hide elements this.responceActive = true; try { @@ -145,11 +113,6 @@ let quizzer = Vue.component("quizzer", { * Process the user's responce. */ Submit: function() { - // Check if Quizzer is active - if (!this.active) { - return; - } - // Parse responce let responce = this.responce.toLowerCase(); // Make responce lowercase responce = responce.replace(/a`/g, "á"); // Apply accented a shortcut @@ -212,11 +175,6 @@ let quizzer = Vue.component("quizzer", { * Process an incorrect responce and then reset the quizzer. */ Continue: function() { - // Check if Quizzer is active - if (!this.active) { - return; - } - // Repeat prompt switch (this.settings.repeatPrompts) { @@ -251,11 +209,6 @@ let quizzer = Vue.component("quizzer", { * Calls Submit or Continue depending on the value of responceActive. */ Enter: function() { - // Check if Quizzer is active - if (!this.active) { - return; - } - if (this.responceActive) { this.Submit(); } @@ -283,6 +236,13 @@ let quizzer = Vue.component("quizzer", { created: function() { // Add keyup handler window.addEventListener("keyup", this.keyup); + + // Update prompts + this.prompts = this.startingPrompts; + this.index = this.startingIndex - 1; + + // Reset quizzer + this.Reset(); }, destroyed: function() { diff --git a/js/settings.js b/js/settings.js @@ -1,856 +0,0 @@ -let settings = Vue.component("settings", { - props: { - category: { - type: String, - default: "verbs", - }, - }, - - data: function() { - return { - darkTheme: document.body.classList.contains("dark"), - verbFilters: [], - vocabFilters: [], - settings: { - promptType: "Text", - inputType: "Text", - onMissedPrompt: "Correct me", - repeatPrompts: "Never", - multiplePrompts: "Show together", - multipleAnswers: "Require all", - }, - }; - }, - - methods: { - /** - * Add a filter to the settings page. - */ - AddFilter: function() { - if (this.category === "verbs") { - this.verbFilters.push({tense:"All Tenses", type:"All Types", subject:"All Subjects", direction:"Eng. → Conj."}); - } - else if (this.category === "vocab") { - this.vocabFilters.push({set:"All Sets", type:"All Types", direction:"Eng. ↔ Esp."}); - } - }, - - /** - * Remove a filter from the settings page. - * @param {Number} index - The index of the verb filter. - */ - RemoveFilter: function(index) { - if (this.category === "verbs") { - this.verbFilters.splice(index, 1); - } - else if (this.category === "vocab") { - this.vocabFilters.splice(index, 1); - } - }, - - /** - * Get the regularity filters available for a verb filter. - * @param {Number} index - The index of the verb filter. - * @returns {object} - An object with boolean properties for each regularity filter. - */ - getTenseTypes: function(index) { - // Get filter options - let filters = {"All Types":true, "Reflexive":true, "Regular":true, "Nonregular":true, "Stem Changing":true, "Orthographic":true, "Irregular":true} - switch(this.verbFilters[index].tense) - { - case "All Tenses": - break; - case "Present Participles": - filters["Reflexive"] = false; // Reflexive - filters["Orthographic"] = false; // Orthographic - break; - case "Present Tense": - filters["Orthographic"] = false; // Orthographic - break; - case "Preterite Tense": - break; - case "Imperfect Tense": - filters["Stem Changing"] = false; // Stem Changing - filters["Orthographic"] = false; // Orthographic - break; - case "Simple Future Tense": - filters["Stem Changing"] = false; // Stem Changing - filters["Orthographic"] = false; // Orthographic - break; - } - - // Reset type if needed - if (!filters[this.verbFilters[index].type]) { - this.verbFilters[index].type = "All Types"; - } - - // Return filters - return filters; - }, - - /** - * Get the subject filters available for a verb filter. - * @param {Number} index - The index of the verb filter. - * @returns {object} - An object with boolean properties for each subject filter. - */ - getTenseSubjects: function(index) { - // Set default filters - let filters = {"All Subjects":true, "Type":true, "Yo":true, "Tú":true, "Él":true, "Nosotros":true, "Ellos":true} - - if (this.verbFilters[index].tense === "Present Participles") { - // Override filters - filters["Yo"] = false; - filters["Tú"] = false; - filters["Él"] = false; - filters["Nosotros"] = false; - filters["Ellos"] = false; - } - - // Reset subject - if (this.verbFilters[index].tense === "Present Participles" && this.verbFilters[index].subject !== "Type") { - this.verbFilters[index].subject = "All Subjects"; - } - - // Return filters - return filters; - }, - - /** - * Get the filters available for a vocab Set. - * @param {Number} index - The index of the vocab filter. - * @returns {Array} - An array containing available filters. - */ - getSetFilters: function(index) { - // Get filter options - let filters = {"All Types":true, "Adjectives":true, "Nouns":true, "Verbs":true} - switch(this.vocabFilters[index].set) - { - case "Verbs": - filters["Adjectives"] = false; - filters["Nouns"] = false; - filters["Verbs"] = false; - break; - - case "Adjectives": - filters["Nouns"] = false; - filters["Verbs"] = false; - break; - - case "Adverbs": - filters["Adjectives"] = false; - filters["Nouns"] = false; - filters["Verbs"] = false; - break; - - case "Prepositions": - case "Transitions": - case "Questions": - filters["Adjectives"] = false; - filters["Nouns"] = false; - filters["Verbs"] = false; - break; - - case "Colors": - filters["Nouns"] = false; - filters["Verbs"] = false; - break; - - case "Days": - case "Months": - filters["Adjectives"] = false; - filters["Verbs"] = false; - break; - - case "Weather": - case "Professions": - filters["Adjectives"] = false; - break; - - case "Family": - case "Clothes": - filters["Verbs"] = false; - break; - - case "Nature": - case "House": - case "Vacation": - case "Childhood": - case "Health": - break; - } - - // Reset type if needed - if (!filters[this.vocabFilters[index].type]) { - this.vocabFilters[index].type = "All Types"; - } - - // Return filters - return filters; - }, - - /** - * Start a new quizzer session - */ - CreateSession: function() { - // Get prompts - let prompts; - if (this.category === "vocab") { - prompts = Shuffle(ApplyFilters(Sets, GetVocabFilters(this.vocabFilters), this.settings.multiplePrompts)); - } - else if (this.category === "verbs") { - // Get prompts - prompts = Shuffle(ApplyFilters(Sets, GetVerbFilters(this.verbFilters), this.settings.multiplePrompts)); - } - - // Set progress - let promptIndex = 0; - - // Validate prompts - if (prompts.length === 0) { - alert("Your custom vocabulary set must contain at least one term."); - return; - } - - // Start quizzer - this.$emit("start-session", prompts, promptIndex, this.settings); - }, - - /** - * Resume the previous quizzer session. - */ - ResumeSession: function() { - // Get localStorage prefix - let prefix; - if (this.category === "vocab") { - prefix = "vocab-" - } - else if (this.category === "verbs") { - prefix = "verb-" - } - - // Load prompts and progress - let prompts = JSON.parse(localStorage.getItem(prefix + "prompts")); - let promptIndex = parseInt(localStorage.getItem(prefix + "prompt")); - - // Validate prompts and promptIndex - if (!prompts) { - alert("An error occured while resuming the previous session."); - return; - } - else if (prompts.length === 0) { - alert("Your custom vocabulary set must contain at least one term."); - return; - } - else if (isNaN(promptIndex) || promptIndex < 0 || promptIndex >= prompts.length) { - alert("An error occured while resuming the previous session."); - return; - } - - // Start quizzer - this.$emit("start-session", prompts, promptIndex, this.settings); - }, - - /** - * Implements keyboard shortcuts. - */ - keyup: function(e) { - try { - if (window.getComputedStyle(this.$refs.container).display === "none") { - return; - } - } - catch { - // Will fail if not mounted - return; - } - - if (e.key === "s") { - this.CreateSession(); - } - if (e.key === "r") { - this.ResumeSession(); - } - } - }, - - watch: { - /** - * Update the app theme. - */ - darkTheme: function(value) { - SetTheme(value); - }, - - /** - * Update setting in localStorage. - * @param {String} value - The settings object. - */ - settings: { - handler: function(value) { - localStorage.setItem("settings", JSON.stringify(value)); - }, - deep: true, - }, - }, - - created: function() { - // Add keyup handler - window.addEventListener("keyup", this.keyup); - - // Parse settings - let parsedSettings - try { - parsedSettings = JSON.parse(localStorage.getItem("settings")); - } - catch { return; } - if (!parsedSettings) { return; } - - // Load settings - if (parsedSettings.promptType && ["Text", "Audio", "Both"].includes(parsedSettings.promptType)) { - this.settings.promptType = parsedSettings.promptType; - } - if (parsedSettings.inputType && ["Text", "Voice", "Either"].includes(parsedSettings.inputType)) { - this.settings.inputType = parsedSettings.inputType; - } - if (parsedSettings.onMissedPrompt && ["Correct me", "Tell me", "Ignore it"].includes(parsedSettings.onMissedPrompt)) { - this.settings.onMissedPrompt = parsedSettings.onMissedPrompt; - } - if (parsedSettings.repeatPrompts && ["Never", "Immediately", "5 prompts later", "At the end"].includes(parsedSettings.repeatPrompts)) { - this.settings.repeatPrompts = parsedSettings.repeatPrompts; - } - if (parsedSettings.multiplePrompts && ["Show together", "Show separately", "Show one"].includes(parsedSettings.multiplePrompts)) { - this.settings.multiplePrompts = parsedSettings.multiplePrompts; - } - if (parsedSettings.multipleAnswers && ["Require one", "Require any"].includes(parsedSettings.multipleAnswers)) { - this.settings.multipleAnswers = parsedSettings.multipleAnswers; - } - }, - - destroyed: function() { - // Remove keyup handler - window.removeEventListener("keyup", this.keyup); - }, - - template: ` - <div class="settings" ref="container"> - <div class="verbSettings" v-show="category === 'verbs'"> - <h1>Choose your settings and then click start.</h1> - - <h2> - Verb Filters - <button @click="AddFilter();">Add Filter</button> - </h2> - - <div v-for="(filter, index) in verbFilters" class="filter"> - <select v-model="filter.tense"> - <option>All Tenses</option> - <option>Present Participles</option> - <option>Present Tense</option> - <option>Preterite Tense</option> - <option>Imperfect Tense</option> - <option>Simple Future Tense</option> - </select> - <select v-model="filter.type"> - <option v-for="(available, type) in getTenseTypes(index)" :disabled="!available">{{ type }}</option> - </select> - <select v-model="filter.subject"> - <option v-for="(available, subject) in getTenseSubjects(index)" :disabled="!available">{{ subject }}</option> - </select> - <select v-model="filter.direction"> - <option>Eng. → Conj.</option> - <option>Esp. → Conj.</option> - <option>Conj. → Eng.</option> - <option>Conj. → Esp.</option> - </select> - <button class="itemRemove" @click="RemoveFilter(index);">╳</button> - </div> - </div> - - - <div class="vocabSettings" v-show="category === 'vocab'"> - <h1>Choose your settings and then click start.</h1> - - <h2> - Vocabulary Sets - <button @click="AddFilter();">Add set</button> - </h2> - - <div v-for="(filter, index) in vocabFilters" class="filter"> - <select class="vocabSetName" v-model="filter.set"> - <option>All Sets</option> - <optgroup label="Common Words"> - <option>Adjectives</option> - <option>Adverbs</option> - <option>Prepositions</option> - <option>Transitions</option> - <option>Verbs</option> - </optgroup> - <optgroup label="Basic Words"> - <option>Colors</option> - <option>Days</option> - <option>Months</option> - <option>Questions</option> - </optgroup> - <optgroup label="Advanced Words"> - <option>Childhood</option> - <option>Clothes</option> - <option>Family</option> - <option>Health</option> - <option>House</option> - <option>Nature</option> - <option>Professions</option> - <option>Vacation</option> - <option>Weather</option> - </optgroup> - </select> - <select v-model="filter.type"> - <option v-for="(available, type) in getSetFilters(index)" :disabled="!available">{{ type }}</option> - </select> - <select v-model="filter.direction"> - <option>Eng. ↔ Esp.</option> - <option>Eng. → Esp.</option> - <option>Esp. → Eng.</option> - </select> - <button class="itemRemove" @click="RemoveFilter(index);">╳</button> - </div> - </div> - - - <div class="quizzerSettings"> - <h2>Quizzer Settings</h2> - - <div> - <input type="checkbox" id="settingsDarkTheme" v-model="darkTheme"> - <label for="settingsDarkTheme">Dark Mode</label> - </div> - <div> - <label for="settingsPromptType">Prompt type</label> - <select id="settingsPromptType" v-model="settings.promptType"> - <option>Text</option> - <option>Audio</option> - <option>Both</option> - </select> - </div> - <div> - <label for="settingsInputType">Input type</label> - <select id="settingsInputType" v-model="settings.inputType"> - <option>Text</option> - <option>Voice</option> - <option>Either</option> - </select> - </div> - <div> - <label for="settingsOnMissedPrompt">When I miss a prompt</label> - <select id="settingsOnMissedPrompt" v-model="settings.onMissedPrompt"> - <option>Correct me</option> - <option>Tell me</option> - <option>Ignore it</option> - </select> - </div> - <div> - <label for="settingsRepeatPrompts">Repeat missed prompts</label> - <select id="settingsRepeatPrompts" v-model="settings.repeatPrompts"> - <option>Never</option> - <option>Immediately</option> - <option>5 prompts later</option> - <option>At the end</option> - </select> - </div> - <div> - <label for="settingsMultiplePrompts">Multiple prompts</label> - <select id="settingsMultiplePrompts" v-model="settings.multiplePrompts"> - <option>Show together</option> - <option>Show separately</option> - <option>Show one</option> - </select> - </div> - <div> - <label for="settingsMultipleAnswers">Multiple answers</label> - <select id="settingsMultipleAnswers" v-model="settings.multipleAnswers"> - <option>Require all</option> - <option>Require any</option> - </select> - </div> - </div> - - <div class="settingButtons"> - <button class="settingsStart" @click="CreateSession();">Start</button> - <button class="settingsResume" @click="ResumeSession();">Resume</button> - </div> - </div> - `, -}); - - - -/** - * Create io-filters from an array of vocab filters. - * @param {Array} rawFilters The array of filters. - * @returns {Array} The io-filters. - */ -function GetVocabFilters(rawFilters) { - // Expand "All Sets" filters - let filters = []; // Format: [{set:"vocab set name", tense:"specific tense", subject:"specific subject", type:"regex"}] - for (let filter of rawFilters) { - if (filter.set === "All Sets") { - filters.push({set:"Verbs", type: filter.type, direction:filter.direction}); - filters.push({set:"Adjectives", type: filter.type, direction:filter.direction}); - filters.push({set:"Adverbs", type: filter.type, direction:filter.direction}); - filters.push({set:"Prepositions", type: filter.type, direction:filter.direction}); - filters.push({set:"Transitions", type: filter.type, direction:filter.direction}); - filters.push({set:"Colors", type: filter.type, direction:filter.direction}); - filters.push({set:"Days", type: filter.type, direction:filter.direction}); - filters.push({set:"Months", type: filter.type, direction:filter.direction}); - filters.push({set:"Questions", type: filter.type, direction:filter.direction}); - filters.push({set:"Weather", type: filter.type, direction:filter.direction}); - filters.push({set:"Family", type: filter.type, direction:filter.direction}); - filters.push({set:"Clothes", type: filter.type, direction:filter.direction}); - filters.push({set:"Nature", type: filter.type, direction:filter.direction}); - filters.push({set:"House", type: filter.type, direction:filter.direction}); - filters.push({set:"Vacation", type: filter.type, direction:filter.direction}); - filters.push({set:"Childhood", type: filter.type, direction:filter.direction}); - filters.push({set:"Professions", type: filter.type, direction:filter.direction}); - filters.push({set:"Health", type: filter.type, direction:filter.direction}); - } - else { - filters.push({set:filter.set, type: filter.type, direction:filter.direction}); - } - } - - // Expand "All directions" filters - for (let filter of filters) { - if (filter.direction === "Eng. ↔ Esp.") { - filter.direction = "Eng. → Esp."; - filters.push({set:filter.set, type: filter.type, direction:"Esp. → Eng."}); - } - } - - // Get type regex filter - for (let filter of filters) { - switch (filter.type.toLowerCase()) { - case "adjectives": - filter.type = "Adjective"; - break; - case "nouns": - filter.type = "Noun"; - break; - case "verbs": - filter.type = "Verb"; - break; - case "all types": - filter.type = ".*"; - break; - default: - throw `Unrecognized filter: ${type}.`; - } - } - - // Create io-filters - let ioFilters = []; // Format: [{set:"vocab set name", outputIndex:0, inputIndex:0, filterIndex:0, filterValue:"regex"}] - for (let filter of filters) { - // Create filter - if (filter.direction.toLowerCase().startsWith("eng")) { - ioFilters.push({set:filter.set, outputIndex:0, inputIndex:1, filterIndex:2, filterValue:filter.type}); - } - else { - ioFilters.push({set:filter.set, outputIndex:1, inputIndex:0, filterIndex:2, filterValue:filter.type}); - } - } - - // Return io-filters - return ioFilters; -} - - - -/** - * Create io-filters from an array of verb filters. - * @param {Array} rawFilters The array of filters. - * @returns {Array} The io-filters. - */ -function GetVerbFilters(rawFilters) { - // Expand "All Tenses" filters - let filters = []; // Format: [{set:"Verbs", tense:"specific tense", subject:"specific subject", type:"regex"}] - for (let filter of rawFilters) { - if (filter.tense.toLowerCase() === "all tenses") { - filters.push({ tense: "present participles", type: filter.type, subject: filter.subject, direction: filter.direction }); - filters.push({ tense: "present tense", type: filter.type, subject: filter.subject, direction: filter.direction }); - filters.push({ tense: "preterite tense", type: filter.type, subject: filter.subject, direction: filter.direction }); - filters.push({ tense: "imperfect tense", type: filter.type, subject: filter.subject, direction: filter.direction }); - filters.push({ tense: "simple future tense", type: filter.type, subject: filter.subject, direction: filter.direction }); - } - else { - filters.push({ tense: filter.tense.toLowerCase(), type: filter.type, subject: filter.subject, direction: filter.direction }); - } - } - - // Expand "All Subjects" filters - for (let filter of filters) { - if (filter.subject.toLowerCase() === "all subjects" && filter.tense !== "present participles") { - filter.subject = "yo"; - filters.push({ tense: filter.tense, type: filter.type, subject: "tú", direction: filter.direction }); - filters.push({ tense: filter.tense, type: filter.type, subject: "él", direction: filter.direction }); - filters.push({ tense: filter.tense, type: filter.type, subject: "nosotros", direction: filter.direction }); - filters.push({ tense: filter.tense, type: filter.type, subject: "ellos", direction: filter.direction }); - } - else { - filter.subject = filter.subject.toLowerCase(); - } - } - - // Replace regularities with regex filters - for (let filter of filters) { - switch (filter.type.toLowerCase()) { - case "regular": - filter.type = "Regular"; - break; - case "reflexive": - filter.type = "Reflexive"; - break; - case "irregular": - filter.type = "Irregular"; - break; - case "stem changing": - filter.type = "Stem.?Changing"; - break; - case "orthographic": - filter.type = "Orthographic"; - break; - case "nonregular": - filter.type = "Irregular|Stem.?Changing|Orthographic"; - break; - case "all types": - filter.type = ".*"; - break; - default: - throw `Unrecognized filter: ${filter.type}.`; - } - } - - // Create io-filters - let ioFilters = []; // Format: [{set:"Verbs", outputIndex:0, inputIndex:0, filterIndex:0, filterValue:"regex"}] - for (let filter of filters) { - // Get output index - let outputIndex; - if (filter.direction.toLowerCase().includes("eng")) { - outputIndex = 0; - } - else if (filter.direction.toLowerCase().includes("esp")) { - outputIndex = 1; - } - - // Get input index and filter index - let inputIndex; - let filterIndex; - switch (filter.tense) { - case "present participles": - filterIndex = 2; - switch (filter.subject) { - case "type": - inputIndex = filterIndex; - break; - default: - inputIndex = 3; - break; - } - break; - case "present tense": - filterIndex = 4; - switch (filter.subject) { - case "type": - inputIndex = filterIndex; - break; - case "yo": - inputIndex = 5; - break; - case "tú": - inputIndex = 6; - break; - case "él": - inputIndex = 7; - break; - case "nosotros": - inputIndex = 8; - break; - case "ellos": - inputIndex = 9; - break; - default: - throw `Unrecognized subject: ${filter.subject}.`; - } - break; - case "preterite tense": - filterIndex = 10; - switch (filter.subject) { - case "type": - inputIndex = filterIndex; - break; - case "yo": - inputIndex = 11; - break; - case "tú": - inputIndex = 12; - break; - case "él": - inputIndex = 13; - break; - case "nosotros": - inputIndex = 14; - break; - case "ellos": - inputIndex = 15; - break; - default: - throw `Unrecognized subject: ${filter.subject}.`; - } - break; - case "imperfect tense": - filterIndex = 16; - switch (filter.subject) { - case "type": - inputIndex = filterIndex; - break; - case "yo": - inputIndex = 17; - break; - case "tú": - inputIndex = 18; - break; - case "él": - inputIndex = 19; - break; - case "nosotros": - inputIndex = 20; - break; - case "ellos": - inputIndex = 21; - break; - default: - throw `Unrecognized subject: ${filter.subject}.`; - } - break; - case "simple future tense": - filterIndex = 22; - switch (filter.subject) { - case "type": - inputIndex = filterIndex; - break; - case "yo": - inputIndex = 23; - break; - case "tú": - inputIndex = 24; - break; - case "él": - inputIndex = 25; - break; - case "nosotros": - inputIndex = 26; - break; - case "ellos": - inputIndex = 27; - break; - default: - throw `Unrecognized subject: ${filter.subject}.`; - } - break; - - default: - throw `Unrecognized tense: ${filter.tense}.`; - } - - // Create filter - if (filter.direction.toLowerCase().startsWith("conj")) { - // Swap input and output - ioFilters.push({set:"Verbs", outputIndex:inputIndex, inputIndex:outputIndex, filterIndex:filterIndex, filterValue:filter.type}) - } - else { - ioFilters.push({set:"Verbs", outputIndex:outputIndex, inputIndex:inputIndex, filterIndex:filterIndex, filterValue:filter.type}) - } - } - - // Return io-filters - return ioFilters; -} - - - -/** - * Creates an array of prompts from an array of io-filters. - * @param {Object} terms The terms to filter. - * @param {Array} filters The io-filters. - * @returns {Array} The prompts. - */ -function ApplyFilters(terms, filters, multiplePrompts="Show together") { - // Filter terms - let results = []; // Format: [[<output label>, <output>, <input label>, <input>]] - for (let filter of filters) { - // Iterate over terms (minus headers) - for (let term of terms[filter.set].slice(1)) { - // Check against filters - if (term[filter.filterIndex].match(filter.filterValue)) { - results.push([terms[filter.set][0][filter.outputIndex], term[filter.outputIndex], terms[filter.set][0][filter.inputIndex], term[filter.inputIndex]]); - } - } - } - - // Iterate over prompts to enforce multiplePrompts setting - for (let result of results) { - // Get array of prompt outputs - let prompts = result[1].split(/\s*,\s*/); - - // Check if multiple outputs exist - if (prompts.length > 1) { - switch (multiplePrompts) { - case "Show one": - // Set current prompt's output to a random prompt - result[1] = prompts[Math.floor(Math.random() * (prompts.length - 1))] - break; - - case "Show separately": - result[1] = prompts[0]; // Set current prompt's output to 1st prompt - for (let prompt of prompts.splice(1)) { - // Add seperate prompts for extra outputs - results.push([result[0], prompt, result[2], result[3]]) - } - break; - - case "Show together": - default: - // Do nothing - break; - } - } - } - - // Return prompts - return results; -} - - - -/** - * Shuffles an array of items. - * @param {Array} items - The array. - */ -function Shuffle(items) { - // Initialize variables - var currentIndex = items.length; - var temp; - var randomIndex; - - // While there are more elements to shuffle - while (0 !== currentIndex) { - // Pick a remaining element - randomIndex = Math.floor(Math.random() * currentIndex); - currentIndex--; - - // Swap the two elements - temp = items[currentIndex]; - items[currentIndex] = items[randomIndex]; - items[randomIndex] = temp; - } - - // Return shuffled items - return items; -} diff --git a/js/settingsInput.js b/js/settingsInput.js @@ -0,0 +1,77 @@ +let settingsInput = Vue.component("settingsInput", { + props: { + value: { + type: Object, + default: getSettings(), + }, + }, + + watch: { + value: { + handler: function(value) { + setSettings(value); + + this.$emit("input", value); + }, + deep: true, + }, + }, + + template: ` + <div class="settingsInput" ref="container"> + <h2>Quizzer Settings</h2> + <div> + <input type="checkbox" id="settingsDarkTheme" v-model="value.darkTheme"> + <label for="settingsDarkTheme">Dark Mode</label> + </div> + <div> + <label for="settingsPromptType">Prompt type</label> + <select id="settingsPromptType" v-model="value.promptType"> + <option>Text</option> + <option>Audio</option> + <option>Both</option> + </select> + </div> + <div> + <label for="settingsInputType">Input type</label> + <select id="settingsInputType" v-model="value.inputType"> + <option>Text</option> + <option>Voice</option> + <option>Either</option> + </select> + </div> + <div> + <label for="settingsOnMissedPrompt">When I miss a prompt</label> + <select id="settingsOnMissedPrompt" v-model="value.onMissedPrompt"> + <option>Correct me</option> + <option>Tell me</option> + <option>Ignore it</option> + </select> + </div> + <div> + <label for="settingsRepeatPrompts">Repeat missed prompts</label> + <select id="settingsRepeatPrompts" v-model="value.repeatPrompts"> + <option>Never</option> + <option>Immediately</option> + <option>5 prompts later</option> + <option>At the end</option> + </select> + </div> + <div> + <label for="settingsMultiplePrompts">Multiple prompts</label> + <select id="settingsMultiplePrompts" v-model="value.multiplePrompts"> + <option>Show together</option> + <option>Show separately</option> + <option>Show one</option> + </select> + </div> + <div> + <label for="settingsMultipleAnswers">Multiple answers</label> + <select id="settingsMultipleAnswers" v-model="value.multipleAnswers"> + <option>Require all</option> + <option>Require any</option> + </select> + </div> + </div> + `, +}); diff --git a/tests/index.html b/tests/index.html @@ -17,9 +17,11 @@ <!-- Scripts being tested --> <script src="../js/global.js"></script> - <script src="../js/home.js"></script> + <script src="../js/app.js"></script> + <script src="../js/filterInput.js"></script> + <script src="../js/settingsInput.js"></script> + <script src="../js/filters.js"></script> <script src="../js/quizzer.js"></script> - <script src="../js/settings.js"></script> <!-- Setup tests --> <script class="mocha-init"> @@ -31,9 +33,11 @@ <!-- Tests --> <script src="test.global.js"></script> <script src="test.app.js"></script> - <script src="test.settings.js"></script> + <script src="test.filterInput.js"></script> + <script src="test.settingsInput.js"></script> + <script src="test.filters.js"></script> <script src="test.quizzer.js"></script> - + <!-- Run tests --> <script class="mocha-exec"> mocha.run(); diff --git a/tests/test.app.js b/tests/test.app.js @@ -8,18 +8,13 @@ describe("App", function() { it("State should be 'home'", function() { expect(app.state).to.equal("home"); }); - + it("Category should be 'verbs'", function() { expect(app.category).to.equal("verbs"); }); - - it("Settings should be correct", function() { - expect(app.settings.promptType).to.equal("Text"); - expect(app.settings.inputType).to.equal("Text"); - expect(app.settings.onMissedPrompt).to.equal("Correct me"); - expect(app.settings.repeatPrompts).to.equal("Never"); - expect(app.settings.multiplePrompts).to.equal("Show together"); - expect(app.settings.multipleAnswers).to.equal("Require all"); + + it("Settings should be correctly loaded", function() { + expect(app.settings).to.deep.equal(getSettings()); }); it("Prompts should be empty", function() { @@ -37,12 +32,12 @@ describe("App", function() { app.state = "home"; app.Back(); expect(app.state).to.equal("home"); - + // Set state and test Back method again app.state = ""; app.Back(); expect(app.state).to.equal("home"); - + // Set state and test Back method again app.state = "test"; app.Back(); @@ -55,7 +50,7 @@ describe("App", function() { app.Back(); expect(app.state).to.equal("home"); }); - + it("Should go to settings when on quizzer", function() { // Set state and test Back method app.state = "quizzer"; @@ -65,23 +60,12 @@ describe("App", function() { }); describe("StartSession method", function() { - it("Should import parameter values", function() { - // Call StartSession - app.StartSession([1, 2, 3], 4, { - promptType: "Text", // Required to prevent browser validation alerts - inputType: "Text", // Required to prevent browser validation alerts - testSetting: "testValue", - }); - - // Assert parameters imported - expect(app.prompts).to.have.members([1, 2, 3]); - expect(app.promptIndex).to.equal(4); - expect(app.settings.testSetting).to.equal("testValue"); - }); - it("Should set state to 'quizzer'", function() { // Initialize settings app.state = "settings"; + app.settings.inputType = "Text"; + app.settings.promptType = "Text"; + app.prompts = ["prompt1", "prompt2", "prompt3"]; // Call StartSession app.StartSession([1, 2, 3], 4, { diff --git a/tests/test.filterInput.js b/tests/test.filterInput.js @@ -0,0 +1,378 @@ +describe("FilterInput", function() { + let FilterInput; + beforeEach(function() { + // Create filtersInput component + FilterInput = new filterInput(); + }); + + describe("Created lifecycle hook", function() { + it("Category should be 'verbs'", function() { + expect(FilterInput.category).to.equal("verbs"); + }); + + it("VerbFilters should be empty", function() { + expect(FilterInput.verbFilters.length).to.equal(0); + }); + + it("VocabFilters should be empty", function() { + expect(FilterInput.vocabFilters.length).to.equal(0); + }); + }); + + describe("Value computed property", function() { + it("Should return verb filters if category is 'verbs'", function() { + // Initialize variables + FilterInput.category = "verbs"; + FilterInput.verbFilters = "verb-filters"; + FilterInput.vocabFilters = "vocab-filters"; + + // Assert value returns verb filters + expect(FilterInput.value, "verb-filters"); + }); + + it("Should return vocab filters if category is 'vocab'", function() { + // Initialize variables + FilterInput.category = "vocab"; + FilterInput.verbFilters = "verb-filters"; + FilterInput.vocabFilters = "vocab-filters"; + + // Assert value returns vocab filters + expect(FilterInput.value, "vocab-filters"); + }); + }); + + describe("Value watch", function() { + it("Should emit input event", async function() { + // Initialize variables + FilterInput.category = "verbs"; + FilterInput.verbFilters = ["filter1"]; + + // Override $emit method + let event = ""; + let event_args; + FilterInput.$emit = function(name, value) { + event = name; + event_args = value; + }; + + // Edit verb filters + FilterInput.verbFilters.push("filter2"); + await FilterInput.$nextTick(); + + // Assert event emited + expect(event).to.equal("input"); + expect(event_args).to.have.deep.members(["filter1", "filter2"]); + }); + }); + + describe("AddFilter method", function() { + it("Should add a verb filter if category is 'verbs'", function() { + // Initialize variables + FilterInput.category = "verbs"; + expect(FilterInput.verbFilters.length).to.equal(0); + expect(FilterInput.vocabFilters.length).to.equal(0); + + // Add filter + FilterInput.AddFilter(); + + // Assert filter added + expect(FilterInput.verbFilters).to.have.deep.members([ + {tense:"All Tenses", type:"All Types", subject:"All Subjects", direction:"Eng. → Conj."}, + ]); + expect(FilterInput.vocabFilters).to.have.deep.members([]); + }); + + it("Should add a vocab filter if category is 'vocab'", function() { + // Initialize variables + FilterInput.category = "vocab"; + expect(FilterInput.verbFilters.length).to.equal(0); + expect(FilterInput.vocabFilters.length).to.equal(0); + + // Add filter + FilterInput.AddFilter(); + + // Assert filter added + expect(FilterInput.vocabFilters).to.have.deep.members([ + {set:"All Sets", type:"All Types", direction:"Eng. ↔ Esp."}, + ]); + expect(FilterInput.verbFilters).to.have.deep.members([]); + }); + }); + + describe("RemoveFilter method", function() { + it("Should remove the specified verb filter", function() { + // Initialize filters + FilterInput.category = "verbs"; + FilterInput.verbFilters = [ + "verb1", + "verb2", + "verb3", + ]; + FilterInput.vocabFilters = [ + "vocab1", + "vocab2", + "vocab3", + ]; + + // Remove filter + FilterInput.RemoveFilter(1); + + // Assert filter removed + expect(FilterInput.verbFilters.length).to.equal(2); + expect(FilterInput.verbFilters[0]).to.equal("verb1"); + expect(FilterInput.verbFilters[1]).to.equal("verb3"); + expect(FilterInput.vocabFilters.length).to.equal(3); + }); + + it("Should remove the specified vocab filter", function() { + // Initialize filters + FilterInput.category = "vocab"; + FilterInput.verbFilters = [ + "verb1", + "verb2", + "verb3", + ]; + FilterInput.vocabFilters = [ + "vocab1", + "vocab2", + "vocab3", + ]; + + // Remove filter + FilterInput.RemoveFilter(1); + + // Assert filter removed + expect(FilterInput.verbFilters.length).to.equal(3); + expect(FilterInput.vocabFilters.length).to.equal(2); + expect(FilterInput.vocabFilters[0]).to.equal("vocab1"); + expect(FilterInput.vocabFilters[1]).to.equal("vocab3"); + }); + }); + + describe("GetTenseTypes method", function() { + it("Should be correct for All Tenses", function() { + // Initialize filters + FilterInput.verbFilters = [ + {"tense":"All Types", "type":"All Types"} + ] + + // Get filters + let filters = FilterInput.getTenseTypes(0); + + // Assert filters are correct + expect(filters["All Types"]).to.equal(true); + expect(filters["Reflexive"]).to.equal(true); + expect(filters["Regular"]).to.equal(true); + expect(filters["Nonregular"]).to.equal(true); + expect(filters["Stem Changing"]).to.equal(true); + expect(filters["Orthographic"]).to.equal(true); + expect(filters["Irregular"]).to.equal(true); + }); + + it("Should be correct for Present Tense", function() { + // Initialize filters + FilterInput.verbFilters = [ + {"tense":"Present Tense", "type":"All Types"} + ] + + // Get filters + let filters = FilterInput.getTenseTypes(0); + + // Assert filters are correct + expect(filters["All Types"]).to.equal(true); + expect(filters["Reflexive"]).to.equal(true); + expect(filters["Regular"]).to.equal(true); + expect(filters["Nonregular"]).to.equal(true); + expect(filters["Stem Changing"]).to.equal(true); + expect(filters["Orthographic"]).to.equal(false); + expect(filters["Irregular"]).to.equal(true); + }); + + it("Should change selection if not available", function() { + // Initialize filters + FilterInput.verbFilters = [ + {"tense":"Present Tense", "type":"Orthographic"} + ] + + // Get filters + let filters = FilterInput.getTenseTypes(0); + + // Assert filters are correct + expect(filters["All Types"]).to.equal(true); + expect(filters["Reflexive"]).to.equal(true); + expect(filters["Regular"]).to.equal(true); + expect(filters["Nonregular"]).to.equal(true); + expect(filters["Stem Changing"]).to.equal(true); + expect(filters["Orthographic"]).to.equal(false); + expect(filters["Irregular"]).to.equal(true); + + // Assert selection changed + expect(FilterInput.verbFilters[0]["type"]).to.equal("All Types"); + }); + + it("Should not change selection if available", function() { + // Initialize filters + FilterInput.verbFilters = [ + {"tense":"Preterite Tense", "type":"Orthographic"} + ] + + // Get filters + let filters = FilterInput.getTenseTypes(0); + + // Assert filters are correct + expect(filters["All Types"]).to.equal(true); + expect(filters["Reflexive"]).to.equal(true); + expect(filters["Regular"]).to.equal(true); + expect(filters["Nonregular"]).to.equal(true); + expect(filters["Stem Changing"]).to.equal(true); + expect(filters["Orthographic"]).to.equal(true); + expect(filters["Irregular"]).to.equal(true); + + // Assert selection not changed + expect(FilterInput.verbFilters[0]["type"]).to.equal("Orthographic"); + }); + }); + + describe("GetTenseSubjects method", function() { + it("Should be correct for All Tenses", function() { + // Initialize filters + FilterInput.verbFilters = [ + {"tense":"All Types", "type":"All Types"} + ] + + // Get filters + let filters = FilterInput.getTenseSubjects(0); + + // Assert filters are correct + expect(filters["All Subjects"]).to.equal(true); + expect(filters["Yo"]).to.equal(true); + expect(filters["Tú"]).to.equal(true); + expect(filters["Él"]).to.equal(true); + expect(filters["Nosotros"]).to.equal(true); + expect(filters["Ellos"]).to.equal(true); + }); + + it("Should be correct for Present Participles", function() { + // Initialize filters + FilterInput.verbFilters = [ + {"tense":"Present Participles", "subject":"All Subjects", "type":"All Types"} + ] + + // Get filters + let filters = FilterInput.getTenseSubjects(0); + + // Assert filters are correct + expect(filters["All Subjects"]).to.equal(true); + expect(filters["Yo"]).to.equal(false); + expect(filters["Tú"]).to.equal(false); + expect(filters["Él"]).to.equal(false); + expect(filters["Nosotros"]).to.equal(false); + expect(filters["Ellos"]).to.equal(false); + }); + + it("Should change selection if not available", function() { + // Initialize filters + FilterInput.verbFilters = [ + {"tense":"Present Participles", "subject":"Yo", "type":"All Types"} + ] + + // Get filters + let filters = FilterInput.getTenseSubjects(0); + + // Assert filters are correct + expect(filters["All Subjects"]).to.equal(true); + expect(filters["Yo"]).to.equal(false); + expect(filters["Tú"]).to.equal(false); + expect(filters["Él"]).to.equal(false); + expect(filters["Nosotros"]).to.equal(false); + expect(filters["Ellos"]).to.equal(false); + + // Assert selection changed + expect(FilterInput.verbFilters[0]["subject"]).to.equal("All Subjects"); + }); + + it("Should not change selection if available", function() { + // Initialize filters + FilterInput.verbFilters = [ + {"tense":"Present Participles", "subject":"Type", "type":"All Types"}, + {"tense":"Preterite Tense", "subject":"Yo", "type":"All Types"}, + ] + + // Get filters + FilterInput.getTenseSubjects(0); + FilterInput.getTenseSubjects(1); + + // Assert selection not changed + expect(FilterInput.verbFilters[0].subject).to.equal("Type"); + expect(FilterInput.verbFilters[1].subject).to.equal("Yo"); + }); + }); + + describe("GetSetFilters method", function() { + it("Should be correct for Verbs", function() { + // Initialize filters + FilterInput.vocabFilters = [ + {"set":"Verbs", "type":"All Definitions"} + ] + + // Get filters + let filters = FilterInput.getSetFilters(0); + + // Assert filters are correct + expect(filters["All Types"]).to.equal(true); + expect(filters["Adjectives"]).to.equal(false); + expect(filters["Nouns"]).to.equal(false); + expect(filters["Verbs"]).to.equal(false); + }); + + it("Should be correct for sets with 1 type", function() { + // Initialize filters + FilterInput.vocabFilters = [ + {"set":"Colors", "type":"All Definitions"} + ] + + // Get filters + let filters = FilterInput.getSetFilters(0); + + // Assert filters are correct + expect(filters["All Types"]).to.equal(true); + expect(filters["Adjectives"]).to.equal(true); + expect(filters["Nouns"]).to.equal(false); + expect(filters["Verbs"]).to.equal(false); + }); + + it("Should change selection if not available", function() { + // Initialize filters + FilterInput.vocabFilters = [ + {"set":"Colors", "type":"Verbs"} + ] + + // Get filters + let filters = FilterInput.getSetFilters(0); + + // Assert selection changed + expect(filters["All Types"]).to.equal(true); + expect(filters["Adjectives"]).to.equal(true); + expect(filters["Nouns"]).to.equal(false); + expect(filters["Verbs"]).to.equal(false); + expect(FilterInput.vocabFilters[0]["type"]).to.equal("All Types"); + }); + + it("Should not change selection if available", function() { + // Initialize filters + FilterInput.vocabFilters = [ + {"set":"Professions", "type":"Verbs"} + ] + + // Get filters + let filters = FilterInput.getSetFilters(0); + + // Assert selection not changed + expect(filters["All Types"]).to.equal(true); + expect(filters["Adjectives"]).to.equal(false); + expect(filters["Nouns"]).to.equal(true); + expect(filters["Verbs"]).to.equal(true); + expect(FilterInput.vocabFilters[0]["type"]).to.equal("Verbs"); + }); + }); +}); diff --git a/tests/test.filters.js b/tests/test.filters.js @@ -0,0 +1,893 @@ +describe("Filters", function() { + describe("GetVocabFilters method", function() { + it("Should correctly filter vocab for All Definitions", function() { + // Initialize expected + let expected = [ + {set:"Colors", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:".*"}, + {set:"Colors", outputIndex:1, inputIndex:0, filterIndex:2, filterValue:".*"}, + ]; + + // Filter vocab + let actual = GetVocabFilters([{set:"Colors", type:"All Types", direction:"Eng. ↔ Esp."}]); + + // Assert filtered vocab is correct + expect(actual).to.have.deep.members(expected); + }); + + it("Should correctly filter vocab for multiple filters", function() { + // Initialize expected + let expected = [ + {set:"Colors", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:".*"}, + {set:"Colors", outputIndex:1, inputIndex:0, filterIndex:2, filterValue:".*"}, + {set:"Months", outputIndex:1, inputIndex:0, filterIndex:2, filterValue:"Verb"}, + ]; + + // Filter vocab + let actual = GetVocabFilters([ + {set:"Colors", type:"All Types", direction:"Eng. ↔ Esp."}, + {set:"Months", type:"Verbs", direction:"Esp. → Eng."}, + ]); + + // Assert filtered vocab is correct + expect(actual).to.have.deep.members(expected); + }); + + describe("Direction filters", function() { + it("Should correctly filter vocab for English to Spanish", function() { + // Initialize expected + let expected = [ + {set:"Colors", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:".*"}, + ]; + + // Filter vocab + let actual = GetVocabFilters([{set:"Colors", type:"All Types", direction:"Eng. → Esp."}]); + + // Assert filtered vocab is correct + expect(actual).to.have.deep.members(expected); + }); + + it("Should correctly filter vocab for Spanish to English", function() { + // Initialize expected + let expected = [ + {set:"Colors", outputIndex:1, inputIndex:0, filterIndex:2, filterValue:".*"}, + ]; + + // Filter vocab + let actual = GetVocabFilters([{set:"Colors", type:"All Types", direction:"Esp. → Eng."}]); + + // Assert filtered vocab is correct + expect(actual).to.have.deep.members(expected); + }); + }); + + describe("Word Type filters", function() { + it("Should correctly filter vocab for Nouns", function() { + // Initialize expected + let expected = [ + {set:"Colors", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:"Noun"}, + {set:"Colors", outputIndex:1, inputIndex:0, filterIndex:2, filterValue:"Noun"}, + ]; + + // Filter vocab + let actual = GetVocabFilters([{set:"Colors", type:"Nouns", direction:"Eng. ↔ Esp."}]); + + // Assert filtered vocab is correct + expect(actual).to.have.deep.members(expected); + }); + + it("Should correctly filter vocab for Adjectives", function() { + // Initialize expected + let expected = [ + {set:"Colors", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:"Adjective"}, + {set:"Colors", outputIndex:1, inputIndex:0, filterIndex:2, filterValue:"Adjective"}, + ]; + + // Filter vocab + let actual = GetVocabFilters([{set:"Colors", type:"Adjectives", direction:"Eng. ↔ Esp."}]); + + // Assert filtered vocab is correct + expect(actual).to.have.deep.members(expected); + }); + + it("Should correctly filter vocab for Verbs", function() { + // Initialize expected + let expected = [ + {set:"Colors", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:"Verb"}, + {set:"Colors", outputIndex:1, inputIndex:0, filterIndex:2, filterValue:"Verb"}, + ]; + + // Filter vocab + let actual = GetVocabFilters([{set:"Colors", type:"Verbs", direction:"Eng. ↔ Esp."}]); + + // Assert filtered vocab is correct + expect(actual).to.have.deep.members(expected); + }); + + it("Should throw error for unknown word type", function() { + expect(() => GetVocabFilters([{set:"Colors", type:"test", direction:"Eng. ↔ Esp."}])).to.throw() + expect(() => GetVocabFilters([{set:"Colors", type:"", direction:"Eng. ↔ Esp."}])).to.throw() + expect(() => GetVocabFilters([{set:"Colors", type:1, direction:"Eng. ↔ Esp."}])).to.throw() + expect(() => GetVocabFilters([{set:"Colors", type:null, direction:"Eng. ↔ Esp."}])).to.throw() + }); + }); + }); + + describe("GetVerbFilters method", function() { + it("Should correctly filter verbs for All Conjugations", function() { + // Initialize expected + let expected = [ + {set:"Verbs", outputIndex:0, inputIndex:03, filterIndex:02, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:05, filterIndex:04, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:06, filterIndex:04, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:07, filterIndex:04, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:08, filterIndex:04, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:09, filterIndex:04, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:11, filterIndex:10, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:12, filterIndex:10, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:13, filterIndex:10, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:14, filterIndex:10, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:15, filterIndex:10, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:17, filterIndex:16, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:18, filterIndex:16, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:19, filterIndex:16, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:20, filterIndex:16, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:21, filterIndex:16, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:23, filterIndex:22, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:24, filterIndex:22, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:25, filterIndex:22, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:26, filterIndex:22, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:27, filterIndex:22, filterValue:".*"}, + ]; + + // Filter verbs + let actual = GetVerbFilters([{tense:"all tenses", subject:"all subjects", type:"all types", direction:"Eng. => Conj."}]); + + // Assert filtered verbs are correct + expect(actual).to.have.deep.members(expected); + }); + + it("Should correctly filter verbs for multiple filters", function() { + // Initialize expected + let expected = [ + {set:"Verbs", outputIndex:0, inputIndex:03, filterIndex:02, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:05, filterIndex:04, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:06, filterIndex:04, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:07, filterIndex:04, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:08, filterIndex:04, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:09, filterIndex:04, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:11, filterIndex:10, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:12, filterIndex:10, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:13, filterIndex:10, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:14, filterIndex:10, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:15, filterIndex:10, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:17, filterIndex:16, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:18, filterIndex:16, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:19, filterIndex:16, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:20, filterIndex:16, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:21, filterIndex:16, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:23, filterIndex:22, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:24, filterIndex:22, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:25, filterIndex:22, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:26, filterIndex:22, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:27, filterIndex:22, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + + {set:"Verbs", outputIndex:0, inputIndex:05, filterIndex:04, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:06, filterIndex:04, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:07, filterIndex:04, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:08, filterIndex:04, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:09, filterIndex:04, filterValue:".*"}, + + {set:"Verbs", outputIndex:03, inputIndex:1, filterIndex:02, filterValue:"Stem.?Changing"}, + {set:"Verbs", outputIndex:08, inputIndex:1, filterIndex:04, filterValue:"Stem.?Changing"}, + {set:"Verbs", outputIndex:14, inputIndex:1, filterIndex:10, filterValue:"Stem.?Changing"}, + {set:"Verbs", outputIndex:20, inputIndex:1, filterIndex:16, filterValue:"Stem.?Changing"}, + {set:"Verbs", outputIndex:26, inputIndex:1, filterIndex:22, filterValue:"Stem.?Changing"}, + ]; + + // Filter verbs + let actual = GetVerbFilters([ + { tense:"all tenses", subject:"all subjects", type:"Nonregular", direction:"Eng. => Conj." }, + { tense:"present tense", subject:"all subjects", type:"all types", direction:"Eng. => Conj." }, + { tense:"all tenses", subject:"nosotros", type:"stem changing", direction:"Conj. => Esp." } + ]); + + // Assert filtered verbs are correct + expect(actual).to.have.deep.members(expected); + }); + + describe("Tense filters", function() { + it("Should correctly filter verbs for Present Participles", function() { + // Initialize expected + let expected = [ + {set:"Verbs", outputIndex:0, inputIndex:3, filterIndex:2, filterValue:".*"}, + ]; + + // Filter verbs + let actual = GetVerbFilters([{tense:"Present Participles", subject:"all subjects", type:"all types", direction:"Eng. => Conj."}]); + + // Assert filtered verbs are correct + expect(actual).to.have.deep.members(expected); + }); + + it("Should correctly filter verbs for Present Tense", function() { + // Initialize expected + let expected = [ + {set:"Verbs", outputIndex:0, inputIndex:5, filterIndex:4, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:6, filterIndex:4, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:7, filterIndex:4, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:8, filterIndex:4, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:9, filterIndex:4, filterValue:".*"}, + ]; + + // Filter verbs + let actual = GetVerbFilters([{tense:"Present Tense", subject:"all subjects", type:"all types", direction:"Eng. => Conj."}]); + + // Assert filtered verbs are correct + expect(actual).to.have.deep.members(expected); + }); + + it("Should correctly filter verbs for Preterite Tense", function() { + // Initialize expected + let expected = [ + {set:"Verbs", outputIndex:0, inputIndex:11, filterIndex:10, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:12, filterIndex:10, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:13, filterIndex:10, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:14, filterIndex:10, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:15, filterIndex:10, filterValue:".*"}, + ]; + + // Filter verbs + let actual = GetVerbFilters([{tense:"Preterite Tense", subject:"all subjects", type:"all types", direction:"Eng. => Conj."}]); + + // Assert filtered verbs are correct + expect(actual).to.have.deep.members(expected); + }); + + it("Should correctly filter verbs for Imperfect Tense", function() { + // Initialize expected + let expected = [ + {set:"Verbs", outputIndex:0, inputIndex:17, filterIndex:16, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:18, filterIndex:16, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:19, filterIndex:16, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:20, filterIndex:16, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:21, filterIndex:16, filterValue:".*"}, + ]; + + // Filter verbs + let actual = GetVerbFilters([{tense:"Imperfect Tense", subject:"all subjects", type:"all types", direction:"Eng. => Conj."}]); + + // Assert filtered verbs are correct + expect(actual).to.have.deep.members(expected); + }); + + it("Should correctly filter verbs for Simple Future Tense", function() { + // Initialize expected + let expected = [ + {set:"Verbs", outputIndex:0, inputIndex:23, filterIndex:22, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:24, filterIndex:22, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:25, filterIndex:22, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:26, filterIndex:22, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:27, filterIndex:22, filterValue:".*"}, + ]; + + // Filter verbs + let actual = GetVerbFilters([{tense:"Simple Future Tense", subject:"all subjects", type:"all types", direction:"Eng. => Conj."}]); + + // Assert filtered verbs are correct + expect(actual).to.have.deep.members(expected); + }); + }); + + describe("Regularity filters", function() { + it("Should correctly filter regular verbs", function() { + // Initialize expected + let expected = [ + {set:"Verbs", outputIndex:0, inputIndex:03, filterIndex:02, filterValue:"Regular"}, + {set:"Verbs", outputIndex:0, inputIndex:05, filterIndex:04, filterValue:"Regular"}, + {set:"Verbs", outputIndex:0, inputIndex:06, filterIndex:04, filterValue:"Regular"}, + {set:"Verbs", outputIndex:0, inputIndex:07, filterIndex:04, filterValue:"Regular"}, + {set:"Verbs", outputIndex:0, inputIndex:08, filterIndex:04, filterValue:"Regular"}, + {set:"Verbs", outputIndex:0, inputIndex:09, filterIndex:04, filterValue:"Regular"}, + {set:"Verbs", outputIndex:0, inputIndex:11, filterIndex:10, filterValue:"Regular"}, + {set:"Verbs", outputIndex:0, inputIndex:12, filterIndex:10, filterValue:"Regular"}, + {set:"Verbs", outputIndex:0, inputIndex:13, filterIndex:10, filterValue:"Regular"}, + {set:"Verbs", outputIndex:0, inputIndex:14, filterIndex:10, filterValue:"Regular"}, + {set:"Verbs", outputIndex:0, inputIndex:15, filterIndex:10, filterValue:"Regular"}, + {set:"Verbs", outputIndex:0, inputIndex:17, filterIndex:16, filterValue:"Regular"}, + {set:"Verbs", outputIndex:0, inputIndex:18, filterIndex:16, filterValue:"Regular"}, + {set:"Verbs", outputIndex:0, inputIndex:19, filterIndex:16, filterValue:"Regular"}, + {set:"Verbs", outputIndex:0, inputIndex:20, filterIndex:16, filterValue:"Regular"}, + {set:"Verbs", outputIndex:0, inputIndex:21, filterIndex:16, filterValue:"Regular"}, + {set:"Verbs", outputIndex:0, inputIndex:23, filterIndex:22, filterValue:"Regular"}, + {set:"Verbs", outputIndex:0, inputIndex:24, filterIndex:22, filterValue:"Regular"}, + {set:"Verbs", outputIndex:0, inputIndex:25, filterIndex:22, filterValue:"Regular"}, + {set:"Verbs", outputIndex:0, inputIndex:26, filterIndex:22, filterValue:"Regular"}, + {set:"Verbs", outputIndex:0, inputIndex:27, filterIndex:22, filterValue:"Regular"}, + ]; + + // Filter verbs + let actual = GetVerbFilters([{tense:"all tenses", subject:"all subjects", type:"Regular", direction:"Eng. => Conj."}]); + + // Assert filtered verbs are correct + expect(actual).to.have.deep.members(expected); + }); + + it("Should correctly filter reflexive verbs", function() { + // Initialize expected + let expected = [ + {set:"Verbs", outputIndex:0, inputIndex:03, filterIndex:02, filterValue:"Reflexive"}, + {set:"Verbs", outputIndex:0, inputIndex:05, filterIndex:04, filterValue:"Reflexive"}, + {set:"Verbs", outputIndex:0, inputIndex:06, filterIndex:04, filterValue:"Reflexive"}, + {set:"Verbs", outputIndex:0, inputIndex:07, filterIndex:04, filterValue:"Reflexive"}, + {set:"Verbs", outputIndex:0, inputIndex:08, filterIndex:04, filterValue:"Reflexive"}, + {set:"Verbs", outputIndex:0, inputIndex:09, filterIndex:04, filterValue:"Reflexive"}, + {set:"Verbs", outputIndex:0, inputIndex:11, filterIndex:10, filterValue:"Reflexive"}, + {set:"Verbs", outputIndex:0, inputIndex:12, filterIndex:10, filterValue:"Reflexive"}, + {set:"Verbs", outputIndex:0, inputIndex:13, filterIndex:10, filterValue:"Reflexive"}, + {set:"Verbs", outputIndex:0, inputIndex:14, filterIndex:10, filterValue:"Reflexive"}, + {set:"Verbs", outputIndex:0, inputIndex:15, filterIndex:10, filterValue:"Reflexive"}, + {set:"Verbs", outputIndex:0, inputIndex:17, filterIndex:16, filterValue:"Reflexive"}, + {set:"Verbs", outputIndex:0, inputIndex:18, filterIndex:16, filterValue:"Reflexive"}, + {set:"Verbs", outputIndex:0, inputIndex:19, filterIndex:16, filterValue:"Reflexive"}, + {set:"Verbs", outputIndex:0, inputIndex:20, filterIndex:16, filterValue:"Reflexive"}, + {set:"Verbs", outputIndex:0, inputIndex:21, filterIndex:16, filterValue:"Reflexive"}, + {set:"Verbs", outputIndex:0, inputIndex:23, filterIndex:22, filterValue:"Reflexive"}, + {set:"Verbs", outputIndex:0, inputIndex:24, filterIndex:22, filterValue:"Reflexive"}, + {set:"Verbs", outputIndex:0, inputIndex:25, filterIndex:22, filterValue:"Reflexive"}, + {set:"Verbs", outputIndex:0, inputIndex:26, filterIndex:22, filterValue:"Reflexive"}, + {set:"Verbs", outputIndex:0, inputIndex:27, filterIndex:22, filterValue:"Reflexive"}, + ]; + + // Filter verbs + let actual = GetVerbFilters([{tense:"all tenses", subject:"all subjects", type:"Reflexive", direction:"Eng. => Conj."}]); + + // Assert filtered verbs are correct + expect(actual).to.have.deep.members(expected); + }); + + it("Should correctly filter stem changing verbs", function() { + // Initialize expected + let expected = [ + {set:"Verbs", outputIndex:0, inputIndex:03, filterIndex:02, filterValue:"Stem.?Changing"}, + {set:"Verbs", outputIndex:0, inputIndex:05, filterIndex:04, filterValue:"Stem.?Changing"}, + {set:"Verbs", outputIndex:0, inputIndex:06, filterIndex:04, filterValue:"Stem.?Changing"}, + {set:"Verbs", outputIndex:0, inputIndex:07, filterIndex:04, filterValue:"Stem.?Changing"}, + {set:"Verbs", outputIndex:0, inputIndex:08, filterIndex:04, filterValue:"Stem.?Changing"}, + {set:"Verbs", outputIndex:0, inputIndex:09, filterIndex:04, filterValue:"Stem.?Changing"}, + {set:"Verbs", outputIndex:0, inputIndex:11, filterIndex:10, filterValue:"Stem.?Changing"}, + {set:"Verbs", outputIndex:0, inputIndex:12, filterIndex:10, filterValue:"Stem.?Changing"}, + {set:"Verbs", outputIndex:0, inputIndex:13, filterIndex:10, filterValue:"Stem.?Changing"}, + {set:"Verbs", outputIndex:0, inputIndex:14, filterIndex:10, filterValue:"Stem.?Changing"}, + {set:"Verbs", outputIndex:0, inputIndex:15, filterIndex:10, filterValue:"Stem.?Changing"}, + {set:"Verbs", outputIndex:0, inputIndex:17, filterIndex:16, filterValue:"Stem.?Changing"}, + {set:"Verbs", outputIndex:0, inputIndex:18, filterIndex:16, filterValue:"Stem.?Changing"}, + {set:"Verbs", outputIndex:0, inputIndex:19, filterIndex:16, filterValue:"Stem.?Changing"}, + {set:"Verbs", outputIndex:0, inputIndex:20, filterIndex:16, filterValue:"Stem.?Changing"}, + {set:"Verbs", outputIndex:0, inputIndex:21, filterIndex:16, filterValue:"Stem.?Changing"}, + {set:"Verbs", outputIndex:0, inputIndex:23, filterIndex:22, filterValue:"Stem.?Changing"}, + {set:"Verbs", outputIndex:0, inputIndex:24, filterIndex:22, filterValue:"Stem.?Changing"}, + {set:"Verbs", outputIndex:0, inputIndex:25, filterIndex:22, filterValue:"Stem.?Changing"}, + {set:"Verbs", outputIndex:0, inputIndex:26, filterIndex:22, filterValue:"Stem.?Changing"}, + {set:"Verbs", outputIndex:0, inputIndex:27, filterIndex:22, filterValue:"Stem.?Changing"}, + ]; + + // Filter verbs + let actual = GetVerbFilters([{tense:"all tenses", subject:"all subjects", type:"Stem Changing", direction:"Eng. => Conj."}]); + + // Assert filtered verbs are correct + expect(actual).to.have.deep.members(expected); + }); + + it("Should correctly filter orthographic verbs", function() { + // Initialize expected + let expected = [ + {set:"Verbs", outputIndex:0, inputIndex:03, filterIndex:02, filterValue:"Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:05, filterIndex:04, filterValue:"Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:06, filterIndex:04, filterValue:"Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:07, filterIndex:04, filterValue:"Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:08, filterIndex:04, filterValue:"Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:09, filterIndex:04, filterValue:"Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:11, filterIndex:10, filterValue:"Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:12, filterIndex:10, filterValue:"Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:13, filterIndex:10, filterValue:"Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:14, filterIndex:10, filterValue:"Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:15, filterIndex:10, filterValue:"Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:17, filterIndex:16, filterValue:"Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:18, filterIndex:16, filterValue:"Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:19, filterIndex:16, filterValue:"Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:20, filterIndex:16, filterValue:"Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:21, filterIndex:16, filterValue:"Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:23, filterIndex:22, filterValue:"Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:24, filterIndex:22, filterValue:"Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:25, filterIndex:22, filterValue:"Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:26, filterIndex:22, filterValue:"Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:27, filterIndex:22, filterValue:"Orthographic"}, + ]; + + // Filter verbs + let actual = GetVerbFilters([{tense:"all tenses", subject:"all subjects", type:"Orthographic", direction:"Eng. => Conj."}]); + + // Assert filtered verbs are correct + expect(actual).to.have.deep.members(expected); + }); + + it("Should correctly filter irregular verbs", function() { + // Initialize expected + let expected = [ + {set:"Verbs", outputIndex:0, inputIndex:03, filterIndex:02, filterValue:"Irregular"}, + {set:"Verbs", outputIndex:0, inputIndex:05, filterIndex:04, filterValue:"Irregular"}, + {set:"Verbs", outputIndex:0, inputIndex:06, filterIndex:04, filterValue:"Irregular"}, + {set:"Verbs", outputIndex:0, inputIndex:07, filterIndex:04, filterValue:"Irregular"}, + {set:"Verbs", outputIndex:0, inputIndex:08, filterIndex:04, filterValue:"Irregular"}, + {set:"Verbs", outputIndex:0, inputIndex:09, filterIndex:04, filterValue:"Irregular"}, + {set:"Verbs", outputIndex:0, inputIndex:11, filterIndex:10, filterValue:"Irregular"}, + {set:"Verbs", outputIndex:0, inputIndex:12, filterIndex:10, filterValue:"Irregular"}, + {set:"Verbs", outputIndex:0, inputIndex:13, filterIndex:10, filterValue:"Irregular"}, + {set:"Verbs", outputIndex:0, inputIndex:14, filterIndex:10, filterValue:"Irregular"}, + {set:"Verbs", outputIndex:0, inputIndex:15, filterIndex:10, filterValue:"Irregular"}, + {set:"Verbs", outputIndex:0, inputIndex:17, filterIndex:16, filterValue:"Irregular"}, + {set:"Verbs", outputIndex:0, inputIndex:18, filterIndex:16, filterValue:"Irregular"}, + {set:"Verbs", outputIndex:0, inputIndex:19, filterIndex:16, filterValue:"Irregular"}, + {set:"Verbs", outputIndex:0, inputIndex:20, filterIndex:16, filterValue:"Irregular"}, + {set:"Verbs", outputIndex:0, inputIndex:21, filterIndex:16, filterValue:"Irregular"}, + {set:"Verbs", outputIndex:0, inputIndex:23, filterIndex:22, filterValue:"Irregular"}, + {set:"Verbs", outputIndex:0, inputIndex:24, filterIndex:22, filterValue:"Irregular"}, + {set:"Verbs", outputIndex:0, inputIndex:25, filterIndex:22, filterValue:"Irregular"}, + {set:"Verbs", outputIndex:0, inputIndex:26, filterIndex:22, filterValue:"Irregular"}, + {set:"Verbs", outputIndex:0, inputIndex:27, filterIndex:22, filterValue:"Irregular"}, + ]; + + // Filter verbs + let actual = GetVerbFilters([{tense:"all tenses", subject:"all subjects", type:"irregular", direction:"Eng. => Conj."}]); + + // Assert filtered verbs are correct + expect(actual).to.have.deep.members(expected); + }); + + it("Should correctly filter nonregular verbs", function() { + // Initialize expected + let expected = [ + {set:"Verbs", outputIndex:0, inputIndex:03, filterIndex:02, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:05, filterIndex:04, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:06, filterIndex:04, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:07, filterIndex:04, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:08, filterIndex:04, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:09, filterIndex:04, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:11, filterIndex:10, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:12, filterIndex:10, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:13, filterIndex:10, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:14, filterIndex:10, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:15, filterIndex:10, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:17, filterIndex:16, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:18, filterIndex:16, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:19, filterIndex:16, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:20, filterIndex:16, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:21, filterIndex:16, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:23, filterIndex:22, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:24, filterIndex:22, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:25, filterIndex:22, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:26, filterIndex:22, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + {set:"Verbs", outputIndex:0, inputIndex:27, filterIndex:22, filterValue:"Irregular|Stem.?Changing|Orthographic"}, + ]; + + // Filter verbs + let actual = GetVerbFilters([{tense:"all tenses", subject:"all subjects", type:"Nonregular", direction:"Eng. => Conj."}]); + + // Assert filtered verbs are correct + expect(actual).to.have.deep.members(expected); + }); + }); + + describe("Subject filters", function() { + it("Should correctly filter type subjects", function() { + // Initialize expected + let expected = [ + {set:"Verbs", outputIndex:0, inputIndex:02, filterIndex:02, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:04, filterIndex:04, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:10, filterIndex:10, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:16, filterIndex:16, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:22, filterIndex:22, filterValue:".*"}, + ]; + + // Filter verbs + let actual = GetVerbFilters([{tense:"all tenses", subject:"type", type:"all types", direction:"Eng. => Conj."}]); + + // Assert filtered verbs are correct + expect(actual).to.have.deep.members(expected); + }); + + it("Should correctly filter yo subjects", function() { + // Initialize expected + let expected = [ + {set:"Verbs", outputIndex:0, inputIndex:03, filterIndex:02, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:05, filterIndex:04, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:11, filterIndex:10, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:17, filterIndex:16, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:23, filterIndex:22, filterValue:".*"}, + ]; + + // Filter verbs + let actual = GetVerbFilters([{tense:"all tenses", subject:"yo", type:"all types", direction:"Eng. => Conj."}]); + + // Assert filtered verbs are correct + expect(actual).to.have.deep.members(expected); + }); + + it("Should correctly filter tú subjects", function() { + // Initialize expected + let expected = [ + {set:"Verbs", outputIndex:0, inputIndex:03, filterIndex:02, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:06, filterIndex:04, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:12, filterIndex:10, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:18, filterIndex:16, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:24, filterIndex:22, filterValue:".*"}, + ]; + + // Filter verbs + let actual = GetVerbFilters([{tense:"all tenses", subject:"tú", type:"all types", direction:"Eng. => Conj."}]); + + // Assert filtered verbs are correct + expect(actual).to.have.deep.members(expected); + }); + + it("Should correctly filter él subjects", function() { + // Initialize expected + let expected = [ + {set:"Verbs", outputIndex:0, inputIndex:03, filterIndex:02, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:07, filterIndex:04, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:13, filterIndex:10, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:19, filterIndex:16, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:25, filterIndex:22, filterValue:".*"}, + ]; + + // Filter verbs + let actual = GetVerbFilters([{tense:"all tenses", subject:"él", type:"all types", direction:"Eng. => Conj."}]); + + // Assert filtered verbs are correct + expect(actual).to.have.deep.members(expected); + }); + + it("Should correctly filter nosotros subjects", function() { + // Initialize expected + let expected = [ + {set:"Verbs", outputIndex:0, inputIndex:03, filterIndex:02, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:08, filterIndex:04, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:14, filterIndex:10, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:20, filterIndex:16, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:26, filterIndex:22, filterValue:".*"}, + ]; + + // Filter verbs + let actual = GetVerbFilters([{tense:"all tenses", subject:"nosotros", type:"all types", direction:"Eng. => Conj."}]); + + // Assert filtered verbs are correct + expect(actual).to.have.deep.members(expected); + }); + + it("Should correctly filter ellos subjects", function() { + // Initialize expected + let expected = [ + {set:"Verbs", outputIndex:0, inputIndex:03, filterIndex:02, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:09, filterIndex:04, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:15, filterIndex:10, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:21, filterIndex:16, filterValue:".*"}, + {set:"Verbs", outputIndex:0, inputIndex:27, filterIndex:22, filterValue:".*"}, + ]; + + // Filter verbs + let actual = GetVerbFilters([{tense:"all tenses", subject:"ellos", type:"all types", direction:"Eng. => Conj."}]); + + // Assert filtered verbs are correct + expect(actual).to.have.deep.members(expected); + }); + }); + + describe("Direction filters", function() { + it("Should correctly filter English to Conjugations", function() { + // Initialize expected + let expected = [ + {set:"Verbs", outputIndex:0, inputIndex:3, filterIndex:2, filterValue:".*"}, + ]; + + // Filter verbs + let actual = GetVerbFilters([{tense:"present participles", subject:"all subjects", type:"all types", direction:"Eng. => Conj."}]); + + // Assert filtered verbs are correct + expect(actual).to.have.deep.members(expected); + }); + + it("Should correctly filter Spanish to Conjugations", function() { + // Initialize expected + let expected = [ + {set:"Verbs", outputIndex:1, inputIndex:3, filterIndex:2, filterValue:".*"}, + ]; + + // Filter verbs + let actual = GetVerbFilters([{tense:"present participles", subject:"all subjects", type:"all types", direction:"Esp. => Conj."}]); + + // Assert filtered verbs are correct + expect(actual).to.have.deep.members(expected); + }); + + it("Should correctly filter Conjugations to English", function() { + // Initialize expected + let expected = [ + {set:"Verbs", outputIndex:3, inputIndex:0, filterIndex:2, filterValue:".*"}, + ]; + + // Filter verbs + let actual = GetVerbFilters([{tense:"present participles", subject:"all subjects", type:"all types", direction:"Conj. => Eng."}]); + + // Assert filtered verbs are correct + expect(actual).to.have.deep.members(expected); + }); + + it("Should correctly filter Conjugations to Spanish", function() { + // Initialize expected + let expected = [ + {set:"Verbs", outputIndex:3, inputIndex:1, filterIndex:2, filterValue:".*"}, + ]; + + // Filter verbs + let actual = GetVerbFilters([{tense:"present participles", subject:"all subjects", type:"all types", direction:"Conj. => Esp."}]); + + // Assert filtered verbs are correct + expect(actual).to.have.deep.members(expected); + }); + }); + }); + + describe("ApplyFilters method", function() { + // Initialize vocab + let vocab = { + "set1": [ + ["Upper", "Lower", "Type1", "Type2"], + ["A", "a", "Noun", "Vowel"], + ["B", "b", "Adjective", "Consonant"], + ["C", "c", "Verb", "Consonant"], + ], + "set2": [ + ["Upper", "Lower", "Type1", "Type2"], + ["Z", "z", "Noun", "Consonant"], + ["Y", "y", "Adjective", "Vowel,Consonant"], + ["X", "x", "Verb", "Consonant"], + ], + }; + + it("Should correctly filter different vocab sets", function() { + // Initialize expected + let expected = [ + ["Upper", "A", "Lower", "a"], + ["Upper", "B", "Lower", "b"], + ["Upper", "C", "Lower", "c"], + ["Upper", "X", "Lower", "x"], + ["Upper", "Y", "Lower", "y"], + ["Upper", "Z", "Lower", "z"], + ]; + + // Call ApplyFilters + let actual = ApplyFilters(vocab, [ + {set:"set1", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:".*"}, + {set:"set2", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:".*"}, + ]); + + // Assert filtered vocab is correct + expect(actual).to.have.deep.members(expected); + }); + + it("Should correctly filter different outputIndexes", function() { + // Initialize expected + let expected = [ + ["Upper", "A", "Lower", "a"], + ["Upper", "B", "Lower", "b"], + ["Upper", "C", "Lower", "c"], + ["Type2", "Vowel", "Lower", "a"], + ["Type2", "Consonant", "Lower", "b"], + ["Type2", "Consonant", "Lower", "c"], + ]; + + // Call ApplyFilters + let actual = ApplyFilters(vocab, [ + {set:"set1", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:".*"}, + {set:"set1", outputIndex:3, inputIndex:1, filterIndex:2, filterValue:".*"}, + ]); + + // Assert filtered vocab is correct + expect(actual).to.have.deep.members(expected); + }); + + it("Should correctly filter different inputIndexes", function() { + // Initialize expected + let expected = [ + ["Upper", "A", "Lower", "a"], + ["Upper", "B", "Lower", "b"], + ["Upper", "C", "Lower", "c"], + ["Upper", "A", "Type2", "Vowel"], + ["Upper", "B", "Type2", "Consonant"], + ["Upper", "C", "Type2", "Consonant"], + ]; + + // Call ApplyFilters + let actual = ApplyFilters(vocab, [ + {set:"set1", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:".*"}, + {set:"set1", outputIndex:0, inputIndex:3, filterIndex:2, filterValue:".*"}, + ]); + + // Assert filtered vocab is correct + expect(actual).to.have.deep.members(expected); + }); + + it("Should correctly filter different filterIndexes and filtervalues", function() { + // Initialize expected + let expected = [ + ["Upper", "C", "Lower", "c"], + ["Upper", "A", "Lower", "a"], + ]; + + // Call ApplyFilters + let actual = ApplyFilters(vocab, [ + {set:"set1", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:"Verb"}, + {set:"set1", outputIndex:0, inputIndex:1, filterIndex:3, filterValue:"Vowel"}, + ]); + + // Assert filtered vocab is correct + expect(actual).to.have.deep.members(expected); + }); + + describe("multiplePrompts setting", function() { + // Initialize vocab2 + let vocab2 = { + "set1": [ + ["Upper", "Lower", "Type1"], + ["A1, A2 , A3", "a", "Noun"], + ["B1, B2", "b", "Adjective"], + ["C", "c", "Verb"], + ], + }; + + it("Shouldn't effect single prompts", function() { + // Initialize expected + let expected = [ + ["Upper", "C", "Lower", "c"], + ]; + + // Call ApplyFilters + let actual = ApplyFilters(vocab2, [{set:"set1", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:"Verb"}], "Show separately"); + + // Assert filtered vocab is correct + expect(actual).to.have.deep.members(expected); + }); + + it("Should't effect prompts if equal to 'Show together'", function() { + // Initialize expected + let expected = [ + ["Upper", "A1, A2 , A3", "Lower", "a"], + ["Upper", "B1, B2", "Lower", "b"], + ]; + + // Call ApplyFilters + let actual = ApplyFilters(vocab2, [{set:"set1", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:"Noun|Adjective"}], "Show together"); + + // Assert filtered vocab is correct + expect(actual).to.have.deep.members(expected); + }); + + it("Should split up prompts if equal to 'Show separately'", function() { + // Initialize expected + let expected = [ + ["Upper", "A1", "Lower", "a"], + ["Upper", "A2", "Lower", "a"], + ["Upper", "A3", "Lower", "a"], + ["Upper", "B1", "Lower", "b"], + ["Upper", "B2", "Lower", "b"], + ]; + + // Call ApplyFilters + let actual = ApplyFilters(vocab2, [{set:"set1", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:"Noun|Adjective"}], "Show separately"); + + // Assert filtered vocab is correct + expect(actual).to.have.deep.members(expected); + }); + + it("Should correctly filter prompts if equal to 'Show one' (Math.random returns 0)", function() { + // Initialize expected + let expected = [ + ["Upper", "A1", "Lower", "a"], + ["Upper", "B1", "Lower", "b"], + ]; + + // Copy original Math.random method + let random = Math.random; + + try { + // Override Math.random method + Math.random = function() { + return 0; + } + + // Call ApplyFilters + let actual = ApplyFilters(vocab2, [{set:"set1", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:"Noun|Adjective"}], "Show one"); + + // Assert filtered vocab is correct + expect(actual).to.have.deep.members(expected); + } + finally { + // Restore Math.random method + Math.random = random; + } + }); + + it("Should correctly filter prompts if equal to 'Show one' (Math.random returns 0.5)", function() { + // Initialize expected + let expected = [ + ["Upper", "A2", "Lower", "a"], + ["Upper", "B1", "Lower", "b"], + ]; + + // Copy original Math.random method + let random = Math.random; + + try { + // Override Math.random method + Math.random = function() { + return 0.5; + } + + // Call ApplyFilters + let actual = ApplyFilters(vocab2, [{set:"set1", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:"Noun|Adjective"}], "Show one"); + + // Assert filtered vocab is correct + expect(actual).to.have.deep.members(expected); + } + finally { + // Restore Math.random method + Math.random = random; + } + }); + + it("Should correctly filter prompts if equal to 'Show one' (Math.random returns 1)", function() { + // Initialize expected + let expected = [ + ["Upper", "A3", "Lower", "a"], + ["Upper", "B2", "Lower", "b"], + ]; + + // Copy original Math.random method + let random = Math.random; + + try { + // Override Math.random method + Math.random = function() { + return 1; + } + + // Call ApplyFilters + let actual = ApplyFilters(vocab2, [{set:"set1", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:"Noun|Adjective"}], "Show one"); + + // Assert filtered vocab is correct + expect(actual).to.have.deep.members(expected); + } + finally { + // Restore Math.random method + Math.random = random; + } + }); + }); + }); + + describe("Shuffle method", function() { + it("Should not alter list", function() { + // Initialize list + let list1 = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o"]; // 15 items + + // Shuffle list + let list2 = Shuffle(list1); + + // Assert list shuffled + expect(list2.length).to.equal(list1.length); + for (let item of list2) { + expect(list1.includes(item)).to.equal(true); + } + }); + }); +}); diff --git a/tests/test.global.js b/tests/test.global.js @@ -1,18 +1,109 @@ describe("Global.js", function() { - describe("GetLang method", function () { + describe("GetLang method", function() { it("Should return English by default", function() { expect(getLang("")).to.equal("en"); expect(getLang("test")).to.equal("en"); }); - + it("Should return English for English labels", function() { expect(getLang("test english test")).to.equal("en"); expect(getLang("ENGLISH")).to.equal("en"); }) - + it("Should return Spanish for Spanish labels", function() { expect(getLang("test spanish test")).to.equal("es"); expect(getLang("SPANISH")).to.equal("es"); }) }); + + describe("GetSettings method", function() { + it("Settings should be loaded", async function() { + // Save original setting from localStorage + let originalValue = localStorage.getItem("settings"); + + // Set localStorage settings + localStorage.setItem("settings", "{\"promptType\":\"Audio\",\"inputType\":\"Voice\",\"onMissedPrompt\":\"Tell me\",\"repeatPrompts\":\"5 prompts later\"}") + + // Call getSettings + let settings = getSettings(); + + // Assert settings loaded + expect(settings.promptType).to.equal("Audio"); + expect(settings.inputType).to.equal("Voice"); + expect(settings.onMissedPrompt).to.equal("Tell me"); + expect(settings.repeatPrompts).to.equal("5 prompts later"); + expect(settings.multiplePrompts).to.equal("Show together"); + expect(settings.multipleAnswers).to.equal("Require all"); + + // Restore original setting to localStorage + localStorage.setItem("settings", originalValue); + }); + + it("Invalid individual settings should not be loaded", async function() { + // Save original setting from localStorage + let originalValue = localStorage.getItem("settings"); + + // Set localStorage settings + localStorage.setItem("settings", "{\"promptType\":\"Audio\",\"inputType\":\"test\",\"onMissedPrompt\":null}") + + // Call getSettings + let settings = getSettings(); + + // Assert default settings loaded + expect(settings.promptType).to.equal("Audio"); // promptType wasn't invalid, so it should still be loaded + expect(settings.inputType).to.equal("Text"); + expect(settings.onMissedPrompt).to.equal("Correct me"); + expect(settings.repeatPrompts).to.equal("Never"); + + // Restore original setting to localStorage + localStorage.setItem("settings", originalValue); + }); + + it("Invalid JSON settings should not be loaded", async function() { + // Save original setting from localStorage + let originalValue = localStorage.getItem("settings"); + + // Set localStorage settings + localStorage.setItem("settings", "asdf") + + // Call getSettings + let settings = getSettings(); + + // Assert default settings loaded + expect(settings.promptType).to.equal("Text"); + expect(settings.inputType).to.equal("Text"); + expect(settings.onMissedPrompt).to.equal("Correct me"); + expect(settings.repeatPrompts).to.equal("Never"); + + // Restore original setting to localStorage + localStorage.setItem("settings", originalValue); + }); + }); + + describe("SetSettings method", function() { + it("Should update setting in localStorage", async function() { + // Save original setting from localStorage + let originalValue = localStorage.getItem("settings"); + + // Set settings + let settings = { + darkTheme : "A", + promptType : "B", + inputType : "C", + onMissedPrompt : "D", + repeatPrompts : "E", + multiplePrompts : "F", + multipleAnswers : "G", + } + + // Call setSettings + setSettings(settings); + + // Assert localStorage setting updated + expect(localStorage.getItem("settings")).to.equal(`{"darkTheme":"A","promptType":"B","inputType":"C","onMissedPrompt":"D","repeatPrompts":"E","multiplePrompts":"F","multipleAnswers":"G"}`); + + // Restore original setting to localStorage + localStorage.setItem("settings", originalValue); + }); + }); }); diff --git a/tests/test.quizzer.js b/tests/test.quizzer.js @@ -6,10 +6,6 @@ describe("Quizzer", function() { }); describe("Initial state", function() { - it("Active should be false", function() { - expect(Quizzer.active).to.equal(false); - }); - it("StartingPrompts should be empty", function() { expect(Quizzer.startingPrompts.length).to.equal(0); }); @@ -44,24 +40,8 @@ describe("Quizzer", function() { }); describe("Reset method", function() { - it("Shouldn't do anything if active is false", function() { - // Initialize quizzer - Quizzer.prompts = [0, 1]; - Quizzer.index = 0; - - // Run Reset - Quizzer.Reset(); - - // Assert nothing changed - expect(Quizzer.prompts).to.have.members([0, 1]); - expect(Quizzer.index).to.equal(0); - expect(Quizzer.responce).to.equal(""); - expect(Quizzer.responceActive).to.equal(true); - }); - it("Should reset responce", function() { // Initialize variables - Quizzer.active = true; Quizzer.responce = "test"; expect(Quizzer.responce).to.equal("test"); @@ -74,7 +54,6 @@ describe("Quizzer", function() { it("Should set responceActive to true", function() { // Initialize variables - Quizzer.active = true; Quizzer.responceActive = false; // Run reset @@ -85,9 +64,6 @@ describe("Quizzer", function() { }); it("Should focus input", function() { - // Initialize variables - Quizzer.active = true; - // Override focus method let focusCalled = true; Quizzer.$refs = { @@ -107,7 +83,6 @@ describe("Quizzer", function() { it("Should emit 'new-prompts' event", function() { // Initialize variables - Quizzer.active = true; Quizzer.prompts = ["prompt 1", "prompt 2"]; Quizzer.index = 0; @@ -126,7 +101,6 @@ describe("Quizzer", function() { it("Should emit 'finished-prompts' event if on last term", function() { // Initialize variables - Quizzer.active = true; Quizzer.prompts = ["prompt 1", "prompt 2"]; Quizzer.index = 1; @@ -145,20 +119,8 @@ describe("Quizzer", function() { }); describe("Submit method", function() { - it("Shouldn't do anything if active is false", function() { - // Initialize variables - Quizzer.responceActive = "test"; // Will be changed whether or not resopnce is correct - - // Run Submit - Quizzer.Submit(); - - // Assert nothing changed - expect(Quizzer.responceActive).to.equal("test"); - }); - it("Should call Reset if responce is correct", function() { // Initialize variables - Quizzer.active = true; Quizzer.prompts = [["A1", "A2", "A3", "A4"]] Quizzer.responce = "A4"; @@ -177,7 +139,6 @@ describe("Quizzer", function() { it("Should call Continue if onMissedPrompt is set to 'Ignore it'", function() { // Initialize variables - Quizzer.active = true; Quizzer.settings.onMissedPrompt = "Ignore it"; Quizzer.prompts = [["A1", "A2", "A3", "A4"], ["B1", "B2", "B3", "B4"]]; Quizzer.responce = "A5"; @@ -197,8 +158,7 @@ describe("Quizzer", function() { it("Should not call Reset if onMissedPrompt is set to 'Tell me'", function() { // Initialize variables - Quizzer.active = true; - Quizzer.onMissedPrompt = "Tell me"; + Quizzer.settings.onMissedPrompt = "Tell me"; Quizzer.prompts = [["A1", "A2", "A3", "A4"]] Quizzer.responce = "A5"; @@ -217,7 +177,6 @@ describe("Quizzer", function() { it("Should set responceActive to false if responce is incorrect", function() { // Initialize variables - Quizzer.active = true; Quizzer.prompts = [["A1", "A2", "A3", "A4"]] Quizzer.responce = "A5"; @@ -230,7 +189,6 @@ describe("Quizzer", function() { it("Should focus input if responce is incorrect", function() { // Initialize variables - Quizzer.active = true; Quizzer.prompts = [["A1", "A2", "A3", "A4"]] Quizzer.responce = "A5"; @@ -253,7 +211,6 @@ describe("Quizzer", function() { it("Should accept multiple responces", function() { // Initialize variables - Quizzer.active = true; Quizzer.prompts = [["A1", "A2", "A3", "A4"]] Quizzer.responce = "A1, A2, A3, A4"; @@ -272,7 +229,6 @@ describe("Quizzer", function() { it("Should accept multiple answers", function() { // Initialize variables - Quizzer.active = true; Quizzer.prompts = [["A1", "A2", "A3", "A1, A2, A3, A4"]] Quizzer.responce = "A1, A2, A3, A4"; @@ -291,7 +247,6 @@ describe("Quizzer", function() { it("Should require all answers if multipleAnswers is set to 'Require all'", function() { // Initialize variables - Quizzer.active = true; Quizzer.settings.multipleAnswers = "Require all"; Quizzer.prompts = [["A1", "A2", "A3", "A1, A2, A3, A4"]] Quizzer.responce = "A1, A2, A3"; @@ -305,7 +260,6 @@ describe("Quizzer", function() { it("Shouldn't require all answers if multipleAnswers is set to 'Require any'", function() { // Initialize variables - Quizzer.active = true; Quizzer.settings.multipleAnswers = "Require any"; Quizzer.prompts = [["A1", "A2", "A3", "A1, A2, A3, A4"]] Quizzer.responce = "A1, A2, A3"; @@ -319,7 +273,6 @@ describe("Quizzer", function() { it("Should accept mixed-case responces", function() { // Initialize variables - Quizzer.active = true; Quizzer.prompts = [["A1", "A2", "A3", "A4"]] Quizzer.responce = "a4"; @@ -338,7 +291,6 @@ describe("Quizzer", function() { it("Should accept responces with extra spaces", function() { // Initialize variables - Quizzer.active = true; Quizzer.prompts = [["A1", "A2", "A3", "A4"]] Quizzer.responce = " a4 "; @@ -357,7 +309,6 @@ describe("Quizzer", function() { it("Should convert accented characters", function() { // Initialize variables - Quizzer.active = true; Quizzer.prompts = [["A1", "A2", "A3", "Á4"]] Quizzer.responce = "a`4"; @@ -376,32 +327,8 @@ describe("Quizzer", function() { }); describe("Continue method", function() { - it("Shouldn't do anything if active is false", function() { - // Initialize variables - Quizzer.prompts = [["A1", "A2", "A3", "A4"], ["B1", "B2", "B3", "B4"]]; - Quizzer.index = 0; - - // Override Reset method - let resetCalled = false; - Quizzer.Reset = function() { - resetCalled = true; - }; - - // Run Continue - Quizzer.Continue(); - - // Assert prompts not changed - expect(Quizzer.prompts[0]).to.have.members(["A1", "A2", "A3", "A4"]); - expect(Quizzer.prompts[1]).to.have.members(["B1", "B2", "B3", "B4"]); - expect(Quizzer.index).to.equal(0); - - // Assert Reset not called - expect(resetCalled).to.equal(false); - }); - it("Shouldn't change prompts if repeatPrompts is Never", function() { // Initialize variables - Quizzer.active = true; Quizzer.prompts = [["A1", "A2", "A3", "A4"], ["B1", "B2", "B3", "B4"]]; Quizzer.index = 0; Quizzer.settings.repeatPrompts = "Never"; @@ -417,7 +344,6 @@ describe("Quizzer", function() { it("Shouldn't change prompts if repeatPrompts isn't recognized", function() { // Initialize variables - Quizzer.active = true; Quizzer.prompts = [["A1", "A2", "A3", "A4"], ["B1", "B2", "B3", "B4"]]; Quizzer.index = 0; Quizzer.settings.repeatPrompts = "test"; @@ -433,7 +359,6 @@ describe("Quizzer", function() { it("Should only change index if repeatPrompts is Immediately", function() { // Initialize variables - Quizzer.active = true; Quizzer.prompts = [["A1", "A2", "A3", "A4"], ["B1", "B2", "B3", "B4"]]; Quizzer.index = 0; Quizzer.settings.repeatPrompts = "Immediately"; @@ -449,7 +374,6 @@ describe("Quizzer", function() { it("Should only update prompts if repeatPrompts is 5 prompts later", function() { // Initialize variables - Quizzer.active = true; Quizzer.prompts = [ ["A1", "A2", "A3", "A4"], ["B1", "B2", "B3", "B4"], @@ -478,7 +402,6 @@ describe("Quizzer", function() { it("Should only update prompts if repeatPrompts is At the end", function() { // Initialize variables - Quizzer.active = true; Quizzer.prompts = [ ["A1", "A2", "A3", "A4"], ["B1", "B2", "B3", "B4"], @@ -507,24 +430,8 @@ describe("Quizzer", function() { }); describe("Enter method", function() { - it("Shouldn't do anything if active is false", function() { - // Initialize variables - Quizzer.prompts = [["A1", "A2", "A3", "A4"], ["B1", "B2", "B3", "B4"]]; // Will change if Continue is called - Quizzer.index = 0; // Will be changed if Reset is called - Quizzer.settings.repeatPrompts = "At the end"; - - // Run Enter - Quizzer.Enter(); - - // Assert nothing changed - expect(Quizzer.prompts[0]).to.have.members(["A1", "A2", "A3", "A4"]); - expect(Quizzer.prompts[1]).to.have.members(["B1", "B2", "B3", "B4"]); - expect(Quizzer.index).to.equal(0); - }); - it("Should call Submit if responceActive is true", function() { // Initialize variables - Quizzer.active = true; Quizzer.responceActive = true; // Override Submit and Continue methods @@ -547,7 +454,6 @@ describe("Quizzer", function() { it("Should call Continue if responceActive is false", function() { // Initialize variables - Quizzer.active = true; Quizzer.responceActive = false; // Override Submit and Continue methods @@ -569,41 +475,6 @@ describe("Quizzer", function() { }); }); - describe("Active watch", function() { - it("Should update prompts and index", async function() { - // Initialize variables - Quizzer.startingPrompts = [["A1", "A2", "A3", "A4"], ["B1", "B2", "B3", "B4"]]; - Quizzer.startingIndex = 1; - - // Assert prompts and index not updated yet - expect(Quizzer.prompts.length).to.equal(0); - expect(Quizzer.index).to.equal(0); - - // Set active to true - Quizzer.active = true; - await Quizzer.$nextTick(); - - // Assert prompts and index updated - expect(Quizzer.prompts).to.have.deep.members([["A1", "A2", "A3", "A4"], ["B1", "B2", "B3", "B4"]]); - expect(Quizzer.index).to.equal(1); - }); - - it("Should call Reset when set to true", async function() { - // Override Reset method - let resetCalled = false; - Quizzer.Reset = function() { - resetCalled = true; - }; - - // Set active to true - Quizzer.active = true; - await Quizzer.$nextTick(); - - // Assert reset called - expect(resetCalled).to.equal(true); - }); - }); - describe("Prompt property", function() { it("Should be empty if there aren't any prompt", function() { // Assert prompts and index are correct diff --git a/tests/test.settings.js b/tests/test.settings.js @@ -1,1311 +0,0 @@ -describe("Settings", function() { - let Settings; - beforeEach(function() { - // Create settings component - Settings = new settings(); - }); - - describe("Created lifecycle hook", function() { - it("Category should be 'verbs'", function() { - expect(Settings.category).to.equal("verbs"); - }); - - it("VerFilters should be empty", function() { - expect(Settings.verbFilters.length).to.equal(0); - }); - - it("VocabFilters should be empty", function() { - expect(Settings.vocabFilters.length).to.equal(0); - }); - - it("Settings should be loaded", async function() { - // Save original setting from localStorage - let originalValue = localStorage.getItem("settings"); - - // Set localStorage settings - localStorage.setItem("settings", "{\"promptType\":\"Audio\",\"inputType\":\"Voice\",\"onMissedPrompt\":\"Tell me\",\"repeatPrompts\":\"5 prompts later\"}") - - // (re)Create settings component - Settings = new settings(); - await Settings.$nextTick(); // Allow Settings to update localStorage (so we can override it later) - - // Assert settings loaded - expect(Settings.settings.promptType).to.equal("Audio"); - expect(Settings.settings.inputType).to.equal("Voice"); - expect(Settings.settings.onMissedPrompt).to.equal("Tell me"); - expect(Settings.settings.repeatPrompts).to.equal("5 prompts later"); - expect(Settings.settings.multiplePrompts).to.equal("Show together"); - expect(Settings.settings.multipleAnswers).to.equal("Require all"); - - // Restore original setting to localStorage - localStorage.setItem("settings", originalValue); - }); - - it("Invalid individual settings should not be loaded", async function() { - // Save original setting from localStorage - let originalValue = localStorage.getItem("settings"); - - // Set localStorage settings - localStorage.setItem("settings", "{\"promptType\":\"Audio\",\"inputType\":\"test\",\"onMissedPrompt\":null}") - - // (re)Create settings component - Settings = new settings(); - await Settings.$nextTick(); // Allow Settings to update localStorage (so we can override it later) - - // Assert default settings loaded - expect(Settings.settings.promptType).to.equal("Audio"); // promptType wasn't invalid, so it should still be loaded - expect(Settings.settings.inputType).to.equal("Text"); - expect(Settings.settings.onMissedPrompt).to.equal("Correct me"); - expect(Settings.settings.repeatPrompts).to.equal("Never"); - - // Restore original setting to localStorage - localStorage.setItem("settings", originalValue); - }); - - it("Invalid JSON settings should not be loaded", async function() { - // Save original setting from localStorage - let originalValue = localStorage.getItem("settings"); - - // Set localStorage settings - localStorage.setItem("settings", "asdf") - - // (re)Create settings component - Settings = new settings(); - await Settings.$nextTick(); // Allow Settings to update localStorage (so we can override it later) - - // Assert default settings loaded - expect(Settings.settings.promptType).to.equal("Text"); - expect(Settings.settings.inputType).to.equal("Text"); - expect(Settings.settings.onMissedPrompt).to.equal("Correct me"); - expect(Settings.settings.repeatPrompts).to.equal("Never"); - - // Restore original setting to localStorage - localStorage.setItem("settings", originalValue); - }); - }); - - describe("AddFilter method", function() { - it("Should add a verb filter if category is 'verbs'", function() { - // Initialize variables - Settings.category = "verbs"; - expect(Settings.verbFilters.length).to.equal(0); - expect(Settings.vocabFilters.length).to.equal(0); - - // Add filter - Settings.AddFilter(); - - // Assert filter added - expect(Settings.verbFilters).to.have.deep.members([ - {tense:"All Tenses", type:"All Types", subject:"All Subjects", direction:"Eng. → Conj."}, - ]); - expect(Settings.vocabFilters).to.have.deep.members([]); - }); - - it("Should add a vocab filter if category is 'vocab'", function() { - // Initialize variables - Settings.category = "vocab"; - expect(Settings.verbFilters.length).to.equal(0); - expect(Settings.vocabFilters.length).to.equal(0); - - // Add filter - Settings.AddFilter(); - - // Assert filter added - expect(Settings.vocabFilters).to.have.deep.members([ - {set:"All Sets", type:"All Types", direction:"Eng. ↔ Esp."}, - ]); - expect(Settings.verbFilters).to.have.deep.members([]); - }); - }); - - describe("RemoveFilter method", function() { - it("Should remove the specified verb filter", function() { - // Initialize filters - Settings.category = "verbs"; - Settings.verbFilters = [ - "verb1", - "verb2", - "verb3", - ]; - Settings.vocabFilters = [ - "vocab1", - "vocab2", - "vocab3", - ]; - - // Remove filter - Settings.RemoveFilter(1); - - // Assert filter removed - expect(Settings.verbFilters.length).to.equal(2); - expect(Settings.verbFilters[0]).to.equal("verb1"); - expect(Settings.verbFilters[1]).to.equal("verb3"); - expect(Settings.vocabFilters.length).to.equal(3); - }); - - it("Should remove the specified vocab filter", function() { - // Initialize filters - Settings.category = "vocab"; - Settings.verbFilters = [ - "verb1", - "verb2", - "verb3", - ]; - Settings.vocabFilters = [ - "vocab1", - "vocab2", - "vocab3", - ]; - - // Remove filter - Settings.RemoveFilter(1); - - // Assert filter removed - expect(Settings.verbFilters.length).to.equal(3); - expect(Settings.vocabFilters.length).to.equal(2); - expect(Settings.vocabFilters[0]).to.equal("vocab1"); - expect(Settings.vocabFilters[1]).to.equal("vocab3"); - }); - }); - - describe("GetTenseTypes method", function() { - it("Should be correct for All Tenses", function() { - // Initialize filters - Settings.verbFilters = [ - {"tense":"All Types", "type":"All Types"} - ] - - // Get filters - let filters = Settings.getTenseTypes(0); - - // Assert filters are correct - expect(filters["All Types"]).to.equal(true); - expect(filters["Reflexive"]).to.equal(true); - expect(filters["Regular"]).to.equal(true); - expect(filters["Nonregular"]).to.equal(true); - expect(filters["Stem Changing"]).to.equal(true); - expect(filters["Orthographic"]).to.equal(true); - expect(filters["Irregular"]).to.equal(true); - }); - - it("Should be correct for Present Tense", function() { - // Initialize filters - Settings.verbFilters = [ - {"tense":"Present Tense", "type":"All Types"} - ] - - // Get filters - let filters = Settings.getTenseTypes(0); - - // Assert filters are correct - expect(filters["All Types"]).to.equal(true); - expect(filters["Reflexive"]).to.equal(true); - expect(filters["Regular"]).to.equal(true); - expect(filters["Nonregular"]).to.equal(true); - expect(filters["Stem Changing"]).to.equal(true); - expect(filters["Orthographic"]).to.equal(false); - expect(filters["Irregular"]).to.equal(true); - }); - - it("Should change selection if not available", function() { - // Initialize filters - Settings.verbFilters = [ - {"tense":"Present Tense", "type":"Orthographic"} - ] - - // Get filters - let filters = Settings.getTenseTypes(0); - - // Assert filters are correct - expect(filters["All Types"]).to.equal(true); - expect(filters["Reflexive"]).to.equal(true); - expect(filters["Regular"]).to.equal(true); - expect(filters["Nonregular"]).to.equal(true); - expect(filters["Stem Changing"]).to.equal(true); - expect(filters["Orthographic"]).to.equal(false); - expect(filters["Irregular"]).to.equal(true); - - // Assert selection changed - expect(Settings.verbFilters[0]["type"]).to.equal("All Types"); - }); - - it("Should not change selection if available", function() { - // Initialize filters - Settings.verbFilters = [ - {"tense":"Preterite Tense", "type":"Orthographic"} - ] - - // Get filters - let filters = Settings.getTenseTypes(0); - - // Assert filters are correct - expect(filters["All Types"]).to.equal(true); - expect(filters["Reflexive"]).to.equal(true); - expect(filters["Regular"]).to.equal(true); - expect(filters["Nonregular"]).to.equal(true); - expect(filters["Stem Changing"]).to.equal(true); - expect(filters["Orthographic"]).to.equal(true); - expect(filters["Irregular"]).to.equal(true); - - // Assert selection not changed - expect(Settings.verbFilters[0]["type"]).to.equal("Orthographic"); - }); - }); - - describe("GetTenseSubjects method", function() { - it("Should be correct for All Tenses", function() { - // Initialize filters - Settings.verbFilters = [ - {"tense":"All Types", "type":"All Types"} - ] - - // Get filters - let filters = Settings.getTenseSubjects(0); - - // Assert filters are correct - expect(filters["All Subjects"]).to.equal(true); - expect(filters["Yo"]).to.equal(true); - expect(filters["Tú"]).to.equal(true); - expect(filters["Él"]).to.equal(true); - expect(filters["Nosotros"]).to.equal(true); - expect(filters["Ellos"]).to.equal(true); - }); - - it("Should be correct for Present Participles", function() { - // Initialize filters - Settings.verbFilters = [ - {"tense":"Present Participles", "subject":"All Subjects", "type":"All Types"} - ] - - // Get filters - let filters = Settings.getTenseSubjects(0); - - // Assert filters are correct - expect(filters["All Subjects"]).to.equal(true); - expect(filters["Yo"]).to.equal(false); - expect(filters["Tú"]).to.equal(false); - expect(filters["Él"]).to.equal(false); - expect(filters["Nosotros"]).to.equal(false); - expect(filters["Ellos"]).to.equal(false); - }); - - it("Should change selection if not available", function() { - // Initialize filters - Settings.verbFilters = [ - {"tense":"Present Participles", "subject":"Yo", "type":"All Types"} - ] - - // Get filters - let filters = Settings.getTenseSubjects(0); - - // Assert filters are correct - expect(filters["All Subjects"]).to.equal(true); - expect(filters["Yo"]).to.equal(false); - expect(filters["Tú"]).to.equal(false); - expect(filters["Él"]).to.equal(false); - expect(filters["Nosotros"]).to.equal(false); - expect(filters["Ellos"]).to.equal(false); - - // Assert selection changed - expect(Settings.verbFilters[0]["subject"]).to.equal("All Subjects"); - }); - - it("Should not change selection if available", function() { - // Initialize filters - Settings.verbFilters = [ - {"tense":"Present Participles", "subject":"Type", "type":"All Types"}, - {"tense":"Preterite Tense", "subject":"Yo", "type":"All Types"}, - ] - - // Get filters - Settings.getTenseSubjects(0); - Settings.getTenseSubjects(1); - - // Assert selection not changed - expect(Settings.verbFilters[0].subject).to.equal("Type"); - expect(Settings.verbFilters[1].subject).to.equal("Yo"); - }); - }); - - describe("GetSetFilters method", function() { - it("Should be correct for Verbs", function() { - // Initialize filters - Settings.vocabFilters = [ - {"set":"Verbs", "type":"All Definitions"} - ] - - // Get filters - let filters = Settings.getSetFilters(0); - - // Assert filters are correct - expect(filters["All Types"]).to.equal(true); - expect(filters["Adjectives"]).to.equal(false); - expect(filters["Nouns"]).to.equal(false); - expect(filters["Verbs"]).to.equal(false); - }); - - it("Should be correct for sets with 1 type", function() { - // Initialize filters - Settings.vocabFilters = [ - {"set":"Colors", "type":"All Definitions"} - ] - - // Get filters - let filters = Settings.getSetFilters(0); - - // Assert filters are correct - expect(filters["All Types"]).to.equal(true); - expect(filters["Adjectives"]).to.equal(true); - expect(filters["Nouns"]).to.equal(false); - expect(filters["Verbs"]).to.equal(false); - }); - - it("Should change selection if not available", function() { - // Initialize filters - Settings.vocabFilters = [ - {"set":"Colors", "type":"Verbs"} - ] - - // Get filters - let filters = Settings.getSetFilters(0); - - // Assert selection changed - expect(filters["All Types"]).to.equal(true); - expect(filters["Adjectives"]).to.equal(true); - expect(filters["Nouns"]).to.equal(false); - expect(filters["Verbs"]).to.equal(false); - expect(Settings.vocabFilters[0]["type"]).to.equal("All Types"); - }); - - it("Should not change selection if available", function() { - // Initialize filters - Settings.vocabFilters = [ - {"set":"Professions", "type":"Verbs"} - ] - - // Get filters - let filters = Settings.getSetFilters(0); - - // Assert selection not changed - expect(filters["All Types"]).to.equal(true); - expect(filters["Adjectives"]).to.equal(false); - expect(filters["Nouns"]).to.equal(true); - expect(filters["Verbs"]).to.equal(true); - expect(Settings.vocabFilters[0]["type"]).to.equal("Verbs"); - }); - }); - - describe("Settings watch", function() { - it("Should update setting in localStorage", async function() { - // Save original setting from localStorage - let originalValue = localStorage.getItem("settings"); - - // Set settings - Settings.settings.promptType = "A"; - Settings.settings.inputType = "B"; - Settings.settings.onMissedPrompt = "C"; - Settings.settings.repeatPrompts = "D"; - Settings.settings.multiplePrompts = "E"; - Settings.settings.multipleAnswers = "F"; - await Settings.$nextTick(); - - // Assert localStorage setting updated - expect(localStorage.getItem("settings")).to.equal(`{"promptType":"A","inputType":"B","onMissedPrompt":"C","repeatPrompts":"D","multiplePrompts":"E","multipleAnswers":"F"}`); - - // Restore original setting to localStorage - localStorage.setItem("settings", originalValue); - }); - }); - - describe("GetVocabFilters method", function() { - it("Should correctly filter vocab for All Definitions", function() { - // Initialize expected - let expected = [ - {set:"Colors", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:".*"}, - {set:"Colors", outputIndex:1, inputIndex:0, filterIndex:2, filterValue:".*"}, - ]; - - // Filter vocab - let actual = GetVocabFilters([{set:"Colors", type:"All Types", direction:"Eng. ↔ Esp."}]); - - // Assert filtered vocab is correct - expect(actual).to.have.deep.members(expected); - }); - - it("Should correctly filter vocab for multiple filters", function() { - // Initialize expected - let expected = [ - {set:"Colors", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:".*"}, - {set:"Colors", outputIndex:1, inputIndex:0, filterIndex:2, filterValue:".*"}, - {set:"Months", outputIndex:1, inputIndex:0, filterIndex:2, filterValue:"Verb"}, - ]; - - // Filter vocab - let actual = GetVocabFilters([ - {set:"Colors", type:"All Types", direction:"Eng. ↔ Esp."}, - {set:"Months", type:"Verbs", direction:"Esp. → Eng."}, - ]); - - // Assert filtered vocab is correct - expect(actual).to.have.deep.members(expected); - }); - - describe("Direction filters", function() { - it("Should correctly filter vocab for English to Spanish", function() { - // Initialize expected - let expected = [ - {set:"Colors", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:".*"}, - ]; - - // Filter vocab - let actual = GetVocabFilters([{set:"Colors", type:"All Types", direction:"Eng. → Esp."}]); - - // Assert filtered vocab is correct - expect(actual).to.have.deep.members(expected); - }); - - it("Should correctly filter vocab for Spanish to English", function() { - // Initialize expected - let expected = [ - {set:"Colors", outputIndex:1, inputIndex:0, filterIndex:2, filterValue:".*"}, - ]; - - // Filter vocab - let actual = GetVocabFilters([{set:"Colors", type:"All Types", direction:"Esp. → Eng."}]); - - // Assert filtered vocab is correct - expect(actual).to.have.deep.members(expected); - }); - }); - - describe("Word Type filters", function() { - it("Should correctly filter vocab for Nouns", function() { - // Initialize expected - let expected = [ - {set:"Colors", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:"Noun"}, - {set:"Colors", outputIndex:1, inputIndex:0, filterIndex:2, filterValue:"Noun"}, - ]; - - // Filter vocab - let actual = GetVocabFilters([{set:"Colors", type:"Nouns", direction:"Eng. ↔ Esp."}]); - - // Assert filtered vocab is correct - expect(actual).to.have.deep.members(expected); - }); - - it("Should correctly filter vocab for Adjectives", function() { - // Initialize expected - let expected = [ - {set:"Colors", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:"Adjective"}, - {set:"Colors", outputIndex:1, inputIndex:0, filterIndex:2, filterValue:"Adjective"}, - ]; - - // Filter vocab - let actual = GetVocabFilters([{set:"Colors", type:"Adjectives", direction:"Eng. ↔ Esp."}]); - - // Assert filtered vocab is correct - expect(actual).to.have.deep.members(expected); - }); - - it("Should correctly filter vocab for Verbs", function() { - // Initialize expected - let expected = [ - {set:"Colors", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:"Verb"}, - {set:"Colors", outputIndex:1, inputIndex:0, filterIndex:2, filterValue:"Verb"}, - ]; - - // Filter vocab - let actual = GetVocabFilters([{set:"Colors", type:"Verbs", direction:"Eng. ↔ Esp."}]); - - // Assert filtered vocab is correct - expect(actual).to.have.deep.members(expected); - }); - - it("Should throw error for unknown word type", function() { - expect(() => GetVocabFilters([{set:"Colors", type:"test", direction:"Eng. ↔ Esp."}])).to.throw() - expect(() => GetVocabFilters([{set:"Colors", type:"", direction:"Eng. ↔ Esp."}])).to.throw() - expect(() => GetVocabFilters([{set:"Colors", type:1, direction:"Eng. ↔ Esp."}])).to.throw() - expect(() => GetVocabFilters([{set:"Colors", type:null, direction:"Eng. ↔ Esp."}])).to.throw() - }); - }); - }); - - describe("GetVerbFilters method", function() { - it("Should correctly filter verbs for All Conjugations", function() { - // Initialize expected - let expected = [ - {set:"Verbs", outputIndex:0, inputIndex:03, filterIndex:02, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:05, filterIndex:04, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:06, filterIndex:04, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:07, filterIndex:04, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:08, filterIndex:04, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:09, filterIndex:04, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:11, filterIndex:10, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:12, filterIndex:10, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:13, filterIndex:10, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:14, filterIndex:10, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:15, filterIndex:10, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:17, filterIndex:16, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:18, filterIndex:16, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:19, filterIndex:16, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:20, filterIndex:16, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:21, filterIndex:16, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:23, filterIndex:22, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:24, filterIndex:22, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:25, filterIndex:22, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:26, filterIndex:22, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:27, filterIndex:22, filterValue:".*"}, - ]; - - // Filter verbs - let actual = GetVerbFilters([{tense:"all tenses", subject:"all subjects", type:"all types", direction:"Eng. => Conj."}]); - - // Assert filtered verbs are correct - expect(actual).to.have.deep.members(expected); - }); - - it("Should correctly filter verbs for multiple filters", function() { - // Initialize expected - let expected = [ - {set:"Verbs", outputIndex:0, inputIndex:03, filterIndex:02, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:05, filterIndex:04, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:06, filterIndex:04, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:07, filterIndex:04, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:08, filterIndex:04, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:09, filterIndex:04, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:11, filterIndex:10, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:12, filterIndex:10, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:13, filterIndex:10, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:14, filterIndex:10, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:15, filterIndex:10, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:17, filterIndex:16, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:18, filterIndex:16, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:19, filterIndex:16, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:20, filterIndex:16, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:21, filterIndex:16, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:23, filterIndex:22, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:24, filterIndex:22, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:25, filterIndex:22, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:26, filterIndex:22, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:27, filterIndex:22, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - - {set:"Verbs", outputIndex:0, inputIndex:05, filterIndex:04, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:06, filterIndex:04, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:07, filterIndex:04, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:08, filterIndex:04, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:09, filterIndex:04, filterValue:".*"}, - - {set:"Verbs", outputIndex:03, inputIndex:1, filterIndex:02, filterValue:"Stem.?Changing"}, - {set:"Verbs", outputIndex:08, inputIndex:1, filterIndex:04, filterValue:"Stem.?Changing"}, - {set:"Verbs", outputIndex:14, inputIndex:1, filterIndex:10, filterValue:"Stem.?Changing"}, - {set:"Verbs", outputIndex:20, inputIndex:1, filterIndex:16, filterValue:"Stem.?Changing"}, - {set:"Verbs", outputIndex:26, inputIndex:1, filterIndex:22, filterValue:"Stem.?Changing"}, - ]; - - // Filter verbs - let actual = GetVerbFilters([ - { tense:"all tenses", subject:"all subjects", type:"Nonregular", direction:"Eng. => Conj." }, - { tense:"present tense", subject:"all subjects", type:"all types", direction:"Eng. => Conj." }, - { tense:"all tenses", subject:"nosotros", type:"stem changing", direction:"Conj. => Esp." } - ]); - - // Assert filtered verbs are correct - expect(actual).to.have.deep.members(expected); - }); - - describe("Tense filters", function() { - it("Should correctly filter verbs for Present Participles", function() { - // Initialize expected - let expected = [ - {set:"Verbs", outputIndex:0, inputIndex:3, filterIndex:2, filterValue:".*"}, - ]; - - // Filter verbs - let actual = GetVerbFilters([{tense:"Present Participles", subject:"all subjects", type:"all types", direction:"Eng. => Conj."}]); - - // Assert filtered verbs are correct - expect(actual).to.have.deep.members(expected); - }); - - it("Should correctly filter verbs for Present Tense", function() { - // Initialize expected - let expected = [ - {set:"Verbs", outputIndex:0, inputIndex:5, filterIndex:4, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:6, filterIndex:4, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:7, filterIndex:4, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:8, filterIndex:4, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:9, filterIndex:4, filterValue:".*"}, - ]; - - // Filter verbs - let actual = GetVerbFilters([{tense:"Present Tense", subject:"all subjects", type:"all types", direction:"Eng. => Conj."}]); - - // Assert filtered verbs are correct - expect(actual).to.have.deep.members(expected); - }); - - it("Should correctly filter verbs for Preterite Tense", function() { - // Initialize expected - let expected = [ - {set:"Verbs", outputIndex:0, inputIndex:11, filterIndex:10, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:12, filterIndex:10, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:13, filterIndex:10, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:14, filterIndex:10, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:15, filterIndex:10, filterValue:".*"}, - ]; - - // Filter verbs - let actual = GetVerbFilters([{tense:"Preterite Tense", subject:"all subjects", type:"all types", direction:"Eng. => Conj."}]); - - // Assert filtered verbs are correct - expect(actual).to.have.deep.members(expected); - }); - - it("Should correctly filter verbs for Imperfect Tense", function() { - // Initialize expected - let expected = [ - {set:"Verbs", outputIndex:0, inputIndex:17, filterIndex:16, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:18, filterIndex:16, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:19, filterIndex:16, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:20, filterIndex:16, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:21, filterIndex:16, filterValue:".*"}, - ]; - - // Filter verbs - let actual = GetVerbFilters([{tense:"Imperfect Tense", subject:"all subjects", type:"all types", direction:"Eng. => Conj."}]); - - // Assert filtered verbs are correct - expect(actual).to.have.deep.members(expected); - }); - - it("Should correctly filter verbs for Simple Future Tense", function() { - // Initialize expected - let expected = [ - {set:"Verbs", outputIndex:0, inputIndex:23, filterIndex:22, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:24, filterIndex:22, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:25, filterIndex:22, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:26, filterIndex:22, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:27, filterIndex:22, filterValue:".*"}, - ]; - - // Filter verbs - let actual = GetVerbFilters([{tense:"Simple Future Tense", subject:"all subjects", type:"all types", direction:"Eng. => Conj."}]); - - // Assert filtered verbs are correct - expect(actual).to.have.deep.members(expected); - }); - }); - - describe("Regularity filters", function() { - it("Should correctly filter regular verbs", function() { - // Initialize expected - let expected = [ - {set:"Verbs", outputIndex:0, inputIndex:03, filterIndex:02, filterValue:"Regular"}, - {set:"Verbs", outputIndex:0, inputIndex:05, filterIndex:04, filterValue:"Regular"}, - {set:"Verbs", outputIndex:0, inputIndex:06, filterIndex:04, filterValue:"Regular"}, - {set:"Verbs", outputIndex:0, inputIndex:07, filterIndex:04, filterValue:"Regular"}, - {set:"Verbs", outputIndex:0, inputIndex:08, filterIndex:04, filterValue:"Regular"}, - {set:"Verbs", outputIndex:0, inputIndex:09, filterIndex:04, filterValue:"Regular"}, - {set:"Verbs", outputIndex:0, inputIndex:11, filterIndex:10, filterValue:"Regular"}, - {set:"Verbs", outputIndex:0, inputIndex:12, filterIndex:10, filterValue:"Regular"}, - {set:"Verbs", outputIndex:0, inputIndex:13, filterIndex:10, filterValue:"Regular"}, - {set:"Verbs", outputIndex:0, inputIndex:14, filterIndex:10, filterValue:"Regular"}, - {set:"Verbs", outputIndex:0, inputIndex:15, filterIndex:10, filterValue:"Regular"}, - {set:"Verbs", outputIndex:0, inputIndex:17, filterIndex:16, filterValue:"Regular"}, - {set:"Verbs", outputIndex:0, inputIndex:18, filterIndex:16, filterValue:"Regular"}, - {set:"Verbs", outputIndex:0, inputIndex:19, filterIndex:16, filterValue:"Regular"}, - {set:"Verbs", outputIndex:0, inputIndex:20, filterIndex:16, filterValue:"Regular"}, - {set:"Verbs", outputIndex:0, inputIndex:21, filterIndex:16, filterValue:"Regular"}, - {set:"Verbs", outputIndex:0, inputIndex:23, filterIndex:22, filterValue:"Regular"}, - {set:"Verbs", outputIndex:0, inputIndex:24, filterIndex:22, filterValue:"Regular"}, - {set:"Verbs", outputIndex:0, inputIndex:25, filterIndex:22, filterValue:"Regular"}, - {set:"Verbs", outputIndex:0, inputIndex:26, filterIndex:22, filterValue:"Regular"}, - {set:"Verbs", outputIndex:0, inputIndex:27, filterIndex:22, filterValue:"Regular"}, - ]; - - // Filter verbs - let actual = GetVerbFilters([{tense:"all tenses", subject:"all subjects", type:"Regular", direction:"Eng. => Conj."}]); - - // Assert filtered verbs are correct - expect(actual).to.have.deep.members(expected); - }); - - it("Should correctly filter reflexive verbs", function() { - // Initialize expected - let expected = [ - {set:"Verbs", outputIndex:0, inputIndex:03, filterIndex:02, filterValue:"Reflexive"}, - {set:"Verbs", outputIndex:0, inputIndex:05, filterIndex:04, filterValue:"Reflexive"}, - {set:"Verbs", outputIndex:0, inputIndex:06, filterIndex:04, filterValue:"Reflexive"}, - {set:"Verbs", outputIndex:0, inputIndex:07, filterIndex:04, filterValue:"Reflexive"}, - {set:"Verbs", outputIndex:0, inputIndex:08, filterIndex:04, filterValue:"Reflexive"}, - {set:"Verbs", outputIndex:0, inputIndex:09, filterIndex:04, filterValue:"Reflexive"}, - {set:"Verbs", outputIndex:0, inputIndex:11, filterIndex:10, filterValue:"Reflexive"}, - {set:"Verbs", outputIndex:0, inputIndex:12, filterIndex:10, filterValue:"Reflexive"}, - {set:"Verbs", outputIndex:0, inputIndex:13, filterIndex:10, filterValue:"Reflexive"}, - {set:"Verbs", outputIndex:0, inputIndex:14, filterIndex:10, filterValue:"Reflexive"}, - {set:"Verbs", outputIndex:0, inputIndex:15, filterIndex:10, filterValue:"Reflexive"}, - {set:"Verbs", outputIndex:0, inputIndex:17, filterIndex:16, filterValue:"Reflexive"}, - {set:"Verbs", outputIndex:0, inputIndex:18, filterIndex:16, filterValue:"Reflexive"}, - {set:"Verbs", outputIndex:0, inputIndex:19, filterIndex:16, filterValue:"Reflexive"}, - {set:"Verbs", outputIndex:0, inputIndex:20, filterIndex:16, filterValue:"Reflexive"}, - {set:"Verbs", outputIndex:0, inputIndex:21, filterIndex:16, filterValue:"Reflexive"}, - {set:"Verbs", outputIndex:0, inputIndex:23, filterIndex:22, filterValue:"Reflexive"}, - {set:"Verbs", outputIndex:0, inputIndex:24, filterIndex:22, filterValue:"Reflexive"}, - {set:"Verbs", outputIndex:0, inputIndex:25, filterIndex:22, filterValue:"Reflexive"}, - {set:"Verbs", outputIndex:0, inputIndex:26, filterIndex:22, filterValue:"Reflexive"}, - {set:"Verbs", outputIndex:0, inputIndex:27, filterIndex:22, filterValue:"Reflexive"}, - ]; - - // Filter verbs - let actual = GetVerbFilters([{tense:"all tenses", subject:"all subjects", type:"Reflexive", direction:"Eng. => Conj."}]); - - // Assert filtered verbs are correct - expect(actual).to.have.deep.members(expected); - }); - - it("Should correctly filter stem changing verbs", function() { - // Initialize expected - let expected = [ - {set:"Verbs", outputIndex:0, inputIndex:03, filterIndex:02, filterValue:"Stem.?Changing"}, - {set:"Verbs", outputIndex:0, inputIndex:05, filterIndex:04, filterValue:"Stem.?Changing"}, - {set:"Verbs", outputIndex:0, inputIndex:06, filterIndex:04, filterValue:"Stem.?Changing"}, - {set:"Verbs", outputIndex:0, inputIndex:07, filterIndex:04, filterValue:"Stem.?Changing"}, - {set:"Verbs", outputIndex:0, inputIndex:08, filterIndex:04, filterValue:"Stem.?Changing"}, - {set:"Verbs", outputIndex:0, inputIndex:09, filterIndex:04, filterValue:"Stem.?Changing"}, - {set:"Verbs", outputIndex:0, inputIndex:11, filterIndex:10, filterValue:"Stem.?Changing"}, - {set:"Verbs", outputIndex:0, inputIndex:12, filterIndex:10, filterValue:"Stem.?Changing"}, - {set:"Verbs", outputIndex:0, inputIndex:13, filterIndex:10, filterValue:"Stem.?Changing"}, - {set:"Verbs", outputIndex:0, inputIndex:14, filterIndex:10, filterValue:"Stem.?Changing"}, - {set:"Verbs", outputIndex:0, inputIndex:15, filterIndex:10, filterValue:"Stem.?Changing"}, - {set:"Verbs", outputIndex:0, inputIndex:17, filterIndex:16, filterValue:"Stem.?Changing"}, - {set:"Verbs", outputIndex:0, inputIndex:18, filterIndex:16, filterValue:"Stem.?Changing"}, - {set:"Verbs", outputIndex:0, inputIndex:19, filterIndex:16, filterValue:"Stem.?Changing"}, - {set:"Verbs", outputIndex:0, inputIndex:20, filterIndex:16, filterValue:"Stem.?Changing"}, - {set:"Verbs", outputIndex:0, inputIndex:21, filterIndex:16, filterValue:"Stem.?Changing"}, - {set:"Verbs", outputIndex:0, inputIndex:23, filterIndex:22, filterValue:"Stem.?Changing"}, - {set:"Verbs", outputIndex:0, inputIndex:24, filterIndex:22, filterValue:"Stem.?Changing"}, - {set:"Verbs", outputIndex:0, inputIndex:25, filterIndex:22, filterValue:"Stem.?Changing"}, - {set:"Verbs", outputIndex:0, inputIndex:26, filterIndex:22, filterValue:"Stem.?Changing"}, - {set:"Verbs", outputIndex:0, inputIndex:27, filterIndex:22, filterValue:"Stem.?Changing"}, - ]; - - // Filter verbs - let actual = GetVerbFilters([{tense:"all tenses", subject:"all subjects", type:"Stem Changing", direction:"Eng. => Conj."}]); - - // Assert filtered verbs are correct - expect(actual).to.have.deep.members(expected); - }); - - it("Should correctly filter orthographic verbs", function() { - // Initialize expected - let expected = [ - {set:"Verbs", outputIndex:0, inputIndex:03, filterIndex:02, filterValue:"Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:05, filterIndex:04, filterValue:"Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:06, filterIndex:04, filterValue:"Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:07, filterIndex:04, filterValue:"Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:08, filterIndex:04, filterValue:"Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:09, filterIndex:04, filterValue:"Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:11, filterIndex:10, filterValue:"Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:12, filterIndex:10, filterValue:"Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:13, filterIndex:10, filterValue:"Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:14, filterIndex:10, filterValue:"Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:15, filterIndex:10, filterValue:"Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:17, filterIndex:16, filterValue:"Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:18, filterIndex:16, filterValue:"Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:19, filterIndex:16, filterValue:"Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:20, filterIndex:16, filterValue:"Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:21, filterIndex:16, filterValue:"Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:23, filterIndex:22, filterValue:"Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:24, filterIndex:22, filterValue:"Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:25, filterIndex:22, filterValue:"Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:26, filterIndex:22, filterValue:"Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:27, filterIndex:22, filterValue:"Orthographic"}, - ]; - - // Filter verbs - let actual = GetVerbFilters([{tense:"all tenses", subject:"all subjects", type:"Orthographic", direction:"Eng. => Conj."}]); - - // Assert filtered verbs are correct - expect(actual).to.have.deep.members(expected); - }); - - it("Should correctly filter irregular verbs", function() { - // Initialize expected - let expected = [ - {set:"Verbs", outputIndex:0, inputIndex:03, filterIndex:02, filterValue:"Irregular"}, - {set:"Verbs", outputIndex:0, inputIndex:05, filterIndex:04, filterValue:"Irregular"}, - {set:"Verbs", outputIndex:0, inputIndex:06, filterIndex:04, filterValue:"Irregular"}, - {set:"Verbs", outputIndex:0, inputIndex:07, filterIndex:04, filterValue:"Irregular"}, - {set:"Verbs", outputIndex:0, inputIndex:08, filterIndex:04, filterValue:"Irregular"}, - {set:"Verbs", outputIndex:0, inputIndex:09, filterIndex:04, filterValue:"Irregular"}, - {set:"Verbs", outputIndex:0, inputIndex:11, filterIndex:10, filterValue:"Irregular"}, - {set:"Verbs", outputIndex:0, inputIndex:12, filterIndex:10, filterValue:"Irregular"}, - {set:"Verbs", outputIndex:0, inputIndex:13, filterIndex:10, filterValue:"Irregular"}, - {set:"Verbs", outputIndex:0, inputIndex:14, filterIndex:10, filterValue:"Irregular"}, - {set:"Verbs", outputIndex:0, inputIndex:15, filterIndex:10, filterValue:"Irregular"}, - {set:"Verbs", outputIndex:0, inputIndex:17, filterIndex:16, filterValue:"Irregular"}, - {set:"Verbs", outputIndex:0, inputIndex:18, filterIndex:16, filterValue:"Irregular"}, - {set:"Verbs", outputIndex:0, inputIndex:19, filterIndex:16, filterValue:"Irregular"}, - {set:"Verbs", outputIndex:0, inputIndex:20, filterIndex:16, filterValue:"Irregular"}, - {set:"Verbs", outputIndex:0, inputIndex:21, filterIndex:16, filterValue:"Irregular"}, - {set:"Verbs", outputIndex:0, inputIndex:23, filterIndex:22, filterValue:"Irregular"}, - {set:"Verbs", outputIndex:0, inputIndex:24, filterIndex:22, filterValue:"Irregular"}, - {set:"Verbs", outputIndex:0, inputIndex:25, filterIndex:22, filterValue:"Irregular"}, - {set:"Verbs", outputIndex:0, inputIndex:26, filterIndex:22, filterValue:"Irregular"}, - {set:"Verbs", outputIndex:0, inputIndex:27, filterIndex:22, filterValue:"Irregular"}, - ]; - - // Filter verbs - let actual = GetVerbFilters([{tense:"all tenses", subject:"all subjects", type:"irregular", direction:"Eng. => Conj."}]); - - // Assert filtered verbs are correct - expect(actual).to.have.deep.members(expected); - }); - - it("Should correctly filter nonregular verbs", function() { - // Initialize expected - let expected = [ - {set:"Verbs", outputIndex:0, inputIndex:03, filterIndex:02, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:05, filterIndex:04, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:06, filterIndex:04, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:07, filterIndex:04, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:08, filterIndex:04, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:09, filterIndex:04, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:11, filterIndex:10, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:12, filterIndex:10, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:13, filterIndex:10, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:14, filterIndex:10, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:15, filterIndex:10, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:17, filterIndex:16, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:18, filterIndex:16, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:19, filterIndex:16, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:20, filterIndex:16, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:21, filterIndex:16, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:23, filterIndex:22, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:24, filterIndex:22, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:25, filterIndex:22, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:26, filterIndex:22, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - {set:"Verbs", outputIndex:0, inputIndex:27, filterIndex:22, filterValue:"Irregular|Stem.?Changing|Orthographic"}, - ]; - - // Filter verbs - let actual = GetVerbFilters([{tense:"all tenses", subject:"all subjects", type:"Nonregular", direction:"Eng. => Conj."}]); - - // Assert filtered verbs are correct - expect(actual).to.have.deep.members(expected); - }); - }); - - describe("Subject filters", function() { - it("Should correctly filter type subjects", function() { - // Initialize expected - let expected = [ - {set:"Verbs", outputIndex:0, inputIndex:02, filterIndex:02, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:04, filterIndex:04, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:10, filterIndex:10, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:16, filterIndex:16, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:22, filterIndex:22, filterValue:".*"}, - ]; - - // Filter verbs - let actual = GetVerbFilters([{tense:"all tenses", subject:"type", type:"all types", direction:"Eng. => Conj."}]); - - // Assert filtered verbs are correct - expect(actual).to.have.deep.members(expected); - }); - - it("Should correctly filter yo subjects", function() { - // Initialize expected - let expected = [ - {set:"Verbs", outputIndex:0, inputIndex:03, filterIndex:02, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:05, filterIndex:04, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:11, filterIndex:10, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:17, filterIndex:16, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:23, filterIndex:22, filterValue:".*"}, - ]; - - // Filter verbs - let actual = GetVerbFilters([{tense:"all tenses", subject:"yo", type:"all types", direction:"Eng. => Conj."}]); - - // Assert filtered verbs are correct - expect(actual).to.have.deep.members(expected); - }); - - it("Should correctly filter tú subjects", function() { - // Initialize expected - let expected = [ - {set:"Verbs", outputIndex:0, inputIndex:03, filterIndex:02, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:06, filterIndex:04, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:12, filterIndex:10, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:18, filterIndex:16, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:24, filterIndex:22, filterValue:".*"}, - ]; - - // Filter verbs - let actual = GetVerbFilters([{tense:"all tenses", subject:"tú", type:"all types", direction:"Eng. => Conj."}]); - - // Assert filtered verbs are correct - expect(actual).to.have.deep.members(expected); - }); - - it("Should correctly filter él subjects", function() { - // Initialize expected - let expected = [ - {set:"Verbs", outputIndex:0, inputIndex:03, filterIndex:02, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:07, filterIndex:04, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:13, filterIndex:10, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:19, filterIndex:16, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:25, filterIndex:22, filterValue:".*"}, - ]; - - // Filter verbs - let actual = GetVerbFilters([{tense:"all tenses", subject:"él", type:"all types", direction:"Eng. => Conj."}]); - - // Assert filtered verbs are correct - expect(actual).to.have.deep.members(expected); - }); - - it("Should correctly filter nosotros subjects", function() { - // Initialize expected - let expected = [ - {set:"Verbs", outputIndex:0, inputIndex:03, filterIndex:02, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:08, filterIndex:04, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:14, filterIndex:10, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:20, filterIndex:16, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:26, filterIndex:22, filterValue:".*"}, - ]; - - // Filter verbs - let actual = GetVerbFilters([{tense:"all tenses", subject:"nosotros", type:"all types", direction:"Eng. => Conj."}]); - - // Assert filtered verbs are correct - expect(actual).to.have.deep.members(expected); - }); - - it("Should correctly filter ellos subjects", function() { - // Initialize expected - let expected = [ - {set:"Verbs", outputIndex:0, inputIndex:03, filterIndex:02, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:09, filterIndex:04, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:15, filterIndex:10, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:21, filterIndex:16, filterValue:".*"}, - {set:"Verbs", outputIndex:0, inputIndex:27, filterIndex:22, filterValue:".*"}, - ]; - - // Filter verbs - let actual = GetVerbFilters([{tense:"all tenses", subject:"ellos", type:"all types", direction:"Eng. => Conj."}]); - - // Assert filtered verbs are correct - expect(actual).to.have.deep.members(expected); - }); - }); - - describe("Direction filters", function() { - it("Should correctly filter English to Conjugations", function() { - // Initialize expected - let expected = [ - {set:"Verbs", outputIndex:0, inputIndex:3, filterIndex:2, filterValue:".*"}, - ]; - - // Filter verbs - let actual = GetVerbFilters([{tense:"present participles", subject:"all subjects", type:"all types", direction:"Eng. => Conj."}]); - - // Assert filtered verbs are correct - expect(actual).to.have.deep.members(expected); - }); - - it("Should correctly filter Spanish to Conjugations", function() { - // Initialize expected - let expected = [ - {set:"Verbs", outputIndex:1, inputIndex:3, filterIndex:2, filterValue:".*"}, - ]; - - // Filter verbs - let actual = GetVerbFilters([{tense:"present participles", subject:"all subjects", type:"all types", direction:"Esp. => Conj."}]); - - // Assert filtered verbs are correct - expect(actual).to.have.deep.members(expected); - }); - - it("Should correctly filter Conjugations to English", function() { - // Initialize expected - let expected = [ - {set:"Verbs", outputIndex:3, inputIndex:0, filterIndex:2, filterValue:".*"}, - ]; - - // Filter verbs - let actual = GetVerbFilters([{tense:"present participles", subject:"all subjects", type:"all types", direction:"Conj. => Eng."}]); - - // Assert filtered verbs are correct - expect(actual).to.have.deep.members(expected); - }); - - it("Should correctly filter Conjugations to Spanish", function() { - // Initialize expected - let expected = [ - {set:"Verbs", outputIndex:3, inputIndex:1, filterIndex:2, filterValue:".*"}, - ]; - - // Filter verbs - let actual = GetVerbFilters([{tense:"present participles", subject:"all subjects", type:"all types", direction:"Conj. => Esp."}]); - - // Assert filtered verbs are correct - expect(actual).to.have.deep.members(expected); - }); - }); - }); - - describe("ApplyFilters method", function() { - // Initialize vocab - let vocab = { - "set1": [ - ["Upper", "Lower", "Type1", "Type2"], - ["A", "a", "Noun", "Vowel"], - ["B", "b", "Adjective", "Consonant"], - ["C", "c", "Verb", "Consonant"], - ], - "set2": [ - ["Upper", "Lower", "Type1", "Type2"], - ["Z", "z", "Noun", "Consonant"], - ["Y", "y", "Adjective", "Vowel,Consonant"], - ["X", "x", "Verb", "Consonant"], - ], - }; - - it("Should correctly filter different vocab sets", function() { - // Initialize expected - let expected = [ - ["Upper", "A", "Lower", "a"], - ["Upper", "B", "Lower", "b"], - ["Upper", "C", "Lower", "c"], - ["Upper", "X", "Lower", "x"], - ["Upper", "Y", "Lower", "y"], - ["Upper", "Z", "Lower", "z"], - ]; - - // Call ApplyFilters - let actual = ApplyFilters(vocab, [ - {set:"set1", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:".*"}, - {set:"set2", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:".*"}, - ]); - - // Assert filtered vocab is correct - expect(actual).to.have.deep.members(expected); - }); - - it("Should correctly filter different outputIndexes", function() { - // Initialize expected - let expected = [ - ["Upper", "A", "Lower", "a"], - ["Upper", "B", "Lower", "b"], - ["Upper", "C", "Lower", "c"], - ["Type2", "Vowel", "Lower", "a"], - ["Type2", "Consonant", "Lower", "b"], - ["Type2", "Consonant", "Lower", "c"], - ]; - - // Call ApplyFilters - let actual = ApplyFilters(vocab, [ - {set:"set1", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:".*"}, - {set:"set1", outputIndex:3, inputIndex:1, filterIndex:2, filterValue:".*"}, - ]); - - // Assert filtered vocab is correct - expect(actual).to.have.deep.members(expected); - }); - - it("Should correctly filter different inputIndexes", function() { - // Initialize expected - let expected = [ - ["Upper", "A", "Lower", "a"], - ["Upper", "B", "Lower", "b"], - ["Upper", "C", "Lower", "c"], - ["Upper", "A", "Type2", "Vowel"], - ["Upper", "B", "Type2", "Consonant"], - ["Upper", "C", "Type2", "Consonant"], - ]; - - // Call ApplyFilters - let actual = ApplyFilters(vocab, [ - {set:"set1", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:".*"}, - {set:"set1", outputIndex:0, inputIndex:3, filterIndex:2, filterValue:".*"}, - ]); - - // Assert filtered vocab is correct - expect(actual).to.have.deep.members(expected); - }); - - it("Should correctly filter different filterIndexes and filtervalues", function() { - // Initialize expected - let expected = [ - ["Upper", "C", "Lower", "c"], - ["Upper", "A", "Lower", "a"], - ]; - - // Call ApplyFilters - let actual = ApplyFilters(vocab, [ - {set:"set1", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:"Verb"}, - {set:"set1", outputIndex:0, inputIndex:1, filterIndex:3, filterValue:"Vowel"}, - ]); - - // Assert filtered vocab is correct - expect(actual).to.have.deep.members(expected); - }); - - describe("multiplePrompts setting", function() { - // Initialize vocab2 - let vocab2 = { - "set1": [ - ["Upper", "Lower", "Type1"], - ["A1, A2 , A3", "a", "Noun"], - ["B1, B2", "b", "Adjective"], - ["C", "c", "Verb"], - ], - }; - - it("Shouldn't effect single prompts", function() { - // Initialize expected - let expected = [ - ["Upper", "C", "Lower", "c"], - ]; - - // Call ApplyFilters - let actual = ApplyFilters(vocab2, [{set:"set1", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:"Verb"}], "Show separately"); - - // Assert filtered vocab is correct - expect(actual).to.have.deep.members(expected); - }); - - it("Should't effect prompts if equal to 'Show together'", function() { - // Initialize expected - let expected = [ - ["Upper", "A1, A2 , A3", "Lower", "a"], - ["Upper", "B1, B2", "Lower", "b"], - ]; - - // Call ApplyFilters - let actual = ApplyFilters(vocab2, [{set:"set1", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:"Noun|Adjective"}], "Show together"); - - // Assert filtered vocab is correct - expect(actual).to.have.deep.members(expected); - }); - - it("Should split up prompts if equal to 'Show separately'", function() { - // Initialize expected - let expected = [ - ["Upper", "A1", "Lower", "a"], - ["Upper", "A2", "Lower", "a"], - ["Upper", "A3", "Lower", "a"], - ["Upper", "B1", "Lower", "b"], - ["Upper", "B2", "Lower", "b"], - ]; - - // Call ApplyFilters - let actual = ApplyFilters(vocab2, [{set:"set1", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:"Noun|Adjective"}], "Show separately"); - - // Assert filtered vocab is correct - expect(actual).to.have.deep.members(expected); - }); - - it("Should correctly filter prompts if equal to 'Show one' (Math.random returns 0)", function() { - // Initialize expected - let expected = [ - ["Upper", "A1", "Lower", "a"], - ["Upper", "B1", "Lower", "b"], - ]; - - // Copy original Math.random method - let random = Math.random; - - try { - // Override Math.random method - Math.random = function() { - return 0; - } - - // Call ApplyFilters - let actual = ApplyFilters(vocab2, [{set:"set1", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:"Noun|Adjective"}], "Show one"); - - // Assert filtered vocab is correct - expect(actual).to.have.deep.members(expected); - } - finally { - // Restore Math.random method - Math.random = random; - } - }); - - it("Should correctly filter prompts if equal to 'Show one' (Math.random returns 0.5)", function() { - // Initialize expected - let expected = [ - ["Upper", "A2", "Lower", "a"], - ["Upper", "B1", "Lower", "b"], - ]; - - // Copy original Math.random method - let random = Math.random; - - try { - // Override Math.random method - Math.random = function() { - return 0.5; - } - - // Call ApplyFilters - let actual = ApplyFilters(vocab2, [{set:"set1", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:"Noun|Adjective"}], "Show one"); - - // Assert filtered vocab is correct - expect(actual).to.have.deep.members(expected); - } - finally { - // Restore Math.random method - Math.random = random; - } - }); - - it("Should correctly filter prompts if equal to 'Show one' (Math.random returns 1)", function() { - // Initialize expected - let expected = [ - ["Upper", "A3", "Lower", "a"], - ["Upper", "B2", "Lower", "b"], - ]; - - // Copy original Math.random method - let random = Math.random; - - try { - // Override Math.random method - Math.random = function() { - return 1; - } - - // Call ApplyFilters - let actual = ApplyFilters(vocab2, [{set:"set1", outputIndex:0, inputIndex:1, filterIndex:2, filterValue:"Noun|Adjective"}], "Show one"); - - // Assert filtered vocab is correct - expect(actual).to.have.deep.members(expected); - } - finally { - // Restore Math.random method - Math.random = random; - } - }); - }); - }); - - describe("Shuffle method", function() { - it("Should not alter list", function() { - // Initialize list - let list1 = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o"]; // 15 items - - // Shuffle list - let list2 = Shuffle(list1); - - // Assert list shuffled - expect(list2.length).to.equal(list1.length); - for (let item of list2) { - expect(list1.includes(item)).to.equal(true); - } - }); - }); -}); diff --git a/tests/test.settingsInput.js b/tests/test.settingsInput.js @@ -0,0 +1,60 @@ +describe("SettingsInput", function() { + let SettingsInput; + beforeEach(function() { + // Create settingsInput component + SettingsInput = new settingsInput(); + }); + + describe("Value watch", function() { + it("Should emit input event", async function() { + // Override $emit method + let event = ""; + let event_args; + SettingsInput.$emit = function(name, value) { + event = name; + event_args = value; + }; + + // Override setSettings method + let old_setSettings = setSettings; + setSettings = function() {}; + + // Edit setting + SettingsInput.value.promptType = "test-prompt-type"; + await SettingsInput.$nextTick(); + + // Assert event emited + expect(event).to.equal("input"); + expect(event_args.promptType).to.equal("test-prompt-type"); + + // Restore setSettings method + setSettings = old_setSettings; + }); + + it("Should call setSettings", async function() { + // Override $emit method + let event = ""; + let event_args; + SettingsInput.$emit = function(name, value) { + event = name; + event_args = value; + }; + + // Override setSettings method + let old_setSettings = setSettings; + let args = null; + setSettings = function(value) { + args = value; + }; + + // Edit setting + SettingsInput.value.inputType = "test-input-type"; + await SettingsInput.$nextTick(); + // Assert setSettings called + expect(args.inputType).to.equal("test-input-type"); + + // Restore setSettings method + setSettings = old_setSettings; + }); + }); +});