@khanacademy/perseus-editor 2.12.1 → 2.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/dist/es/index.js +40 -48
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +38 -50
- package/dist/index.js.map +1 -1
- package/dist/item-extras-editor.d.ts +12 -12
- package/dist/widgets/expression-editor.d.ts +1 -5
- package/dist/widgets/label-image/behavior.d.ts +4 -1
- package/package.json +9 -9
- package/src/__tests__/items-extras-editors.test.tsx +68 -0
- package/src/item-extras-editor.tsx +17 -13
- package/src/widgets/__tests__/expression-editor.test.tsx +347 -0
- package/src/widgets/expression-editor.tsx +34 -70
- package/src/widgets/label-image/__stories__/behavior.stories.tsx +1 -1
- package/src/widgets/label-image/behavior.tsx +32 -0
- package/src/widgets/label-image-editor.tsx +1 -0
- package/tsconfig-build.tsbuildinfo +1 -1
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import PropTypes from "prop-types";
|
|
2
1
|
import * as React from "react";
|
|
3
|
-
type
|
|
2
|
+
type ItemExtrasProps = {
|
|
3
|
+
calculator: boolean;
|
|
4
|
+
chi2Table: boolean;
|
|
5
|
+
periodicTable: boolean;
|
|
6
|
+
periodicTableWithKey: boolean;
|
|
7
|
+
tTable: boolean;
|
|
8
|
+
zTable: boolean;
|
|
9
|
+
};
|
|
10
|
+
type Props = ItemExtrasProps & {
|
|
11
|
+
onChange: (props: Partial<ItemExtrasProps>) => void;
|
|
12
|
+
};
|
|
4
13
|
declare class ItemExtrasEditor extends React.Component<Props> {
|
|
5
|
-
static
|
|
6
|
-
calculator: PropTypes.Requireable<boolean>;
|
|
7
|
-
chi2Table: PropTypes.Requireable<boolean>;
|
|
8
|
-
onChange: PropTypes.Validator<(...args: any[]) => any>;
|
|
9
|
-
periodicTable: PropTypes.Requireable<boolean>;
|
|
10
|
-
periodicTableWithKey: PropTypes.Requireable<boolean>;
|
|
11
|
-
tTable: PropTypes.Requireable<boolean>;
|
|
12
|
-
zTable: PropTypes.Requireable<boolean>;
|
|
13
|
-
};
|
|
14
|
-
static defaultProps: Props;
|
|
14
|
+
static defaultProps: ItemExtrasProps;
|
|
15
15
|
serialize: () => any;
|
|
16
16
|
render(): React.ReactNode;
|
|
17
17
|
}
|
|
@@ -11,13 +11,9 @@ type DefaultProps = {
|
|
|
11
11
|
buttonSets: Props["buttonSets"];
|
|
12
12
|
functions: Props["functions"];
|
|
13
13
|
};
|
|
14
|
-
|
|
15
|
-
isTex: boolean;
|
|
16
|
-
};
|
|
17
|
-
declare class ExpressionEditor extends React.Component<Props, State> {
|
|
14
|
+
declare class ExpressionEditor extends React.Component<Props> {
|
|
18
15
|
static widgetName: "expression";
|
|
19
16
|
static defaultProps: DefaultProps;
|
|
20
|
-
constructor(props: Props);
|
|
21
17
|
change(...args: any[]): any;
|
|
22
18
|
render(): React.ReactNode;
|
|
23
19
|
serialize: () => any;
|
|
@@ -2,13 +2,16 @@
|
|
|
2
2
|
* Controlled component to display and change widget options.
|
|
3
3
|
*/
|
|
4
4
|
import * as React from "react";
|
|
5
|
+
export type PreferredPopoverDirection = "NONE" | "UP" | "DOWN" | "LEFT" | "RIGHT";
|
|
5
6
|
type Props = {
|
|
6
7
|
multipleAnswers: boolean;
|
|
7
8
|
hideChoicesFromInstructions: boolean;
|
|
9
|
+
preferredPopoverDirection: PreferredPopoverDirection;
|
|
8
10
|
onChange: (options: {
|
|
9
11
|
multipleAnswers?: boolean;
|
|
10
12
|
hideChoicesFromInstructions?: boolean;
|
|
13
|
+
preferredPopoverDirection?: PreferredPopoverDirection;
|
|
11
14
|
}) => void;
|
|
12
15
|
};
|
|
13
|
-
declare const Behavior: ({ multipleAnswers, hideChoicesFromInstructions, onChange, }: Props) => React.ReactElement;
|
|
16
|
+
declare const Behavior: ({ multipleAnswers, hideChoicesFromInstructions, preferredPopoverDirection, onChange, }: Props) => React.ReactElement;
|
|
14
17
|
export default Behavior;
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Perseus editors",
|
|
4
4
|
"author": "Khan Academy",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"version": "2.
|
|
6
|
+
"version": "2.14.0",
|
|
7
7
|
"publishConfig": {
|
|
8
8
|
"access": "public"
|
|
9
9
|
},
|
|
@@ -22,18 +22,18 @@
|
|
|
22
22
|
"test": "bash -c 'yarn --silent --cwd \"../..\" test ${@:0} $($([[ ${@: -1} = -* ]] || [[ ${@: -1} = bash ]]) && echo $PWD)'"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@khanacademy/kas": "^0.3.
|
|
26
|
-
"@khanacademy/kmath": "^0.1.
|
|
27
|
-
"@khanacademy/perseus": "^
|
|
28
|
-
"@khanacademy/perseus-core": "1.4.
|
|
25
|
+
"@khanacademy/kas": "^0.3.7",
|
|
26
|
+
"@khanacademy/kmath": "^0.1.8",
|
|
27
|
+
"@khanacademy/perseus": "^17.1.0",
|
|
28
|
+
"@khanacademy/perseus-core": "1.4.1"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@khanacademy/wonder-blocks-button": "^6.2.
|
|
31
|
+
"@khanacademy/wonder-blocks-button": "^6.2.4",
|
|
32
32
|
"@khanacademy/wonder-blocks-clickable": "^4.0.11",
|
|
33
33
|
"@khanacademy/wonder-blocks-color": "^3.0.0",
|
|
34
34
|
"@khanacademy/wonder-blocks-core": "^6.3.0",
|
|
35
|
-
"@khanacademy/wonder-blocks-icon": "2.2.1",
|
|
36
35
|
"@khanacademy/wonder-blocks-i18n": "^2.0.2",
|
|
36
|
+
"@khanacademy/wonder-blocks-icon": "4.0.0",
|
|
37
37
|
"@khanacademy/wonder-blocks-spacing": "^4.0.1",
|
|
38
38
|
"@khanacademy/wonder-blocks-typography": "^2.1.9",
|
|
39
39
|
"@khanacademy/wonder-stuff-core": "^1.5.1",
|
|
@@ -50,12 +50,12 @@
|
|
|
50
50
|
"underscore": "^1.4.4"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
53
|
-
"@khanacademy/wonder-blocks-button": "^6.2.
|
|
53
|
+
"@khanacademy/wonder-blocks-button": "^6.2.4",
|
|
54
54
|
"@khanacademy/wonder-blocks-clickable": "^4.0.11",
|
|
55
55
|
"@khanacademy/wonder-blocks-color": "^3.0.0",
|
|
56
56
|
"@khanacademy/wonder-blocks-core": "^6.3.0",
|
|
57
|
-
"@khanacademy/wonder-blocks-icon": "2.2.1",
|
|
58
57
|
"@khanacademy/wonder-blocks-i18n": "^2.0.2",
|
|
58
|
+
"@khanacademy/wonder-blocks-icon": "4.0.0",
|
|
59
59
|
"@khanacademy/wonder-blocks-spacing": "^4.0.1",
|
|
60
60
|
"@khanacademy/wonder-blocks-typography": "^2.1.9",
|
|
61
61
|
"@khanacademy/wonder-stuff-core": "^1.5.1",
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import "@testing-library/jest-dom";
|
|
2
|
+
import {render, screen} from "@testing-library/react";
|
|
3
|
+
import userEvent from "@testing-library/user-event";
|
|
4
|
+
import React from "react";
|
|
5
|
+
|
|
6
|
+
import ItemExtrasEditor from "../item-extras-editor";
|
|
7
|
+
|
|
8
|
+
describe("ItemExtrasEditor", () => {
|
|
9
|
+
it("should render correctly with default props", () => {
|
|
10
|
+
// Act
|
|
11
|
+
render(<ItemExtrasEditor onChange={() => {}} />);
|
|
12
|
+
|
|
13
|
+
// Assert
|
|
14
|
+
expect(screen.getByLabelText("Show calculator:")).not.toBeChecked();
|
|
15
|
+
expect(screen.getByLabelText("Show periodic table:")).not.toBeChecked();
|
|
16
|
+
expect(
|
|
17
|
+
screen.queryByText("Include key/legend with periodic table:"),
|
|
18
|
+
).not.toBeInTheDocument();
|
|
19
|
+
expect(
|
|
20
|
+
screen.getByLabelText("Show z table (statistics):"),
|
|
21
|
+
).not.toBeChecked();
|
|
22
|
+
expect(
|
|
23
|
+
screen.getByLabelText("Show t table (statistics):"),
|
|
24
|
+
).not.toBeChecked();
|
|
25
|
+
expect(
|
|
26
|
+
screen.getByLabelText("Show chi-squared table (statistics):"),
|
|
27
|
+
).not.toBeChecked();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("should call onChange with updated calculator value", () => {
|
|
31
|
+
// Arrange
|
|
32
|
+
const onChangeMock = jest.fn();
|
|
33
|
+
render(<ItemExtrasEditor calculator={false} onChange={onChangeMock} />);
|
|
34
|
+
const checkbox = screen.getByLabelText("Show calculator:");
|
|
35
|
+
|
|
36
|
+
// Act
|
|
37
|
+
userEvent.click(checkbox);
|
|
38
|
+
|
|
39
|
+
// Assert
|
|
40
|
+
expect(onChangeMock).toHaveBeenCalledWith({calculator: true});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it("should call onChange with updated periodicTableWithKey value when periodicTable is unchecked", () => {
|
|
44
|
+
// Arrange
|
|
45
|
+
const onChangeMock = jest.fn();
|
|
46
|
+
render(
|
|
47
|
+
<ItemExtrasEditor
|
|
48
|
+
periodicTable={true}
|
|
49
|
+
periodicTableWithKey={true}
|
|
50
|
+
onChange={onChangeMock}
|
|
51
|
+
/>,
|
|
52
|
+
);
|
|
53
|
+
const checkbox = screen.getByLabelText("Show periodic table:");
|
|
54
|
+
|
|
55
|
+
// Act
|
|
56
|
+
userEvent.click(checkbox);
|
|
57
|
+
|
|
58
|
+
// Assert
|
|
59
|
+
// visible when periodicTable is checked
|
|
60
|
+
expect(
|
|
61
|
+
screen.getByText("Include key/legend with periodic table:"),
|
|
62
|
+
).toBeInTheDocument();
|
|
63
|
+
expect(onChangeMock).toHaveBeenCalledWith({
|
|
64
|
+
periodicTable: false,
|
|
65
|
+
periodicTableWithKey: false,
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
});
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import {components} from "@khanacademy/perseus";
|
|
2
|
-
import PropTypes from "prop-types";
|
|
3
2
|
import * as React from "react";
|
|
4
3
|
|
|
5
4
|
const {InfoTip} = components;
|
|
6
5
|
|
|
7
|
-
type
|
|
6
|
+
type ItemExtrasProps = {
|
|
7
|
+
calculator: boolean;
|
|
8
|
+
chi2Table: boolean;
|
|
9
|
+
periodicTable: boolean;
|
|
10
|
+
periodicTableWithKey: boolean;
|
|
11
|
+
tTable: boolean;
|
|
12
|
+
zTable: boolean;
|
|
13
|
+
};
|
|
8
14
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
chi2Table: PropTypes.bool,
|
|
13
|
-
onChange: PropTypes.func.isRequired,
|
|
14
|
-
periodicTable: PropTypes.bool,
|
|
15
|
-
periodicTableWithKey: PropTypes.bool,
|
|
16
|
-
tTable: PropTypes.bool,
|
|
17
|
-
zTable: PropTypes.bool,
|
|
18
|
-
};
|
|
15
|
+
type Props = ItemExtrasProps & {
|
|
16
|
+
onChange: (props: Partial<ItemExtrasProps>) => void;
|
|
17
|
+
};
|
|
19
18
|
|
|
20
|
-
|
|
19
|
+
class ItemExtrasEditor extends React.Component<Props> {
|
|
20
|
+
static defaultProps: ItemExtrasProps = {
|
|
21
21
|
calculator: false,
|
|
22
22
|
chi2Table: false,
|
|
23
23
|
periodicTable: false,
|
|
@@ -71,6 +71,10 @@ class ItemExtrasEditor extends React.Component<Props> {
|
|
|
71
71
|
onChange={(e) => {
|
|
72
72
|
this.props.onChange({
|
|
73
73
|
periodicTable: e.target.checked,
|
|
74
|
+
// If the periodic table is unchecked,
|
|
75
|
+
// this needs to be reset. If table is
|
|
76
|
+
// checked, it should already be false.
|
|
77
|
+
periodicTableWithKey: false,
|
|
74
78
|
});
|
|
75
79
|
}}
|
|
76
80
|
/>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {Dependencies} from "@khanacademy/perseus";
|
|
2
2
|
import {render, screen} from "@testing-library/react";
|
|
3
|
+
import userEvent from "@testing-library/user-event";
|
|
3
4
|
import * as React from "react";
|
|
4
5
|
|
|
5
6
|
import "@testing-library/jest-dom";
|
|
@@ -53,4 +54,350 @@ describe("expression-editor", () => {
|
|
|
53
54
|
|
|
54
55
|
expect(await screen.findByText(/π/)).toBeInTheDocument();
|
|
55
56
|
});
|
|
57
|
+
|
|
58
|
+
it("should toggle multiplication checkbox", () => {
|
|
59
|
+
const onChangeMock = jest.fn();
|
|
60
|
+
|
|
61
|
+
render(<ExpressionEditor onChange={onChangeMock} />);
|
|
62
|
+
|
|
63
|
+
userEvent.click(
|
|
64
|
+
screen.getByRole("checkbox", {
|
|
65
|
+
name: "Use × for rendering multiplication instead of a center dot.",
|
|
66
|
+
}),
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
expect(onChangeMock).toBeCalledWith({times: true});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it("should be possible to change function variables", () => {
|
|
73
|
+
const onChangeMock = jest.fn();
|
|
74
|
+
|
|
75
|
+
render(<ExpressionEditor onChange={onChangeMock} functions={[]} />);
|
|
76
|
+
|
|
77
|
+
const input = screen.getByRole("textbox", {
|
|
78
|
+
name: "Function variables:",
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
userEvent.type(input, "x");
|
|
82
|
+
|
|
83
|
+
expect(onChangeMock).toBeCalledWith({functions: ["x"]});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("should toggle division checkbox", () => {
|
|
87
|
+
const onChangeMock = jest.fn();
|
|
88
|
+
|
|
89
|
+
render(<ExpressionEditor onChange={onChangeMock} />);
|
|
90
|
+
|
|
91
|
+
userEvent.click(
|
|
92
|
+
screen.getByRole("checkbox", {
|
|
93
|
+
name: "show \\div button",
|
|
94
|
+
}),
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
expect(onChangeMock).toBeCalledWith(
|
|
98
|
+
{
|
|
99
|
+
answerForms: [],
|
|
100
|
+
buttonSets: ["basic+div"],
|
|
101
|
+
functions: ["f", "g", "h"],
|
|
102
|
+
times: false,
|
|
103
|
+
},
|
|
104
|
+
undefined,
|
|
105
|
+
);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it("should toggle trig checkbox", () => {
|
|
109
|
+
const onChangeMock = jest.fn();
|
|
110
|
+
|
|
111
|
+
render(<ExpressionEditor onChange={onChangeMock} />);
|
|
112
|
+
|
|
113
|
+
userEvent.click(
|
|
114
|
+
screen.getByRole("checkbox", {
|
|
115
|
+
name: "trig",
|
|
116
|
+
}),
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
expect(onChangeMock).toBeCalledWith({
|
|
120
|
+
buttonSets: ["basic", "trig"],
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it("should toggle prealgebra checkbox", () => {
|
|
125
|
+
const onChangeMock = jest.fn();
|
|
126
|
+
|
|
127
|
+
render(<ExpressionEditor onChange={onChangeMock} />);
|
|
128
|
+
|
|
129
|
+
userEvent.click(
|
|
130
|
+
screen.getByRole("checkbox", {
|
|
131
|
+
name: "prealgebra",
|
|
132
|
+
}),
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
expect(onChangeMock).toBeCalledWith({
|
|
136
|
+
buttonSets: ["basic", "prealgebra"],
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it("should toggle prealgebra checkbox", () => {
|
|
141
|
+
const onChangeMock = jest.fn();
|
|
142
|
+
|
|
143
|
+
render(<ExpressionEditor onChange={onChangeMock} />);
|
|
144
|
+
|
|
145
|
+
userEvent.click(
|
|
146
|
+
screen.getByRole("checkbox", {
|
|
147
|
+
name: "logarithms",
|
|
148
|
+
}),
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
expect(onChangeMock).toBeCalledWith({
|
|
152
|
+
buttonSets: ["basic", "logarithms"],
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it("should toggle prealgebra checkbox", () => {
|
|
157
|
+
const onChangeMock = jest.fn();
|
|
158
|
+
|
|
159
|
+
render(<ExpressionEditor onChange={onChangeMock} />);
|
|
160
|
+
|
|
161
|
+
userEvent.click(
|
|
162
|
+
screen.getByRole("checkbox", {
|
|
163
|
+
name: "basic relations",
|
|
164
|
+
}),
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
expect(onChangeMock).toBeCalledWith({
|
|
168
|
+
buttonSets: ["basic", "basic relations"],
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it("should toggle prealgebra checkbox", () => {
|
|
173
|
+
const onChangeMock = jest.fn();
|
|
174
|
+
|
|
175
|
+
render(<ExpressionEditor onChange={onChangeMock} />);
|
|
176
|
+
|
|
177
|
+
userEvent.click(
|
|
178
|
+
screen.getByRole("checkbox", {
|
|
179
|
+
name: "advanced relations",
|
|
180
|
+
}),
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
expect(onChangeMock).toBeCalledWith({
|
|
184
|
+
buttonSets: ["basic", "advanced relations"],
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it("should be possible to add an answer", () => {
|
|
189
|
+
const onChangeMock = jest.fn();
|
|
190
|
+
|
|
191
|
+
render(<ExpressionEditor onChange={onChangeMock} />);
|
|
192
|
+
|
|
193
|
+
userEvent.click(
|
|
194
|
+
screen.getByRole("button", {
|
|
195
|
+
name: "Add new answer",
|
|
196
|
+
}),
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
expect(onChangeMock).toBeCalledWith(
|
|
200
|
+
{
|
|
201
|
+
answerForms: [
|
|
202
|
+
{
|
|
203
|
+
considered: "correct",
|
|
204
|
+
form: false,
|
|
205
|
+
key: 0,
|
|
206
|
+
simplify: false,
|
|
207
|
+
value: "",
|
|
208
|
+
},
|
|
209
|
+
],
|
|
210
|
+
buttonSets: ["basic"],
|
|
211
|
+
functions: ["f", "g", "h"],
|
|
212
|
+
times: false,
|
|
213
|
+
},
|
|
214
|
+
undefined,
|
|
215
|
+
);
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
it("should be possible to update answer", () => {
|
|
219
|
+
const onChangeMock = jest.fn();
|
|
220
|
+
|
|
221
|
+
render(
|
|
222
|
+
<ExpressionEditor
|
|
223
|
+
onChange={onChangeMock}
|
|
224
|
+
answerForms={[
|
|
225
|
+
{
|
|
226
|
+
considered: "correct",
|
|
227
|
+
form: false,
|
|
228
|
+
key: "0",
|
|
229
|
+
simplify: false,
|
|
230
|
+
value: "",
|
|
231
|
+
},
|
|
232
|
+
]}
|
|
233
|
+
/>,
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
userEvent.click(
|
|
237
|
+
screen.getByRole("switch", {
|
|
238
|
+
name: "open math keypad",
|
|
239
|
+
}),
|
|
240
|
+
);
|
|
241
|
+
|
|
242
|
+
userEvent.click(
|
|
243
|
+
screen.getByRole("button", {
|
|
244
|
+
name: "9",
|
|
245
|
+
}),
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
expect(onChangeMock).toBeCalledWith(
|
|
249
|
+
{
|
|
250
|
+
answerForms: [
|
|
251
|
+
{
|
|
252
|
+
buttonSets: ["basic"],
|
|
253
|
+
buttonsVisible: "focused",
|
|
254
|
+
considered: "correct",
|
|
255
|
+
form: false,
|
|
256
|
+
functions: ["f", "g", "h"],
|
|
257
|
+
key: "0",
|
|
258
|
+
linterContext: {
|
|
259
|
+
contentType: "",
|
|
260
|
+
highlightLint: false,
|
|
261
|
+
paths: [],
|
|
262
|
+
stack: [],
|
|
263
|
+
},
|
|
264
|
+
simplify: false,
|
|
265
|
+
times: false,
|
|
266
|
+
value: "9",
|
|
267
|
+
},
|
|
268
|
+
],
|
|
269
|
+
buttonSets: ["basic"],
|
|
270
|
+
functions: ["f", "g", "h"],
|
|
271
|
+
times: false,
|
|
272
|
+
},
|
|
273
|
+
undefined,
|
|
274
|
+
);
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
it("should be possible to toggle same form", () => {
|
|
278
|
+
const onChangeMock = jest.fn();
|
|
279
|
+
|
|
280
|
+
render(
|
|
281
|
+
<ExpressionEditor
|
|
282
|
+
onChange={onChangeMock}
|
|
283
|
+
answerForms={[
|
|
284
|
+
{
|
|
285
|
+
considered: "correct",
|
|
286
|
+
form: false,
|
|
287
|
+
key: "0",
|
|
288
|
+
simplify: false,
|
|
289
|
+
value: "",
|
|
290
|
+
},
|
|
291
|
+
]}
|
|
292
|
+
/>,
|
|
293
|
+
);
|
|
294
|
+
|
|
295
|
+
userEvent.click(
|
|
296
|
+
screen.getByRole("checkbox", {
|
|
297
|
+
name: "Answer expression must have the same form.",
|
|
298
|
+
}),
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
expect(onChangeMock).toBeCalledWith(
|
|
302
|
+
{
|
|
303
|
+
answerForms: [
|
|
304
|
+
{
|
|
305
|
+
considered: "correct",
|
|
306
|
+
form: true,
|
|
307
|
+
key: "0",
|
|
308
|
+
simplify: false,
|
|
309
|
+
value: "",
|
|
310
|
+
},
|
|
311
|
+
],
|
|
312
|
+
buttonSets: ["basic"],
|
|
313
|
+
functions: ["f", "g", "h"],
|
|
314
|
+
times: false,
|
|
315
|
+
},
|
|
316
|
+
undefined,
|
|
317
|
+
);
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
it("should be possible to toggle expanded and simplified", () => {
|
|
321
|
+
const onChangeMock = jest.fn();
|
|
322
|
+
|
|
323
|
+
render(
|
|
324
|
+
<ExpressionEditor
|
|
325
|
+
onChange={onChangeMock}
|
|
326
|
+
answerForms={[
|
|
327
|
+
{
|
|
328
|
+
considered: "correct",
|
|
329
|
+
form: false,
|
|
330
|
+
key: "0",
|
|
331
|
+
simplify: false,
|
|
332
|
+
value: "",
|
|
333
|
+
},
|
|
334
|
+
]}
|
|
335
|
+
/>,
|
|
336
|
+
);
|
|
337
|
+
|
|
338
|
+
userEvent.click(
|
|
339
|
+
screen.getByRole("checkbox", {
|
|
340
|
+
name: "Answer expression must be fully expanded and simplified.",
|
|
341
|
+
}),
|
|
342
|
+
);
|
|
343
|
+
|
|
344
|
+
expect(onChangeMock).toBeCalledWith(
|
|
345
|
+
{
|
|
346
|
+
answerForms: [
|
|
347
|
+
{
|
|
348
|
+
considered: "correct",
|
|
349
|
+
form: false,
|
|
350
|
+
key: "0",
|
|
351
|
+
simplify: true,
|
|
352
|
+
value: "",
|
|
353
|
+
},
|
|
354
|
+
],
|
|
355
|
+
buttonSets: ["basic"],
|
|
356
|
+
functions: ["f", "g", "h"],
|
|
357
|
+
times: false,
|
|
358
|
+
},
|
|
359
|
+
undefined,
|
|
360
|
+
);
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
it("should be possible to delete answer", () => {
|
|
364
|
+
const onChangeMock = jest.fn();
|
|
365
|
+
|
|
366
|
+
render(
|
|
367
|
+
<ExpressionEditor
|
|
368
|
+
onChange={onChangeMock}
|
|
369
|
+
answerForms={[
|
|
370
|
+
{
|
|
371
|
+
considered: "correct",
|
|
372
|
+
form: false,
|
|
373
|
+
key: "0",
|
|
374
|
+
simplify: false,
|
|
375
|
+
value: "",
|
|
376
|
+
},
|
|
377
|
+
]}
|
|
378
|
+
/>,
|
|
379
|
+
);
|
|
380
|
+
|
|
381
|
+
userEvent.click(
|
|
382
|
+
screen.getByRole("button", {
|
|
383
|
+
name: "Delete",
|
|
384
|
+
}),
|
|
385
|
+
);
|
|
386
|
+
|
|
387
|
+
userEvent.click(
|
|
388
|
+
screen.getByRole("button", {
|
|
389
|
+
name: "I'm sure!",
|
|
390
|
+
}),
|
|
391
|
+
);
|
|
392
|
+
|
|
393
|
+
expect(onChangeMock).toBeCalledWith(
|
|
394
|
+
{
|
|
395
|
+
answerForms: [],
|
|
396
|
+
buttonSets: ["basic"],
|
|
397
|
+
functions: ["f", "g", "h"],
|
|
398
|
+
times: false,
|
|
399
|
+
},
|
|
400
|
+
undefined,
|
|
401
|
+
);
|
|
402
|
+
});
|
|
56
403
|
});
|