diff --git a/packages/doenetml-worker/src/test/tagSpecific/answer.test.ts b/packages/doenetml-worker/src/test/tagSpecific/answer.test.ts index 9f83627ea..e8f198841 100644 --- a/packages/doenetml-worker/src/test/tagSpecific/answer.test.ts +++ b/packages/doenetml-worker/src/test/tagSpecific/answer.test.ts @@ -1462,7 +1462,7 @@ describe("Answer tag tests", async () => { expect(errorWarnings.warnings.length).eq(1); expect(errorWarnings.warnings[0].message).contain( - "An award for this answer is based on the answer's own submitted response", + "An award for this answer is based on the answer tag's own submitted response", ); expect(errorWarnings.warnings[0].level).eq(1); expect(errorWarnings.warnings[0].doenetMLrange.lineBegin).eq(2); diff --git a/packages/doenetml-worker/src/test/tagSpecific/sequence.test.ts b/packages/doenetml-worker/src/test/tagSpecific/sequence.test.ts new file mode 100644 index 000000000..06ed1b6eb --- /dev/null +++ b/packages/doenetml-worker/src/test/tagSpecific/sequence.test.ts @@ -0,0 +1,1748 @@ +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("Sequence tag tests", async () => { + it("number sequence, no parameters", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(10); + for (let i = 0; i < 10; i++) { + expect(children[i].stateValues.value).eq(i + 1); + } + }); + + it("number sequence, just from", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(10); + for (let i = 0; i < 10; i++) { + expect(children[i].stateValues.value).eq(i - 4); + } + }); + + it("number sequence, just to", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(3); + for (let i = 0; i < 3; i++) { + expect(children[i].stateValues.value).eq(3 + i - 2); + } + }); + + it("number sequence, just step", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(10); + for (let i = 0; i < 10; i++) { + expect(children[i].stateValues.value).eq(1 + i * -2); + } + }); + + it("number sequence, just length", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(5); + for (let i = 0; i < 5; i++) { + expect(children[i].stateValues.value).eq(1 + i); + } + }); + + it("number sequence, from and to", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(8); + for (let i = 0; i < 8; i++) { + expect(children[i].stateValues.value).eq(-3 + i); + } + }); + + it("number sequence, from and to, not matching", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(8); + for (let i = 0; i < 8; i++) { + expect(children[i].stateValues.value).eq(-3 + i); + } + }); + + it("number sequence, from and to, adjust for round-off error", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(8); + for (let i = 0; i < 8; i++) { + expect(children[i].stateValues.value).eq(i + 1); + } + }); + + it("math sequence, from and to, adjust for round-off error", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(8); + for (let i = 0; i < 8; i++) { + expect(children[i].stateValues.value.tree).eq(i + 1); + } + }); + + it("number sequence, from and step", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(10); + for (let i = 0; i < 10; i++) { + expect(children[i].stateValues.value).eq(2 + i * -4); + } + }); + + it("number sequence, from and length", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(3); + for (let i = 0; i < 3; i++) { + expect(children[i].stateValues.value).eq(11 + i); + } + }); + + it("number sequence, to and step", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(7); + for (let i = 0; i < 7; i++) { + expect(children[i].stateValues.value).eq(21 + 3 * (i - 6)); + } + }); + + it("number sequence, to and step, adjust for round-off error", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(5); + for (let i = 0; i < 5; i++) { + expect( + Math.abs(children[i].stateValues.value - (1 + i * 0.1)), + ).lessThan(1e-14); + } + }); + + it("math sequence, to and step, adjust for round-off error", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(5); + for (let i = 0; i < 5; i++) { + expect( + Math.abs(children[i].stateValues.value - (1 + i * 0.1)), + ).lessThan(1e-14); + } + }); + + it("number sequence, to and length", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(4); + for (let i = 0; i < 4; i++) { + expect(children[i].stateValues.value).eq(-8 + (i - 3)); + } + }); + + it("number sequence, step and length", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(6); + for (let i = 0; i < 6; i++) { + expect(children[i].stateValues.value).eq(1 + 5 * i); + } + }); + + it("number sequence, from, to, and step", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(4); + for (let i = 0; i < 4; i++) { + expect(children[i].stateValues.value).eq(9 - 2 * i); + } + }); + + it("number sequence, from, to, and step, adjust for round-off errors", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let sequence = [0.2, 0.3, 0.4, 0.5]; + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(4); + for (let i = 0; i < 4; i++) { + expect( + Math.abs(children[i].stateValues.value - sequence[i]), + ).lessThan(1e-14); + } + }); + + it("math sequence, from, to, and step, adjust for round-off errors", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let sequence = [0.2, 0.3, 0.4, 0.5]; + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(4); + for (let i = 0; i < 4; i++) { + expect( + Math.abs(children[i].stateValues.value - sequence[i]), + ).lessThan(1e-14); + } + }); + + it("number sequence, from, to, and length", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(6); + for (let i = 0; i < 6; i++) { + expect(children[i].stateValues.value).eq(-5 + 2 * i); + } + }); + + it("number sequence, from, step, and length", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(5); + for (let i = 0; i < 5; i++) { + expect(children[i].stateValues.value).eq(8 - 2 * i); + } + }); + + it("number sequence, to, step, and length", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(5); + for (let i = 0; i < 5; i++) { + expect(children[i].stateValues.value).eq(8 - 2 * (i - 4)); + } + }); + + it("letters sequence, lowercase", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(5); + expect(children[0].stateValues.value).eq("c"); + expect(children[1].stateValues.value).eq("f"); + expect(children[2].stateValues.value).eq("i"); + expect(children[3].stateValues.value).eq("l"); + expect(children[4].stateValues.value).eq("o"); + }); + + it("letters sequence, uppercase", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(5); + expect(children[0].stateValues.value).eq("Y"); + expect(children[1].stateValues.value).eq("U"); + expect(children[2].stateValues.value).eq("Q"); + expect(children[3].stateValues.value).eq("M"); + expect(children[4].stateValues.value).eq("I"); + }); + + it("letters sequence, multicharacter", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(4); + expect(children[0].stateValues.value).eq("az"); + expect(children[1].stateValues.value).eq("bc"); + expect(children[2].stateValues.value).eq("bf"); + expect(children[3].stateValues.value).eq("bi"); + }); + + it("letters sequence, stays valid", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(6); + expect(children[0].stateValues.value).eq("b"); + expect(children[1].stateValues.value).eq("e"); + expect(children[2].stateValues.value).eq("h"); + expect(children[3].stateValues.value).eq("k"); + expect(children[4].stateValues.value).eq("n"); + expect(children[5].stateValues.value).eq("q"); + }); + + it("letters sequence, no parameters", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(10); + expect(children[0].stateValues.value).eq("a"); + expect(children[1].stateValues.value).eq("b"); + expect(children[2].stateValues.value).eq("c"); + expect(children[3].stateValues.value).eq("d"); + expect(children[4].stateValues.value).eq("e"); + expect(children[5].stateValues.value).eq("f"); + expect(children[6].stateValues.value).eq("g"); + expect(children[7].stateValues.value).eq("h"); + expect(children[8].stateValues.value).eq("i"); + expect(children[9].stateValues.value).eq("j"); + }); + + it("math sequence, calculate step", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(4); + expect(children[0].stateValues.value.tree).eqls(["*", 3, "x"]); + expect(children[1].stateValues.value.tree).eqls([ + "+", + ["*", 2, "x"], + "y", + ]); + expect(children[2].stateValues.value.tree).eqls([ + "+", + "x", + ["*", 2, "y"], + ]); + expect(children[3].stateValues.value.tree).eqls(["*", 3, "y"]); + }); + + it("number sequence, excludes", async () => { + let core = await createTestCore({ + doenetML: ` +

+

Also exclude:

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(8); + let ind = 0; + for (let i = 0; i < 10; i++) { + if (i == 1 || i == 7) { + continue; + } + expect(children[ind].stateValues.value).eq(i - 1); + ind++; + } + + // also exclude 7 + await updateMathInputValue({ + latex: "7", + componentName: "/exclude2", + core, + }); + + stateVariables = await returnAllStateVariables(core); + children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(7); + ind = 0; + for (let i = 0; i < 10; i++) { + if (i == 1 || i == 7 || i == 8) { + continue; + } + expect(children[ind].stateValues.value).eq(i - 1); + ind++; + } + + // also exclude 6 twice + await updateMathInputValue({ + latex: "6", + componentName: "/exclude2", + core, + }); + + stateVariables = await returnAllStateVariables(core); + children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(8); + ind = 0; + for (let i = 0; i < 10; i++) { + if (i == 1 || i == 7) { + continue; + } + expect(children[ind].stateValues.value).eq(i - 1); + ind++; + } + + // also exclude 12 + await updateMathInputValue({ + latex: "12", + componentName: "/exclude2", + core, + }); + + stateVariables = await returnAllStateVariables(core); + children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(8); + ind = 0; + for (let i = 0; i < 10; i++) { + if (i == 1 || i == 7) { + continue; + } + expect(children[ind].stateValues.value).eq(i - 1); + ind++; + } + + // also exclude 3 + await updateMathInputValue({ + latex: "3", + componentName: "/exclude2", + core, + }); + + stateVariables = await returnAllStateVariables(core); + children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(7); + ind = 0; + for (let i = 0; i < 10; i++) { + if (i == 1 || i == 7 || i == 4) { + continue; + } + expect(children[ind].stateValues.value).eq(i - 1); + ind++; + } + + // don't exclude anything else + await updateMathInputValue({ + latex: "", + componentName: "/exclude2", + core, + }); + + stateVariables = await returnAllStateVariables(core); + children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(8); + ind = 0; + for (let i = 0; i < 10; i++) { + if (i == 1 || i == 7) { + continue; + } + expect(children[ind].stateValues.value).eq(i - 1); + ind++; + } + }); + + it("number sequence, excludes, adjust for round-off errors", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let sequence = [0.1, 0.2, 0.4, 0.5, 0.8]; + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(5); + for (let i = 0; i < 5; i++) { + expect( + Math.abs(children[i].stateValues.value - sequence[i]), + ).lessThan(1e-14); + } + }); + + it("letters sequence, excludes", async () => { + let core = await createTestCore({ + doenetML: ` +

+

Also exclude:

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(8); + let ind = 0; + for (let i = 0; i < 10; i++) { + if (i == 1 || i == 5) { + continue; + } + expect(children[ind].stateValues.value).eq( + String.fromCharCode(97 + i), + ); + ind++; + } + + // also exclude i + await updateTextInputValue({ text: "i", componentName: "/e", core }); + stateVariables = await returnAllStateVariables(core); + children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(7); + ind = 0; + for (let i = 0; i < 10; i++) { + if (i == 1 || i == 5 || i == 8) { + continue; + } + expect(children[ind].stateValues.value).eq( + String.fromCharCode(97 + i), + ); + ind++; + } + + // also exclude f twice + await updateTextInputValue({ text: "f", componentName: "/e", core }); + + stateVariables = await returnAllStateVariables(core); + children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(8); + ind = 0; + for (let i = 0; i < 10; i++) { + if (i == 1 || i == 5) { + continue; + } + expect(children[ind].stateValues.value).eq( + String.fromCharCode(97 + i), + ); + ind++; + } + + // also exclude l + await updateTextInputValue({ text: "l", componentName: "/e", core }); + + stateVariables = await returnAllStateVariables(core); + children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(8); + ind = 0; + for (let i = 0; i < 10; i++) { + if (i == 1 || i == 5) { + continue; + } + expect(children[ind].stateValues.value).eq( + String.fromCharCode(97 + i), + ); + ind++; + } + + // also exclude C + await updateTextInputValue({ text: "C", componentName: "/e", core }); + + stateVariables = await returnAllStateVariables(core); + children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(7); + ind = 0; + for (let i = 0; i < 10; i++) { + if (i == 1 || i == 5 || i == 2) { + continue; + } + expect(children[ind].stateValues.value).eq( + String.fromCharCode(97 + i), + ); + ind++; + } + + // don't exclude anything else + await updateTextInputValue({ text: "", componentName: "/e", core }); + + stateVariables = await returnAllStateVariables(core); + children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(8); + ind = 0; + for (let i = 0; i < 10; i++) { + if (i == 1 || i == 5) { + continue; + } + expect(children[ind].stateValues.value).eq( + String.fromCharCode(97 + i), + ); + ind++; + } + }); + + it("math sequence, excludes", async () => { + let core = await createTestCore({ + doenetML: ` +

+

Also exclude:

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(8); + let ind = 0; + for (let i = 0; i < 10; i++) { + if (i == 1 || i == 5) { + continue; + } + expect( + me + .fromAst(children[ind].stateValues.value) + .equals(me.fromText((1 + i).toString() + "x")), + ).eq(true); + ind++; + } + + // also exclude 9x + await updateMathInputValue({ latex: "9x", componentName: "/e", core }); + + stateVariables = await returnAllStateVariables(core); + children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(7); + ind = 0; + for (let i = 0; i < 10; i++) { + if (i == 1 || i == 5 || i == 8) { + continue; + } + expect( + me + .fromAst(children[ind].stateValues.value) + .equals(me.fromText((1 + i).toString() + "x")), + ).eq(true); + ind++; + } + + // also exclude 6x twice + await updateMathInputValue({ latex: "6x", componentName: "/e", core }); + + stateVariables = await returnAllStateVariables(core); + children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(8); + ind = 0; + for (let i = 0; i < 10; i++) { + if (i == 1 || i == 5) { + continue; + } + expect( + me + .fromAst(children[ind].stateValues.value) + .equals(me.fromText((1 + i).toString() + "x")), + ).eq(true); + ind++; + } + + // also exclude 12x + await updateMathInputValue({ latex: "12x", componentName: "/e", core }); + + stateVariables = await returnAllStateVariables(core); + children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(8); + ind = 0; + for (let i = 0; i < 10; i++) { + if (i == 1 || i == 5) { + continue; + } + expect( + me + .fromAst(children[ind].stateValues.value) + .equals(me.fromText((1 + i).toString() + "x")), + ).eq(true); + ind++; + } + + // also exclude 3x + await updateMathInputValue({ latex: "3x", componentName: "/e", core }); + + stateVariables = await returnAllStateVariables(core); + children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(7); + ind = 0; + for (let i = 0; i < 10; i++) { + if (i == 1 || i == 5 || i == 2) { + continue; + } + expect( + me + .fromAst(children[ind].stateValues.value) + .equals(me.fromText((1 + i).toString() + "x")), + ).eq(true); + ind++; + } + + // don't exclude anything else + await updateMathInputValue({ latex: "", componentName: "/e", core }); + + stateVariables = await returnAllStateVariables(core); + children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(8); + ind = 0; + for (let i = 0; i < 10; i++) { + if (i == 1 || i == 5) { + continue; + } + expect( + me + .fromAst(children[ind].stateValues.value) + .equals(me.fromText((1 + i).toString() + "x")), + ).eq(true); + ind++; + } + }); + + it("math sequence, excludes, adjust for round-off errors", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let sequence = [0.1, 0.2, 0.4, 0.5, 0.8]; + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(5); + for (let i = 0; i < 5; i++) { + expect( + Math.abs(children[i].stateValues.value - sequence[i]), + ).lessThan(1e-14); + } + }); + + it("sequence of decimals rounds on display", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + // Round when displaying to show 10ths correctly + // But, don't round internally + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(11); + + for (let i = 0; i < 11; i++) { + // Note: i/10 is rounded to have one decimal + // but 0.1*i can have extra decimals due to round-off errors + expect(children[i].stateValues.valueForDisplay).eq(i / 10); + expect(children[i].stateValues.value).eq(0.1 * i); + } + }); + + it("sequence with number operators", async () => { + let core = await createTestCore({ + doenetML: ` + 5 + 10 +

+ + $n11 + + + $m+311 + + `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(9); + + for (let i = 0; i < 9; i++) { + expect(children[i].stateValues.valueForDisplay).eq(i + 5); + expect(children[i].stateValues.value).eq(i + 5); + } + }); + + it("initially invalid to", async () => { + let core = await createTestCore({ + doenetML: ` + +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/seq"].stateValues.validSequence).eq(false); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(0); + + await updateMathInputValue({ latex: "2", componentName: "/n", core }); + + stateVariables = await returnAllStateVariables(core); + children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(1); + expect(stateVariables[children[0].componentName].stateValues.value).eq( + 2, + ); + expect(stateVariables["/seq"].stateValues.validSequence).eq(true); + }); + + it("number sequence, excluding every 3 plus another", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/p"].stateValues.text).eq("1, 3, 4, 6, 7, 10"); + }); + + it("number sequence, excluding from different sources", async () => { + let core = await createTestCore({ + doenetML: ` + 4 62 87 +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/p"].stateValues.text).eq("1, 3, 5, 9, 10"); + }); + + it("sequences hide dynamically", async () => { + let core = await createTestCore({ + doenetML: ` + + + + + + +

Length of sequence 1:

+

Length of sequence 2:

+ +

sequence 1:

+

sequence 2:

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/s1"].stateValues.text).eq( + "sequence 1: 1, 2, 3, 4", + ); + expect(stateVariables["/s2"].stateValues.text).eq("sequence 2: "); + + await updateMathInputValue({ latex: "6", componentName: "/n1", core }); + await updateMathInputValue({ latex: "6", componentName: "/n2", core }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/s1"].stateValues.text).eq( + "sequence 1: 1, 2, 3, 4, 5, 6", + ); + expect(stateVariables["/s2"].stateValues.text).eq("sequence 2: "); + + await updateBooleanInputValue({ + boolean: true, + componentName: "/h1", + core, + }); + await updateBooleanInputValue({ + boolean: false, + componentName: "/h2", + core, + }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/s1"].stateValues.text).eq("sequence 1: "); + expect(stateVariables["/s2"].stateValues.text).eq( + "sequence 2: 1, 2, 3, 4, 5, 6", + ); + + await updateMathInputValue({ latex: "8", componentName: "/n1", core }); + await updateMathInputValue({ latex: "8", componentName: "/n2", core }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/s1"].stateValues.text).eq("sequence 1: "); + expect(stateVariables["/s2"].stateValues.text).eq( + "sequence 2: 1, 2, 3, 4, 5, 6, 7, 8", + ); + + await updateBooleanInputValue({ + boolean: false, + componentName: "/h1", + core, + }); + await updateBooleanInputValue({ + boolean: true, + componentName: "/h2", + core, + }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/s1"].stateValues.text).eq( + "sequence 1: 1, 2, 3, 4, 5, 6, 7, 8", + ); + expect(stateVariables["/s2"].stateValues.text).eq("sequence 2: "); + + await updateMathInputValue({ latex: "3", componentName: "/n1", core }); + await updateMathInputValue({ latex: "3", componentName: "/n2", core }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/s1"].stateValues.text).eq( + "sequence 1: 1, 2, 3", + ); + expect(stateVariables["/s2"].stateValues.text).eq("sequence 2: "); + + await updateBooleanInputValue({ + boolean: true, + componentName: "/h1", + core, + }); + await updateBooleanInputValue({ + boolean: false, + componentName: "/h2", + core, + }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/s1"].stateValues.text).eq("sequence 1: "); + expect(stateVariables["/s2"].stateValues.text).eq( + "sequence 2: 1, 2, 3", + ); + + await updateMathInputValue({ latex: "4", componentName: "/n1", core }); + await updateMathInputValue({ latex: "4", componentName: "/n2", core }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/s1"].stateValues.text).eq("sequence 1: "); + expect(stateVariables["/s2"].stateValues.text).eq( + "sequence 2: 1, 2, 3, 4", + ); + }); + + it("sequence fixed by default", async () => { + let core = await createTestCore({ + doenetML: ` +

From:

+

Step:

+ +

+ +

Change first:

+

Change second:

+ + `, + }); + + let stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("1, 3, 5, 7"); + + await updateMathInputValue({ latex: "21", componentName: "/a2", core }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("1, 3, 5, 7"); + + await updateMathInputValue({ latex: "2", componentName: "/b2", core }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("1, 3, 5, 7"); + + await updateMathInputValue({ + latex: "4", + componentName: "/from", + core, + }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("4, 6"); + + await updateMathInputValue({ latex: "8", componentName: "/a2", core }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("4, 6"); + + await updateMathInputValue({ latex: "2", componentName: "/b2", core }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("4, 6"); + + await updateMathInputValue({ + latex: "6", + componentName: "/step", + core, + }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("4"); + + await updateMathInputValue({ latex: "9", componentName: "/a2", core }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("4"); + + await updateMathInputValue({ latex: "41", componentName: "/b2", core }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("4"); + }); + + it("can override fixed property", async () => { + let core = await createTestCore({ + doenetML: ` +

From:

+

Step:

+

Fixed:

+ +

+ +

Change first:

+

Change second:

+ + `, + }); + + let stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("1, 3, 5, 7"); + + await updateMathInputValue({ latex: "21", componentName: "/a2", core }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("21, 3, 5, 7"); + + await updateMathInputValue({ latex: "0", componentName: "/b2", core }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("21, 0, 5, 7"); + + await updateMathInputValue({ + latex: "4", + componentName: "/from", + core, + }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("4, 6"); + + await updateMathInputValue({ latex: "8", componentName: "/a2", core }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("8, 6"); + + await updateMathInputValue({ latex: "2", componentName: "/b2", core }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("8, 2"); + + await updateMathInputValue({ + latex: "6", + componentName: "/step", + core, + }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("4"); + + await updateMathInputValue({ latex: "9", componentName: "/a2", core }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("9"); + + await updateMathInputValue({ latex: "41", componentName: "/b2", core }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("9"); + + await updateBooleanInputValue({ + boolean: true, + componentName: "/fx", + core, + }); + + await updateMathInputValue({ + latex: "1", + componentName: "/step", + core, + }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("4, 5, 6, 7"); + + await updateMathInputValue({ latex: "9", componentName: "/a2", core }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("4, 5, 6, 7"); + + await updateMathInputValue({ latex: "41", componentName: "/b2", core }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("4, 5, 6, 7"); + + await updateBooleanInputValue({ + boolean: false, + componentName: "/fx", + core, + }); + + await updateMathInputValue({ latex: "9", componentName: "/a2", core }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("9, 5, 6, 7"); + + await updateMathInputValue({ latex: "41", componentName: "/b2", core }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("9, 41, 6, 7"); + }); + + it('copies with link="false" are not fixed', async () => { + let core = await createTestCore({ + doenetML: ` +

From:

+

Step:

+ +

+ +

Change first:

+

Change second:

+ +

Copy of a2: $a2{name="a3"}

+

Copy of b2: $b2{name="b3"}

+ + `, + }); + + let stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("1, 3, 5, 7"); + expect(stateVariables["/a2"].stateValues.value.tree).eq(1); + expect(stateVariables["/b2"].stateValues.value.tree).eq(3); + expect(stateVariables["/a3"].stateValues.value.tree).eq(1); + expect(stateVariables["/b3"].stateValues.value.tree).eq(3); + + await updateMathInputValue({ latex: "21", componentName: "/a2", core }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("1, 3, 5, 7"); + expect(stateVariables["/a2"].stateValues.value.tree).eq(21); + expect(stateVariables["/b2"].stateValues.value.tree).eq(3); + expect(stateVariables["/a3"].stateValues.value.tree).eq(21); + expect(stateVariables["/b3"].stateValues.value.tree).eq(3); + + await updateMathInputValue({ latex: "0", componentName: "/b2", core }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("1, 3, 5, 7"); + expect(stateVariables["/a2"].stateValues.value.tree).eq(21); + expect(stateVariables["/b2"].stateValues.value.tree).eq(0); + expect(stateVariables["/a3"].stateValues.value.tree).eq(21); + expect(stateVariables["/b3"].stateValues.value.tree).eq(0); + + await updateMathInputValue({ + latex: "4", + componentName: "/from", + core, + }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("4, 6"); + expect(stateVariables["/a2"].stateValues.value.tree).eq(21); + expect(stateVariables["/b2"].stateValues.value.tree).eq(0); + expect(stateVariables["/a3"].stateValues.value.tree).eq(21); + expect(stateVariables["/b3"].stateValues.value.tree).eq(0); + + await updateMathInputValue({ latex: "8", componentName: "/a2", core }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("4, 6"); + expect(stateVariables["/a2"].stateValues.value.tree).eq(8); + expect(stateVariables["/b2"].stateValues.value.tree).eq(0); + expect(stateVariables["/a3"].stateValues.value.tree).eq(8); + expect(stateVariables["/b3"].stateValues.value.tree).eq(0); + + await updateMathInputValue({ + latex: "6", + componentName: "/step", + core, + }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("4"); + expect(stateVariables["/a2"].stateValues.value.tree).eq(8); + expect(stateVariables["/b2"].stateValues.value.tree).eq(0); + expect(stateVariables["/a3"].stateValues.value.tree).eq(8); + expect(stateVariables["/b3"].stateValues.value.tree).eq(0); + + await updateMathInputValue({ latex: "9", componentName: "/a2", core }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("4"); + expect(stateVariables["/a2"].stateValues.value.tree).eq(9); + expect(stateVariables["/b2"].stateValues.value.tree).eq(0); + expect(stateVariables["/a3"].stateValues.value.tree).eq(9); + expect(stateVariables["/b3"].stateValues.value.tree).eq(0); + + await updateMathInputValue({ latex: "2", componentName: "/b2", core }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("4"); + expect(stateVariables["/a2"].stateValues.value.tree).eq(9); + expect(stateVariables["/b2"].stateValues.value.tree).eq(2); + expect(stateVariables["/a3"].stateValues.value.tree).eq(9); + expect(stateVariables["/b3"].stateValues.value.tree).eq(2); + + await updateMathInputValue({ + latex: "8", + componentName: "/from", + core, + }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq(""); + expect(stateVariables["/a2"].stateValues.value.tree).eq(9); + expect(stateVariables["/b2"].stateValues.value.tree).eq(2); + expect(stateVariables["/a3"].stateValues.value.tree).eq(9); + expect(stateVariables["/b3"].stateValues.value.tree).eq(2); + + await updateMathInputValue({ latex: "3", componentName: "/a2", core }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq(""); + expect(stateVariables["/a2"].stateValues.value.tree).eq(3); + expect(stateVariables["/b2"].stateValues.value.tree).eq(2); + expect(stateVariables["/a3"].stateValues.value.tree).eq(3); + expect(stateVariables["/b3"].stateValues.value.tree).eq(2); + + await updateMathInputValue({ + latex: "3", + componentName: "/step", + core, + }); + await updateMathInputValue({ + latex: "0", + componentName: "/from", + core, + }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("0, 3, 6"); + expect(stateVariables["/a2"].stateValues.value.tree).eq(3); + expect(stateVariables["/b2"].stateValues.value.tree).eq(2); + expect(stateVariables["/a3"].stateValues.value.tree).eq(3); + expect(stateVariables["/b3"].stateValues.value.tree).eq(2); + + await updateMathInputValue({ latex: "8", componentName: "/a2", core }); + await updateMathInputValue({ latex: "7", componentName: "/b2", core }); + stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/theList"].stateValues.text).eq("0, 3, 6"); + expect(stateVariables["/a2"].stateValues.value.tree).eq(8); + expect(stateVariables["/b2"].stateValues.value.tree).eq(7); + expect(stateVariables["/a3"].stateValues.value.tree).eq(8); + expect(stateVariables["/b3"].stateValues.value.tree).eq(7); + }); + + it("number sequence, from and to using strings with operators", async () => { + let core = await createTestCore({ + doenetML: ` +

+ `, + }); + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(8); + for (let i = 0; i < 8; i++) { + expect(children[i].stateValues.value).eq(-3 + i); + } + }); + + it("number sequence, excludes with operators from macros", async () => { + let core = await createTestCore({ + doenetML: ` + 2 + 6 +

+ `, + }); + + let nums = [0, 1, 5, 6, 8]; + + let stateVariables = await returnAllStateVariables(core); + let children = stateVariables["/p"].activeChildren.map( + (x) => stateVariables[x.componentName], + ); + expect(children.length).eq(nums.length); + for (let [ind, child] of children.entries()) { + expect(child.stateValues.value).eq(nums[ind]); + } + }); + + it("warnings", async () => { + let core = await createTestCore({ + doenetML: ` + + + + + + + + + + + + `, + }); + + let errorWarnings = core.errorWarnings; + + expect(errorWarnings.errors.length).eq(0); + expect(errorWarnings.warnings.length).eq(9); + + expect(errorWarnings.warnings[0].message).contain( + `Invalid length of sequence. Must be a non-negative integer`, + ); + expect(errorWarnings.warnings[0].level).eq(1); + expect(errorWarnings.warnings[0].doenetMLrange.lineBegin).eq(2); + expect(errorWarnings.warnings[0].doenetMLrange.charBegin).eq(5); + expect(errorWarnings.warnings[0].doenetMLrange.lineEnd).eq(2); + expect(errorWarnings.warnings[0].doenetMLrange.charEnd).eq(27); + + expect(errorWarnings.warnings[1].message).contain( + `Invalid step of sequence. Must be a number for sequence of type number`, + ); + expect(errorWarnings.warnings[1].level).eq(1); + expect(errorWarnings.warnings[1].doenetMLrange.lineBegin).eq(3); + expect(errorWarnings.warnings[1].doenetMLrange.charBegin).eq(5); + expect(errorWarnings.warnings[1].doenetMLrange.lineEnd).eq(3); + expect(errorWarnings.warnings[1].doenetMLrange.charEnd).eq(24); + + expect(errorWarnings.warnings[2].message).contain( + `Invalid step of sequence. Must be a number for sequence of type letters`, + ); + expect(errorWarnings.warnings[2].level).eq(1); + expect(errorWarnings.warnings[2].doenetMLrange.lineBegin).eq(4); + expect(errorWarnings.warnings[2].doenetMLrange.charBegin).eq(5); + expect(errorWarnings.warnings[2].doenetMLrange.lineEnd).eq(4); + expect(errorWarnings.warnings[2].doenetMLrange.charEnd).eq(40); + + expect(errorWarnings.warnings[3].message).contain( + `Invalid "from" of number sequence. Must be a number`, + ); + expect(errorWarnings.warnings[3].level).eq(1); + expect(errorWarnings.warnings[3].doenetMLrange.lineBegin).eq(5); + expect(errorWarnings.warnings[3].doenetMLrange.charBegin).eq(5); + expect(errorWarnings.warnings[3].doenetMLrange.lineEnd).eq(5); + expect(errorWarnings.warnings[3].doenetMLrange.charEnd).eq(25); + + expect(errorWarnings.warnings[4].message).contain( + `Invalid "from" of letters sequence. Must be a letter combination`, + ); + expect(errorWarnings.warnings[4].level).eq(1); + expect(errorWarnings.warnings[4].doenetMLrange.lineBegin).eq(6); + expect(errorWarnings.warnings[4].doenetMLrange.charBegin).eq(5); + expect(errorWarnings.warnings[4].doenetMLrange.lineEnd).eq(6); + expect(errorWarnings.warnings[4].doenetMLrange.charEnd).eq(40); + + expect(errorWarnings.warnings[5].message).contain( + `Invalid "from" of sequence`, + ); + expect(errorWarnings.warnings[5].level).eq(1); + expect(errorWarnings.warnings[5].doenetMLrange.lineBegin).eq(7); + expect(errorWarnings.warnings[5].doenetMLrange.charBegin).eq(5); + expect(errorWarnings.warnings[5].doenetMLrange.lineEnd).eq(7); + expect(errorWarnings.warnings[5].doenetMLrange.charEnd).eq(40); + + expect(errorWarnings.warnings[6].message).contain( + `Invalid "to" of number sequence. Must be a number.`, + ); + expect(errorWarnings.warnings[6].level).eq(1); + expect(errorWarnings.warnings[6].doenetMLrange.lineBegin).eq(8); + expect(errorWarnings.warnings[6].doenetMLrange.charBegin).eq(5); + expect(errorWarnings.warnings[6].doenetMLrange.lineEnd).eq(8); + expect(errorWarnings.warnings[6].doenetMLrange.charEnd).eq(23); + + expect(errorWarnings.warnings[7].message).contain( + `Invalid "to" of letters sequence. Must be a letter combination`, + ); + expect(errorWarnings.warnings[7].level).eq(1); + expect(errorWarnings.warnings[7].doenetMLrange.lineBegin).eq(9); + expect(errorWarnings.warnings[7].doenetMLrange.charBegin).eq(5); + expect(errorWarnings.warnings[7].doenetMLrange.lineEnd).eq(9); + expect(errorWarnings.warnings[7].doenetMLrange.charEnd).eq(38); + + expect(errorWarnings.warnings[8].message).contain( + `Invalid "to" of sequence`, + ); + expect(errorWarnings.warnings[8].level).eq(1); + expect(errorWarnings.warnings[8].doenetMLrange.lineBegin).eq(10); + expect(errorWarnings.warnings[8].doenetMLrange.charBegin).eq(5); + expect(errorWarnings.warnings[8].doenetMLrange.lineEnd).eq(10); + expect(errorWarnings.warnings[8].doenetMLrange.charEnd).eq(38); + }); + + it("sequence displays as list by default", async () => { + let core = await createTestCore({ + doenetML: ` +

+

+

+

$default

+

$nocommas

+

$withcommas

+

$default{asList="false"}

+

$withcommas{asList="false"}

+

$nocommas{asList="true"}

+

+

+

+

+

+

+

+

+

+ + `, + }); + + let stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/pdefault"].stateValues.text).eq( + "1, 2, 3, 4, 5, 6, 7, 8, 9, 10", + ); + expect(stateVariables["/pdefault2"].stateValues.text).eq( + "1, 2, 3, 4, 5, 6, 7, 8, 9, 10", + ); + expect(stateVariables["/pdefault4"].stateValues.text).eq( + "1, 2, 3, 4, 5, 6, 7, 8, 9, 10", + ); + expect(stateVariables["/pdefault5"].stateValues.text).eq( + "1, 2, 3, 4, 5, 6, 7, 8, 9, 10", + ); + expect(stateVariables["/pnocommas"].stateValues.text).eq("12345678910"); + expect(stateVariables["/pnocommas2"].stateValues.text).eq( + "12345678910", + ); + expect(stateVariables["/pnocommas3"].stateValues.text).eq( + "12345678910", + ); + expect(stateVariables["/pnocommas3a"].stateValues.text).eq( + "12345678910", + ); + expect(stateVariables["/pnocommas4"].stateValues.text).eq( + "12345678910", + ); + expect(stateVariables["/pnocommas5"].stateValues.text).eq( + "12345678910", + ); + expect(stateVariables["/pnocommas6"].stateValues.text).eq( + "12345678910", + ); + expect(stateVariables["/pnocommas6a"].stateValues.text).eq( + "12345678910", + ); + expect(stateVariables["/pwithcommas"].stateValues.text).eq( + "1, 2, 3, 4, 5, 6, 7, 8, 9, 10", + ); + expect(stateVariables["/pwithcommas2"].stateValues.text).eq( + "1, 2, 3, 4, 5, 6, 7, 8, 9, 10", + ); + expect(stateVariables["/pwithcommas3"].stateValues.text).eq( + "1, 2, 3, 4, 5, 6, 7, 8, 9, 10", + ); + expect(stateVariables["/pwithcommas4"].stateValues.text).eq( + "1, 2, 3, 4, 5, 6, 7, 8, 9, 10", + ); + expect(stateVariables["/pwithcommas5"].stateValues.text).eq( + "1, 2, 3, 4, 5, 6, 7, 8, 9, 10", + ); + expect(stateVariables["/pwithcommas6"].stateValues.text).eq( + "1, 2, 3, 4, 5, 6, 7, 8, 9, 10", + ); + }); + + it("rounding", async () => { + let core = await createTestCore({ + doenetML: ` + a +

+

+

+

+ +

$n1a $n1b $n1c

+

$n2a $n2b $n2c

+

$n3a $n3b $n3c

+

$n4a $n4b $n4c

+ + `, + }); + + let na = 10.12345; + let nb = na + 0.03257; + let nc = nb + 0.03257; + + let stateVariables = await returnAllStateVariables(core); + expect(stateVariables["/n1a"].stateValues.text).eq( + String(Math.round(na * 10 ** 8) / 10 ** 8), + ); + expect(stateVariables["/n1b"].stateValues.text).eq( + String(Math.round(nb * 10 ** 8) / 10 ** 8), + ); + expect(stateVariables["/n1c"].stateValues.text).eq( + String(Math.round(nc * 10 ** 8) / 10 ** 8), + ); + expect(stateVariables["/n2a"].stateValues.text).eq( + String(Math.round(na * 10 ** 1) / 10 ** 1), + ); + expect(stateVariables["/n2b"].stateValues.text).eq( + String(Math.round(nb * 10 ** 1) / 10 ** 1), + ); + expect(stateVariables["/n2c"].stateValues.text).eq( + String(Math.round(nc * 10 ** 1) / 10 ** 1), + ); + expect(stateVariables["/n3a"].stateValues.text).eq( + String(Math.round(na * 10 ** 3) / 10 ** 3), + ); + expect(stateVariables["/n3b"].stateValues.text).eq( + String(Math.round(nb * 10 ** 3) / 10 ** 3), + ); + expect(stateVariables["/n3c"].stateValues.text).eq( + String(Math.round(nc * 10 ** 3) / 10 ** 3), + ); + expect(stateVariables["/n4a"].stateValues.text).eq("10.0"); + expect(stateVariables["/n4b"].stateValues.text).eq("11.0"); + expect(stateVariables["/n4c"].stateValues.text).eq("12.0"); + + expect(stateVariables["/n1a1"].stateValues.text).eq( + String(Math.round(na * 10 ** 8) / 10 ** 8), + ); + expect(stateVariables["/n1b1"].stateValues.text).eq( + String(Math.round(nb * 10 ** 8) / 10 ** 8), + ); + expect(stateVariables["/n1c1"].stateValues.text).eq( + String(Math.round(nc * 10 ** 8) / 10 ** 8), + ); + expect(stateVariables["/n2a1"].stateValues.text).eq( + String(Math.round(na * 10 ** 1) / 10 ** 1), + ); + expect(stateVariables["/n2b1"].stateValues.text).eq( + String(Math.round(nb * 10 ** 1) / 10 ** 1), + ); + expect(stateVariables["/n2c1"].stateValues.text).eq( + String(Math.round(nc * 10 ** 1) / 10 ** 1), + ); + expect(stateVariables["/n3a1"].stateValues.text).eq( + String(Math.round(na * 10 ** 3) / 10 ** 3), + ); + expect(stateVariables["/n3b1"].stateValues.text).eq( + String(Math.round(nb * 10 ** 3) / 10 ** 3), + ); + expect(stateVariables["/n3c1"].stateValues.text).eq( + String(Math.round(nc * 10 ** 3) / 10 ** 3), + ); + expect(stateVariables["/n4a1"].stateValues.text).eq("10.0"); + expect(stateVariables["/n4b1"].stateValues.text).eq("11.0"); + expect(stateVariables["/n4c1"].stateValues.text).eq("12.0"); + }); +}); diff --git a/packages/doenetml-worker/src/test/tagSpecific/triggerset.test.ts b/packages/doenetml-worker/src/test/tagSpecific/triggerset.test.ts index ada369f93..e43851bc6 100644 --- a/packages/doenetml-worker/src/test/tagSpecific/triggerset.test.ts +++ b/packages/doenetml-worker/src/test/tagSpecific/triggerset.test.ts @@ -1091,7 +1091,7 @@ describe("TriggerSet tag tests", async () => { ); }); - it.only("triggerSet in graph", async () => { + it("triggerSet in graph", async () => { let core = await createTestCore({ doenetML: `

n: 1

diff --git a/packages/test-cypress/cypress/e2e/tagSpecific/sequence.cy.js b/packages/test-cypress/cypress/e2e/tagSpecific/sequence.cy.js deleted file mode 100644 index 05106af38..000000000 --- a/packages/test-cypress/cypress/e2e/tagSpecific/sequence.cy.js +++ /dev/null @@ -1,2406 +0,0 @@ -import me from "math-expressions"; -import { cesc, cesc2 } from "@doenet/utils"; - -describe("Sequence Tag Tests", function () { - beforeEach(() => { - cy.clearIndexedDB(); - cy.visit("/"); - }); - - it("number sequence, no parameters", () => { - 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(); - let children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(10); - for (let i = 0; i < 10; i++) { - expect(children[i].stateValues.value).eq(i + 1); - } - }); - }); - - it("number sequence, just from", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - `, - }, - "*", - ); - }); - - 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 children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(10); - for (let i = 0; i < 10; i++) { - expect(children[i].stateValues.value).eq(i - 4); - } - }); - }); - - it("number sequence, just to", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - `, - }, - "*", - ); - }); - - 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 children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(3); - for (let i = 0; i < 3; i++) { - expect(children[i].stateValues.value).eq(3 + i - 2); - } - }); - }); - - it("number sequence, just step", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - `, - }, - "*", - ); - }); - - 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 children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(10); - for (let i = 0; i < 10; i++) { - expect(children[i].stateValues.value).eq(1 + i * -2); - } - }); - }); - - it("number sequence, just length", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - `, - }, - "*", - ); - }); - - 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 children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(5); - for (let i = 0; i < 5; i++) { - expect(children[i].stateValues.value).eq(1 + i); - } - }); - }); - - it("number sequence, from and to", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - `, - }, - "*", - ); - }); - - 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 children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(8); - for (let i = 0; i < 8; i++) { - expect(children[i].stateValues.value).eq(-3 + i); - } - }); - }); - - it("number sequence, from and to, not matching", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - `, - }, - "*", - ); - }); - - 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 children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(8); - for (let i = 0; i < 8; i++) { - expect(children[i].stateValues.value).eq(-3 + i); - } - }); - }); - - it("number sequence, from and to, adjust for round-off error", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - `, - }, - "*", - ); - }); - - 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 children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(8); - for (let i = 0; i < 8; i++) { - expect(children[i].stateValues.value).eq(i + 1); - } - }); - }); - - it("math sequence, from and to, adjust for round-off error", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - `, - }, - "*", - ); - }); - - 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 children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(8); - for (let i = 0; i < 8; i++) { - expect(children[i].stateValues.value).eq(i + 1); - } - }); - }); - - it("number sequence, from and step", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - `, - }, - "*", - ); - }); - - 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 children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(10); - for (let i = 0; i < 10; i++) { - expect(children[i].stateValues.value).eq(2 + i * -4); - } - }); - }); - - it("number sequence, from and length", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - `, - }, - "*", - ); - }); - - 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 children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(3); - for (let i = 0; i < 3; i++) { - expect(children[i].stateValues.value).eq(11 + i); - } - }); - }); - - it("number sequence, to and step", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - `, - }, - "*", - ); - }); - - 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 children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(7); - for (let i = 0; i < 7; i++) { - expect(children[i].stateValues.value).eq(21 + 3 * (i - 6)); - } - }); - }); - - it("number sequence, to and step, adjust for round-off error", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - `, - }, - "*", - ); - }); - - 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 children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(5); - for (let i = 0; i < 5; i++) { - expect( - Math.abs(children[i].stateValues.value - (1 + i * 0.1)), - ).lessThan(1e-14); - } - }); - }); - - it("math sequence, to and step, adjust for round-off error", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - `, - }, - "*", - ); - }); - - 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 children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(5); - for (let i = 0; i < 5; i++) { - expect( - Math.abs(children[i].stateValues.value - (1 + i * 0.1)), - ).lessThan(1e-14); - } - }); - }); - - it("number sequence, to and length", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - `, - }, - "*", - ); - }); - - 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 children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(4); - for (let i = 0; i < 4; i++) { - expect(children[i].stateValues.value).eq(-8 + (i - 3)); - } - }); - }); - - it("number sequence, step and length", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - `, - }, - "*", - ); - }); - - 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 children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(6); - for (let i = 0; i < 6; i++) { - expect(children[i].stateValues.value).eq(1 + 5 * i); - } - }); - }); - - it("number sequence, from, to, and step", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - `, - }, - "*", - ); - }); - - 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 children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(4); - for (let i = 0; i < 4; i++) { - expect(children[i].stateValues.value).eq(9 - 2 * i); - } - }); - }); - - it("number sequence, from, to, and step, adjust for round-off errors", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - `, - }, - "*", - ); - }); - - cy.get(cesc("#\\/_text1")).should("have.text", "a"); // to wait for page to load - - let sequence = [0.2, 0.3, 0.4, 0.5]; - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(4); - for (let i = 0; i < 4; i++) { - expect( - Math.abs(children[i].stateValues.value - sequence[i]), - ).lessThan(1e-14); - } - }); - }); - - it("math sequence, from, to, and step, adjust for round-off errors", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - `, - }, - "*", - ); - }); - - cy.get(cesc("#\\/_text1")).should("have.text", "a"); // to wait for page to load - - let sequence = [0.2, 0.3, 0.4, 0.5]; - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(4); - for (let i = 0; i < 4; i++) { - expect( - Math.abs(children[i].stateValues.value - sequence[i]), - ).lessThan(1e-14); - } - }); - }); - - it("number sequence, from, to, and length", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - `, - }, - "*", - ); - }); - - 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 children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(6); - for (let i = 0; i < 6; i++) { - expect(children[i].stateValues.value).eq(-5 + 2 * i); - } - }); - }); - - it("number sequence, from, step, and length", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - `, - }, - "*", - ); - }); - - 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 children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(5); - for (let i = 0; i < 5; i++) { - expect(children[i].stateValues.value).eq(8 - 2 * i); - } - }); - }); - - it("number sequence, to, step, and length", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - `, - }, - "*", - ); - }); - - 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 children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(5); - for (let i = 0; i < 5; i++) { - expect(children[i].stateValues.value).eq(8 - 2 * (i - 4)); - } - }); - }); - - it("letters sequence, lowercase", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - `, - }, - "*", - ); - }); - - 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 children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(5); - expect(children[0].stateValues.value).eq("c"); - expect(children[1].stateValues.value).eq("f"); - expect(children[2].stateValues.value).eq("i"); - expect(children[3].stateValues.value).eq("l"); - expect(children[4].stateValues.value).eq("o"); - }); - }); - - it("letters sequence, uppercase", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - `, - }, - "*", - ); - }); - - 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 children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(5); - expect(children[0].stateValues.value).eq("Y"); - expect(children[1].stateValues.value).eq("U"); - expect(children[2].stateValues.value).eq("Q"); - expect(children[3].stateValues.value).eq("M"); - expect(children[4].stateValues.value).eq("I"); - }); - }); - - it("letters sequence, multicharacter", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - `, - }, - "*", - ); - }); - - 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 children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(4); - expect(children[0].stateValues.value).eq("az"); - expect(children[1].stateValues.value).eq("bc"); - expect(children[2].stateValues.value).eq("bf"); - expect(children[3].stateValues.value).eq("bi"); - }); - }); - - it("letters sequence, stays valid", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - `, - }, - "*", - ); - }); - - 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 children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(6); - expect(children[0].stateValues.value).eq("b"); - expect(children[1].stateValues.value).eq("e"); - expect(children[2].stateValues.value).eq("h"); - expect(children[3].stateValues.value).eq("k"); - expect(children[4].stateValues.value).eq("n"); - expect(children[5].stateValues.value).eq("q"); - }); - }); - - it("letters sequence, no parameters", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - `, - }, - "*", - ); - }); - - 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 children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(10); - expect(children[0].stateValues.value).eq("a"); - expect(children[1].stateValues.value).eq("b"); - expect(children[2].stateValues.value).eq("c"); - expect(children[3].stateValues.value).eq("d"); - expect(children[4].stateValues.value).eq("e"); - expect(children[5].stateValues.value).eq("f"); - expect(children[6].stateValues.value).eq("g"); - expect(children[7].stateValues.value).eq("h"); - expect(children[8].stateValues.value).eq("i"); - expect(children[9].stateValues.value).eq("j"); - }); - }); - - it("math sequence, calculate step", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - `, - }, - "*", - ); - }); - - 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 children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(4); - expect(children[0].stateValues.value).eqls(["*", 3, "x"]); - expect(children[1].stateValues.value).eqls([ - "+", - ["*", 2, "x"], - "y", - ]); - expect(children[2].stateValues.value).eqls([ - "+", - "x", - ["*", 2, "y"], - ]); - expect(children[3].stateValues.value).eqls(["*", 3, "y"]); - }); - }); - - it("number sequence, excludes", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - -

Also exclude:

-

$exclude2.value{assignNames="exclude2a"}

- `, - }, - "*", - ); - }); - - 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 children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(8); - let ind = 0; - for (let i = 0; i < 10; i++) { - if (i == 1 || i == 7) { - continue; - } - expect(children[ind].stateValues.value).eq(i - 1); - ind++; - } - }); - - cy.log("also exclude 7"); - cy.get(cesc("#\\/exclude2") + " textarea").type( - `{end}{backspace}7{enter}`, - { force: true }, - ); - cy.get(cesc("#\\/exclude2a")).should("contain.text", "7"); - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(7); - let ind = 0; - for (let i = 0; i < 10; i++) { - if (i == 1 || i == 7 || i == 8) { - continue; - } - expect(children[ind].stateValues.value).eq(i - 1); - ind++; - } - }); - - cy.log("also exclude 6 twice"); - cy.get(cesc("#\\/exclude2") + " textarea").type( - `{end}{backspace}6{enter}`, - { force: true }, - ); - cy.get(cesc("#\\/exclude2a")).should("contain.text", "6"); - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(8); - let ind = 0; - for (let i = 0; i < 10; i++) { - if (i == 1 || i == 7) { - continue; - } - expect(children[ind].stateValues.value).eq(i - 1); - ind++; - } - }); - - cy.log("also exclude 12"); - cy.get(cesc("#\\/exclude2") + " textarea").type( - `{end}{backspace}12{enter}`, - { force: true }, - ); - cy.get(cesc("#\\/exclude2a")).should("contain.text", "12"); - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(8); - let ind = 0; - for (let i = 0; i < 10; i++) { - if (i == 1 || i == 7) { - continue; - } - expect(children[ind].stateValues.value).eq(i - 1); - ind++; - } - }); - - cy.log("also exclude 3"); - cy.get(cesc("#\\/exclude2") + " textarea").type( - `{end}{backspace}{backspace}3{enter}`, - { force: true }, - ); - cy.get(cesc("#\\/exclude2a")).should("contain.text", "3"); - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(7); - let ind = 0; - for (let i = 0; i < 10; i++) { - if (i == 1 || i == 7 || i == 4) { - continue; - } - expect(children[ind].stateValues.value).eq(i - 1); - ind++; - } - }); - - cy.log("don't exclude anything else"); - cy.get(cesc("#\\/exclude2") + " textarea").type( - `{end}{backspace}{enter}`, - { - force: true, - }, - ); - cy.get(cesc("#\\/exclude2a")).should("not.contain.text", "3"); - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(8); - let ind = 0; - for (let i = 0; i < 10; i++) { - if (i == 1 || i == 7) { - continue; - } - expect(children[ind].stateValues.value).eq(i - 1); - ind++; - } - }); - }); - - it("number sequence, excludes, adjust for round-off errors", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - - `, - }, - "*", - ); - }); - - cy.get(cesc("#\\/_text1")).should("have.text", "a"); // to wait for page to load - - let sequence = [0.1, 0.2, 0.4, 0.5, 0.8]; - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(5); - for (let i = 0; i < 5; i++) { - expect( - Math.abs(children[i].stateValues.value - sequence[i]), - ).lessThan(1e-14); - } - }); - }); - - it("letters sequence, excludes", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - -

Also exclude:

-

$e.value{assignNames="ea"}

- `, - }, - "*", - ); - }); - - 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 children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(8); - let ind = 0; - for (let i = 0; i < 10; i++) { - if (i == 1 || i == 5) { - continue; - } - expect(children[ind].stateValues.value).eq( - String.fromCharCode(97 + i), - ); - ind++; - } - }); - - cy.log("also exclude i"); - cy.get(cesc("#\\/e_input")).clear().type(`i{enter}`); - cy.get(cesc("#\\/ea")).should("contain.text", "i"); - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(7); - let ind = 0; - for (let i = 0; i < 10; i++) { - if (i == 1 || i == 5 || i == 8) { - continue; - } - expect(children[ind].stateValues.value).eq( - String.fromCharCode(97 + i), - ); - ind++; - } - }); - - cy.log("also exclude f twice"); - cy.get(cesc("#\\/e_input")).clear().type(`f{enter}`); - cy.get(cesc("#\\/ea")).should("contain.text", "f"); - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(8); - let ind = 0; - for (let i = 0; i < 10; i++) { - if (i == 1 || i == 5) { - continue; - } - expect(children[ind].stateValues.value).eq( - String.fromCharCode(97 + i), - ); - ind++; - } - }); - - cy.log("also exclude l"); - cy.get(cesc("#\\/e_input")).clear().type(`l{enter}`); - cy.get(cesc("#\\/ea")).should("contain.text", "l"); - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(8); - let ind = 0; - for (let i = 0; i < 10; i++) { - if (i == 1 || i == 5) { - continue; - } - expect(children[ind].stateValues.value).eq( - String.fromCharCode(97 + i), - ); - ind++; - } - }); - - cy.log("also exclude C"); - cy.get(cesc("#\\/e_input")).clear().type(`C{enter}`); - cy.get(cesc("#\\/ea")).should("contain.text", "C"); - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(7); - let ind = 0; - for (let i = 0; i < 10; i++) { - if (i == 1 || i == 5 || i == 2) { - continue; - } - expect(children[ind].stateValues.value).eq( - String.fromCharCode(97 + i), - ); - ind++; - } - }); - - cy.log("don't exclude anything else"); - cy.get(cesc("#\\/e_input")).clear().type(`{enter}`); - cy.get(cesc("#\\/ea")).should("have.text", ""); - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(8); - let ind = 0; - for (let i = 0; i < 10; i++) { - if (i == 1 || i == 5) { - continue; - } - expect(children[ind].stateValues.value).eq( - String.fromCharCode(97 + i), - ); - ind++; - } - }); - }); - - it("math sequence, excludes", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - - -

Also exclude:

-

$e.value{assignNames="ea"}

- `, - }, - "*", - ); - }); - - 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 children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(8); - let ind = 0; - for (let i = 0; i < 10; i++) { - if (i == 1 || i == 5) { - continue; - } - expect( - me - .fromAst(children[ind].stateValues.value) - .equals(me.fromText((1 + i).toString() + "x")), - ).eq(true); - ind++; - } - }); - - cy.log("also exclude 9x"); - cy.get(cesc("#\\/e") + " textarea").type(`{end}{backspace}9x{enter}`, { - force: true, - }); - cy.get(cesc("#\\/ea")).should("contain.text", "9x"); - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(7); - let ind = 0; - for (let i = 0; i < 10; i++) { - if (i == 1 || i == 5 || i == 8) { - continue; - } - expect( - me - .fromAst(children[ind].stateValues.value) - .equals(me.fromText((1 + i).toString() + "x")), - ).eq(true); - ind++; - } - }); - - cy.log("also exclude 6x twice"); - cy.get(cesc("#\\/e") + " textarea").type( - `{end}{backspace}{backspace}6x{enter}`, - { force: true }, - ); - cy.get(cesc("#\\/ea")).should("contain.text", "6x"); - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(8); - let ind = 0; - for (let i = 0; i < 10; i++) { - if (i == 1 || i == 5) { - continue; - } - expect( - me - .fromAst(children[ind].stateValues.value) - .equals(me.fromText((1 + i).toString() + "x")), - ).eq(true); - ind++; - } - }); - - cy.log("also exclude 12x"); - cy.get(cesc("#\\/e") + " textarea").type( - `{end}{backspace}{backspace}12x{enter}`, - { force: true }, - ); - cy.get(cesc("#\\/ea")).should("contain.text", "12x"); - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(8); - let ind = 0; - for (let i = 0; i < 10; i++) { - if (i == 1 || i == 5) { - continue; - } - expect( - me - .fromAst(children[ind].stateValues.value) - .equals(me.fromText((1 + i).toString() + "x")), - ).eq(true); - ind++; - } - }); - - cy.log("also exclude 3x"); - cy.get(cesc("#\\/e") + " textarea").type( - `{ctrl+home}{shift+end}{backspace}3x{enter}`, - { force: true }, - ); - cy.get(cesc("#\\/ea")).should("contain.text", "3x"); - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(7); - let ind = 0; - for (let i = 0; i < 10; i++) { - if (i == 1 || i == 5 || i == 2) { - continue; - } - expect( - me - .fromAst(children[ind].stateValues.value) - .equals(me.fromText((1 + i).toString() + "x")), - ).eq(true); - ind++; - } - }); - - cy.log("don't exclude anything else"); - cy.get(cesc("#\\/e") + " textarea").type( - `{end}{backspace}{backspace}{enter}`, - { force: true }, - ); - cy.get(cesc("#\\/ea")).should("not.contain.text", "3x"); - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(8); - let ind = 0; - for (let i = 0; i < 10; i++) { - if (i == 1 || i == 5) { - continue; - } - expect( - me - .fromAst(children[ind].stateValues.value) - .equals(me.fromText((1 + i).toString() + "x")), - ).eq(true); - ind++; - } - }); - }); - - it("math sequence, excludes, adjust for round-off errors", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - - `, - }, - "*", - ); - }); - - cy.get(cesc("#\\/_text1")).should("have.text", "a"); // to wait for page to load - - let sequence = [0.1, 0.2, 0.4, 0.5, 0.8]; - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(5); - for (let i = 0; i < 5; i++) { - expect( - Math.abs(children[i].stateValues.value - sequence[i]), - ).lessThan(1e-14); - } - }); - }); - - it("sequence of decimals rounds on display", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - `, - }, - "*", - ); - }); - - cy.get(cesc("#\\/_text1")).should("have.text", "a"); // to wait for page to load - - cy.log("Round when displaying to show 10ths correctly"); - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let replacements = stateVariables["/_sequence1"].replacements; - - for (let i = 0; i < 11; i++) { - cy.get(cesc2("#" + replacements[i].componentName)) - .invoke("text") - .then((text) => { - expect(text.trim()).equal((i / 10).toString()); - }); - } - }); - - cy.log("Don't round internaly"); - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let replacements = stateVariables["/_sequence1"].replacements.map( - (x) => stateVariables[x.componentName], - ); - - for (let i = 0; i < 11; i++) { - expect(replacements[i].stateValues.value).eq(0.1 * i); - } - }); - }); - - it("sequence with number operators ", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - 5 - 10 - - - - - $n11 - - - $m+311 - - `, - }, - "*", - ); - }); - - 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 replacements = stateVariables["/_sequence1"].replacements; - for (let i = 0; i < 9; i++) { - cy.get(cesc2("#" + replacements[i].componentName)) - .invoke("text") - .then((text) => { - expect(text.trim()).equal((i + 5).toString()); - }); - } - }); - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let replacements = stateVariables["/_sequence1"].replacements.map( - (x) => stateVariables[x.componentName], - ); - for (let i = 0; i < 9; i++) { - expect(replacements[i].stateValues.value).eq(i + 5); - } - }); - }); - - it("initially invalid to", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - -

$n.value{assignNames="n2"}

- `, - }, - "*", - ); - }); - - cy.get(cesc("#\\/_text1")).should("have.text", "a"); // to wait for page to load - - cy.log("sequence starts off invalid"); - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/_sequence1"].stateValues.validSequence).eq( - false, - ); - expect(stateVariables["/_sequence1"].replacements.length).eq(0); - }); - - cy.get(cesc("#\\/n") + " textarea").type("2{enter}", { force: true }); - cy.get(cesc("#\\/n2")).should("contain.text", "2"); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let number1 = stateVariables["/_sequence1"].replacements[0]; - let number1Name = number1.componentName; - let number1Anchor = cesc2("#" + number1Name); - - cy.get(number1Anchor).should("have.text", "2"); - - cy.window().then(async (win) => { - expect( - stateVariables["/_sequence1"].stateValues.validSequence, - ).eq(true); - expect(stateVariables["/_sequence1"].replacements.length).eq(1); - }); - }); - }); - - it("number sequence, excluding every 3 plus another", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a -

- `, - }, - "*", - ); - }); - - cy.get(cesc("#\\/_text1")).should("have.text", "a"); // to wait for page to load - - cy.get(cesc("#\\/_p1")).should("have.text", "1, 3, 4, 6, 7, 10"); - }); - - it("number sequence, excluding from different sources", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - 4 62 87 -

