diff --git a/packages/doenetml-worker/src/test/tagSpecific/evaluate.test.ts b/packages/doenetml-worker/src/test/tagSpecific/evaluate.test.ts index b4da5cfc9..66b033413 100644 --- a/packages/doenetml-worker/src/test/tagSpecific/evaluate.test.ts +++ b/packages/doenetml-worker/src/test/tagSpecific/evaluate.test.ts @@ -3703,7 +3703,7 @@ describe("Evaluate tag tests", async () => { expect(stateVariables["/pha"].stateValues.text).eq("5"); }); - it.only("evaluate functions based on interpolated function", async () => { + it("evaluate functions based on interpolated function", async () => { let core = await createTestCore({ doenetML: `

f: x^2

diff --git a/packages/doenetml-worker/src/test/tagSpecific/selectfromsequence.test.ts b/packages/doenetml-worker/src/test/tagSpecific/selectfromsequence.test.ts new file mode 100644 index 000000000..5b81fbdb3 --- /dev/null +++ b/packages/doenetml-worker/src/test/tagSpecific/selectfromsequence.test.ts @@ -0,0 +1,1468 @@ +import { describe, expect, it, vi } from "vitest"; +import { createTestCore, returnAllStateVariables } from "../utils/test-core"; +import { cleanLatex } from "../utils/math"; +import { + updateBooleanInputValue, + updateMathInputValue, + updateMatrixInputValue, + updateTextInputValue, +} from "../utils/actions"; +import me from "math-expressions"; + +const Mock = vi.fn(); +vi.stubGlobal("postMessage", Mock); + +describe("SelectFromSequence tag tests", async () => { + async function test_values_separately({ + doenetML, + componentNames, + valid_values, + num_samples, + }: { + doenetML: string; + componentNames: string[]; + valid_values: any[][]; + num_samples: number; + }) { + for (let i = 0; i < num_samples; i++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: i, + }); + const stateVariables = await returnAllStateVariables(core); + for (let [ind, name] of componentNames.entries()) { + let value = stateVariables[name].stateValues.value; + expect(valid_values[ind].includes(value)).eq( + true, + `Expected ${value} to be in ${valid_values[ind]}`, + ); + } + } + } + + async function test_values_separately_math({ + doenetML, + componentNames, + valid_values, + num_samples, + }: { + doenetML: string; + componentNames: string[]; + valid_values: any[][]; + num_samples: number; + }) { + for (let i = 0; i < num_samples; i++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: i, + }); + const stateVariables = await returnAllStateVariables(core); + for (let [ind, name] of componentNames.entries()) { + let value = stateVariables[name].stateValues.value; + expect(valid_values[ind].some((v) => v.equals(value))).eq( + true, + `Expected ${value} to be in ${valid_values[ind]}`, + ); + } + } + } + + async function test_combined_values({ + doenetML, + componentNames, + valid_combinations, + num_samples, + }: { + doenetML: string; + componentNames: string[]; + valid_combinations: any[][]; + num_samples: number; + }) { + for (let i = 0; i < num_samples; i++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: i, + }); + const stateVariables = await returnAllStateVariables(core); + let values = componentNames.map( + (name) => stateVariables[name].stateValues.value, + ); + + expect( + valid_combinations.some((comb) => + comb.every((v, i) => v === values[i]), + ), + ).eq( + true, + `Expected (${values}) to be in ${valid_combinations.map((comb) => `(${comb})`)}`, + ); + } + } + + async function test_combined_values_math({ + doenetML, + componentNames, + valid_combinations, + num_samples, + }: { + doenetML: string; + componentNames: string[]; + valid_combinations: any[][]; + num_samples: number; + }) { + for (let i = 0; i < num_samples; i++) { + let core = await createTestCore({ + doenetML, + requestedVariantIndex: i, + }); + const stateVariables = await returnAllStateVariables(core); + let values = componentNames.map( + (name) => stateVariables[name].stateValues.value, + ); + + expect( + valid_combinations.some((comb) => + comb.every((v, i) => v.equals(values[i])), + ), + ).eq( + true, + `Expected (${values}) to be in ${valid_combinations.map((comb) => `(${comb})`)}`, + ); + } + } + + it("no parameters, select single number from 1 to 10", async () => { + const doenetML = ``; + const valid_values = [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]; + const componentNames = ["/res"]; + + await test_values_separately({ + doenetML, + valid_values, + componentNames, + num_samples: 30, + }); + }); + + it("select single number from 1 to 6", async () => { + const doenetML = ``; + const valid_values = [[1, 2, 3, 4, 5, 6]]; + const componentNames = ["/res"]; + + await test_values_separately({ + doenetML, + valid_values, + componentNames, + num_samples: 30, + }); + }); + + it("select single number from -3 to 5", async () => { + const doenetML = ``; + const valid_values = [[-3, -2, -1, 0, 1, 2, 3, 4, 5]]; + const componentNames = ["/res"]; + + await test_values_separately({ + doenetML, + valid_values, + componentNames, + num_samples: 30, + }); + }); + + it("select single number from -3 to 5, excluding 0", async () => { + const doenetML = ``; + const valid_values = [[-3, -2, -1, 1, 2, 3, 4, 5]]; + const componentNames = ["/res"]; + + await test_values_separately({ + doenetML, + valid_values, + componentNames, + num_samples: 30, + }); + }); + + it("select single odd number from -3 to 5", async () => { + const doenetML = ``; + const valid_values = [[-3, -1, 1, 3, 5]]; + const componentNames = ["/res"]; + + await test_values_separately({ + doenetML, + valid_values, + componentNames, + num_samples: 30, + }); + }); + + it("select single letter from c to h", async () => { + const doenetML = ``; + const valid_values = [["c", "d", "e", "f", "g", "h"]]; + const componentNames = ["/res"]; + + await test_values_separately({ + doenetML, + valid_values, + componentNames, + num_samples: 30, + }); + }); + + it("select two even numbers from -4 to 4, excluding 0", async () => { + const doenetML = ``; + const valid_values = [ + [-4, -2, 2, 4], + [-4, -2, 2, 4], + ]; + const componentNames = ["/res1", "/res2"]; + + await test_values_separately({ + doenetML, + valid_values, + componentNames, + num_samples: 30, + }); + }); + + it("select two even numbers from -4 to 2, excluding 0 and combinations", async () => { + const doenetML = ``; + const valid_combinations = [ + [-4, 2], + [-2, -4], + [2, -2], + ]; + const componentNames = ["/res1", "/res2"]; + + await test_combined_values({ + doenetML, + valid_combinations, + componentNames, + num_samples: 10, + }); + }); + + it("select two even numbers from -4 to 2, excluding 0 and combinations, as copies", async () => { + const doenetML = ` + -4 -2 + -2 + 2 + -4 + -4 -2 + -2 2 + 2 -4 + +

`; + const valid_combinations = [ + [-4, 2], + [-2, -4], + [2, -2], + ]; + const componentNames = ["/res1", "/res2"]; + + await test_combined_values({ + doenetML, + valid_combinations, + componentNames, + num_samples: 10, + }); + }); + + it("select two even numbers from -4 to 2, excluding 0 and combinations, exclude extras", async () => { + const doenetML = ``; + const valid_combinations = [ + [-4, 2], + [-2, -4], + [2, -2], + ]; + const componentNames = ["/res1", "/res2"]; + + await test_combined_values({ + doenetML, + valid_combinations, + componentNames, + num_samples: 10, + }); + }); + + it("select three numbers from 1 to 3, exclude combinations with two 1s", async () => { + const doenetML = ``; + const valid_combinations = [ + [1, 2, 2], + [1, 2, 3], + [1, 3, 2], + [1, 3, 3], + [2, 1, 2], + [2, 1, 3], + [3, 1, 2], + [3, 1, 3], + [2, 2, 1], + [2, 3, 1], + [3, 2, 1], + [3, 3, 1], + [2, 2, 2], + [2, 2, 3], + [2, 3, 2], + [3, 2, 2], + [3, 3, 2], + [3, 2, 3], + [2, 3, 3], + [3, 3, 3], + ]; + const componentNames = ["/res1", "/res2", "/res3"]; + + await test_combined_values({ + doenetML, + valid_combinations, + componentNames, + num_samples: 10, + }); + }); + + it("select three numbers from 1 to 3, exclude combinations with two 1s, duplicate excludes", async () => { + const doenetML = ``; + const valid_combinations = [ + [1, 2, 2], + [1, 2, 3], + [1, 3, 2], + [1, 3, 3], + [2, 1, 2], + [2, 1, 3], + [3, 1, 2], + [3, 1, 3], + [2, 2, 1], + [2, 3, 1], + [3, 2, 1], + [3, 3, 1], + [2, 2, 2], + [2, 2, 3], + [2, 3, 2], + [3, 2, 2], + [3, 3, 2], + [3, 2, 3], + [2, 3, 3], + [3, 3, 3], + ]; + const componentNames = ["/res1", "/res2", "/res3"]; + + await test_combined_values({ + doenetML, + valid_combinations, + componentNames, + num_samples: 10, + }); + }); + + it("select four numbers from 0 to 3, exclude positions of each number", async () => { + const doenetML = ``; + const valid_values = [ + [1, 2, 3], + [0, 2, 3], + [0, 1, 3], + [0, 1, 2], + ]; + + const componentNames = ["/res1", "/res2", "/res3", "/res4"]; + + await test_values_separately({ + doenetML, + valid_values, + componentNames, + num_samples: 10, + }); + }); + + it("select three numbers from 1 to 3, without replacement exclude positions of each number", async () => { + const doenetML = ``; + const valid_values = [ + [2, 3], + [1, 3], + [1, 2], + ]; + + const componentNames = ["/res1", "/res2", "/res3"]; + + await test_values_separately({ + doenetML, + valid_values, + componentNames, + num_samples: 10, + }); + }); + + it("display error when select three numbers from 1 to 3, without replacement, exclude any place for 1", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let errorWarnings = core.errorWarnings; + + expect(errorWarnings.errors.length).eq(1); + expect(errorWarnings.warnings.length).eq(0); + + expect(errorWarnings.errors[0].message).contain("Excluded over 70%"); + expect(errorWarnings.errors[0].doenetMLrange.lineBegin).eq(2); + expect(errorWarnings.errors[0].doenetMLrange.charBegin).eq(8); + expect(errorWarnings.errors[0].doenetMLrange.lineEnd).eq(2); + expect(errorWarnings.errors[0].doenetMLrange.charEnd).eq(122); + }); + + it("select 10 numbers from 1 to 10, without replacement, exclude positions of each number", async () => { + // make sure that exclude combinations does not enumerate all combinations excluded + // to count them + const doenetML = ``; + let allNumbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + + const valid_values: number[][] = []; + + for (let j = 0; j < 10; j++) { + let validNs = [...allNumbers]; + validNs.splice(j, 1); + valid_values.push(validNs); + } + + const componentNames = [ + "/res1", + "/res2", + "/res3", + "/res4", + "/res5", + "/res6", + "/res7", + "/res8", + "/res9", + "/res10", + ]; + + await test_values_separately({ + doenetML, + valid_values, + componentNames, + num_samples: 5, + }); + }); + + it("select five even numbers with replacement from -4 to 4, excluding 0", async () => { + const doenetML = ``; + const valid_values = [ + [-4, -2, 2, 4], + [-4, -2, 2, 4], + [-4, -2, 2, 4], + [-4, -2, 2, 4], + [-4, -2, 2, 4], + ]; + + const componentNames = ["/res1", "/res2", "/res3", "/res4", "/res5"]; + + await test_values_separately({ + doenetML, + valid_values, + componentNames, + num_samples: 10, + }); + }); + + it("select five (number initially unresolved) even numbers with replacement from -4 to 4, excluding 0", async () => { + const doenetML = ` + + $n3{name="n2"} + $num1{name="n"} + $n2+$num2+2 + $n3+$num3 + $num3{name="n3"} + 1`; + + const valid_values = [ + [-4, -2, 2, 4], + [-4, -2, 2, 4], + [-4, -2, 2, 4], + [-4, -2, 2, 4], + [-4, -2, 2, 4], + ]; + + const componentNames = ["/res1", "/res2", "/res3", "/res4", "/res5"]; + + await test_values_separately({ + doenetML, + valid_values, + componentNames, + num_samples: 3, + }); + }); + + it("asList", async () => { + let core = await createTestCore({ + doenetML: ` +

+

+ + `, + }); + + let results: number[] = []; + + let stateVariables = await returnAllStateVariables(core); + + results.push(stateVariables["/u"].stateValues.value); + results.push(stateVariables["/v"].stateValues.value); + results.push(stateVariables["/w"].stateValues.value); + results.push(stateVariables["/x"].stateValues.value); + results.push(stateVariables["/y"].stateValues.value); + + for (let num of results) { + expect(num).gte(175).lte(205); + } + expect(stateVariables["/p1"].stateValues.text).eq(results.join(", ")); + expect(stateVariables["/p2"].stateValues.text).eq(results.join("")); + }); + + it("copies don't resample", async () => { + let core = await createTestCore({ + doenetML: ` +

+ + +

+ +

+ $sample1{name="noresample1"} + $sample2{name="noresample2"} + $noresample1{name="noreresample1"} + $noresample2{name="noreresample2"} +

+ +

+ +

+ + `, + }); + + let stateVariables = await returnAllStateVariables(core); + let num1 = stateVariables["/n1"].stateValues.value; + let num2 = stateVariables["/n2"].stateValues.value; + expect(Number.isInteger(num1) && num1 >= 1 && num1 <= 100).eq(true); + expect(Number.isInteger(num2) && num2 >= 1 && num2 <= 100).eq(true); + expect( + stateVariables[ + stateVariables["/noresample1"].replacements![0].componentName + ].stateValues.value, + ).eq(num1); + expect( + stateVariables[ + stateVariables["/noresample2"].replacements![0].componentName + ].stateValues.value, + ).eq(num2); + expect( + stateVariables[ + stateVariables["/noreresample1"].replacements![0].componentName + ].stateValues.value, + ).eq(num1); + expect( + stateVariables[ + stateVariables["/noreresample2"].replacements![0].componentName + ].stateValues.value, + ).eq(num2); + + expect( + stateVariables[ + stateVariables["/noresamplep"].activeChildren[1].componentName + ].stateValues.value, + ).eq(num1); + expect( + stateVariables[ + stateVariables["/noresamplep"].activeChildren[3].componentName + ].stateValues.value, + ).eq(num2); + expect( + stateVariables[ + stateVariables["/noreresamplep"].activeChildren[1].componentName + ].stateValues.value, + ).eq(num1); + expect( + stateVariables[ + stateVariables["/noreresamplep"].activeChildren[3].componentName + ].stateValues.value, + ).eq(num2); + }); + + it("select doesn't change dynamically", async () => { + let core = await createTestCore({ + doenetML: ` + + +

+ +

+ + + +

+ +

+

$maxNum2.value{assignNames="maxNum2a"}

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let sample1replacements = stateVariables["/sample1"].replacements!; + let sample2replacements = stateVariables["/sample2"].replacements!; + expect(sample1replacements.length).eq(5); + expect(sample2replacements.length).eq(2); + let sample1numbers = sample1replacements.map( + (x) => stateVariables[x.componentName].stateValues.value, + ); + let sample2numbers = sample2replacements.map( + (x) => stateVariables[x.componentName].stateValues.value, + ); + + for (let num of sample1numbers) { + expect([1, 2, 3].includes(num)).eq(true); + } + for (let num of sample2numbers) { + expect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10].includes(num)).eq(true); + } + + // Nothing changes when change mathInputs + await updateMathInputValue({ + latex: "7", + componentName: "/numToSelect", + core, + }); + await updateMathInputValue({ + latex: "11", + componentName: "/maxNum", + core, + }); + await updateMathInputValue({ + latex: "16", + componentName: "/numToSelect2", + core, + }); + await updateMathInputValue({ + latex: "18", + componentName: "/maxNum2", + core, + }); + + stateVariables = await returnAllStateVariables(core); + sample1replacements = stateVariables["/sample1"].replacements!; + sample2replacements = stateVariables["/sample2"].replacements!; + + expect( + sample1replacements.map( + (x) => stateVariables[x.componentName].stateValues.value, + ), + ).eqls(sample1numbers); + expect( + sample2replacements.map( + (x) => stateVariables[x.componentName].stateValues.value, + ), + ).eqls(sample2numbers); + }); + + it("select doesn't resample in dynamic map", async () => { + let core = await createTestCore({ + doenetML: ` + How many numbers do you want? +

+ + + + +

+ +

$map1

+ + $p1{name="p3"} + $p2{name="p4"} + + $p3{name="p5"} + $p4{name="p6"} + `, + }); + + async function check_sampled_numbers(sampledNumbers: number[]) { + let num = sampledNumbers.length; + const stateVariables = await returnAllStateVariables(core); + + expect( + stateVariables["/p1"].activeChildren.map( + (child) => + stateVariables[child.componentName].stateValues.value, + ), + ).eqls(sampledNumbers); + + expect( + stateVariables["/p2"].activeChildren.map( + (child) => + stateVariables[child.componentName].stateValues.value, + ), + ).eqls(sampledNumbers); + + expect( + stateVariables["/p3"].activeChildren.map( + (child) => + stateVariables[child.componentName].stateValues.value, + ), + ).eqls(sampledNumbers); + + expect( + stateVariables["/p4"].activeChildren.map( + (child) => + stateVariables[child.componentName].stateValues.value, + ), + ).eqls(sampledNumbers); + + expect( + stateVariables["/p5"].activeChildren.map( + (child) => + stateVariables[child.componentName].stateValues.value, + ), + ).eqls(sampledNumbers); + + expect( + stateVariables["/p6"].activeChildren.map( + (child) => + stateVariables[child.componentName].stateValues.value, + ), + ).eqls(sampledNumbers); + } + + let sampledNumbers: number[] = []; + + // initially nothing + await check_sampled_numbers([]); + + // sample one variable + await updateMathInputValue({ latex: "1", componentName: "/mi1", core }); + + let stateVariables = await returnAllStateVariables(core); + sampledNumbers.push(stateVariables["/a/n"].stateValues.value); + await check_sampled_numbers(sampledNumbers); + + // go back to nothing + await updateMathInputValue({ latex: "0", componentName: "/mi1", core }); + await check_sampled_numbers([]); + + // get same number back + await updateMathInputValue({ latex: "1", componentName: "/mi1", core }); + await check_sampled_numbers(sampledNumbers); + + // get two more samples + await updateMathInputValue({ latex: "3", componentName: "/mi1", core }); + + stateVariables = await returnAllStateVariables(core); + let n1 = stateVariables["/a/n"].stateValues.value; + let n2 = stateVariables["/b/n"].stateValues.value; + let n3 = stateVariables["/c/n"].stateValues.value; + expect(n1).eq(sampledNumbers[0]); + sampledNumbers.push(n2); + sampledNumbers.push(n3); + await check_sampled_numbers(sampledNumbers); + + // go back to nothing + await updateMathInputValue({ latex: "0", componentName: "/mi1", core }); + await check_sampled_numbers([]); + + // get first two numbers back + await updateMathInputValue({ latex: "2", componentName: "/mi1", core }); + await check_sampled_numbers(sampledNumbers.slice(0, 2)); + + // get six total samples + await updateMathInputValue({ latex: "6", componentName: "/mi1", core }); + + stateVariables = await returnAllStateVariables(core); + n1 = stateVariables["/a/n"].stateValues.value; + n2 = stateVariables["/b/n"].stateValues.value; + n3 = stateVariables["/c/n"].stateValues.value; + let n4 = stateVariables["/d/n"].stateValues.value; + let n5 = stateVariables["/e/n"].stateValues.value; + let n6 = stateVariables["/f/n"].stateValues.value; + expect(n1).eq(sampledNumbers[0]); + expect(n2).eq(sampledNumbers[1]); + expect(n3).eq(sampledNumbers[2]); + sampledNumbers.push(n4); + sampledNumbers.push(n5); + sampledNumbers.push(n6); + await check_sampled_numbers(sampledNumbers); + + // go back to nothing + await updateMathInputValue({ latex: "0", componentName: "/mi1", core }); + await check_sampled_numbers([]); + + // get all six back + await updateMathInputValue({ latex: "6", componentName: "/mi1", core }); + await check_sampled_numbers(sampledNumbers); + }); + + it("select single math", async () => { + const doenetML = ``; + const valid_values = [ + [me.fromText("x"), me.fromText("x+y"), me.fromText("x+2y")], + ]; + const componentNames = ["/res"]; + + await test_values_separately_math({ + doenetML, + valid_values, + componentNames, + num_samples: 3, + }); + }); + + it("select multiple maths", async () => { + const doenetML = ``; + const valid_values = [ + [me.fromText("x"), me.fromText("x+y"), me.fromText("x+2y")], + [me.fromText("x"), me.fromText("x+y"), me.fromText("x+2y")], + [me.fromText("x"), me.fromText("x+y"), me.fromText("x+2y")], + ]; + const componentNames = ["/res1", "/res2", "/res3"]; + + await test_values_separately_math({ + doenetML, + valid_values, + componentNames, + num_samples: 3, + }); + }); + + it("select multiple maths, new namespace", async () => { + const doenetML = ``; + const valid_values = [ + [me.fromText("x"), me.fromText("x+y"), me.fromText("x+2y")], + [me.fromText("x"), me.fromText("x+y"), me.fromText("x+2y")], + [me.fromText("x"), me.fromText("x+y"), me.fromText("x+2y")], + ]; + const componentNames = ["/s/res1", "/s/res2", "/s/res3"]; + + await test_values_separately_math({ + doenetML, + valid_values, + componentNames, + num_samples: 3, + }); + }); + + it("selectFromSequence with hide will hide replacements", async () => { + let core = await createTestCore({ + doenetML: ` +

,

+

$c, $d{hide="false"}

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let c = await stateVariables["/c"].stateValues.value; + let d = await stateVariables["/d"].stateValues.value; + expect(["a", "b", "c", "d", "e"].includes(c)).eq(true); + expect(["a", "b", "c", "d", "e"].includes(d)).eq(true); + + expect(stateVariables["/p1"].stateValues.text).eq(`${c}, `); + expect(stateVariables["/p2"].stateValues.text).eq(`${c}, ${d}`); + }); + + it("select multiple numbers with excludeCombinations, handles round-off error", async () => { + // Third number selected will be 0.1*3, which isn't exactly 0.3 due to round off error. + // Even so, excluding 0.3 works successfully. + const doenetML = ``; + const valid_combinations = [ + [0.1, 0.2], + [0.2, 0.1], + [0.1 * 3, 0.2], + ]; + const componentNames = ["/res1", "/res2"]; + + await test_combined_values({ + doenetML, + valid_combinations, + componentNames, + num_samples: 10, + }); + }); + + it("select multiple maths with excludeCombinations, handles round-off error", async () => { + // Third number selected will be 0.1*3, which isn't exactly 0.3 due to round off error. + // Even so, excluding 0.3 works successfully. + const doenetML = ``; + const valid_combinations = [ + [me.fromAst(0.1), me.fromAst(0.2)], + [me.fromAst(0.2), me.fromAst(0.1)], + [me.fromAst(0.3), me.fromAst(0.2)], + ]; + const componentNames = ["/res1", "/res2"]; + + await test_combined_values_math({ + doenetML, + valid_combinations, + componentNames, + num_samples: 10, + }); + }); + + it("select multiple maths with excludes and excludeCombinations", async () => { + const doenetML = ``; + const valid_combinations = [ + [me.fromText("x"), me.fromText("x+3y")], + [me.fromText("x+y"), me.fromText("x")], + [me.fromText("x+3y"), me.fromText("x+y")], + ]; + const componentNames = ["/res1", "/res2"]; + + await test_combined_values_math({ + doenetML, + valid_combinations, + componentNames, + num_samples: 10, + }); + }); + + it("select multiple maths with excludes and excludeCombinations, as copies", async () => { + const doenetML = ` + x x+y + x+y + x+3y + x + x x+y + x+y x+3y + `; + const valid_combinations = [ + [me.fromText("x"), me.fromText("x+3y")], + [me.fromText("x+y"), me.fromText("x")], + [me.fromText("x+3y"), me.fromText("x+y")], + ]; + const componentNames = ["/res1", "/res2"]; + + await test_combined_values_math({ + doenetML, + valid_combinations, + componentNames, + num_samples: 10, + }); + }); + + it("select multiple maths with excludes and excludeCombinations, exclude extras", async () => { + const doenetML = ``; + const valid_combinations = [ + [me.fromText("x"), me.fromText("x+3y")], + [me.fromText("x+y"), me.fromText("x")], + [me.fromText("x+3y"), me.fromText("x+y")], + ]; + const componentNames = ["/res1", "/res2"]; + + await test_combined_values_math({ + doenetML, + valid_combinations, + componentNames, + num_samples: 10, + }); + }); + + it("select multiple letters with excludes and excludeCombinations", async () => { + const doenetML = ``; + const valid_combinations = [ + ["m", "s"], + ["s", "v"], + ["v", "m"], + ]; + const componentNames = ["/res1", "/res2"]; + + await test_combined_values({ + doenetML, + valid_combinations, + componentNames, + num_samples: 10, + }); + }); + + it("select multiple letters with excludes and excludeCombinations, as copies", async () => { + const doenetML = ` + m v + s + v + s + m v + s m + `; + const valid_combinations = [ + ["m", "s"], + ["s", "v"], + ["v", "m"], + ]; + const componentNames = ["/res1", "/res2"]; + + await test_combined_values({ + doenetML, + valid_combinations, + componentNames, + num_samples: 10, + }); + }); + + it("select multiple letters with excludes and excludeCombinations, exclude extras", async () => { + const doenetML = ``; + const valid_combinations = [ + ["m", "s"], + ["s", "v"], + ["v", "m"], + ]; + const componentNames = ["/res1", "/res2"]; + + await test_combined_values({ + doenetML, + valid_combinations, + componentNames, + num_samples: 10, + }); + }); + + it("select numbers and sort", async () => { + let core = await createTestCore({ + doenetML: ` +

+ + $p1{name="p2"} + `, + }); + + let stateVariables = await returnAllStateVariables(core); + + let originalNumbers = stateVariables["/p1"].activeChildren.map( + (x) => stateVariables[x.componentName].stateValues.value, + ); + let secondNumbers = stateVariables["/p2"].activeChildren.map( + (x) => stateVariables[x.componentName].stateValues.value, + ); + + expect([...originalNumbers].sort((a, b) => a - b)).eqls( + originalNumbers, + ); + expect(secondNumbers).eqls(originalNumbers); + }); + + it("select letters and sort", async () => { + let core = await createTestCore({ + doenetML: ` +

+ + $p1{name="p2"} + `, + }); + + let stateVariables = await returnAllStateVariables(core); + + let originalNumbers = stateVariables["/p1"].activeChildren.map( + (x) => stateVariables[x.componentName].stateValues.value, + ); + let secondNumbers = stateVariables["/p2"].activeChildren.map( + (x) => stateVariables[x.componentName].stateValues.value, + ); + + function compare_letters(a: string, b: string) { + // shorter letter combinations are sorted before longer ones + if (a.length === b.length) { + if (a < b) { + return -1; + } else if (a > b) { + return 1; + } else { + return 0; + } + } else { + return a.length - b.length; + } + } + expect([...originalNumbers].sort(compare_letters)).eqls( + originalNumbers, + ); + expect(secondNumbers).eqls(originalNumbers); + }); + + // Note: this test encodes undesired behavior (see issue #246) + // When this issue is resolved, change this test to make sure the references + // are hidden when the selectFromSequence is hidden + it("selectFromSequence hides dynamically", async () => { + let core = await createTestCore({ + doenetML: ` + + + + + + + +

,

+

$c, $d

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let c = await stateVariables["/c"].stateValues.value; + let d = await stateVariables["/d"].stateValues.value; + expect(["a", "b", "c", "d", "e"].includes(c)).eq(true); + expect(["a", "b", "c", "d", "e"].includes(d)).eq(true); + + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/p1"].stateValues.text).eq(`${c}, `); + expect(stateVariables["/p2"].stateValues.text).eq(`${c}, ${d}`); + + await updateBooleanInputValue({ + boolean: true, + componentName: "/h1", + core, + }); + await updateBooleanInputValue({ + boolean: false, + componentName: "/h2", + core, + }); + + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/p1"].stateValues.text).eq(`, ${d}`); + expect(stateVariables["/p2"].stateValues.text).eq(`${c}, ${d}`); + + await updateBooleanInputValue({ + boolean: false, + componentName: "/h1", + core, + }); + await updateBooleanInputValue({ + boolean: true, + componentName: "/h2", + core, + }); + + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/p1"].stateValues.text).eq(`${c}, `); + expect(stateVariables["/p2"].stateValues.text).eq(`${c}, ${d}`); + }); + + it("selectFromSequence defaults to fixed", async () => { + let core = await createTestCore({ + doenetML: ` + + + + + + +

+ + + +

+

+ $a{name="a2"} + $b{name="b2"} + $c{name="c2"} +

+

+ $a + $b + $c +

+

+ $a2 + $b2 + $c2 +

+

+ $a.fixed{assignNames="af"} + $b.fixed{assignNames="bf"} + $c.fixed{assignNames="cf"} +

+

+ $a2.fixed{assignNames="a2f"} + $b2.fixed{assignNames="b2f"} + $c2.fixed{assignNames="c2f"} +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let a = stateVariables["/a"].stateValues.value; + let b = stateVariables["/b"].stateValues.value; + let c = stateVariables["/c"].stateValues.value; + expect(["a", "b", "c", "d", "e"].includes(a)).eq(true); + expect(["a", "b", "c", "d", "e"].includes(b)).eq(true); + expect(["a", "b", "c", "d", "e"].includes(c)).eq(true); + + expect(stateVariables["/a2"].stateValues.value).eq(a); + expect(stateVariables["/b2"].stateValues.value).eq(b); + expect(stateVariables["/c2"].stateValues.value).eq(c); + + expect(stateVariables["/af"].stateValues.value).eq(true); + expect(stateVariables["/bf"].stateValues.value).eq(false); + expect(stateVariables["/cf"].stateValues.value).eq(true); + expect(stateVariables["/a2f"].stateValues.value).eq(true); + expect(stateVariables["/b2f"].stateValues.value).eq(false); + expect(stateVariables["/c2f"].stateValues.value).eq(true); + + await updateTextInputValue({ text: "f", componentName: "/a3", core }); + await updateTextInputValue({ text: "g", componentName: "/b3", core }); + await updateTextInputValue({ text: "h", componentName: "/c3", core }); + stateVariables = await returnAllStateVariables(core); + + expect(stateVariables["/a"].stateValues.value).eq(a); + expect(stateVariables["/b"].stateValues.value).eq("g"); + expect(stateVariables["/c"].stateValues.value).eq(c); + expect(stateVariables["/a2"].stateValues.value).eq(a); + expect(stateVariables["/b2"].stateValues.value).eq("g"); + expect(stateVariables["/c2"].stateValues.value).eq(c); + + await updateTextInputValue({ text: "i", componentName: "/a4", core }); + await updateTextInputValue({ text: "j", componentName: "/b4", core }); + await updateTextInputValue({ text: "k", componentName: "/c4", core }); + stateVariables = await returnAllStateVariables(core); + + expect(stateVariables["/a"].stateValues.value).eq(a); + expect(stateVariables["/b"].stateValues.value).eq("j"); + expect(stateVariables["/c"].stateValues.value).eq(c); + expect(stateVariables["/a2"].stateValues.value).eq(a); + expect(stateVariables["/b2"].stateValues.value).eq("j"); + expect(stateVariables["/c2"].stateValues.value).eq(c); + + await updateBooleanInputValue({ + boolean: true, + componentName: "/f1", + core, + }); + await updateBooleanInputValue({ + boolean: false, + componentName: "/f2", + core, + }); + stateVariables = await returnAllStateVariables(core); + + expect(stateVariables["/af"].stateValues.value).eq(true); + expect(stateVariables["/bf"].stateValues.value).eq(true); + expect(stateVariables["/cf"].stateValues.value).eq(false); + expect(stateVariables["/a2f"].stateValues.value).eq(true); + expect(stateVariables["/b2f"].stateValues.value).eq(true); + expect(stateVariables["/c2f"].stateValues.value).eq(false); + + await updateTextInputValue({ text: "l", componentName: "/a3", core }); + await updateTextInputValue({ text: "m", componentName: "/b3", core }); + await updateTextInputValue({ text: "n", componentName: "/c3", core }); + stateVariables = await returnAllStateVariables(core); + + expect(stateVariables["/a"].stateValues.value).eq(a); + expect(stateVariables["/b"].stateValues.value).eq("j"); + expect(stateVariables["/c"].stateValues.value).eq("n"); + expect(stateVariables["/a2"].stateValues.value).eq(a); + expect(stateVariables["/b2"].stateValues.value).eq("j"); + expect(stateVariables["/c2"].stateValues.value).eq("n"); + + await updateTextInputValue({ text: "o", componentName: "/a4", core }); + await updateTextInputValue({ text: "p", componentName: "/b4", core }); + await updateTextInputValue({ text: "q", componentName: "/c4", core }); + stateVariables = await returnAllStateVariables(core); + + expect(stateVariables["/a"].stateValues.value).eq(a); + expect(stateVariables["/b"].stateValues.value).eq("j"); + expect(stateVariables["/c"].stateValues.value).eq("q"); + expect(stateVariables["/a2"].stateValues.value).eq(a); + expect(stateVariables["/b2"].stateValues.value).eq("j"); + expect(stateVariables["/c2"].stateValues.value).eq("q"); + }); + + it("numToSelect from selectFromSequence", async () => { + let core = await createTestCore({ + doenetML: ` +

n1 =

+

nums =

+

a1=$a1, b1=$b1, c1=$c1, d1=$d1, e1=$e1

+ +

n2 =

+

nums =

+

a2=$a2, b2=$b2, c2=$c2, d2=$d2, e2=$e2

+ +

n3 =

+

nums =

+

a3=$a3, b3=$b3, c3=$c3, d3=$d3, e3=$e3

+ +

n4 =

+

nums =

+

a4=$a4, b4=$b4, c4=$c4, d4=$d4, e4=$e4

+ +

n5 =

+

nums =

+

a5=$a5, b5=$b5, c5=$c5, d5=$d5, e5=$e5

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let n1 = stateVariables["/n1"].stateValues.value; + let n2 = stateVariables["/n2"].stateValues.value; + let n3 = stateVariables["/n3"].stateValues.value; + let n4 = stateVariables["/n4"].stateValues.value; + let n5 = stateVariables["/n5"].stateValues.value; + + let nums1 = stateVariables["/nums1"].replacements!.map( + (x) => stateVariables[x.componentName].stateValues.value, + ); + let nums2 = stateVariables["/nums2"].replacements!.map( + (x) => stateVariables[x.componentName].stateValues.value, + ); + let nums3 = stateVariables["/nums3"].replacements!.map( + (x) => stateVariables[x.componentName].stateValues.value, + ); + let nums4 = stateVariables["/nums4"].replacements!.map( + (x) => stateVariables[x.componentName].stateValues.value, + ); + let nums5 = stateVariables["/nums5"].replacements!.map( + (x) => stateVariables[x.componentName].stateValues.value, + ); + + expect(nums1.length).eq(n1); + expect(nums2.length).eq(n2); + expect(nums3.length).eq(n3); + expect(nums4.length).eq(n4); + expect(nums5.length).eq(n5); + + nums1.length = 5; + nums2.length = 5; + nums3.length = 5; + nums4.length = 5; + nums5.length = 5; + + nums1.fill("", n1); + nums2.fill("", n2); + nums3.fill("", n3); + nums4.fill("", n4); + nums5.fill("", n5); + + let l = ["a", "b", "c", "d", "e"]; + + expect(stateVariables["/p1"].stateValues.text).eq( + nums1.map((v, i) => `${l[i]}1=${v}`).join(", "), + ); + expect(stateVariables["/p2"].stateValues.text).eq( + nums2.map((v, i) => `${l[i]}2=${v}`).join(", "), + ); + expect(stateVariables["/p3"].stateValues.text).eq( + nums3.map((v, i) => `${l[i]}3=${v}`).join(", "), + ); + expect(stateVariables["/p4"].stateValues.text).eq( + nums4.map((v, i) => `${l[i]}4=${v}`).join(", "), + ); + expect(stateVariables["/p5"].stateValues.text).eq( + nums5.map((v, i) => `${l[i]}5=${v}`).join(", "), + ); + }); + + it("rounding", async () => { + let core = await createTestCore({ + doenetML: ` +

+

+

+

+ +

$n1

+

$n2

+

$n3

+

$n4

+ + `, + }); + + let stateVariables = await returnAllStateVariables(core); + + let n1 = stateVariables["/n1"].stateValues.value; + let n2 = stateVariables["/n2"].stateValues.value; + let n3 = stateVariables["/n3"].stateValues.value; + let n4 = stateVariables["/n4"].stateValues.value; + + expect(stateVariables["/n1"].stateValues.text).eq( + String(Math.round(n1 * 10 ** 8) / 10 ** 8), + ); + expect(stateVariables["/n2"].stateValues.text).eq( + String(Math.round(n2 * 10 ** 1) / 10 ** 1), + ); + expect(stateVariables["/n3"].stateValues.text).eq( + String(Math.round(n3 * 10 ** 3) / 10 ** 3), + ); + expect(stateVariables["/n4"].stateValues.text).eq(String(n4) + ".0"); + + expect(stateVariables["/n1a"].stateValues.text).eq( + String(Math.round(n1 * 10 ** 8) / 10 ** 8), + ); + expect(stateVariables["/n2a"].stateValues.text).eq( + String(Math.round(n2 * 10 ** 1) / 10 ** 1), + ); + expect(stateVariables["/n3a"].stateValues.text).eq( + String(Math.round(n3 * 10 ** 3) / 10 ** 3), + ); + expect(stateVariables["/n4a"].stateValues.text).eq(String(n4) + ".0"); + }); + + it("display error when select 3 from 1, inside text", async () => { + let core = await createTestCore({ + doenetML: ` + + `, + }); + + let errorWarnings = core.errorWarnings; + + expect(errorWarnings.errors.length).eq(1); + expect(errorWarnings.warnings.length).eq(0); + + expect(errorWarnings.errors[0].message).contain( + "Cannot select 3 values from a sequence of length 1", + ); + expect(errorWarnings.errors[0].doenetMLrange.lineBegin).eq(2); + expect(errorWarnings.errors[0].doenetMLrange.charBegin).eq(17); + expect(errorWarnings.errors[0].doenetMLrange.lineEnd).eq(2); + expect(errorWarnings.errors[0].doenetMLrange.charEnd).eq(65); + }); + + it("check bugfix for non-constant exclude and unique variants", async () => { + let core = await createTestCore({ + doenetML: ` + +

Number to exclude: 2

+

+ +

$n

+ + `, + }); + + let stateVariables = await returnAllStateVariables(core); + + let n = stateVariables["/n"].stateValues.value; + + expect(stateVariables["/n"].stateValues.value).eq(n); + + expect(stateVariables["/na"].stateValues.value).eq(n); + + expect(n === 1 || n === 3).eq(true); + }); + + it("check bugfix for non-constant exclude and defaulting to unique variants", async () => { + let core = await createTestCore({ + doenetML: ` +

Number to exclude: 2

+

+ +

$n

+ + `, + }); + + let stateVariables = await returnAllStateVariables(core); + + let n = stateVariables["/n"].stateValues.value; + + expect(stateVariables["/n"].stateValues.value).eq(n); + + expect(stateVariables["/na"].stateValues.value).eq(n); + + expect(n === 1 || n === 3).eq(true); + }); +}); diff --git a/packages/test-cypress/cypress/e2e/tagSpecific/selectfromsequence.cy.js b/packages/test-cypress/cypress/e2e/tagSpecific/selectfromsequence.cy.js index c5e57ef39..4d3323107 100644 --- a/packages/test-cypress/cypress/e2e/tagSpecific/selectfromsequence.cy.js +++ b/packages/test-cypress/cypress/e2e/tagSpecific/selectfromsequence.cy.js @@ -1,4 +1,3 @@ -import me from "math-expressions"; import { cesc, cesc2 } from "@doenet/utils"; describe("SelectFromSequence Tag Tests", function () { @@ -7,3827 +6,6 @@ describe("SelectFromSequence Tag Tests", function () { cy.visit("/"); }); - it("no parameters, select single number from 1 to 10", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_math1") + " .mjx-mrow") - .eq(0) - .invoke("text") - .then((text) => { - expect(text.trim()).equal("1"); - }); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - for (let ind = 1; ind <= 30; ind++) { - let num = - stateVariables[ - stateVariables["/sample" + ind].replacements[0] - .componentName - ].stateValues.value; - expect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10].includes(num)).eq(true); - } - }); - }); - - it("select single number from 1 to 6", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_math1") + " .mjx-mrow") - .eq(0) - .invoke("text") - .then((text) => { - expect(text.trim()).equal("1"); - }); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - for (let ind = 1; ind <= 30; ind++) { - let num = - stateVariables[ - stateVariables["/sample" + ind].replacements[0] - .componentName - ].stateValues.value; - expect([1, 2, 3, 4, 5, 6].includes(num)).eq(true); - } - }); - }); - - it("select single number from -3 to 5", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_math1") + " .mjx-mrow") - .eq(0) - .invoke("text") - .then((text) => { - expect(text.trim()).equal("1"); - }); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - for (let ind = 1; ind <= 30; ind++) { - let num = - stateVariables[ - stateVariables["/sample" + ind].replacements[0] - .componentName - ].stateValues.value; - expect([-3, -2, -1, 0, 1, 2, 3, 4, 5].includes(num)).eq(true); - } - }); - }); - - it("select single number from -3 to 5, excluding 0", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_math1") + " .mjx-mrow") - .eq(0) - .invoke("text") - .then((text) => { - expect(text.trim()).equal("1"); - }); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - for (let ind = 1; ind <= 30; ind++) { - let num = - stateVariables[ - stateVariables["/sample" + ind].replacements[0] - .componentName - ].stateValues.value; - expect([-3, -2, -1, 1, 2, 3, 4, 5].includes(num)).eq(true); - } - }); - }); - - it("select single odd number from -3 to 5", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_math1") + " .mjx-mrow") - .eq(0) - .invoke("text") - .then((text) => { - expect(text.trim()).equal("1"); - }); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - for (let ind = 1; ind <= 30; ind++) { - let num = - stateVariables[ - stateVariables["/sample" + ind].replacements[0] - .componentName - ].stateValues.value; - expect([-3, -1, 1, 3, 5].includes(num)).eq(true); - } - }); - }); - - it("select single letter from c to h", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_math1") + " .mjx-mrow") - .eq(0) - .invoke("text") - .then((text) => { - expect(text.trim()).equal("1"); - }); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - for (let ind = 1; ind <= 30; ind++) { - let letter = - stateVariables[ - stateVariables["/sample" + ind].replacements[0] - .componentName - ].stateValues.value; - expect(["c", "d", "e", "f", "g", "h"].includes(letter)).eq( - true, - ); - } - }); - }); - - it("select two even numbers from -4 to 4, excluding 0", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - 1 - - - - - - - - - - - - - - - - - - - - - - - `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_math1") + " .mjx-mrow") - .eq(0) - .invoke("text") - .then((text) => { - expect(text.trim()).equal("1"); - }); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - for (let ind = 1; ind <= 20; ind++) { - let num1 = - stateVariables[ - stateVariables["/sample" + ind].replacements[0] - .componentName - ].stateValues.value; - let num2 = - stateVariables[ - stateVariables["/sample" + ind].replacements[1] - .componentName - ].stateValues.value; - expect([-4, -2, 2, 4].includes(num1)).eq(true); - expect([-4, -2, 2, 4].includes(num2)).eq(true); - expect(num1).not.eq(num2); - } - }); - }); - - it("select two even numbers from -4 to 2, excluding 0 and combinations", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a -

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

- `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", "a"); - - let allowedCombinations = [ - [-4, 2], - [-2, -4], - [2, -2], - ]; - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - for (let ind = 1; ind <= 20; ind++) { - let num1 = - stateVariables[ - stateVariables["/sample" + ind].replacements[0] - .componentName - ].stateValues.value; - let num2 = - stateVariables[ - stateVariables["/sample" + ind].replacements[1] - .componentName - ].stateValues.value; - - expect( - allowedCombinations.some( - (v) => v[0] === num1 && v[1] === num2, - ), - ).eq(true); - } - }); - }); - - it("select two even numbers from -4 to 2, excluding 0 and combinations, as copies", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - -4 -2 - -2 - 2 - -4 - -4 -2 - -2 2 - 2 -4 - -

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

- `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", "a"); - - let allowedCombinations = [ - [-4, 2], - [-2, -4], - [2, -2], - ]; - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - for (let ind = 1; ind <= 20; ind++) { - let num1 = - stateVariables[ - stateVariables["/sample" + ind].replacements[0] - .componentName - ].stateValues.value; - let num2 = - stateVariables[ - stateVariables["/sample" + ind].replacements[1] - .componentName - ].stateValues.value; - - expect( - allowedCombinations.some( - (v) => v[0] === num1 && v[1] === num2, - ), - ).eq(true); - } - }); - }); - - it("select two even numbers from -4 to 2, excluding 0 and combinations, exclude extras", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a -

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

- `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", "a"); - - let allowedCombinations = [ - [-4, 2], - [-2, -4], - [2, -2], - ]; - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - for (let ind = 1; ind <= 20; ind++) { - let num1 = - stateVariables[ - stateVariables["/sample" + ind].replacements[0] - .componentName - ].stateValues.value; - let num2 = - stateVariables[ - stateVariables["/sample" + ind].replacements[1] - .componentName - ].stateValues.value; - - expect( - allowedCombinations.some( - (v) => v[0] === num1 && v[1] === num2, - ), - ).eq(true); - } - }); - }); - - it("select three numbers from 1 to 3, exclude combinations with two 1s", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a -

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

- `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", "a"); - - let allowedCombinations = [ - [1, 2, 2], - [1, 2, 3], - [1, 3, 2], - [1, 3, 3], - [2, 1, 2], - [2, 1, 3], - [3, 1, 2], - [3, 1, 3], - [2, 2, 1], - [2, 3, 1], - [3, 2, 1], - [3, 3, 1], - [2, 2, 2], - [2, 2, 3], - [2, 3, 2], - [3, 2, 2], - [3, 3, 2], - [3, 2, 3], - [2, 3, 3], - [3, 3, 3], - ]; - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - for (let ind = 1; ind <= 20; ind++) { - let num1 = - stateVariables[ - stateVariables["/sample" + ind].replacements[0] - .componentName - ].stateValues.value; - let num2 = - stateVariables[ - stateVariables["/sample" + ind].replacements[1] - .componentName - ].stateValues.value; - let num3 = - stateVariables[ - stateVariables["/sample" + ind].replacements[2] - .componentName - ].stateValues.value; - - expect( - allowedCombinations.some( - (v) => v[0] === num1 && v[1] === num2 && v[2] === num3, - ), - ).eq(true); - } - }); - }); - - it("select three numbers from 1 to 3, exclude combinations with two 1s, duplicate excludes", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a -

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

- `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", "a"); - - let allowedCombinations = [ - [1, 2, 2], - [1, 2, 3], - [1, 3, 2], - [1, 3, 3], - [2, 1, 2], - [2, 1, 3], - [3, 1, 2], - [3, 1, 3], - [2, 2, 1], - [2, 3, 1], - [3, 2, 1], - [3, 3, 1], - [2, 2, 2], - [2, 2, 3], - [2, 3, 2], - [3, 2, 2], - [3, 3, 2], - [3, 2, 3], - [2, 3, 3], - [3, 3, 3], - ]; - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - for (let ind = 1; ind <= 20; ind++) { - let num1 = - stateVariables[ - stateVariables["/sample" + ind].replacements[0] - .componentName - ].stateValues.value; - let num2 = - stateVariables[ - stateVariables["/sample" + ind].replacements[1] - .componentName - ].stateValues.value; - let num3 = - stateVariables[ - stateVariables["/sample" + ind].replacements[2] - .componentName - ].stateValues.value; - - expect( - allowedCombinations.some( - (v) => v[0] === num1 && v[1] === num2 && v[2] === num3, - ), - ).eq(true); - } - }); - }); - - it("select four numbers from 0 to 3, exclude positions of each number", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a -

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

- `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", "a"); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - for (let ind = 1; ind <= 20; ind++) { - let num1 = - stateVariables[ - stateVariables["/sample" + ind].replacements[0] - .componentName - ].stateValues.value; - let num2 = - stateVariables[ - stateVariables["/sample" + ind].replacements[1] - .componentName - ].stateValues.value; - let num3 = - stateVariables[ - stateVariables["/sample" + ind].replacements[2] - .componentName - ].stateValues.value; - let num4 = - stateVariables[ - stateVariables["/sample" + ind].replacements[3] - .componentName - ].stateValues.value; - - expect([1, 2, 3].includes(num1)).eq(true); - expect([0, 2, 3].includes(num2)).eq(true); - expect([0, 1, 3].includes(num3)).eq(true); - expect([0, 1, 2].includes(num4)).eq(true); - } - }); - }); - - it("select three numbers from 1 to 3, without replacement exclude positions of each number", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a -

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

- `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", "a"); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - for (let ind = 1; ind <= 20; ind++) { - let num1 = - stateVariables[ - stateVariables["/sample" + ind].replacements[0] - .componentName - ].stateValues.value; - let num2 = - stateVariables[ - stateVariables["/sample" + ind].replacements[1] - .componentName - ].stateValues.value; - let num3 = - stateVariables[ - stateVariables["/sample" + ind].replacements[2] - .componentName - ].stateValues.value; - - expect([2, 3].includes(num1)).eq(true); - expect([1, 3].includes(num2)).eq(true); - expect([1, 2].includes(num3)).eq(true); - } - }); - }); - - it("display error when select three numbers from 1 to 3, without replacement, exclude any place for 1", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` -

- `, - }, - "*", - ); - }); - - cy.get(cesc2("#/_document1")).should( - "contain.text", - "Excluded over 70%", - ); - cy.get(cesc2("#/_document1")).should("contain.text", "line 2"); - - cy.window().then(async (win) => { - let errorWarnings = await win.returnErrorWarnings1(); - - expect(errorWarnings.errors.length).eq(1); - expect(errorWarnings.warnings.length).eq(0); - - expect(errorWarnings.errors[0].message).contain( - "Excluded over 70%", - ); - expect(errorWarnings.errors[0].doenetMLrange.lineBegin).eq(2); - expect(errorWarnings.errors[0].doenetMLrange.charBegin).eq(16); - expect(errorWarnings.errors[0].doenetMLrange.lineEnd).eq(2); - expect(errorWarnings.errors[0].doenetMLrange.charEnd).eq(130); - }); - }); - - it("select 10 numbers from 1 to 10, without replacement, exclude positions of each number", () => { - // make sure that exclude combinations does not enumerate all combinations excluded - // to count them - - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a -

-

-

-

-

-

-

-

-

-

- `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", "a"); - - let allNumbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - for (let ind = 1; ind <= 10; ind++) { - for (let j = 0; j < 10; j++) { - let num = - stateVariables[ - stateVariables["/sample" + ind].replacements[j] - .componentName - ].stateValues.value; - - let validNums = [...allNumbers]; - validNums.splice(j, 1); - - expect(validNums.includes(num)).eq(true); - } - } - }); - }); - - it("select five even numbers with replacement from -4 to 4, excluding 0", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - 1 - - - - - - - - - - - - - - - - - - - - - - - `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_math1") + " .mjx-mrow") - .eq(0) - .invoke("text") - .then((text) => { - expect(text.trim()).equal("1"); - }); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - for (let ind = 1; ind <= 20; ind++) { - let num1 = - stateVariables[ - stateVariables["/sample" + ind].replacements[0] - .componentName - ].stateValues.value; - let num2 = - stateVariables[ - stateVariables["/sample" + ind].replacements[1] - .componentName - ].stateValues.value; - let num3 = - stateVariables[ - stateVariables["/sample" + ind].replacements[2] - .componentName - ].stateValues.value; - let num4 = - stateVariables[ - stateVariables["/sample" + ind].replacements[3] - .componentName - ].stateValues.value; - let num5 = - stateVariables[ - stateVariables["/sample" + ind].replacements[4] - .componentName - ].stateValues.value; - expect([-4, -2, 2, 4].includes(num1)).eq(true); - expect([-4, -2, 2, 4].includes(num2)).eq(true); - expect([-4, -2, 2, 4].includes(num3)).eq(true); - expect([-4, -2, 2, 4].includes(num4)).eq(true); - expect([-4, -2, 2, 4].includes(num5)).eq(true); - } - }); - }); - - it("select five (number initially unresolved) even numbers with replacement from -4 to 4, excluding 0", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - - - - - - - - - - - - - - - - - - - - - - $n3{name="n2"} - $num1{name="n"} - $n2+$num2+2 - $n3+$num3 - $num3{name="n3"} - 1 - `, - }, - "*", - ); - }); - - cy.get(cesc("#\\/_text1")).should("have.text", "a"); // to wait for page to load - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - for (let ind = 1; ind <= 20; ind++) { - let num1 = - stateVariables[ - stateVariables["/sample" + ind].replacements[0] - .componentName - ].stateValues.value; - let num2 = - stateVariables[ - stateVariables["/sample" + ind].replacements[1] - .componentName - ].stateValues.value; - let num3 = - stateVariables[ - stateVariables["/sample" + ind].replacements[2] - .componentName - ].stateValues.value; - let num4 = - stateVariables[ - stateVariables["/sample" + ind].replacements[3] - .componentName - ].stateValues.value; - let num5 = - stateVariables[ - stateVariables["/sample" + ind].replacements[4] - .componentName - ].stateValues.value; - expect([-4, -2, 2, 4].includes(num1)).eq(true); - expect([-4, -2, 2, 4].includes(num2)).eq(true); - expect([-4, -2, 2, 4].includes(num3)).eq(true); - expect([-4, -2, 2, 4].includes(num4)).eq(true); - expect([-4, -2, 2, 4].includes(num5)).eq(true); - } - }); - }); - - it("asList", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a -

-

- - `, - }, - "*", - ); - }); - - cy.get(cesc("#\\/_text1")).should("have.text", "a"); //wait for page to load - - let results = []; - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - - results.push(stateVariables["/u"].stateValues.value); - results.push(stateVariables["/v"].stateValues.value); - results.push(stateVariables["/w"].stateValues.value); - results.push(stateVariables["/x"].stateValues.value); - results.push(stateVariables["/y"].stateValues.value); - - for (let num of results) { - expect(num).gte(175).lte(205); - } - cy.get(cesc2("#/_p1")).should("have.text", results.join(", ")); - cy.get(cesc2("#/_p2")).should("have.text", results.join("")); - }); - }); - - it("copies don't resample", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - 1 -

