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+3 11
+
+ `,
+ });
+
+ 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 6 2 8 7
+
+ `,
+ });
+
+ 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: `
+
+ Hide first sequence
+
+
+ Hide second sequence
+
+ 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+3 11
-
- `,
- },
- "*",
- );
- });
-
- 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 6 2 8 7
-
- `,
- },
- "*",
- );
- });
-
- 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
-
-
- Hide first sequence
-
-
- Hide second sequence
-
- 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");
- });
-});