- `, - }, - "*", - ); - }); - - cy.get(cesc("#\\/_text1")).should("have.text", "a"); // to wait for page to load - - cy.get(cesc("#\\/_p1")).should("have.text", "1, 3, 5, 9, 10"); - }); - - it("sequences hide dynamically", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - - - - - - -

Length of sequence 1:

-

Length of sequence 2:

- -

sequence 1:

-

sequence 2:

- `, - }, - "*", - ); - }); - - cy.get(cesc("#\\/_text1")).should("have.text", "a"); // to wait for page to load - - cy.get(cesc("#\\/s1")).should("have.text", "sequence 1: 1, 2, 3, 4"); - cy.get(cesc("#\\/s2")).should("have.text", "sequence 2: "); - - cy.get(cesc("#\\/n1") + " textarea").type("{end}{backspace}6{enter}", { - force: true, - }); - cy.get(cesc("#\\/n2") + " textarea").type("{end}{backspace}6{enter}", { - force: true, - }); - - cy.get(cesc("#\\/s1")).should( - "have.text", - "sequence 1: 1, 2, 3, 4, 5, 6", - ); - cy.get(cesc("#\\/s2")).should("have.text", "sequence 2: "); - - cy.get(cesc("#\\/h1")).click(); - cy.get(cesc("#\\/h2")).click(); - - cy.get(cesc("#\\/s1")).should("have.text", "sequence 1: "); - cy.get(cesc("#\\/s2")).should( - "have.text", - "sequence 2: 1, 2, 3, 4, 5, 6", - ); - - cy.get(cesc("#\\/n1") + " textarea").type("{end}{backspace}8{enter}", { - force: true, - }); - cy.get(cesc("#\\/n2") + " textarea").type("{end}{backspace}8{enter}", { - force: true, - }); - - cy.get(cesc("#\\/s1")).should("have.text", "sequence 1: "); - cy.get(cesc("#\\/s2")).should( - "have.text", - "sequence 2: 1, 2, 3, 4, 5, 6, 7, 8", - ); - - cy.get(cesc("#\\/h1")).click(); - cy.get(cesc("#\\/h2")).click(); - - cy.get(cesc("#\\/s1")).should( - "have.text", - "sequence 1: 1, 2, 3, 4, 5, 6, 7, 8", - ); - cy.get(cesc("#\\/s2")).should("have.text", "sequence 2: "); - - cy.get(cesc("#\\/n1") + " textarea").type("{end}{backspace}3{enter}", { - force: true, - }); - cy.get(cesc("#\\/n2") + " textarea").type("{end}{backspace}3{enter}", { - force: true, - }); - - cy.get(cesc("#\\/s1")).should("have.text", "sequence 1: 1, 2, 3"); - cy.get(cesc("#\\/s2")).should("have.text", "sequence 2: "); - - cy.get(cesc("#\\/h1")).click(); - cy.get(cesc("#\\/h2")).click(); - - cy.get(cesc("#\\/s1")).should("have.text", "sequence 1: "); - cy.get(cesc("#\\/s2")).should("have.text", "sequence 2: 1, 2, 3"); - - cy.get(cesc("#\\/n1") + " textarea").type("{end}{backspace}4{enter}", { - force: true, - }); - cy.get(cesc("#\\/n2") + " textarea").type("{end}{backspace}4{enter}", { - force: true, - }); - - cy.get(cesc("#\\/s1")).should("have.text", "sequence 1: "); - cy.get(cesc("#\\/s2")).should("have.text", "sequence 2: 1, 2, 3, 4"); - }); - - it("sequence fixed by default", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - -

From:

-

Step:

- -

- -

Change first:

-

Change second:

- - `, - }, - "*", - ); - }); - - cy.get(cesc("#\\/_text1")).should("have.text", "a"); // to wait for page to load - - cy.get(cesc("#\\/thelist")).should("have.text", "1, 3, 5, 7"); - - cy.get(cesc("#\\/a2") + " textarea").type("{end}{backspace}21{enter}", { - force: true, - }); - cy.get(cesc("#\\/thelist")).should("have.text", "1, 3, 5, 7"); - - cy.get(cesc("#\\/b2") + " textarea").type("{end}{backspace}0{enter}", { - force: true, - }); - cy.get(cesc("#\\/thelist")).should("have.text", "1, 3, 5, 7"); - - cy.get(cesc("#\\/from") + " textarea").type( - "{end}{backspace}4{enter}", - { - force: true, - }, - ); - cy.get(cesc("#\\/thelist")).should("have.text", "4, 6"); - - cy.get(cesc("#\\/a2") + " textarea").type("{end}{backspace}8{enter}", { - force: true, - }); - cy.get(cesc("#\\/thelist")).should("have.text", "4, 6"); - - cy.get(cesc("#\\/b2") + " textarea").type("{end}{backspace}2{enter}", { - force: true, - }); - cy.get(cesc("#\\/thelist")).should("have.text", "4, 6"); - - cy.get(cesc("#\\/step") + " textarea").type( - "{end}{backspace}6{enter}", - { - force: true, - }, - ); - cy.get(cesc("#\\/thelist")).should("have.text", "4"); - - cy.get(cesc("#\\/a2") + " textarea").type("{end}{backspace}9{enter}", { - force: true, - }); - cy.get(cesc("#\\/thelist")).should("have.text", "4"); - - cy.get(cesc("#\\/b2") + " textarea").type("{end}{backspace}41{enter}", { - force: true, - }); - cy.get(cesc("#\\/thelist")).should("have.text", "4"); - }); - - it("can override fixed property", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - -

From:

-

Step:

-

Fixed:

- -

- -

Change first:

-

Change second:

- - `, - }, - "*", - ); - }); - - cy.get(cesc("#\\/_text1")).should("have.text", "a"); // to wait for page to load - - cy.get(cesc("#\\/thelist")).should("have.text", "1, 3, 5, 7"); - - cy.get(cesc("#\\/a2") + " textarea").type("{end}{backspace}21{enter}", { - force: true, - }); - cy.get(cesc("#\\/thelist")).should("have.text", "21, 3, 5, 7"); - - cy.get(cesc("#\\/b2") + " textarea").type("{end}{backspace}0{enter}", { - force: true, - }); - cy.get(cesc("#\\/thelist")).should("have.text", "21, 0, 5, 7"); - - cy.get(cesc("#\\/from") + " textarea").type( - "{end}{backspace}4{enter}", - { - force: true, - }, - ); - cy.get(cesc("#\\/thelist")).should("have.text", "4, 6"); - - cy.get(cesc("#\\/a2") + " textarea").type("{end}{backspace}8{enter}", { - force: true, - }); - cy.get(cesc("#\\/thelist")).should("have.text", "8, 6"); - - cy.get(cesc("#\\/b2") + " textarea").type("{end}{backspace}2{enter}", { - force: true, - }); - cy.get(cesc("#\\/thelist")).should("have.text", "8, 2"); - - cy.get(cesc("#\\/step") + " textarea").type( - "{end}{backspace}6{enter}", - { - force: true, - }, - ); - cy.get(cesc("#\\/thelist")).should("have.text", "4"); - - cy.get(cesc("#\\/a2") + " textarea").type("{end}{backspace}9{enter}", { - force: true, - }); - cy.get(cesc("#\\/thelist")).should("have.text", "9"); - - cy.get(cesc("#\\/b2") + " textarea").type("{end}{backspace}41{enter}", { - force: true, - }); - cy.get(cesc("#\\/thelist")).should("have.text", "9"); - - cy.get(cesc("#\\/fx")).click(); - cy.get(cesc("#\\/step") + " textarea").type( - "{end}{backspace}1{enter}", - { - force: true, - }, - ); - cy.get(cesc("#\\/thelist")).should("have.text", "4, 5, 6, 7"); - - cy.get(cesc("#\\/a2") + " textarea").type("{end}{backspace}9{enter}", { - force: true, - }); - cy.get(cesc("#\\/thelist")).should("have.text", "4, 5, 6, 7"); - - cy.get(cesc("#\\/b2") + " textarea").type("{end}{backspace}41{enter}", { - force: true, - }); - cy.get(cesc("#\\/thelist")).should("have.text", "4, 5, 6, 7"); - - cy.get(cesc("#\\/fx")).click(); - - cy.get(cesc("#\\/a2") + " textarea").type("{end}{backspace}9{enter}", { - force: true, - }); - cy.get(cesc("#\\/thelist")).should("have.text", "9, 5, 6, 7"); - - cy.get(cesc("#\\/b2") + " textarea").type("{end}{backspace}41{enter}", { - force: true, - }); - cy.get(cesc("#\\/thelist")).should("have.text", "9, 41, 6, 7"); - }); - - it('copies with link="false" are not fixed', () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - -

From:

-

Step:

- -

- -

Change first:

-

Change second:

- -