- - -

- -

- $sample1{name="noresample1"} - $sample2{name="noresample2"} - $noresample1{name="noreresample1"} - $noresample2{name="noreresample2"} -

- -

$_aslist1{name="noresamplelist"}

- -

$noresamplelist{name="noreresamplelist"}

- - $_p1{name="noresamplep"} - $noresamplep{name="noreresamplep"} - `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_math1") + " .mjx-mrow") - .eq(0) - .invoke("text") - .then((text) => { - expect(text.trim()).equal("1"); - }); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let num1 = - stateVariables[ - stateVariables["/sample1"].replacements[0].componentName - ].stateValues.value; - let num2 = - stateVariables[ - stateVariables["/sample2"].replacements[0].componentName - ].stateValues.value; - expect(Number.isInteger(num1) && num1 >= 1 && num1 <= 100).eq(true); - expect(Number.isInteger(num2) && num2 >= 1 && num2 <= 100).eq(true); - expect( - stateVariables[ - stateVariables["/noresample1"].replacements[0].componentName - ].stateValues.value, - ).eq(num1); - expect( - stateVariables[ - stateVariables["/noresample2"].replacements[0].componentName - ].stateValues.value, - ).eq(num2); - expect( - stateVariables[ - stateVariables["/noreresample1"].replacements[0] - .componentName - ].stateValues.value, - ).eq(num1); - expect( - stateVariables[ - stateVariables["/noreresample2"].replacements[0] - .componentName - ].stateValues.value, - ).eq(num2); - - expect( - stateVariables[ - stateVariables["/noresamplelist"].activeChildren[0] - .componentName - ].stateValues.value, - ).eq(num1); - expect( - stateVariables[ - stateVariables["/noresamplelist"].activeChildren[1] - .componentName - ].stateValues.value, - ).eq(num2); - expect( - stateVariables[ - stateVariables["/noreresamplelist"].activeChildren[0] - .componentName - ].stateValues.value, - ).eq(num1); - expect( - stateVariables[ - stateVariables["/noreresamplelist"].activeChildren[1] - .componentName - ].stateValues.value, - ).eq(num2); - - expect( - stateVariables[ - stateVariables[ - stateVariables["/noresamplep"].activeChildren[0] - .componentName - ].activeChildren[0].componentName - ].stateValues.value, - ).eq(num1); - expect( - stateVariables[ - stateVariables[ - stateVariables["/noresamplep"].activeChildren[0] - .componentName - ].activeChildren[1].componentName - ].stateValues.value, - ).eq(num2); - expect( - stateVariables[ - stateVariables[ - stateVariables["/noreresamplep"].activeChildren[0] - .componentName - ].activeChildren[0].componentName - ].stateValues.value, - ).eq(num1); - expect( - stateVariables[ - stateVariables[ - stateVariables["/noreresamplep"].activeChildren[0] - .componentName - ].activeChildren[1].componentName - ].stateValues.value, - ).eq(num2); - }); - }); - - it("select doesn't change dynamically", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - 1 - - -

- -

- - - -

- -

-

$maxnum2.value{assignNames="maxnum2a"}

- `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_math1") + " .mjx-mrow") - .eq(0) - .invoke("text") - .then((text) => { - expect(text.trim()).equal("1"); - }); - - let sample1numbers, sample2numbers; - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let sample1replacements = stateVariables["/sample1"].replacements; - let sample2replacements = stateVariables["/sample2"].replacements; - expect(sample1replacements.length).eq(5); - expect(sample2replacements.length).eq(2); - sample1numbers = sample1replacements.map( - (x) => stateVariables[x.componentName].stateValues.value, - ); - sample2numbers = sample2replacements.map( - (x) => stateVariables[x.componentName].stateValues.value, - ); - - for (let num of sample1numbers) { - expect([1, 2, 3].includes(num)).eq(true); - } - for (let num of sample2numbers) { - expect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10].includes(num)).eq(true); - } - }); - - cy.log("Nothing changes when change mathinputs"); - cy.get(cesc("#\\/numToSelect") + " textarea").type( - `{end}{backspace}7{enter}`, - { force: true }, - ); - cy.get(cesc("#\\/maxnum") + " textarea").type( - `{end}{backspace}11{enter}`, - { - force: true, - }, - ); - cy.get(cesc("#\\/numToSelect2") + " textarea").type( - `{end}{backspace}15{enter}`, - { force: true }, - ); - cy.get(cesc("#\\/maxnum2") + " textarea").type( - `{end}{backspace}{backspace}18{enter}`, - { force: true }, - ); - cy.get(cesc("#\\/maxnum2a")).should("contain.text", "18"); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let sample1replacements = stateVariables["/sample1"].replacements; - let sample2replacements = stateVariables["/sample2"].replacements; - - expect( - sample1replacements.map( - (x) => stateVariables[x.componentName].stateValues.value, - ), - ).eqls(sample1numbers); - expect( - sample2replacements.map( - (x) => stateVariables[x.componentName].stateValues.value, - ), - ).eqls(sample2numbers); - }); - }); - - it("select doesn't resample in dynamic map", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - How many numbers do you want? -

