commit 6e9b17b31dbeb8ba7e4503608f4156e34116e5f0
parent 3dc3c57588308f3946d67235202636e8bc2dbe25
Author: AsherMorgan <59518073+AsherMorgan@users.noreply.github.com>
Date: Sun, 18 Oct 2020 19:48:32 -0700
Merge pull request #22 from AsherMorgan/settings-component
Implement settings component.
Diffstat:
| M | css/settings.css | | | 43 | ++++++++++++++++++------------------------- |
| M | index.html | | | 135 | ++----------------------------------------------------------------------------- |
| M | js/home.js | | | 260 | ++++++++++++++----------------------------------------------------------------- |
| M | js/settings.js | | | 528 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------ |
| M | tests/test.app.js | | | 389 | ++++++++----------------------------------------------------------------------- |
| M | tests/test.settings.js | | | 433 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- |
6 files changed, 904 insertions(+), 884 deletions(-)
diff --git a/css/settings.css b/css/settings.css
@@ -1,22 +1,22 @@
/* Settings */
-#settings {
+.settings {
display: flex;
flex-direction: column;
align-items: center;
}
-#settings[hidden] {
+.settings[hidden] {
display: none;
}
-#settings h1 {
+.settings h1 {
font-size: 16px;
font-weight: normal;
margin-bottom: 10px;
}
-#settings h2 {
+.settings h2 {
font-size: 20px;
margin-bottom: 5px;
}
-#vocabSettings, #verbSettings, #quizzerSettings, #studyMethodDiv {
+.vocabSettings, .verbSettings, .quizzerSettings {
margin-left: 5px;
margin-right: 5px;
margin-top: 10px;
@@ -25,7 +25,7 @@
/* Filters */
-#vocabSettings h2 button, #verbSettings h2 button {
+.vocabSettings h2 button, .verbSettings h2 button {
padding: 3px;
}
.filter {
@@ -49,21 +49,21 @@
/* Quizzer Settings div */
-#quizzerSettings div {
+.quizzerSettings div {
text-align: left;
}
-#quizzerSettings input[type=number] {
+.quizzerSettings input[type=number] {
width: 50px;
}
/* Start/Resume Buttons */
-#settingButtons {
+.settingButtons {
margin-top: 20px;
margin-bottom: 10px;
}
-#settingButtons button {
+.settingButtons button {
width: 100px;
height: 40px;
font-size: 18px;
@@ -71,10 +71,10 @@
}
@media only screen and (max-width: 510px) {
/* Expand Start/Resume buttons */
- #settingButtons {
+ .settingButtons {
width: calc(100% - 10px);
}
- #settingButtons button {
+ .settingButtons button {
width: calc(50% - 15px);
height: 50px;
}
@@ -82,23 +82,16 @@
-/* Error Message */
-#settingsError {
- margin: 0px 10px;
-}
-
-
-
/* Conjugation settings on mobile devices */
@media only screen and (max-width: 510px) {
- #verbSettings {
+ .verbSettings {
width: calc(100% - 20px);
}
- #verbSettings .filter {
+ .verbSettings .filter {
width: 100%;
margin: 10px auto;
}
- #verbSettings .filter select, #verbSettings .filter button {
+ .verbSettings .filter select, .verbSettings .filter button {
width: 100%;
height: 30px;
margin: 3px 0px;
@@ -109,14 +102,14 @@
/* Vocab settings on mobile devices */
@media only screen and (max-width: 350px) {
- #vocabSettings {
+ .vocabSettings {
width: calc(100% - 20px);
}
- #vocabSettings .filter {
+ .vocabSettings .filter {
width: 100%;
margin: 10px auto;
}
- #vocabSettings .filter select, #vocabSettings s.filter button {
+ .vocabSettings .filter select, .vocabSettings s.filter button {
width: 100%;
height: 30px;
margin: 3px 0px;
diff --git a/index.html b/index.html
@@ -46,138 +46,9 @@
</div>
- <div id="settings" v-show="state === 'verbSettings' || state === 'vocabSettings'" hidden>
- <div id="verbSettings" v-show="state === 'verbSettings'">
- <h1>Choose your settings and then click start.</h1>
-
- <h2>
- Verb Filters
- <button @click="AddVerbFilter();">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>
- </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="RemoveVerbFilter(index);">╳</button>
- </div>
- </div>
-
-
- <div id="vocabSettings" v-show="state === 'vocabSettings'">
- <h1>Choose your settings and then click start.</h1>
-
- <h2>
- Vocabulary Sets
- <button @click="AddVocabFilter();">Add set</button>
- </h2>
-
- <div v-for="(filter, index) in vocabFilters" class="filter">
- <select class="vocabSetName" v-model="filter.set">
- <optgroup label="Common Words">
- <option>Verbs</option>
- <option>Adjectives</option>
- <option>Adverbs</option>
- <option>Prepositions</option>
- <option>Transitions</option>
- </optgroup>
- <optgroup label="Spanish 1">
- <option>Colors</option>
- <option>Days</option>
- <option>Months</option>
- <option>Questions</option>
- <option>Weather</option>
- <option>Family</option>
- <option>Clothes</option>
- </optgroup>
- <optgroup label="Spanish 2">
- <option>Nature</option>
- <option>House</option>
- <option>Vacation</option>
- <option>Childhood</option>
- <option>Professions</option>
- <option>Health</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="RemoveVocabFilter(index);">╳</button>
- </div>
- </div>
-
-
- <div id="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="promptType">
- <option>Text</option>
- <option>Audio</option>
- <option>Both</option>
- </select>
- </div>
- <div>
- <label for="settingsInputType">Input type</label>
- <select id="settingsInputType" v-model="inputType">
- <option>Text</option>
- <option>Voice</option>
- <option>Either</option>
- </select>
- </div>
- <div>
- <label for="settingsRepeatPrompts">When I miss a prompt</label>
- <select id="settingsRepeatPrompts" v-model="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="repeatPrompts">
- <option>Never</option>
- <option>Immediately</option>
- <option>5 prompts later</option>
- <option>At the end</option>
- </select>
- </div>
- </div>
-
- <div id="settingButtons">
- <button id="settingsStart" onclick="CreateSession();">Start</button>
- <button id="settingsResume" onclick="ResumeSession();">Resume</button>
- </div>
-
- <div id="settingsError" v-show="errorMsg" class="centered bad">{{ errorMsg }}</div>
- </div>
-
+ <settings id="settings" v-show="state === 'verbSettings' || state === 'vocabSettings'" hidden
+ :category="state === 'verbSettings' ? 'verbs' : 'vocab'" @start-session="StartSession">
+ </settings>
<quizzer id="quizzer" v-show="state === 'verbQuizzer' || state === 'vocabQuizzer'" :active="state === 'verbQuizzer' || state === 'vocabQuizzer'" hidden
:starting-index="promptIndex" :starting-prompts="prompts" @new-prompt="updateProgress"
diff --git a/js/home.js b/js/home.js
@@ -13,14 +13,10 @@ function loadVue() {
data: {
state: "home",
- darkTheme: document.body.classList.contains("dark"),
- verbFilters: [],
- vocabFilters: [],
- errorMsg: "",
- promptType: localStorage.getItem("promptType") || "Text",
- inputType: localStorage.getItem("inputType") || "Text",
- onMissedPrompt: localStorage.getItem("onMissedPrompt") || "Correct me",
- repeatPrompts: localStorage.getItem("repeatPrompts") || "Never",
+ promptType: "Text",
+ inputType: "Text",
+ onMissedPrompt: "Correct me",
+ repeatPrompts: "Never",
prompts: [],
promptIndex: 0,
@@ -48,172 +44,6 @@ function loadVue() {
},
/**
- * Add a verb filter on the settings page.
- */
- AddVerbFilter: function() {
- this.verbFilters.push({tense:"All Tenses", type:"All Types", subject:"All Subjects", direction:"Eng. → Conj."});
- },
-
- /**
- * Remove a verb filter from the settings page.
- * @param {Number} index - The index of the verb filter.
- */
- RemoveVerbFilter: function(index) {
- // Remove filter
- this.verbFilters.splice(index, 1);
- },
-
- /**
- * Add a vocab filter on the settings page.
- */
- AddVocabFilter: function() {
- this.vocabFilters.push({set:"Verbs", type:"All Types", direction:"Eng. ↔ Esp."});
- },
-
- /**
- * Remove a vocab filter from the settings page.
- * @param {Number} index - The index of the vocab filter.
- */
- RemoveVocabFilter: function(index) {
- // Remove filter
- 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;
- }
-
- // 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, "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
- 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;
- },
-
- /**
* Update the user's progress in localStorage.
* @param {Array} prompts - The list of prompts.
* @param {Number} index - The index of the current prompt.
@@ -234,55 +64,55 @@ function loadVue() {
// Save progress to local storage
localStorage.setItem(prefix + "prompts", JSON.stringify(prompts));
localStorage.setItem(prefix + "prompt", JSON.stringify(index));
- }
- },
-
- watch: {
- /**
- * Update the app theme.
- */
- darkTheme: function(value) {
- SetTheme(value);
},
/**
- * Update the promptType setting in localStorage.
- * @param {String} value - The prompt type.
+ * 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 {String} promptType - The prompt type.
+ * @param {String} inputType - The input type.
+ * @param {String} onMissedPrompt - The onMissedPrompt setting value.
+ * @param {String} repeatPrompts - The repeat prompts setting value.
*/
- promptType: function(value) {
- localStorage.setItem("promptType", value);
- },
+ StartSession: function(prompts, promptIndex, promptType, inputType, onMissedPrompt, repeatPrompts) {
+ // Validate browser for voice input
+ if (this.inputType !== "Text") {
+ if (typeof InstallTrigger !== "undefined") {
+ // Browser is Firefox
+ alert("You must enable speech recognition in about:config.");
+ }
+ else if (!window.chrome || (!window.chrome.webstore && !window.chrome.runtime)) {
+ // Browser is not Googole Chrome or Microsoft (Chromium) Edge
+ alert("Your browser does not support voice input.");
+ return;
+ }
+ }
- /**
- * Update the inputType setting in localStorage.
- * @param {String} value - The input type.
- */
- inputType: function(value) {
- localStorage.setItem("inputType", value);
- },
+ // Give iOS devices ringer warning for prompt audio
+ if (this.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.");
+ }
+ }
- /**
- * Update the onMissedPrompt setting in localStorage.
- * @param {String} value - The onMissedPrompt setting value.
- */
- onMissedPrompt: function(value) {
- localStorage.setItem("onMissedPrompt", value);
- },
+ // Copy over prompts and promptIndex
+ this.prompts = prompts;
+ this.promptIndex = promptIndex;
- /**
- * Update the repeatPrompts setting in localStorage.
- * @param {String} value - The repeat prompts setting value.
- */
- repeatPrompts: function(value) {
- localStorage.setItem("repeatPrompts", value);
- },
+ // Copy over settings
+ this.promptType = promptType
+ this.inputType = inputType
+ this.onMissedPrompt = onMissedPrompt
+ this.repeatPrompts = repeatPrompts
- /**
- * Clear the error message when the state changes.
- */
- state: function() {
- // Reset error message
- app.errorMsg = "";
+ // Show and hide elements (also enables the quizzer)
+ if (this.state === "verbSettings") {
+ this.state = "verbQuizzer";
+ }
+ else if (this.state === "vocabSettings") {
+ this.state = "vocabQuizzer";
+ }
}
},
});
diff --git a/js/settings.js b/js/settings.js
@@ -1,132 +1,428 @@
-/**
- * Start a new quizzer session
- */
-function CreateSession() {
- // Get prompts
- if (app.state === "vocabSettings") {
- // Filter and load Sets into prompts
- app.prompts = [];
- for (let filter of app.vocabFilters)
- {
- // Add filtered set
- app.prompts.push(...ApplyVocabFilter(Sets[filter.set], filter.type, filter.direction));
- }
+let settings = Vue.component("settings", {
+ props: {
+ category: {
+ type: Boolean,
+ default: "verbs",
+ },
+ },
- // Shuffle prompts
- app.prompts = Shuffle(app.prompts);
- }
- else if (app.state === "verbSettings") {
- // Get prompts
- app.prompts = Shuffle(ApplyVerbFilter(Sets["Verbs"], app.verbFilters));
- }
+ data: function() {
+ return {
+ darkTheme: document.body.classList.contains("dark"),
+ verbFilters: [],
+ vocabFilters: [],
+ promptType: localStorage.getItem("promptType") || "Text",
+ inputType: localStorage.getItem("inputType") || "Text",
+ onMissedPrompt: localStorage.getItem("onMissedPrompt") || "Correct me",
+ repeatPrompts: localStorage.getItem("repeatPrompts") || "Never",
+ };
+ },
- // Set progress
- app.promptIndex = 0;
-
- // Start quizzer
- try {
- StartSession();
- }
- catch (e) {
- switch (e) {
- case "Terms is empty.":
- app.errorMsg = "Your custom vocabulary set must contain at least one term.";
- document.getElementById("settingsError").scrollIntoView(false);
- break;
- default:
- app.errorMsg = "An error occured.";
- document.getElementById("settingsError").scrollIntoView(false);
- throw e;
- }
- }
-}
+ 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:"Verbs", 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;
+ }
-/**
- * Resume the previous quizzer session.
- */
-function ResumeSession() {
- // Get localStorage prefix
- let prefix;
- if (app.state === "vocabSettings") {
- prefix = "vocab-"
- }
- else if (app.state === "verbSettings") {
- prefix = "verb-"
- }
+ // Reset type if needed
+ if (!filters[this.verbFilters[index].type]) {
+ this.verbFilters[index].type = "All Types";
+ }
- // Load prompts and progress
- app.prompts = JSON.parse(localStorage.getItem(prefix + "prompts"));
- app.promptIndex = parseInt(localStorage.getItem(prefix + "prompt"));
+ // Return filters
+ return filters;
+ },
- // Start quizzer
- try {
- StartSession();
- }
- catch (e) {
- switch (e) {
- case "Bad arguments.":
- app.errorMsg = "An error occured while resuming the previous session.";
- document.getElementById("settingsError").scrollIntoView(false);
- break;
- case "Terms is empty.":
- app.errorMsg = "Your custom vocabulary set must contain at least one term.";
- document.getElementById("settingsError").scrollIntoView(false);
- break;
- default:
- app.errorMsg = "An error occured.";
- document.getElementById("settingsError").scrollIntoView(false);
- throw e;
- }
- }
-}
+ /**
+ * 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, "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
+ 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;
-/**
- * Perform validation checks and then start the quizzer.
- */
-function StartSession() {
- // Validate prompts and promptIndex
- if (!app.prompts) {
- throw "Bad arguments.";
- }
- else if (app.prompts.length === 0) {
- throw "Terms is empty.";
- }
- else if (isNaN(app.promptIndex) || app.promptIndex < 0 || app.promptIndex >= app.prompts.length) {
- throw "Bad arguments.";
- }
+ case "Adverbs":
+ filters["Adjectives"] = false;
+ filters["Nouns"] = false;
+ filters["Verbs"] = false;
+ break;
- // Validate browser for voice input
- if (app.inputType !== "Text") {
- if (typeof InstallTrigger !== "undefined") {
- // Browser is Firefox
- alert("You must enable speech recognition in about:config.");
- }
- else if (!window.chrome || (!window.chrome.webstore && !window.chrome.runtime)) {
- // Browser is not Googole Chrome or Microsoft (Chromium) Edge
- alert("Your browser does not support voice input.");
- return;
- }
- }
+ 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;
- // Give iOS devices ringer warning for prompt audio
- if (app.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.");
- }
- }
+ case "Family":
+ case "Clothes":
+ filters["Verbs"] = false;
+ break;
+
+ case "Nature":
+ case "House":
+ case "Vacation":
+ case "Childhood":
+ case "Health":
+ break;
+ }
- // Show and hide elements (also enables the quizzer)
- if (app.state === "verbSettings") {
- app.state = "verbQuizzer";
- }
- else if (app.state === "vocabSettings") {
- app.state = "vocabQuizzer";
- }
-}
+ // 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") {
+ // Filter and load Sets into prompts
+ prompts = [];
+ for (let filter of this.vocabFilters)
+ {
+ // Add filtered set
+ prompts.push(...ApplyVocabFilter(Sets[filter.set], filter.type, filter.direction));
+ }
+
+ // Shuffle prompts
+ prompts = Shuffle(prompts);
+ }
+ else if (this.category === "verbs") {
+ // Get prompts
+ prompts = Shuffle(ApplyVerbFilter(Sets["Verbs"], this.verbFilters));
+ }
+
+ // 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.promptType, this.inputType, this.onMissedPrompt, this.repeatPrompts);
+ },
+
+ /**
+ * 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.promptType, this.inputType, this.onMissedPrompt, this.repeatPrompts);
+ },
+ },
+
+ watch: {
+ /**
+ * Update the app theme.
+ */
+ darkTheme: function(value) {
+ SetTheme(value);
+ },
+
+ /**
+ * Update the promptType setting in localStorage.
+ * @param {String} value - The prompt type.
+ */
+ promptType: function(value) {
+ localStorage.setItem("promptType", value);
+ },
+
+ /**
+ * Update the inputType setting in localStorage.
+ * @param {String} value - The input type.
+ */
+ inputType: function(value) {
+ localStorage.setItem("inputType", value);
+ },
+
+ /**
+ * Update the onMissedPrompt setting in localStorage.
+ * @param {String} value - The onMissedPrompt setting value.
+ */
+ onMissedPrompt: function(value) {
+ localStorage.setItem("onMissedPrompt", value);
+ },
+
+ /**
+ * Update the repeatPrompts setting in localStorage.
+ * @param {String} value - The repeat prompts setting value.
+ */
+ repeatPrompts: function(value) {
+ localStorage.setItem("repeatPrompts", value);
+ },
+ },
+
+ template: `
+ <div class="settings">
+ <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>
+ </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">
+ <optgroup label="Common Words">
+ <option>Verbs</option>
+ <option>Adjectives</option>
+ <option>Adverbs</option>
+ <option>Prepositions</option>
+ <option>Transitions</option>
+ </optgroup>
+ <optgroup label="Spanish 1">
+ <option>Colors</option>
+ <option>Days</option>
+ <option>Months</option>
+ <option>Questions</option>
+ <option>Weather</option>
+ <option>Family</option>
+ <option>Clothes</option>
+ </optgroup>
+ <optgroup label="Spanish 2">
+ <option>Nature</option>
+ <option>House</option>
+ <option>Vacation</option>
+ <option>Childhood</option>
+ <option>Professions</option>
+ <option>Health</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="promptType">
+ <option>Text</option>
+ <option>Audio</option>
+ <option>Both</option>
+ </select>
+ </div>
+ <div>
+ <label for="settingsInputType">Input type</label>
+ <select id="settingsInputType" v-model="inputType">
+ <option>Text</option>
+ <option>Voice</option>
+ <option>Either</option>
+ </select>
+ </div>
+ <div>
+ <label for="settingsRepeatPrompts">When I miss a prompt</label>
+ <select id="settingsRepeatPrompts" v-model="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="repeatPrompts">
+ <option>Never</option>
+ <option>Immediately</option>
+ <option>5 prompts later</option>
+ <option>At the end</option>
+ </select>
+ </div>
+ </div>
+
+ <div class="settingButtons">
+ <button class="settingsStart" @click="CreateSession();">Start</button>
+ <button class="settingsResume" @click="ResumeSession();">Resume</button>
+ </div>
+ </div>
+ `,
+});
diff --git a/tests/test.app.js b/tests/test.app.js
@@ -9,20 +9,24 @@ describe("App", function() {
expect(app.state).to.equal("home");
});
- it("VerFilters should be empty", function() {
- expect(app.verbFilters.length).to.equal(0);
+ it("PromptType should be 'Text'", function() {
+ expect(app.promptType).to.equal("Text");
});
- it("VocabFilters should be empty", function() {
- expect(app.vocabFilters.length).to.equal(0);
+ it("InputType should be 'Text'", function() {
+ expect(app.inputType).to.equal("Text");
});
- it("ErrorMsg should be empty", function() {
- expect(app.errorMsg).to.equal("");
+ it("OnMissedPrompt should be 'Correct me'", function() {
+ expect(app.onMissedPrompt).to.equal("Correct me");
+ });
+
+ it("RepeatPrompts should be 'Never'", function() {
+ expect(app.repeatPrompts).to.equal("Never");
});
it("Prompts should be empty", function() {
- expect(app.vocabFilters.length).to.equal(0);
+ expect(app.prompts.length).to.equal(0);
});
it("PromptIndex should be 0", function() {
@@ -75,361 +79,40 @@ describe("App", function() {
});
});
- describe("AddVerbFilter method", function() {
- it("Should add a verb filter", function() {
- // Assert filters is empty
- expect(app.verbFilters.length).to.equal(0);
-
- // Add filter
- app.AddVerbFilter();
-
- // Assert filter added
- expect(app.verbFilters.length).to.equal(1);
- expect(app.verbFilters[0]["tense"]).to.equal("All Tenses");
- expect(app.verbFilters[0]["type"]).to.equal("All Types");
- expect(app.verbFilters[0]["subject"]).to.equal("All Subjects");
- expect(app.verbFilters[0]["direction"]).to.equal("Eng. → Conj.");
- });
- });
-
- describe("RemoveVerbFilter method", function() {
- it("Should remove the specified filter", function() {
- // Initialize filters
- app.verbFilters = [
- {"tense":"Present Tense", "type":"All Types"},
- {"tense":"Preterite Tense", "type":"All Types"},
- {"tense":"Imperfect Tense", "type":"All Types"}
- ]
-
- // Remove filter
- app.RemoveVerbFilter(1);
-
- // Assert filter removed
- expect(app.verbFilters.length).to.equal(2);
- expect(app.verbFilters[0]["tense"]).to.equal("Present Tense");
- expect(app.verbFilters[0]["type"]).to.equal("All Types");
- expect(app.verbFilters[1]["tense"]).to.equal("Imperfect Tense");
- expect(app.verbFilters[1]["type"]).to.equal("All Types");
- });
- });
-
- describe("AddVocabFilter method", function() {
- it("Should add a vocab filter", function() {
- // Assert filters is empty
- expect(app.vocabFilters.length).to.equal(0);
-
- // Add filter
- app.AddVocabFilter();
-
- // Assert filter added
- expect(app.vocabFilters.length).to.equal(1);
- expect(app.vocabFilters[0]["set"]).to.equal("Verbs");
- expect(app.vocabFilters[0]["type"]).to.equal("All Types");
- expect(app.vocabFilters[0]["direction"]).to.equal("Eng. ↔ Esp.");
- });
- });
-
- describe("RemoveVocabFilter method", function() {
- it("Should remove the specified filter", function() {
- // Initialize filters
- app.vocabFilters = [
- {"set":"Verbs", "type":"All Definitions"},
- {"set":"Adjectives", "type":"All Definitions"},
- {"set":"Adverbs", "type":"All Definitions"},
- ]
-
- // Remove filter
- app.RemoveVocabFilter(1);
-
- // Assert filter removed
- expect(app.vocabFilters.length).to.equal(2);
- expect(app.vocabFilters[0]["set"]).to.equal("Verbs");
- expect(app.vocabFilters[0]["type"]).to.equal("All Definitions");
- expect(app.vocabFilters[1]["set"]).to.equal("Adverbs");
- expect(app.vocabFilters[1]["type"]).to.equal("All Definitions");
- });
- });
-
- describe("GetTenseTypes method", function() {
- it("Should be correct for All Tenses", function() {
- // Initialize filters
- app.verbFilters = [
- {"tense":"All Types", "type":"All Types"}
- ]
-
- // Get filters
- let filters = app.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
- app.verbFilters = [
- {"tense":"Present Tense", "type":"All Types"}
- ]
-
- // Get filters
- let filters = app.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
- app.verbFilters = [
- {"tense":"Present Tense", "type":"Orthographic"}
- ]
-
- // Get filters
- let filters = app.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(app.verbFilters[0]["type"]).to.equal("All Types");
- });
-
- it("Should not change selection if available", function() {
- // Initialize filters
- app.verbFilters = [
- {"tense":"Preterite Tense", "type":"Orthographic"}
- ]
-
- // Get filters
- let filters = app.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(app.verbFilters[0]["type"]).to.equal("Orthographic");
- });
- });
-
- describe("GetTenseSubjects method", function() {
- it("Should be correct for All Tenses", function() {
- // Initialize filters
- app.verbFilters = [
- {"tense":"All Types", "type":"All Types"}
- ]
-
- // Get filters
- let filters = app.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
- app.verbFilters = [
- {"tense":"Present Participles", "subject":"All Subjects", "type":"All Types"}
- ]
-
- // Get filters
- let filters = app.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
- app.verbFilters = [
- {"tense":"Present Participles", "subject":"Yo", "type":"All Types"}
- ]
-
- // Get filters
- let filters = app.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(app.verbFilters[0]["subject"]).to.equal("All Subjects");
- });
-
- it("Should not change selection if available", function() {
- // Initialize filters
- app.verbFilters = [
- {"tense":"Preterite Tense", "subject":"Yo", "type":"All Types"}
- ]
-
- // Get filters
- let filters = app.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);
-
- // Assert selection not changed
- expect(app.verbFilters[0]["subject"]).to.equal("Yo");
- });
- });
-
- describe("GetSetFilters method", function() {
- it("Should be correct for Verbs", function() {
- // Initialize filters
- app.vocabFilters = [
- {"set":"Verbs", "type":"All Definitions"}
- ]
-
- // Get filters
- let filters = app.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
- app.vocabFilters = [
- {"set":"Colors", "type":"All Definitions"}
- ]
-
- // Get filters
- let filters = app.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
- app.vocabFilters = [
- {"set":"Colors", "type":"Verbs"}
- ]
-
- // Get filters
- let filters = app.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(app.vocabFilters[0]["type"]).to.equal("All Types");
- });
-
- it("Should not change selection if available", function() {
- // Initialize filters
- app.vocabFilters = [
- {"set":"Professions", "type":"Verbs"}
- ]
-
- // Get filters
- let filters = app.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(app.vocabFilters[0]["type"]).to.equal("Verbs");
- });
- });
-
- describe("PromptType watch", function() {
- it("Should update setting in localStorage", async function() {
- // Save original setting from localStorage
- let originalValue = localStorage.getItem("promptType");
-
- // Set promptType
- app.promptType = "test";
- await app.$nextTick();
+ describe("StartSession method", function() {
+ it("Should import parameter values", function() {
+ // Call StartSession
+ app.StartSession([1, 2, 3], 4, "a", "b", "c", "d");
- // Assert localStorage setting updated
- expect(localStorage.getItem("promptType")).to.equal("test");
-
- // Restore original setting to localStorage
- localStorage.setItem("promptType", originalValue);
+ // Assert parameters imported
+ expect(app.prompts).to.have.members([1, 2, 3]);
+ expect(app.promptIndex).to.equal(4);
+ expect(app.promptType).to.equal("a");
+ expect(app.inputType).to.equal("b");
+ expect(app.onMissedPrompt).to.equal("c");
+ expect(app.repeatPrompts).to.equal("d");
});
- });
- describe("InputType watch", function() {
- it("Should update setting in localStorage", async function() {
- // Save original setting from localStorage
- let originalValue = localStorage.getItem("inputType");
-
- // Set inputType
- app.inputType = "test";
- await app.$nextTick();
+ it("Should set state to 'verbQuizzer' if state is 'verbSettings'", function() {
+ // Initialize settings
+ app.state = "verbSettings";
- // Assert localStorage setting updated
- expect(localStorage.getItem("inputType")).to.equal("test");
+ // Call StartSession
+ app.StartSession([1, 2, 3], 4, "a", "b", "c", "d");
- // Restore original setting to localStorage
- localStorage.setItem("inputType", originalValue);
+ // Assert parameters imported
+ expect(app.state).to.equal("verbQuizzer");
});
- });
- describe("RepeatPrompts watch", function() {
- it("Should update setting in localStorage", async function() {
- // Save original setting from localStorage
- let originalValue = localStorage.getItem("repeatPrompts");
-
- // Set repeatPrompts
- app.repeatPrompts = "test";
- await app.$nextTick();
+ it("Should set state to 'vocabQuizzer' if state is 'vocabSettings'", function() {
+ // Initialize settings
+ app.state = "vocabSettings";
- // Assert localStorage setting updated
- expect(localStorage.getItem("repeatPrompts")).to.equal("test");
+ // Call StartSession
+ app.StartSession([1, 2, 3], 4, "a", "b", "c", "d");
- // Restore original setting to localStorage
- localStorage.setItem("repeatPrompts", originalValue);
+ // Assert parameters imported
+ expect(app.state).to.equal("vocabQuizzer");
});
});
});
diff --git a/tests/test.settings.js b/tests/test.settings.js
@@ -1,4 +1,394 @@
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);
+ });
+ });
+
+ 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.length).to.equal(1);
+ expect(Settings.verbFilters[0]["tense"]).to.equal("All Tenses");
+ expect(Settings.verbFilters[0]["type"]).to.equal("All Types");
+ expect(Settings.verbFilters[0]["subject"]).to.equal("All Subjects");
+ expect(Settings.verbFilters[0]["direction"]).to.equal("Eng. → Conj.");
+ expect(Settings.vocabFilters.length).to.equal(0);
+ });
+
+ 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.length).to.equal(1);
+ expect(Settings.vocabFilters[0]["set"]).to.equal("Verbs");
+ expect(Settings.vocabFilters[0]["type"]).to.equal("All Types");
+ expect(Settings.vocabFilters[0]["direction"]).to.equal("Eng. ↔ Esp.");
+ expect(Settings.verbFilters.length).to.equal(0);
+ });
+ });
+
+ 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":"Preterite Tense", "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(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);
+
+ // Assert selection not changed
+ expect(Settings.verbFilters[0]["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("PromptType watch", function() {
+ it("Should update setting in localStorage", async function() {
+ // Save original setting from localStorage
+ let originalValue = localStorage.getItem("promptType");
+
+ // Set promptType
+ Settings.promptType = "test";
+ await Settings.$nextTick();
+
+ // Assert localStorage setting updated
+ expect(localStorage.getItem("promptType")).to.equal("test");
+
+ // Restore original setting to localStorage
+ localStorage.setItem("promptType", originalValue);
+ });
+ });
+
+ describe("InputType watch", function() {
+ it("Should update setting in localStorage", async function() {
+ // Save original setting from localStorage
+ let originalValue = localStorage.getItem("inputType");
+
+ // Set inputType
+ Settings.inputType = "test";
+ await Settings.$nextTick();
+
+ // Assert localStorage setting updated
+ expect(localStorage.getItem("inputType")).to.equal("test");
+
+ // Restore original setting to localStorage
+ localStorage.setItem("inputType", originalValue);
+ });
+ });
+
+ describe("RepeatPrompts watch", function() {
+ it("Should update setting in localStorage", async function() {
+ // Save original setting from localStorage
+ let originalValue = localStorage.getItem("repeatPrompts");
+
+ // Set repeatPrompts
+ Settings.repeatPrompts = "test";
+ await Settings.$nextTick();
+
+ // Assert localStorage setting updated
+ expect(localStorage.getItem("repeatPrompts")).to.equal("test");
+
+ // Restore original setting to localStorage
+ localStorage.setItem("repeatPrompts", originalValue);
+ });
+ });
+
describe("ApplyVocabFilter method", function() {
// Initialize vocab
let vocab = [
@@ -500,49 +890,6 @@ describe("Settings", function() {
});
});
- describe("StartSession method", function() {
- beforeEach(function() {
- // Initialize Vue
- loadVue();
- });
-
- it("Should throw \"Bad Arguments\" when prompts is null", function() {
- // Initialize prompts and promptIndex
- app.prompts = null;
- app.promptIndex = 0;
-
- // Assert raises error
- expect(StartSession).to.throw("Bad arguments.");
- });
-
- it("Should throw \"Bad Arguments\" when promptIndex is negative", function() {
- // Initialize prompts and promptIndex
- app.prompts = ["a", "b", "c"];
- app.promptIndex = -1;
-
- // Assert raises error
- expect(StartSession).to.throw("Bad arguments.");
- });
-
- it("Should throw \"Bad Arguments\" when promptIndex is invalid", function() {
- // Initialize prompts and promptIndex
- app.prompts = ["a", "b", "c"];
- app.promptIndex = 3;
-
- // Assert raises error
- expect(StartSession).to.throw("Bad arguments.");
- });
-
- it("Should throw \"Terms is empty\" when prompts is empty", function() {
- // Initialize prompts and promptIndex
- app.prompts = [];
- app.promptIndex = 0;
-
- // Assert raises error
- expect(StartSession).to.throw("Terms is empty.");
- });
- });
-
describe("Shuffle method", function() {
it("Should not alter list", function() {
// Initialize list