Copy of a2: $a2{name="a3"}

-

Copy of b2: $b2{name="b3"}

- - `, - }, - "*", - ); - }); - - cy.get(cesc("#\\/_text1")).should("have.text", "a"); // to wait for page to load - - cy.get(cesc("#\\/thelist")).should("have.text", "1, 3, 5, 7"); - cy.get(cesc(`#\\/a2`) + ` .mq-editable-field`).should("have.text", "1"); - cy.get(cesc(`#\\/b2`) + ` .mq-editable-field`).should("have.text", "3"); - cy.get(cesc("#\\/a3") + " .mjx-mrow") - .eq(0) - .should("have.text", "1"); - cy.get(cesc("#\\/b3") + " .mjx-mrow") - .eq(0) - .should("have.text", "3"); - - cy.get(cesc("#\\/a2") + " textarea") - .type("{end}{backspace}21{enter}", { force: true }) - .blur(); - cy.get(cesc("#\\/a3") + " .mjx-mrow").should("contain.text", "21"); - cy.get(cesc("#\\/thelist")).should("have.text", "1, 3, 5, 7"); - cy.get(cesc(`#\\/a2`) + ` .mq-editable-field`).should( - "have.text", - "21", - ); - cy.get(cesc(`#\\/b2`) + ` .mq-editable-field`).should("have.text", "3"); - cy.get(cesc("#\\/a3") + " .mjx-mrow") - .eq(0) - .should("have.text", "21"); - cy.get(cesc("#\\/b3") + " .mjx-mrow") - .eq(0) - .should("have.text", "3"); - - cy.get(cesc("#\\/b2") + " textarea") - .type("{end}{backspace}0{enter}", { force: true }) - .blur(); - cy.get(cesc("#\\/b3") + " .mjx-mrow").should("contain.text", "0"); - cy.get(cesc("#\\/thelist")).should("have.text", "1, 3, 5, 7"); - cy.get(cesc(`#\\/a2`) + ` .mq-editable-field`).should( - "have.text", - "21", - ); - cy.get(cesc(`#\\/b2`) + ` .mq-editable-field`).should("have.text", "0"); - cy.get(cesc("#\\/a3") + " .mjx-mrow") - .eq(0) - .should("have.text", "21"); - cy.get(cesc("#\\/b3") + " .mjx-mrow") - .eq(0) - .should("have.text", "0"); - - cy.get(cesc("#\\/from") + " textarea").type( - "{end}{backspace}4{enter}", - { - force: true, - }, - ); - cy.get(cesc("#\\/thelist")).should("have.text", "4, 6"); - cy.get(cesc(`#\\/a2`) + ` .mq-editable-field`).should( - "have.text", - "21", - ); - cy.get(cesc(`#\\/b2`) + ` .mq-editable-field`).should("have.text", "0"); - cy.get(cesc("#\\/a3") + " .mjx-mrow") - .eq(0) - .should("have.text", "21"); - cy.get(cesc("#\\/b3") + " .mjx-mrow") - .eq(0) - .should("have.text", "0"); - - cy.get(cesc("#\\/a2") + " textarea") - .type("{end}{backspace}{backspace}8{enter}", { force: true }) - .blur(); - cy.get(cesc("#\\/a3") + " .mjx-mrow").should("contain.text", "8"); - cy.get(cesc("#\\/thelist")).should("have.text", "4, 6"); - cy.get(cesc(`#\\/a2`) + ` .mq-editable-field`).should("have.text", "8"); - cy.get(cesc(`#\\/b2`) + ` .mq-editable-field`).should("have.text", "0"); - cy.get(cesc("#\\/a3") + " .mjx-mrow") - .eq(0) - .should("have.text", "8"); - cy.get(cesc("#\\/b3") + " .mjx-mrow") - .eq(0) - .should("have.text", "0"); - - cy.get(cesc("#\\/step") + " textarea").type( - "{end}{backspace}6{enter}", - { - force: true, - }, - ); - cy.get(cesc("#\\/thelist")).should("have.text", "4"); - cy.get(cesc(`#\\/a2`) + ` .mq-editable-field`).should("have.text", "8"); - cy.get(cesc(`#\\/b2`) + ` .mq-editable-field`).should("have.text", "0"); - cy.get(cesc("#\\/a3") + " .mjx-mrow") - .eq(0) - .should("have.text", "8"); - cy.get(cesc("#\\/b3") + " .mjx-mrow") - .eq(0) - .should("have.text", "0"); - - cy.get(cesc("#\\/a2") + " textarea") - .type("{end}{backspace}9{enter}", { force: true }) - .blur(); - cy.get(cesc("#\\/a3") + " .mjx-mrow").should("contain.text", "9"); - cy.get(cesc("#\\/thelist")).should("have.text", "4"); - cy.get(cesc(`#\\/a2`) + ` .mq-editable-field`).should("have.text", "9"); - cy.get(cesc(`#\\/b2`) + ` .mq-editable-field`).should("have.text", "0"); - cy.get(cesc("#\\/a3") + " .mjx-mrow") - .eq(0) - .should("have.text", "9"); - cy.get(cesc("#\\/b3") + " .mjx-mrow") - .eq(0) - .should("have.text", "0"); - - cy.get(cesc("#\\/b2") + " textarea") - .type("{end}{backspace}2{enter}", { force: true }) - .blur(); - cy.get(cesc("#\\/b3") + " .mjx-mrow").should("contain.text", "2"); - cy.get(cesc("#\\/thelist")).should("have.text", "4"); - cy.get(cesc(`#\\/a2`) + ` .mq-editable-field`).should("have.text", "9"); - cy.get(cesc(`#\\/b2`) + ` .mq-editable-field`).should("have.text", "2"); - cy.get(cesc("#\\/a3") + " .mjx-mrow") - .eq(0) - .should("have.text", "9"); - cy.get(cesc("#\\/b3") + " .mjx-mrow") - .eq(0) - .should("have.text", "2"); - - cy.get(cesc("#\\/from") + " textarea").type( - "{end}{backspace}8{enter}", - { - force: true, - }, - ); - cy.get(cesc("#\\/thelist")).should("have.text", ""); - cy.get(cesc(`#\\/a2`) + ` .mq-editable-field`).should("have.text", "9"); - cy.get(cesc(`#\\/b2`) + ` .mq-editable-field`).should("have.text", "2"); - cy.get(cesc("#\\/a3") + " .mjx-mrow") - .eq(0) - .should("have.text", "9"); - cy.get(cesc("#\\/b3") + " .mjx-mrow") - .eq(0) - .should("have.text", "2"); - - cy.get(cesc("#\\/a2") + " textarea") - .type("{end}{backspace}3{enter}", { force: true }) - .blur(); - cy.get(cesc("#\\/a3") + " .mjx-mrow").should("contain.text", "3"); - cy.get(cesc("#\\/thelist")).should("have.text", ""); - cy.get(cesc(`#\\/a2`) + ` .mq-editable-field`).should("have.text", "3"); - cy.get(cesc(`#\\/b2`) + ` .mq-editable-field`).should("have.text", "2"); - cy.get(cesc("#\\/a3") + " .mjx-mrow") - .eq(0) - .should("have.text", "3"); - cy.get(cesc("#\\/b3") + " .mjx-mrow") - .eq(0) - .should("have.text", "2"); - - cy.get(cesc("#\\/step") + " textarea").type( - "{end}{backspace}3{enter}", - { - force: true, - }, - ); - cy.get(cesc("#\\/from") + " textarea").type( - "{end}{backspace}0{enter}", - { - force: true, - }, - ); - cy.get(cesc("#\\/thelist")).should("have.text", "0, 3, 6"); - cy.get(cesc(`#\\/a2`) + ` .mq-editable-field`).should("have.text", "3"); - cy.get(cesc(`#\\/b2`) + ` .mq-editable-field`).should("have.text", "2"); - cy.get(cesc("#\\/a3") + " .mjx-mrow") - .eq(0) - .should("have.text", "3"); - cy.get(cesc("#\\/b3") + " .mjx-mrow") - .eq(0) - .should("have.text", "2"); - - cy.get(cesc("#\\/a2") + " textarea") - .type("{end}{backspace}8{enter}", { force: true }) - .blur(); - cy.get(cesc("#\\/a3") + " .mjx-mrow").should("contain.text", "8"); - cy.get(cesc("#\\/thelist")).should("have.text", "0, 3, 6"); - cy.get(cesc(`#\\/a2`) + ` .mq-editable-field`).should("have.text", "8"); - cy.get(cesc(`#\\/b2`) + ` .mq-editable-field`).should("have.text", "2"); - cy.get(cesc("#\\/a3") + " .mjx-mrow") - .eq(0) - .should("have.text", "8"); - cy.get(cesc("#\\/b3") + " .mjx-mrow") - .eq(0) - .should("have.text", "2"); - - cy.get(cesc("#\\/b2") + " textarea") - .type("{end}{backspace}7{enter}", { force: true }) - .blur(); - cy.get(cesc("#\\/b3") + " .mjx-mrow").should("contain.text", "7"); - cy.get(cesc("#\\/thelist")).should("have.text", "0, 3, 6"); - cy.get(cesc(`#\\/a2`) + ` .mq-editable-field`).should("have.text", "8"); - cy.get(cesc(`#\\/b2`) + ` .mq-editable-field`).should("have.text", "7"); - cy.get(cesc("#\\/a3") + " .mjx-mrow") - .eq(0) - .should("have.text", "8"); - cy.get(cesc("#\\/b3") + " .mjx-mrow") - .eq(0) - .should("have.text", "7"); - }); - - it("number sequence, from and to using strings with operators", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - - `, - }, - "*", - ); - }); - - 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 children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(8); - for (let i = 0; i < 8; i++) { - expect(children[i].stateValues.value).eq(-3 + i); - } - }); - }); - - it("number sequence, excludes with operators from macros", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a - 2 - 6 -