- - - - - - -

- -

$_map1

-

$_aslist1

- - $p1{name="p4"} - $p2{name="p5"} - $p3{name="p6"} - - $p4{name="p7"} - $p5{name="p8"} - $p6{name="p9"} -

$_mathinput1.value{assignNames="m1"}

- `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", "a"); - - let samplednumbers = []; - - cy.log("initially nothing"); - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables[ - stateVariables["/p1"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p2"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p3"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p4"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p5"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p6"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p7"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p8"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p9"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - }); - - cy.log("sample one variable"); - cy.get(cesc("#\\/_mathinput1") + " textarea").type( - `{end}{backspace}1{enter}`, - { force: true }, - ); - cy.get(cesc("#\\/m1")).should("contain.text", "1"); - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let n1 = stateVariables["/a/n"].stateValues.value; - samplednumbers.push(n1); - expect( - stateVariables[ - stateVariables["/p1"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(1); - expect( - stateVariables[ - stateVariables["/p2"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(1); - expect( - stateVariables[ - stateVariables["/p3"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(1); - expect( - stateVariables[ - stateVariables["/p4"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(1); - expect( - stateVariables[ - stateVariables["/p5"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(1); - expect( - stateVariables[ - stateVariables["/p6"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(1); - expect( - stateVariables[ - stateVariables["/p7"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(1); - expect( - stateVariables[ - stateVariables["/p8"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(1); - expect( - stateVariables[ - stateVariables["/p9"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(1); - for (let ind = 0; ind < 1; ind++) { - expect( - stateVariables[ - stateVariables[ - stateVariables["/p1"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p2"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p3"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p4"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p5"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p6"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p7"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p8"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p9"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - } - }); - - cy.log("go back to nothing"); - cy.get(cesc("#\\/_mathinput1") + " textarea").type( - `{end}{backspace}0{enter}`, - { force: true }, - ); - cy.get(cesc("#\\/m1")).should("contain.text", "0"); - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables[ - stateVariables["/p1"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p2"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p3"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p4"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p5"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p6"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p7"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p8"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p9"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - }); - - cy.log("get same number back"); - cy.get(cesc("#\\/_mathinput1") + " textarea").type( - `{end}{backspace}1{enter}`, - { force: true }, - ); - cy.get(cesc("#\\/m1")).should("contain.text", "1"); - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let n1 = stateVariables["/a/n"].stateValues.value; - expect(n1).eq(samplednumbers[0]); - expect( - stateVariables[ - stateVariables["/p1"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(1); - expect( - stateVariables[ - stateVariables["/p2"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(1); - expect( - stateVariables[ - stateVariables["/p3"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(1); - expect( - stateVariables[ - stateVariables["/p4"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(1); - expect( - stateVariables[ - stateVariables["/p5"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(1); - expect( - stateVariables[ - stateVariables["/p6"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(1); - expect( - stateVariables[ - stateVariables["/p7"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(1); - expect( - stateVariables[ - stateVariables["/p8"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(1); - expect( - stateVariables[ - stateVariables["/p9"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(1); - - for (let ind = 0; ind < 1; ind++) { - expect( - stateVariables[ - stateVariables[ - stateVariables["/p1"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p2"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p3"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p4"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p5"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p6"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p7"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p8"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p9"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - } - }); - - cy.log("get two more samples"); - cy.get(cesc("#\\/_mathinput1") + " textarea").type( - `{end}{backspace}3{enter}`, - { force: true }, - ); - cy.get(cesc("#\\/m1")).should("contain.text", "3"); - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let n1 = stateVariables["/a/n"].stateValues.value; - let n2 = stateVariables["/b/n"].stateValues.value; - let n3 = stateVariables["/c/n"].stateValues.value; - expect(n1).eq(samplednumbers[0]); - samplednumbers.push(n2); - samplednumbers.push(n3); - expect( - stateVariables[ - stateVariables["/p1"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(3); - expect( - stateVariables[ - stateVariables["/p2"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(3); - expect( - stateVariables[ - stateVariables["/p3"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(3); - expect( - stateVariables[ - stateVariables["/p4"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(3); - expect( - stateVariables[ - stateVariables["/p5"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(3); - expect( - stateVariables[ - stateVariables["/p6"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(3); - expect( - stateVariables[ - stateVariables["/p7"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(3); - expect( - stateVariables[ - stateVariables["/p8"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(3); - expect( - stateVariables[ - stateVariables["/p9"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(3); - for (let ind = 0; ind < 3; ind++) { - expect( - stateVariables[ - stateVariables[ - stateVariables["/p1"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p2"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p3"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p4"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p5"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p6"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p7"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p8"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p9"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - } - }); - - cy.log("go back to nothing"); - cy.get(cesc("#\\/_mathinput1") + " textarea").type( - `{end}{backspace}0{enter}`, - { force: true }, - ); - cy.get(cesc("#\\/m1")).should("contain.text", "0"); - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables[ - stateVariables["/p1"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p2"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p3"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p4"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p5"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p6"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p7"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p8"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p9"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - }); - - cy.log("get first two numbers back"); - cy.get(cesc("#\\/_mathinput1") + " textarea").type( - `{end}{backspace}2{enter}`, - { force: true }, - ); - cy.get(cesc("#\\/m1")).should("contain.text", "2"); - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let n1 = stateVariables["/a/n"].stateValues.value; - let n2 = stateVariables["/b/n"].stateValues.value; - expect(n1).eq(samplednumbers[0]); - expect(n2).eq(samplednumbers[1]); - expect( - stateVariables[ - stateVariables["/p1"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(2); - expect( - stateVariables[ - stateVariables["/p2"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(2); - expect( - stateVariables[ - stateVariables["/p3"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(2); - expect( - stateVariables[ - stateVariables["/p4"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(2); - expect( - stateVariables[ - stateVariables["/p5"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(2); - expect( - stateVariables[ - stateVariables["/p6"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(2); - expect( - stateVariables[ - stateVariables["/p7"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(2); - expect( - stateVariables[ - stateVariables["/p8"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(2); - expect( - stateVariables[ - stateVariables["/p9"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(2); - - for (let ind = 0; ind < 2; ind++) { - expect( - stateVariables[ - stateVariables[ - stateVariables["/p1"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p2"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p3"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p4"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p5"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p6"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p7"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p8"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p9"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - } - }); - - cy.log("get six total samples"); - cy.get(cesc("#\\/_mathinput1") + " textarea").type( - `{end}{backspace}6{enter}`, - { force: true }, - ); - cy.get(cesc("#\\/m1")).should("contain.text", "6"); - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let n1 = stateVariables["/a/n"].stateValues.value; - let n2 = stateVariables["/b/n"].stateValues.value; - let n3 = stateVariables["/c/n"].stateValues.value; - let n4 = stateVariables["/d/n"].stateValues.value; - let n5 = stateVariables["/e/n"].stateValues.value; - let n6 = stateVariables["/f/n"].stateValues.value; - expect(n1).eq(samplednumbers[0]); - expect(n2).eq(samplednumbers[1]); - expect(n3).eq(samplednumbers[2]); - samplednumbers.push(n4); - samplednumbers.push(n5); - samplednumbers.push(n6); - expect( - stateVariables[ - stateVariables["/p1"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(6); - expect( - stateVariables[ - stateVariables["/p2"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(6); - expect( - stateVariables[ - stateVariables["/p3"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(6); - expect( - stateVariables[ - stateVariables["/p4"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(6); - expect( - stateVariables[ - stateVariables["/p5"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(6); - expect( - stateVariables[ - stateVariables["/p6"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(6); - expect( - stateVariables[ - stateVariables["/p7"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(6); - expect( - stateVariables[ - stateVariables["/p8"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(6); - expect( - stateVariables[ - stateVariables["/p9"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(6); - for (let ind = 0; ind < 6; ind++) { - expect( - stateVariables[ - stateVariables[ - stateVariables["/p1"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p2"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p3"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p4"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p5"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p6"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p7"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p8"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p9"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - } - }); - - cy.log("go back to nothing"); - cy.get(cesc("#\\/_mathinput1") + " textarea").type( - `{end}{backspace}0{enter}`, - { force: true }, - ); - cy.get(cesc("#\\/m1")).should("contain.text", "0"); - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect( - stateVariables[ - stateVariables["/p1"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p2"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p3"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p4"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p5"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p6"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p7"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p8"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - expect( - stateVariables[ - stateVariables["/p9"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(0); - }); - - cy.log("get all six back"); - cy.get(cesc("#\\/_mathinput1") + " textarea").type( - `{end}{backspace}6{enter}`, - { force: true }, - ); - cy.get(cesc("#\\/m1")).should("contain.text", "6"); - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let n1 = stateVariables["/a/n"].stateValues.value; - let n2 = stateVariables["/b/n"].stateValues.value; - let n3 = stateVariables["/c/n"].stateValues.value; - let n4 = stateVariables["/d/n"].stateValues.value; - let n5 = stateVariables["/e/n"].stateValues.value; - let n6 = stateVariables["/f/n"].stateValues.value; - expect(n1).eq(samplednumbers[0]); - expect(n2).eq(samplednumbers[1]); - expect(n3).eq(samplednumbers[2]); - expect(n4).eq(samplednumbers[3]); - expect(n5).eq(samplednumbers[4]); - expect(n6).eq(samplednumbers[5]); - expect( - stateVariables[ - stateVariables["/p1"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(6); - expect( - stateVariables[ - stateVariables["/p2"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(6); - expect( - stateVariables[ - stateVariables["/p3"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(6); - expect( - stateVariables[ - stateVariables["/p4"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(6); - expect( - stateVariables[ - stateVariables["/p5"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(6); - expect( - stateVariables[ - stateVariables["/p6"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(6); - expect( - stateVariables[ - stateVariables["/p7"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(6); - expect( - stateVariables[ - stateVariables["/p8"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(6); - expect( - stateVariables[ - stateVariables["/p9"].activeChildren[0].componentName - ].activeChildren.length, - ).eq(6); - for (let ind = 0; ind < 6; ind++) { - expect( - stateVariables[ - stateVariables[ - stateVariables["/p1"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p2"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p3"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p4"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p5"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p6"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p7"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p8"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - expect( - stateVariables[ - stateVariables[ - stateVariables["/p9"].activeChildren[0] - .componentName - ].activeChildren[ind].componentName - ].stateValues.value, - ).eq(samplednumbers[ind]); - } - }); - }); - - it("select single math, assign name", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a -

-

-

-

$u{name="u2"}

-

$v{name="v2"}

-

$w{name="w2"}

- `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", "a"); - - let options = [ - me.fromText("x"), - me.fromText("x+y"), - me.fromText("x+2y"), - ]; - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - - let u = stateVariables["/u"]; - let u2 = stateVariables["/u2"]; - let comparisons = options.map((el) => - el.equals(me.fromAst(u.stateValues.value)), - ); - expect(comparisons.includes(true)).eq(true); - expect(u.stateValues.value).eqls(u2.stateValues.value); - - let v = stateVariables["/v"]; - let v2 = stateVariables["/v2"]; - comparisons = options.map((el) => - el.equals(me.fromAst(v.stateValues.value)), - ); - expect(comparisons.includes(true)).eq(true); - expect(v.stateValues.value).eqls(v2.stateValues.value); - - let w = stateVariables["/w"]; - let w2 = stateVariables["/w2"]; - comparisons = options.map((el) => - el.equals(me.fromAst(w.stateValues.value)), - ); - expect(comparisons.includes(true)).eq(true); - expect(w.stateValues.value).eqls(w2.stateValues.value); - }); - }); - - it("select multiple maths, assign names", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - 1 -

- -

-

$u{name="u2"}

-

$v{name="v2"}

-

$w{name="w2"}

- `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_math1") + " .mjx-mrow") - .eq(0) - .invoke("text") - .then((text) => { - expect(text.trim()).equal("1"); - }); - - let options = [ - me.fromText("x"), - me.fromText("x+y"), - me.fromText("x+2y"), - ]; - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - - let u = stateVariables["/u"]; - let u2 = stateVariables["/u2"]; - let comparisons = options.map((el) => - el.equals(me.fromAst(u.stateValues.value)), - ); - expect(comparisons.includes(true)).eq(true); - expect(u.stateValues.value).eqls(u2.stateValues.value); - - let v = stateVariables["/v"]; - let v2 = stateVariables["/v2"]; - comparisons = options.map((el) => - el.equals(me.fromAst(v.stateValues.value)), - ); - expect(comparisons.includes(true)).eq(true); - expect(v.stateValues.value).eqls(v2.stateValues.value); - - let w = stateVariables["/w"]; - let w2 = stateVariables["/w2"]; - comparisons = options.map((el) => - el.equals(me.fromAst(w.stateValues.value)), - ); - expect(comparisons.includes(true)).eq(true); - expect(w.stateValues.value).eqls(w2.stateValues.value); - - let s = stateVariables["/s"]; - for (let ind = 3; ind < 6; ind++) { - let r = stateVariables[s.replacements[ind].componentName]; - comparisons = options.map((el) => - el.equals(me.fromAst(r.stateValues.value)), - ); - expect(comparisons.includes(true)).eq(true); - } - }); - }); - - it("select multiple maths, assign names, new namespace", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - 1 -

- -

-

$(s/u{name="u2"})

-

$(s/v{name="v2"})

-

$(s/w{name="w2"})

- `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_math1") + " .mjx-mrow") - .eq(0) - .invoke("text") - .then((text) => { - expect(text.trim()).equal("1"); - }); - - let options = [ - me.fromText("x"), - me.fromText("x+y"), - me.fromText("x+2y"), - ]; - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - - let u = stateVariables["/s/u"]; - let u2 = stateVariables["/u2"]; - let comparisons = options.map((el) => - el.equals(me.fromAst(u.stateValues.value)), - ); - expect(comparisons.includes(true)).eq(true); - expect(u.stateValues.value).eqls(u2.stateValues.value); - - let v = stateVariables["/s/v"]; - let v2 = stateVariables["/v2"]; - comparisons = options.map((el) => - el.equals(me.fromAst(v.stateValues.value)), - ); - expect(comparisons.includes(true)).eq(true); - expect(v.stateValues.value).eqls(v2.stateValues.value); - - let w = stateVariables["/s/w"]; - let w2 = stateVariables["/w2"]; - comparisons = options.map((el) => - el.equals(me.fromAst(w.stateValues.value)), - ); - expect(comparisons.includes(true)).eq(true); - expect(w.stateValues.value).eqls(w2.stateValues.value); - - let s = stateVariables["/s"]; - for (let ind = 3; ind < 6; ind++) { - let r = stateVariables[s.replacements[ind].componentName]; - comparisons = options.map((el) => - el.equals(me.fromAst(r.stateValues.value)), - ); - expect(comparisons.includes(true)).eq(true); - } - }); - }); - - it("selectfromsequence with hide will hide replacements", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` -