- `, - }, - "*", - ); - }); - - cy.get(cesc("#\\/_text1")).should("have.text", "a"); // to wait for page to load - - let nums = [0, 1, 5, 6, 8]; - - cy.get(cesc("#\\/_p1")).should("have.text", nums.join(", ")); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - let children = stateVariables["/_aslist1"].activeChildren.map( - (x) => stateVariables[x.componentName], - ); - expect(children.length).eq(nums.length); - for (let [ind, child] of children.entries()) { - expect(child.stateValues.value).eq(nums[ind]); - } - }); - }); - - it("warnings", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - - - - - - - - - - - - `, - }, - "*", - ); - }); - - cy.get(cesc2("#/nan")).should("have.text", "NaN"); - - cy.window().then(async (win) => { - let errorWarnings = await win.returnErrorWarnings1(); - - expect(errorWarnings.errors.length).eq(0); - expect(errorWarnings.warnings.length).eq(9); - - expect(errorWarnings.warnings[0].message).contain( - `Invalid length of sequence. Must be a non-negative integer`, - ); - expect(errorWarnings.warnings[0].level).eq(1); - expect(errorWarnings.warnings[0].doenetMLrange.lineBegin).eq(2); - expect(errorWarnings.warnings[0].doenetMLrange.charBegin).eq(5); - expect(errorWarnings.warnings[0].doenetMLrange.lineEnd).eq(2); - expect(errorWarnings.warnings[0].doenetMLrange.charEnd).eq(27); - - expect(errorWarnings.warnings[1].message).contain( - `Invalid step of sequence. Must be a number for sequence of type number`, - ); - expect(errorWarnings.warnings[1].level).eq(1); - expect(errorWarnings.warnings[1].doenetMLrange.lineBegin).eq(3); - expect(errorWarnings.warnings[1].doenetMLrange.charBegin).eq(5); - expect(errorWarnings.warnings[1].doenetMLrange.lineEnd).eq(3); - expect(errorWarnings.warnings[1].doenetMLrange.charEnd).eq(24); - - expect(errorWarnings.warnings[2].message).contain( - `Invalid step of sequence. Must be a number for sequence of type letters`, - ); - expect(errorWarnings.warnings[2].level).eq(1); - expect(errorWarnings.warnings[2].doenetMLrange.lineBegin).eq(4); - expect(errorWarnings.warnings[2].doenetMLrange.charBegin).eq(5); - expect(errorWarnings.warnings[2].doenetMLrange.lineEnd).eq(4); - expect(errorWarnings.warnings[2].doenetMLrange.charEnd).eq(40); - - expect(errorWarnings.warnings[3].message).contain( - `Invalid "from" of number sequence. Must be a number`, - ); - expect(errorWarnings.warnings[3].level).eq(1); - expect(errorWarnings.warnings[3].doenetMLrange.lineBegin).eq(5); - expect(errorWarnings.warnings[3].doenetMLrange.charBegin).eq(5); - expect(errorWarnings.warnings[3].doenetMLrange.lineEnd).eq(5); - expect(errorWarnings.warnings[3].doenetMLrange.charEnd).eq(25); - - expect(errorWarnings.warnings[4].message).contain( - `Invalid "from" of letters sequence. Must be a letter combination`, - ); - expect(errorWarnings.warnings[4].level).eq(1); - expect(errorWarnings.warnings[4].doenetMLrange.lineBegin).eq(6); - expect(errorWarnings.warnings[4].doenetMLrange.charBegin).eq(5); - expect(errorWarnings.warnings[4].doenetMLrange.lineEnd).eq(6); - expect(errorWarnings.warnings[4].doenetMLrange.charEnd).eq(40); - - expect(errorWarnings.warnings[5].message).contain( - `Invalid "from" of sequence`, - ); - expect(errorWarnings.warnings[5].level).eq(1); - expect(errorWarnings.warnings[5].doenetMLrange.lineBegin).eq(7); - expect(errorWarnings.warnings[5].doenetMLrange.charBegin).eq(5); - expect(errorWarnings.warnings[5].doenetMLrange.lineEnd).eq(7); - expect(errorWarnings.warnings[5].doenetMLrange.charEnd).eq(40); - - expect(errorWarnings.warnings[6].message).contain( - `Invalid "to" of number sequence. Must be a number.`, - ); - expect(errorWarnings.warnings[6].level).eq(1); - expect(errorWarnings.warnings[6].doenetMLrange.lineBegin).eq(8); - expect(errorWarnings.warnings[6].doenetMLrange.charBegin).eq(5); - expect(errorWarnings.warnings[6].doenetMLrange.lineEnd).eq(8); - expect(errorWarnings.warnings[6].doenetMLrange.charEnd).eq(23); - - expect(errorWarnings.warnings[7].message).contain( - `Invalid "to" of letters sequence. Must be a letter combination`, - ); - expect(errorWarnings.warnings[7].level).eq(1); - expect(errorWarnings.warnings[7].doenetMLrange.lineBegin).eq(9); - expect(errorWarnings.warnings[7].doenetMLrange.charBegin).eq(5); - expect(errorWarnings.warnings[7].doenetMLrange.lineEnd).eq(9); - expect(errorWarnings.warnings[7].doenetMLrange.charEnd).eq(38); - - expect(errorWarnings.warnings[8].message).contain( - `Invalid "to" of sequence`, - ); - expect(errorWarnings.warnings[8].level).eq(1); - expect(errorWarnings.warnings[8].doenetMLrange.lineBegin).eq(10); - expect(errorWarnings.warnings[8].doenetMLrange.charBegin).eq(5); - expect(errorWarnings.warnings[8].doenetMLrange.lineEnd).eq(10); - expect(errorWarnings.warnings[8].doenetMLrange.charEnd).eq(38); - }); - }); - - it("sequence displays as list by default", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` -

-

-

-

$default

-

$nocommas

-

$withcommas

-

$default{asList="false"}

-

$withcommas{asList="false"}

-

$nocommas{asList="true"}

-

-

-

-

-

-

-

-

-

- - `, - }, - "*", - ); - }); - - cy.get(cesc2("#/default")).should( - "have.text", - "1, 2, 3, 4, 5, 6, 7, 8, 9, 10", - ); - cy.get(cesc2("#/pdefault2")).should( - "have.text", - "1, 2, 3, 4, 5, 6, 7, 8, 9, 10", - ); - cy.get(cesc2("#/pdefault4")).should( - "have.text", - "1, 2, 3, 4, 5, 6, 7, 8, 9, 10", - ); - cy.get(cesc2("#/pdefault5")).should( - "have.text", - "1, 2, 3, 4, 5, 6, 7, 8, 9, 10", - ); - - cy.get(cesc2("#/nocommas")).should("have.text", "12345678910"); - cy.get(cesc2("#/pnocommas2")).should("have.text", "12345678910"); - cy.get(cesc2("#/pnocommas3")).should("have.text", "12345678910"); - cy.get(cesc2("#/pnocommas3a")).should("have.text", "12345678910"); - cy.get(cesc2("#/pnocommas4")).should("have.text", "12345678910"); - cy.get(cesc2("#/pnocommas5")).should("have.text", "12345678910"); - cy.get(cesc2("#/pnocommas6")).should("have.text", "12345678910"); - cy.get(cesc2("#/pnocommas6a")).should("have.text", "12345678910"); - - cy.get(cesc2("#/withcommas")).should( - "have.text", - "1, 2, 3, 4, 5, 6, 7, 8, 9, 10", - ); - cy.get(cesc2("#/pwithcommas2")).should( - "have.text", - "1, 2, 3, 4, 5, 6, 7, 8, 9, 10", - ); - - cy.window().then(async (win) => { - let stateVariables = await win.returnAllStateVariables1(); - expect(stateVariables["/pdefault"].stateValues.text).eq( - "1, 2, 3, 4, 5, 6, 7, 8, 9, 10", - ); - expect(stateVariables["/pdefault2"].stateValues.text).eq( - "1, 2, 3, 4, 5, 6, 7, 8, 9, 10", - ); - expect(stateVariables["/pdefault4"].stateValues.text).eq( - "1, 2, 3, 4, 5, 6, 7, 8, 9, 10", - ); - expect(stateVariables["/pdefault5"].stateValues.text).eq( - "1, 2, 3, 4, 5, 6, 7, 8, 9, 10", - ); - expect(stateVariables["/pnocommas"].stateValues.text).eq( - "12345678910", - ); - expect(stateVariables["/pnocommas2"].stateValues.text).eq( - "12345678910", - ); - expect(stateVariables["/pnocommas3"].stateValues.text).eq( - "12345678910", - ); - expect(stateVariables["/pnocommas3a"].stateValues.text).eq( - "12345678910", - ); - expect(stateVariables["/pnocommas4"].stateValues.text).eq( - "12345678910", - ); - expect(stateVariables["/pnocommas5"].stateValues.text).eq( - "12345678910", - ); - expect(stateVariables["/pnocommas6"].stateValues.text).eq( - "12345678910", - ); - expect(stateVariables["/pnocommas6a"].stateValues.text).eq( - "12345678910", - ); - expect(stateVariables["/pwithcommas"].stateValues.text).eq( - "1, 2, 3, 4, 5, 6, 7, 8, 9, 10", - ); - expect(stateVariables["/pwithcommas2"].stateValues.text).eq( - "1, 2, 3, 4, 5, 6, 7, 8, 9, 10", - ); - expect(stateVariables["/pwithcommas3"].stateValues.text).eq( - "1, 2, 3, 4, 5, 6, 7, 8, 9, 10", - ); - expect(stateVariables["/pwithcommas4"].stateValues.text).eq( - "1, 2, 3, 4, 5, 6, 7, 8, 9, 10", - ); - expect(stateVariables["/pwithcommas5"].stateValues.text).eq( - "1, 2, 3, 4, 5, 6, 7, 8, 9, 10", - ); - expect(stateVariables["/pwithcommas6"].stateValues.text).eq( - "1, 2, 3, 4, 5, 6, 7, 8, 9, 10", - ); - }); - }); - - it("rounding", () => { - cy.window().then(async (win) => { - win.postMessage( - { - doenetML: ` - a -

-

-

-

- -

$n1a $n1b $n1c

-

$n2a $n2b $n2c

-

$n3a $n3b $n3c

-

$n4a $n4b $n4c

- - `, - }, - "*", - ); - }); - - cy.get(cesc("#\\/_text1")).should("have.text", "a"); //wait for page to load - - let na = 10.12345; - let nb = na + 0.03257; - let nc = nb + 0.03257; - - cy.get(cesc("#\\/n1a")).should( - "have.text", - String(Math.round(na * 10 ** 8) / 10 ** 8), - ); - cy.get(cesc("#\\/n1b")).should( - "have.text", - String(Math.round(nb * 10 ** 8) / 10 ** 8), - ); - cy.get(cesc("#\\/n1c")).should( - "have.text", - String(Math.round(nc * 10 ** 8) / 10 ** 8), - ); - cy.get(cesc("#\\/n2a")).should( - "have.text", - String(Math.round(na * 10 ** 1) / 10 ** 1), - ); - cy.get(cesc("#\\/n2b")).should( - "have.text", - String(Math.round(nb * 10 ** 1) / 10 ** 1), - ); - cy.get(cesc("#\\/n2c")).should( - "have.text", - String(Math.round(nc * 10 ** 1) / 10 ** 1), - ); - cy.get(cesc("#\\/n3a")).should( - "have.text", - String(Math.round(na * 10 ** 3) / 10 ** 3), - ); - cy.get(cesc("#\\/n3b")).should( - "have.text", - String(Math.round(nb * 10 ** 3) / 10 ** 3), - ); - cy.get(cesc("#\\/n3c")).should( - "have.text", - String(Math.round(nc * 10 ** 3) / 10 ** 3), - ); - cy.get(cesc("#\\/n4a")).should("have.text", "10.0"); - cy.get(cesc("#\\/n4b")).should("have.text", "11.0"); - cy.get(cesc("#\\/n4c")).should("have.text", "12.0"); - - cy.get(cesc("#\\/n1a1")).should( - "have.text", - String(Math.round(na * 10 ** 8) / 10 ** 8), - ); - cy.get(cesc("#\\/n1b1")).should( - "have.text", - String(Math.round(nb * 10 ** 8) / 10 ** 8), - ); - cy.get(cesc("#\\/n1c1")).should( - "have.text", - String(Math.round(nc * 10 ** 8) / 10 ** 8), - ); - cy.get(cesc("#\\/n2a1")).should( - "have.text", - String(Math.round(na * 10 ** 1) / 10 ** 1), - ); - cy.get(cesc("#\\/n2b1")).should( - "have.text", - String(Math.round(nb * 10 ** 1) / 10 ** 1), - ); - cy.get(cesc("#\\/n2c1")).should( - "have.text", - String(Math.round(nc * 10 ** 1) / 10 ** 1), - ); - cy.get(cesc("#\\/n3a1")).should( - "have.text", - String(Math.round(na * 10 ** 3) / 10 ** 3), - ); - cy.get(cesc("#\\/n3b1")).should( - "have.text", - String(Math.round(nb * 10 ** 3) / 10 ** 3), - ); - cy.get(cesc("#\\/n3c1")).should( - "have.text", - String(Math.round(nc * 10 ** 3) / 10 ** 3), - ); - cy.get(cesc("#\\/n4a1")).should("have.text", "10.0"); - cy.get(cesc("#\\/n4b1")).should("have.text", "11.0"); - cy.get(cesc("#\\/n4c1")).should("have.text", "12.0"); - }); -});