Selectfromsequences and hide

-

,

-

$c,

- `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_p1")).should( - "have.text", - "Selectfromsequences and hide", - ); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let c = await stateVariables["/c"].stateValues.value; - let d = await stateVariables["/d"].stateValues.value; - expect(["a", "b", "c", "d", "e"].includes(c)).eq(true); - expect(["a", "b", "c", "d", "e"].includes(d)).eq(true); - - cy.get(cesc(`#\\/_p2`)).should("have.text", `${c}, `); - cy.get(cesc(`#\\/_p3`)).should("have.text", `${c}, ${d}`); - }); - }); - - it("select multiple numbers with excludecombinations, adjust for round-off error", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a -

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

- `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", "a"); - - let allowedCombinations = [ - [0.1, 0.2], - [0.2, 0.1], - [0.3, 0.2], - ]; - let foundCombination = [false, false, false]; - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - for (let ind = 1; ind <= 20; ind++) { - let x1 = - stateVariables[ - stateVariables["/sample" + ind].replacements[0] - .componentName - ].stateValues.value; - let x2 = - stateVariables[ - stateVariables["/sample" + ind].replacements[1] - .componentName - ].stateValues.value; - - let combination = -1; - for (let [ind, comb] of allowedCombinations.entries()) { - if ( - Math.abs(comb[0] - x1) < 1e-14 && - Math.abs(comb[1] - x2) < 1e-14 - ) { - combination = ind; - } - } - - expect(combination).not.eq(-1); - - foundCombination[combination] = true; - } - - for (let i = 0; i < 3; i++) { - expect(foundCombination[i]).be.true; - } - }); - }); - - it("select multiple math with excludecombinations, adjust for round-off error", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a -

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

- `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", "a"); - - let allowedCombinations = [ - [0.1, 0.2], - [0.2, 0.1], - [0.3, 0.2], - ]; - let foundCombination = [false, false, false]; - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - for (let ind = 1; ind <= 20; ind++) { - let x1 = - stateVariables[ - stateVariables["/sample" + ind].replacements[0] - .componentName - ].stateValues.value; - let x2 = - stateVariables[ - stateVariables["/sample" + ind].replacements[1] - .componentName - ].stateValues.value; - - let combination = -1; - for (let [ind, comb] of allowedCombinations.entries()) { - if ( - Math.abs(comb[0] - x1) < 1e-14 && - Math.abs(comb[1] - x2) < 1e-14 - ) { - combination = ind; - } - } - - expect(combination).not.eq(-1); - - foundCombination[combination] = true; - } - - for (let i = 0; i < 3; i++) { - expect(foundCombination[i]).be.true; - } - }); - }); - - it("select multiple maths with excludes and excludecombinations", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a -

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

- `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", "a"); - - let allowedCombinations = [ - [me.fromText("x"), me.fromText("x+3y")], - [me.fromText("x+y"), me.fromText("x")], - [me.fromText("x+3y"), me.fromText("x+y")], - ]; - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - for (let ind = 1; ind <= 20; ind++) { - let x1 = me.fromAst( - stateVariables[ - stateVariables["/sample" + ind].replacements[0] - .componentName - ].stateValues.value, - ); - let x2 = me.fromAst( - stateVariables[ - stateVariables["/sample" + ind].replacements[1] - .componentName - ].stateValues.value, - ); - - expect( - allowedCombinations.some( - (v) => v[0].equals(x1) && v[1].equals(x2), - ), - ).eq(true); - } - }); - }); - - it("select multiple maths with excludes and excludecombinations, as copies", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - x x+y - x+y - x+3y - x - x x+y - x+y x+3y - -

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

- `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", "a"); - - let allowedCombinations = [ - [me.fromText("x"), me.fromText("x+3y")], - [me.fromText("x+y"), me.fromText("x")], - [me.fromText("x+3y"), me.fromText("x+y")], - ]; - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - for (let ind = 1; ind <= 20; ind++) { - let x1 = me.fromAst( - stateVariables[ - stateVariables["/sample" + ind].replacements[0] - .componentName - ].stateValues.value, - ); - let x2 = me.fromAst( - stateVariables[ - stateVariables["/sample" + ind].replacements[1] - .componentName - ].stateValues.value, - ); - - expect( - allowedCombinations.some( - (v) => v[0].equals(x1) && v[1].equals(x2), - ), - ).eq(true); - } - }); - }); - - it("select multiple maths with excludes and excludecombinations, exclude extras", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a -

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

- `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", "a"); - - let allowedCombinations = [ - [me.fromText("x"), me.fromText("x+3y")], - [me.fromText("x+y"), me.fromText("x")], - [me.fromText("x+3y"), me.fromText("x+y")], - ]; - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - for (let ind = 1; ind <= 20; ind++) { - let x1 = me.fromAst( - stateVariables[ - stateVariables["/sample" + ind].replacements[0] - .componentName - ].stateValues.value, - ); - let x2 = me.fromAst( - stateVariables[ - stateVariables["/sample" + ind].replacements[1] - .componentName - ].stateValues.value, - ); - - expect( - allowedCombinations.some( - (v) => v[0].equals(x1) && v[1].equals(x2), - ), - ).eq(true); - } - }); - }); - - it("select multiple letters with excludes and excludecombinations", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a -

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

- `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", "a"); - - let allowedCombinations = [ - ["m", "s"], - ["s", "v"], - ["v", "m"], - ]; - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - for (let ind = 1; ind <= 20; ind++) { - let x1 = - stateVariables[ - stateVariables["/sample" + ind].replacements[0] - .componentName - ].stateValues.value; - let x2 = - stateVariables[ - stateVariables["/sample" + ind].replacements[1] - .componentName - ].stateValues.value; - - expect( - allowedCombinations.some((v) => v[0] === x1 && v[1] === x2), - ).eq(true); - } - }); - }); - - it("select multiple letters with excludes and excludecombinations, as copies", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - m v - s - v - s - m v - s m - -

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

- `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", "a"); - - let allowedCombinations = [ - ["m", "s"], - ["s", "v"], - ["v", "m"], - ]; - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - for (let ind = 1; ind <= 20; ind++) { - let x1 = - stateVariables[ - stateVariables["/sample" + ind].replacements[0] - .componentName - ].stateValues.value; - let x2 = - stateVariables[ - stateVariables["/sample" + ind].replacements[1] - .componentName - ].stateValues.value; - - expect( - allowedCombinations.some((v) => v[0] === x1 && v[1] === x2), - ).eq(true); - } - }); - }); - - it("select multiple letters with excludes and excludecombinations, exclude extras", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a -

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

- `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", "a"); - - let allowedCombinations = [ - ["m", "s"], - ["s", "v"], - ["v", "m"], - ]; - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - for (let ind = 1; ind <= 20; ind++) { - let x1 = - stateVariables[ - stateVariables["/sample" + ind].replacements[0] - .componentName - ].stateValues.value; - let x2 = - stateVariables[ - stateVariables["/sample" + ind].replacements[1] - .componentName - ].stateValues.value; - - expect( - allowedCombinations.some((v) => v[0] === x1 && v[1] === x2), - ).eq(true); - } - }); - }); - - it("select numbers and sort", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a -

- -

$_aslist1{name="aslist2"}

- $_p1{name="p3"} - `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", "a"); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - - let lastnumber = -20; - let originalnumbers = stateVariables[ - "/_selectfromsequence1" - ].replacements.map((x) => stateVariables[x.componentName]); - let secondnumbers = stateVariables["/aslist2"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - let thirdnumbers = stateVariables[ - stateVariables["/p3"].activeChildren[0].componentName - ].activeChildren.map((x) => stateVariables[x.componentName]); - for (let i = 0; i < 20; i++) { - let newnumber = originalnumbers[i].stateValues.value; - expect(newnumber).gte(lastnumber); - lastnumber = newnumber; - expect(secondnumbers[i].stateValues.value).eq(newnumber); - expect(thirdnumbers[i].stateValues.value).eq(newnumber); - } - }); - }); - - it("select letters and sort", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a -

- -

$_aslist1{name="aslist2"}

- $_p1{name="p3"} - `, - }, - "*", - ); - }); - - // to wait for page to load - cy.get(cesc("#\\/_text1")).should("have.text", "a"); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - - let lastletter = "a"; - let originalletters = stateVariables[ - "/_selectfromsequence1" - ].replacements.map((x) => stateVariables[x.componentName]); - let secondletters = stateVariables["/aslist2"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - let thirdletters = stateVariables[ - stateVariables["/p3"].activeChildren[0].componentName - ].activeChildren.map((x) => stateVariables[x.componentName]); - for (let i = 0; i < 20; i++) { - let newletter = originalletters[i].stateValues.value; - expect(newletter.length).gte(lastletter.length); - expect( - newletter.length > lastletter.length || - newletter >= lastletter, - ).to.be.true; - lastletter = newletter; - expect(secondletters[i].stateValues.value).eq(newletter); - expect(thirdletters[i].stateValues.value).eq(newletter); - } - }); - }); - - it("selectfromsequence hides dynamically", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - - - - - - -

,

-

$c, $d

- `, - }, - "*", - ); - }); - - cy.get(cesc("#\\/_text1")).should("have.text", "a"); // to wait for page to load - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let c = await stateVariables["/c"].stateValues.value; - let d = await stateVariables["/d"].stateValues.value; - expect(["a", "b", "c", "d", "e"].includes(c)).eq(true); - expect(["a", "b", "c", "d", "e"].includes(d)).eq(true); - - cy.get(cesc(`#\\/_p1`)).should("have.text", `${c}, `); - cy.get(cesc(`#\\/_p2`)).should("have.text", `${c}, ${d}`); - - cy.get(cesc("#\\/h1")).click(); - cy.get(cesc("#\\/h2")).click(); - - cy.get(cesc(`#\\/_p1`)).should("have.text", `, ${d}`); - cy.get(cesc(`#\\/_p2`)).should("have.text", `${c}, ${d}`); - - cy.get(cesc("#\\/h1")).click(); - cy.get(cesc("#\\/h2")).click(); - - cy.get(cesc(`#\\/_p1`)).should("have.text", `${c}, `); - cy.get(cesc(`#\\/_p2`)).should("have.text", `${c}, ${d}`); - }); - }); - - it("selectfromsequence defaults to fixed", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - - - - - - -

- - - -

-

- $a{name="a2"} - $b{name="b2"} - $c{name="c2"} -

-

- - - -

-

- - - -

-

- $a.fixed{assignNames="af"} - $b.fixed{assignNames="bf"} - $c.fixed{assignNames="cf"} -

-

- $a2.fixed{assignNames="a2f"} - $b2.fixed{assignNames="b2f"} - $c2.fixed{assignNames="c2f"} -

- `, - }, - "*", - ); - }); - - cy.get(cesc("#\\/_text1")).should("have.text", "a"); // to wait for page to load - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let a = stateVariables["/a"].stateValues.value; - let b = stateVariables["/b"].stateValues.value; - let c = stateVariables["/c"].stateValues.value; - expect(["a", "b", "c", "d", "e"].includes(a)).eq(true); - expect(["a", "b", "c", "d", "e"].includes(b)).eq(true); - expect(["a", "b", "c", "d", "e"].includes(c)).eq(true); - - cy.get(cesc("#\\/a")).should("have.text", a); - cy.get(cesc("#\\/b")).should("have.text", b); - cy.get(cesc("#\\/c")).should("have.text", c); - cy.get(cesc("#\\/a2")).should("have.text", a); - cy.get(cesc("#\\/b2")).should("have.text", b); - cy.get(cesc("#\\/c2")).should("have.text", c); - - cy.get(cesc("#\\/af")).should("have.text", "true"); - cy.get(cesc("#\\/bf")).should("have.text", "false"); - cy.get(cesc("#\\/cf")).should("have.text", "true"); - cy.get(cesc("#\\/a2f")).should("have.text", "true"); - cy.get(cesc("#\\/b2f")).should("have.text", "false"); - cy.get(cesc("#\\/c2f")).should("have.text", "true"); - - cy.get(cesc("#\\/a3_input")).clear().type("f{enter}"); - cy.get(cesc("#\\/b3_input")).clear().type("g{enter}"); - cy.get(cesc("#\\/c3_input")).clear().type("h{enter}"); - - cy.get(cesc("#\\/a")).should("have.text", a); - cy.get(cesc("#\\/b")).should("have.text", "g"); - cy.get(cesc("#\\/c")).should("have.text", c); - cy.get(cesc("#\\/a2")).should("have.text", a); - cy.get(cesc("#\\/b2")).should("have.text", "g"); - cy.get(cesc("#\\/c2")).should("have.text", c); - - cy.get(cesc("#\\/a4_input")).clear().type("i{enter}"); - cy.get(cesc("#\\/b4_input")).clear().type("j{enter}"); - cy.get(cesc("#\\/c4_input")).clear().type("k{enter}"); - - cy.get(cesc("#\\/a")).should("have.text", a); - cy.get(cesc("#\\/b")).should("have.text", "j"); - cy.get(cesc("#\\/c")).should("have.text", c); - cy.get(cesc("#\\/a2")).should("have.text", a); - cy.get(cesc("#\\/b2")).should("have.text", "j"); - cy.get(cesc("#\\/c2")).should("have.text", c); - - cy.get(cesc("#\\/f1")).click(); - cy.get(cesc("#\\/f2")).click(); - - cy.get(cesc("#\\/af")).should("have.text", "true"); - cy.get(cesc("#\\/bf")).should("have.text", "true"); - cy.get(cesc("#\\/cf")).should("have.text", "false"); - cy.get(cesc("#\\/a2f")).should("have.text", "true"); - cy.get(cesc("#\\/b2f")).should("have.text", "true"); - cy.get(cesc("#\\/c2f")).should("have.text", "false"); - - cy.get(cesc("#\\/a3_input")).clear().type("l{enter}"); - cy.get(cesc("#\\/b3_input")).clear().type("m{enter}"); - cy.get(cesc("#\\/c3_input")).clear().type("n{enter}"); - - cy.get(cesc("#\\/a")).should("have.text", a); - cy.get(cesc("#\\/b")).should("have.text", "j"); - cy.get(cesc("#\\/c")).should("have.text", "n"); - cy.get(cesc("#\\/a2")).should("have.text", a); - cy.get(cesc("#\\/b2")).should("have.text", "j"); - cy.get(cesc("#\\/c2")).should("have.text", "n"); - - cy.get(cesc("#\\/a4_input")).clear().type("o{enter}"); - cy.get(cesc("#\\/b4_input")).clear().type("p{enter}"); - cy.get(cesc("#\\/c4_input")).clear().type("q{enter}"); - - cy.get(cesc("#\\/a")).should("have.text", a); - cy.get(cesc("#\\/b")).should("have.text", "j"); - cy.get(cesc("#\\/c")).should("have.text", "q"); - cy.get(cesc("#\\/a2")).should("have.text", a); - cy.get(cesc("#\\/b2")).should("have.text", "j"); - cy.get(cesc("#\\/c2")).should("have.text", "q"); - }); - }); - - it("numToSelect from selectfromsequence", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - -

n1 =

-

nums =

-

a1=$a1, b1=$b1, c1=$c1, d1=$d1, e1=$e1

- -

n2 =

-

nums =

-

a2=$a2, b2=$b2, c2=$c2, d2=$d2, e2=$e2

- -

n3 =

-

nums =

-

a3=$a3, b3=$b3, c3=$c3, d3=$d3, e3=$e3

- -

n4 =

-

nums =

-

a4=$a4, b4=$b4, c4=$c4, d4=$d4, e4=$e4

- -

n5 =

-

nums =

-

a5=$a5, b5=$b5, c5=$c5, d5=$d5, e5=$e5

- `, - }, - "*", - ); - }); - - cy.get(cesc("#\\/_text1")).should("have.text", "a"); // to wait for page to load - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let n1 = stateVariables["/n1"].stateValues.value; - let n2 = stateVariables["/n2"].stateValues.value; - let n3 = stateVariables["/n3"].stateValues.value; - let n4 = stateVariables["/n4"].stateValues.value; - let n5 = stateVariables["/n5"].stateValues.value; - - let nums1 = stateVariables["/nums1"].replacements.map( - (x) => stateVariables[x.componentName].stateValues.value, - ); - let nums2 = stateVariables["/nums2"].replacements.map( - (x) => stateVariables[x.componentName].stateValues.value, - ); - let nums3 = stateVariables["/nums3"].replacements.map( - (x) => stateVariables[x.componentName].stateValues.value, - ); - let nums4 = stateVariables["/nums4"].replacements.map( - (x) => stateVariables[x.componentName].stateValues.value, - ); - let nums5 = stateVariables["/nums5"].replacements.map( - (x) => stateVariables[x.componentName].stateValues.value, - ); - - expect(nums1.length).eq(n1); - expect(nums2.length).eq(n2); - expect(nums3.length).eq(n3); - expect(nums4.length).eq(n4); - expect(nums5.length).eq(n5); - - nums1.length = 5; - nums2.length = 5; - nums3.length = 5; - nums4.length = 5; - nums5.length = 5; - - nums1.fill("", n1); - nums2.fill("", n2); - nums3.fill("", n3); - nums4.fill("", n4); - nums5.fill("", n5); - - let l = ["a", "b", "c", "d", "e"]; - - cy.get(cesc("#\\/p1")).should( - "have.text", - nums1.map((v, i) => `${l[i]}1=${v}`).join(", "), - ); - cy.get(cesc("#\\/p2")).should( - "have.text", - nums2.map((v, i) => `${l[i]}2=${v}`).join(", "), - ); - cy.get(cesc("#\\/p3")).should( - "have.text", - nums3.map((v, i) => `${l[i]}3=${v}`).join(", "), - ); - cy.get(cesc("#\\/p4")).should( - "have.text", - nums4.map((v, i) => `${l[i]}4=${v}`).join(", "), - ); - cy.get(cesc("#\\/p5")).should( - "have.text", - nums5.map((v, i) => `${l[i]}5=${v}`).join(", "), - ); - }); - }); - - it("rounding", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a -

-

-

-

- -

$n1

-

$n2

-

$n3

-

$n4

- - `, - }, - "*", - ); - }); - - cy.get(cesc("#\\/_text1")).should("have.text", "a"); //wait for page to load - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - - let n1 = stateVariables["/n1"].stateValues.value; - let n2 = stateVariables["/n2"].stateValues.value; - let n3 = stateVariables["/n3"].stateValues.value; - let n4 = stateVariables["/n4"].stateValues.value; - - cy.get(cesc("#\\/n1")).should( - "have.text", - String(Math.round(n1 * 10 ** 8) / 10 ** 8), - ); - cy.get(cesc("#\\/n2")).should( - "have.text", - String(Math.round(n2 * 10 ** 1) / 10 ** 1), - ); - cy.get(cesc("#\\/n3")).should( - "have.text", - String(Math.round(n3 * 10 ** 3) / 10 ** 3), - ); - cy.get(cesc("#\\/n4")).should("have.text", String(n4) + ".0"); - - cy.get(cesc("#\\/n1a")).should( - "have.text", - String(Math.round(n1 * 10 ** 8) / 10 ** 8), - ); - cy.get(cesc("#\\/n2a")).should( - "have.text", - String(Math.round(n2 * 10 ** 1) / 10 ** 1), - ); - cy.get(cesc("#\\/n3a")).should( - "have.text", - String(Math.round(n3 * 10 ** 3) / 10 ** 3), - ); - cy.get(cesc("#\\/n4a")).should("have.text", String(n4) + ".0"); - }); - }); - - it("display error when select 3 from 1, inside text", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - - `, - }, - "*", - ); - }); - - cy.get(cesc2("#/_document1")).should( - "contain.text", - "Cannot select 3 values from a sequence of length 1", - ); - cy.get(cesc2("#/_document1")).should("contain.text", "line 2"); - - cy.window().then(async (win) => { - let errorWarnings = await win.returnErrorWarnings1(); - - expect(errorWarnings.errors.length).eq(1); - expect(errorWarnings.warnings.length).eq(0); - - expect(errorWarnings.errors[0].message).contain( - "Cannot select 3 values from a sequence of length 1", - ); - expect(errorWarnings.errors[0].doenetMLrange.lineBegin).eq(2); - expect(errorWarnings.errors[0].doenetMLrange.charBegin).eq(17); - expect(errorWarnings.errors[0].doenetMLrange.lineEnd).eq(2); - expect(errorWarnings.errors[0].doenetMLrange.charEnd).eq(65); - }); - }); - - it("check bugfix for non-constant exclude and unique variants", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - - a -

Number to exclude: 2

-

- -

$n

- - `, - }, - "*", - ); - }); - - cy.get(cesc("#\\/_text1")).should("have.text", "a"); //wait for page to load - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - - let n = stateVariables["/n"].stateValues.value; - - cy.get(cesc("#\\/n")).should("have.text", String(n)); - - cy.get(cesc("#\\/na")).should("have.text", String(n)); - - expect(n === 1 || n === 3).eq(true); - }); - }); - - it("check bugfix for non-constant exclude and defaulting to unique variants", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a -

Number to exclude: 2

-

- -

$n

- - `, - }, - "*", - ); - }); - - cy.get(cesc("#\\/_text1")).should("have.text", "a"); //wait for page to load - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - - let n = stateVariables["/n"].stateValues.value; - - cy.get(cesc("#\\/n")).should("have.text", String(n)); - - cy.get(cesc("#\\/na")).should("have.text", String(n)); - - expect(n === 1 || n === 3).eq(true); - }); - }); - it("selectfromsequence depending on selectfromsequence handles reload", () => { cy.get("#testRunner_toggleControls").click(); cy.get("#testRunner_allowLocalState").click();