@khanacademy/perseus-editor 0.0.1 → 0.1.2

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.
Files changed (127) hide show
  1. package/.babelrc.js +1 -1
  2. package/CHANGELOG.md +26 -0
  3. package/dist/es/index.css +1020 -0
  4. package/dist/es/index.js +9 -1
  5. package/dist/es/index.js.map +1 -1
  6. package/dist/index.css +1020 -0
  7. package/dist/index.js +9 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/strings.js +6 -1
  10. package/package.json +16 -4
  11. package/src/README.md +7 -0
  12. package/src/__stories__/editor.stories.js +33 -0
  13. package/src/__stories__/section-control-button.stories.jsx +27 -0
  14. package/src/__testdata__/input-number_testdata.js +28 -0
  15. package/src/__tests__/editor_test.jsx +123 -0
  16. package/src/__tests__/i18n_test.jsx +585 -0
  17. package/src/__tests__/traversal_test.jsx +378 -0
  18. package/src/all-editors.js +85 -0
  19. package/src/all-editors_test.js +17 -0
  20. package/src/all-widgets.js +10 -0
  21. package/src/article-editor.jsx +437 -0
  22. package/src/components/__stories__/blur-input.stories.jsx +24 -0
  23. package/src/components/blur-input.jsx +62 -0
  24. package/src/components/checkbox.jsx +194 -0
  25. package/src/components/device-framer.jsx +91 -0
  26. package/src/components/drag-target.jsx +88 -0
  27. package/src/components/dropdown-option.jsx +318 -0
  28. package/src/components/form-wrapped-text-field.jsx +248 -0
  29. package/src/components/graph-settings.jsx +631 -0
  30. package/src/components/hover-behavior.jsx +178 -0
  31. package/src/components/json-editor.jsx +121 -0
  32. package/src/components/link.jsx +173 -0
  33. package/src/components/simple-button.jsx +86 -0
  34. package/src/components/sortable.jsx +186 -0
  35. package/src/components/util.js +39 -0
  36. package/src/components/viewport-resizer.jsx +73 -0
  37. package/src/diffs/__stories__/perseus-diff-wrapper.jsx +8 -0
  38. package/src/diffs/__stories__/structured-item-diff.stories.jsx +855 -0
  39. package/src/diffs/__stories__/tags-diff.stories.jsx +38 -0
  40. package/src/diffs/__stories__/text-diff.stories.jsx +37 -0
  41. package/src/diffs/__tests__/split-diff_test.js +34 -0
  42. package/src/diffs/__tests__/string-array-diff_test.js +74 -0
  43. package/src/diffs/__tests__/structured-item-diff_test.js +432 -0
  44. package/src/diffs/__tests__/widget-diff-performer_test.js +44 -0
  45. package/src/diffs/article-diff.jsx +70 -0
  46. package/src/diffs/item-diff.jsx +77 -0
  47. package/src/diffs/renderer-diff.jsx +143 -0
  48. package/src/diffs/split-diff.jsx +30 -0
  49. package/src/diffs/string-array-diff.jsx +75 -0
  50. package/src/diffs/structured-item-diff.jsx +269 -0
  51. package/src/diffs/tags-diff.jsx +50 -0
  52. package/src/diffs/text-diff.jsx +194 -0
  53. package/src/diffs/widget-diff-performer.jsx +74 -0
  54. package/src/diffs/widget-diff.jsx +291 -0
  55. package/src/editor-page.jsx +351 -0
  56. package/src/editor.jsx +1364 -0
  57. package/src/hint-editor.jsx +447 -0
  58. package/src/i18n.jsx +139 -0
  59. package/src/iframe-content-renderer.jsx +201 -0
  60. package/src/index.js +27 -8
  61. package/src/item-editor.jsx +159 -0
  62. package/src/item-extras-editor.jsx +150 -0
  63. package/src/katex-error-view.jsx +87 -0
  64. package/src/multirenderer-editor.jsx +1074 -0
  65. package/src/section-control-button.jsx +53 -0
  66. package/src/stateful-article-editor.jsx +176 -0
  67. package/src/stateful-editor-page.jsx +90 -0
  68. package/src/styles/perseus-editor.less +1339 -0
  69. package/src/testing-widgets.js +12 -0
  70. package/src/util/register-all-widgets-and-editors-for-testing.js +15 -0
  71. package/src/util/register-all-widgets-and-editors-for-testing_test.js +18 -0
  72. package/src/widgets/__stories__/label-image-editor.stories.jsx +97 -0
  73. package/src/widgets/categorizer-editor.jsx +103 -0
  74. package/src/widgets/cs-program-editor.jsx +258 -0
  75. package/src/widgets/definition-editor.jsx +75 -0
  76. package/src/widgets/dropdown-editor.jsx +201 -0
  77. package/src/widgets/example-graphie-widget-editor.jsx +70 -0
  78. package/src/widgets/example-graphie-widget.jsx +175 -0
  79. package/src/widgets/example-widget-editor.jsx +60 -0
  80. package/src/widgets/example-widget.jsx +153 -0
  81. package/src/widgets/explanation-editor.jsx +89 -0
  82. package/src/widgets/expression-editor.jsx +560 -0
  83. package/src/widgets/graded-group-editor.jsx +162 -0
  84. package/src/widgets/graded-group-set-editor.jsx +101 -0
  85. package/src/widgets/grapher-editor.jsx +154 -0
  86. package/src/widgets/group-editor.jsx +83 -0
  87. package/src/widgets/iframe-editor.jsx +200 -0
  88. package/src/widgets/image-editor.jsx +326 -0
  89. package/src/widgets/input-number-editor.jsx +269 -0
  90. package/src/widgets/interaction/constraint-editor.jsx +147 -0
  91. package/src/widgets/interaction-editor.jsx +1389 -0
  92. package/src/widgets/interactive-graph-editor.jsx +322 -0
  93. package/src/widgets/label-image/__stories__/answer-choices.stories.jsx +81 -0
  94. package/src/widgets/label-image/__stories__/behavior.stories.jsx +32 -0
  95. package/src/widgets/label-image/__stories__/marker.stories.jsx +76 -0
  96. package/src/widgets/label-image/__stories__/question-markers.stories.jsx +106 -0
  97. package/src/widgets/label-image/__stories__/select-image.stories.jsx +60 -0
  98. package/src/widgets/label-image/answer-choices.jsx +231 -0
  99. package/src/widgets/label-image/behavior.jsx +92 -0
  100. package/src/widgets/label-image/marker.jsx +292 -0
  101. package/src/widgets/label-image/question-markers.jsx +181 -0
  102. package/src/widgets/label-image/select-image.jsx +86 -0
  103. package/src/widgets/label-image-editor.jsx +257 -0
  104. package/src/widgets/lights-puzzle-editor.jsx +267 -0
  105. package/src/widgets/matcher-editor.jsx +147 -0
  106. package/src/widgets/matrix-editor.jsx +155 -0
  107. package/src/widgets/measurer-editor.jsx +245 -0
  108. package/src/widgets/molecule-editor.jsx +63 -0
  109. package/src/widgets/number-line-editor.jsx +498 -0
  110. package/src/widgets/numeric-input-editor.jsx +554 -0
  111. package/src/widgets/orderer-editor.jsx +166 -0
  112. package/src/widgets/passage-editor.jsx +115 -0
  113. package/src/widgets/passage-ref-editor.jsx +77 -0
  114. package/src/widgets/passage-ref-target-editor.jsx +47 -0
  115. package/src/widgets/plotter-editor.jsx +537 -0
  116. package/src/widgets/radio/editor.jsx +398 -0
  117. package/src/widgets/reaction-diagram-editor.jsx +127 -0
  118. package/src/widgets/sequence-editor.jsx +205 -0
  119. package/src/widgets/simple-markdown-tester-editor.jsx +84 -0
  120. package/src/widgets/simple-markdown-tester.jsx +91 -0
  121. package/src/widgets/simulator-editor.jsx +144 -0
  122. package/src/widgets/sorter-editor.jsx +100 -0
  123. package/src/widgets/table-editor.jsx +164 -0
  124. package/src/widgets/transformer-editor.jsx +1006 -0
  125. package/src/widgets/unit-editor.jsx +293 -0
  126. package/src/widgets/video-editor.jsx +74 -0
  127. package/src/__tests__/index.test.js +0 -15
@@ -0,0 +1,585 @@
1
+ // @flow
2
+ import {Dependencies} from "@khanacademy/perseus";
3
+ import _ from "underscore";
4
+
5
+ import {testDependencies} from "../../../../testing/test-dependencies.js";
6
+ import i18n from "../i18n.jsx";
7
+ import {registerAllWidgetsAndEditorsForTesting} from "../util/register-all-widgets-and-editors-for-testing.js";
8
+
9
+ const exerciseImagesEverywhere = {
10
+ question: {
11
+ content:
12
+ "![question-a](question-a)\n\n![question-b](question-b)\n\n[[☃ categorizer 1]]\n\n[[☃ group 1]]\n\n[[☃ image 1]]\n\n[[☃ matcher 1]]\n\n[[☃ matrix 1]]\n\n[[☃ orderer 1]]\n\n[[☃ passage 1]]\n\n[[☃ radio 1]]\n\n[[☃ sorter 1]]\n\n[[☃ table 1]]\n\n[[☃ grapher 1]]\n\n[[☃ interactive-graph 1]]\n\n[[☃ measurer 1]]\n\n[[☃ plotter 1]]\n\n[[☃ transformer 1]]",
13
+ images: {},
14
+ widgets: {
15
+ "categorizer 1": {
16
+ type: "categorizer",
17
+ graded: true,
18
+ options: {
19
+ items: [
20
+ "![category-item-a](category-item-a)",
21
+ "![category-item-b](category-item-b)",
22
+ ],
23
+ categories: [
24
+ "![category-category-a](category-category-a)",
25
+ "![category-category-b](category-category-b)",
26
+ ],
27
+ values: [],
28
+ randomizeItems: false,
29
+ },
30
+ version: {major: 0, minor: 0},
31
+ },
32
+ "group 1": {
33
+ type: "group",
34
+ graded: true,
35
+ options: {
36
+ content:
37
+ "![group-a](group-a)\n\n![group-b](group-b)\n\n[[☃ image 1]]",
38
+ images: {},
39
+ widgets: {
40
+ "image 1": {
41
+ type: "image",
42
+ graded: true,
43
+ options: {
44
+ title: "![group-image-title-a](group-image-title-a) ![group-image-title-b](group-image-title-b)",
45
+ range: [
46
+ [0, 10],
47
+ [0, 10],
48
+ ],
49
+ box: [0, 0],
50
+ backgroundImage: {
51
+ url: "group-image-a",
52
+ width: 0,
53
+ height: 0,
54
+ },
55
+ labels: [],
56
+ alt: "",
57
+ caption:
58
+ "![group-image-caption-a](group-image-caption-a) ![group-image-caption-b](group-image-caption-b)",
59
+ },
60
+ version: {major: 0, minor: 0},
61
+ },
62
+ },
63
+ },
64
+ version: {major: 0, minor: 0},
65
+ },
66
+ "image 1": {
67
+ type: "image",
68
+ graded: true,
69
+ options: {
70
+ title: "![image-title-a](image-title-a) ![image-title-b](image-title-b)",
71
+ range: [
72
+ [0, 10],
73
+ [0, 10],
74
+ ],
75
+ box: [0, 0],
76
+ backgroundImage: {url: "image-a", width: 0, height: 0},
77
+ labels: [],
78
+ alt: "",
79
+ caption:
80
+ "![image-caption-a](image-caption-a) ![image-caption-b](image-caption-b)",
81
+ },
82
+ version: {major: 0, minor: 0},
83
+ },
84
+ "matcher 1": {
85
+ type: "matcher",
86
+ graded: true,
87
+ options: {
88
+ left: [
89
+ "![matcher-left-a](matcher-left-a)",
90
+ "![matcher-left-b](matcher-left-b)",
91
+ ],
92
+ right: [
93
+ "![matcher-right-a](matcher-right-a)",
94
+ "![matcher-right-b](matcher-right-b)",
95
+ ],
96
+ labels: [
97
+ "![matcher-label-a](matcher-label-a)",
98
+ "![matcher-label-b](matcher-label-b)",
99
+ ],
100
+ orderMatters: false,
101
+ padding: true,
102
+ },
103
+ version: {major: 0, minor: 0},
104
+ },
105
+ "matrix 1": {
106
+ type: "matrix",
107
+ graded: true,
108
+ options: {
109
+ matrixBoardSize: [3, 3],
110
+ answers: [[]],
111
+ prefix: "![matrix-prefix-a](matrix-prefix-a) ![matrix-prefix-b](matrix-prefix-b)",
112
+ suffix: "![matrix-suffix-a](matrix-suffix-a) ![matrix-suffix-b](matrix-suffix-b)",
113
+ cursorPosition: [0, 0],
114
+ },
115
+ version: {major: 0, minor: 0},
116
+ },
117
+ "orderer 1": {
118
+ type: "orderer",
119
+ graded: true,
120
+ options: {
121
+ options: [
122
+ {content: "![orderer-correct-a](orderer-correct-a)"},
123
+ {content: "![orderer-correct-b](orderer-correct-b)"},
124
+ {content: "![orderer-other-a](orderer-other-a)"},
125
+ {content: "![orderer-other-b](orderer-other-b)"},
126
+ ],
127
+ correctOptions: [
128
+ {content: "![orderer-correct-a](orderer-correct-a)"},
129
+ {content: "![orderer-correct-b](orderer-correct-b)"},
130
+ ],
131
+ otherOptions: [
132
+ {content: "![orderer-other-a](orderer-other-a)"},
133
+ {content: "![orderer-other-b](orderer-other-b)"},
134
+ ],
135
+ height: "normal",
136
+ layout: "horizontal",
137
+ },
138
+ version: {major: 0, minor: 0},
139
+ },
140
+ "passage 1": {
141
+ type: "passage",
142
+ graded: true,
143
+ options: {
144
+ passageTitle:
145
+ "![passage-title-a](passage-title-a) ![passage-title-b](passage-title-b)",
146
+ passageText: "",
147
+ footnotes: "",
148
+ showLineNumbers: true,
149
+ },
150
+ version: {major: 0, minor: 0},
151
+ },
152
+ "radio 1": {
153
+ type: "radio",
154
+ graded: true,
155
+ options: {
156
+ choices: [
157
+ {
158
+ content:
159
+ "![radio-choice1-a](radio-choice1-a) ![radio-choice1-b](radio-choice1-b)",
160
+ },
161
+ {
162
+ content:
163
+ "![radio-choice2-a](radio-choice2-a) ![radio-choice2-b](radio-choice2-b)",
164
+ },
165
+ ],
166
+ randomize: false,
167
+ multipleSelect: false,
168
+ displayCount: null,
169
+ hasNoneOfTheAbove: false,
170
+ onePerLine: true,
171
+ deselectEnabled: false,
172
+ },
173
+ version: {major: 1, minor: 0},
174
+ },
175
+ "sorter 1": {
176
+ type: "sorter",
177
+ graded: true,
178
+ options: {
179
+ correct: [
180
+ "![sorter-correct-a](sorter-correct-a)",
181
+ "![sorter-correct-b](sorter-correct-b)",
182
+ "![sorter-correct-c](sorter-correct-c)",
183
+ ],
184
+ layout: "horizontal",
185
+ padding: true,
186
+ },
187
+ version: {major: 0, minor: 0},
188
+ },
189
+ "table 1": {
190
+ type: "table",
191
+ graded: true,
192
+ options: {
193
+ headers: [
194
+ "![table-header-a](table-header-a)",
195
+ "![table-header-b](table-header-b)",
196
+ "![table-header-c](table-header-c)",
197
+ ],
198
+ rows: 4,
199
+ columns: 3,
200
+ answers: [
201
+ ["", "", ""],
202
+ ["", "", ""],
203
+ ["", "", ""],
204
+ ["", "", ""],
205
+ ],
206
+ },
207
+ version: {major: 0, minor: 0},
208
+ },
209
+ "grapher 1": {
210
+ type: "grapher",
211
+ graded: true,
212
+ options: {
213
+ correct: {type: "linear", coords: null, asymptote: null},
214
+ availableTypes: ["linear"],
215
+ graph: {
216
+ editableSettings: ["graph", "snap", "image"],
217
+ range: [
218
+ [-10, 10],
219
+ [-10, 10],
220
+ ],
221
+ labels: ["x", "y"],
222
+ step: [1, 1],
223
+ gridStep: [1, 1],
224
+ snapStep: [1, 1],
225
+ valid: true,
226
+ backgroundImage: {
227
+ url: "grapher-a",
228
+ width: 32,
229
+ height: 32,
230
+ },
231
+ markings: "graph",
232
+ rulerLabel: "",
233
+ rulerTicks: 10,
234
+ showProtractor: false,
235
+ showRuler: false,
236
+ },
237
+ },
238
+ version: {major: 0, minor: 0},
239
+ },
240
+ "interactive-graph 1": {
241
+ type: "interactive-graph",
242
+ graded: true,
243
+ options: {
244
+ step: [1, 1],
245
+ backgroundImage: {
246
+ url: "interactive-graph-a",
247
+ width: 32,
248
+ height: 32,
249
+ },
250
+ markings: "graph",
251
+ labels: ["x", "y"],
252
+ showProtractor: false,
253
+ showRuler: false,
254
+ rulerLabel: "",
255
+ rulerTicks: 10,
256
+ range: [
257
+ [-10, 10],
258
+ [-10, 10],
259
+ ],
260
+ gridStep: [1, 1],
261
+ snapStep: [0.5, 0.5],
262
+ graph: {type: "linear"},
263
+ correct: {type: "linear", coords: null},
264
+ },
265
+ version: {major: 0, minor: 0},
266
+ },
267
+ "measurer 1": {
268
+ type: "measurer",
269
+ graded: true,
270
+ options: {
271
+ box: [480, 480],
272
+ image: {url: "measurer-a"},
273
+ showProtractor: true,
274
+ showRuler: false,
275
+ rulerLabel: "",
276
+ rulerTicks: 10,
277
+ rulerPixels: 40,
278
+ rulerLength: 10,
279
+ },
280
+ version: {major: 1, minor: 0},
281
+ },
282
+ "plotter 1": {
283
+ type: "plotter",
284
+ graded: true,
285
+ options: {
286
+ correct: [1, 1],
287
+ starting: [1, 1],
288
+ type: "pic",
289
+ labels: ["", ""],
290
+ categories: ["a", "a"],
291
+ scaleY: 1,
292
+ maxY: 10,
293
+ snapsPerLine: 2,
294
+ labelInterval: 1,
295
+ picUrl: "plotter-a",
296
+ },
297
+ version: {major: 0, minor: 0},
298
+ },
299
+ "transformer 1": {
300
+ type: "transformer",
301
+ graded: true,
302
+ options: {
303
+ starting: {
304
+ shape: {
305
+ type: "polygon-3",
306
+ coords: [
307
+ [2, 2],
308
+ [2, 6],
309
+ [7, 2],
310
+ ],
311
+ },
312
+ transformations: [],
313
+ },
314
+ graphMode: "interactive",
315
+ listMode: "dynamic",
316
+ tools: {
317
+ translation: {
318
+ enabled: true,
319
+ required: false,
320
+ constraints: {},
321
+ },
322
+ rotation: {
323
+ enabled: true,
324
+ required: false,
325
+ constraints: {fixed: false},
326
+ coord: [1, 6],
327
+ },
328
+ reflection: {
329
+ enabled: true,
330
+ required: false,
331
+ constraints: {fixed: false},
332
+ coords: [
333
+ [2, -4],
334
+ [2, 2],
335
+ ],
336
+ },
337
+ dilation: {
338
+ enabled: true,
339
+ required: false,
340
+ constraints: {fixed: false},
341
+ coord: [6, 6],
342
+ },
343
+ },
344
+ drawSolutionShape: true,
345
+ gradeEmpty: false,
346
+ graph: {
347
+ range: [
348
+ [-10, 10],
349
+ [-10, 10],
350
+ ],
351
+ step: [1, 1],
352
+ markings: "grid",
353
+ labels: ["x", "y"],
354
+ backgroundImage: {
355
+ url: "transformer-a",
356
+ width: 32,
357
+ height: 32,
358
+ },
359
+ showProtractor: false,
360
+ showRuler: false,
361
+ rulerLabel: "",
362
+ rulerTicks: 10,
363
+ gridStep: [1, 1],
364
+ snapStep: [0.5, 0.5],
365
+ },
366
+ version: 1.2,
367
+ correct: {
368
+ transformations: [],
369
+ shape: {
370
+ type: ["polygon-3"],
371
+ coords: [
372
+ [2, 2],
373
+ [2, 6],
374
+ [7, 2],
375
+ ],
376
+ options: [{}],
377
+ },
378
+ },
379
+ },
380
+ version: {major: 0, minor: 0},
381
+ },
382
+ },
383
+ },
384
+ answerArea: {calculator: false},
385
+ itemDataVersion: {major: 0, minor: 1},
386
+ hints: [
387
+ {
388
+ content:
389
+ "![hint1-a](hint1-a)\n\n![hint1-b](hint1-b)\n\n[[☃ image 1]]",
390
+ images: {},
391
+ widgets: {
392
+ "image 1": {
393
+ type: "image",
394
+ graded: true,
395
+ options: {
396
+ title: "![hint1-image-title-a](hint1-image-title-a) ![hint1-image-title-b](hint1-image-title-b)",
397
+ range: [
398
+ [0, 10],
399
+ [0, 10],
400
+ ],
401
+ box: [0, 0],
402
+ backgroundImage: {
403
+ url: "hint1-image-a",
404
+ width: 0,
405
+ height: 0,
406
+ },
407
+ labels: [],
408
+ alt: "",
409
+ caption:
410
+ "![hint1-image-caption-a](hint1-image-caption-a) ![hint1-image-caption-b](hint1-image-caption-b)",
411
+ },
412
+ version: {major: 0, minor: 0},
413
+ },
414
+ },
415
+ },
416
+ {
417
+ content:
418
+ "![hint2-a](hint2-a)\n\n![hint2-b](hint2-b)\n\n[[☃ image 1]]",
419
+ images: {},
420
+ widgets: {
421
+ "image 1": {
422
+ type: "image",
423
+ graded: true,
424
+ options: {
425
+ title: "![hint2-image-title-a](hint2-image-title-a) ![hint2-image-title-b](hint2-image-title-b)",
426
+ range: [
427
+ [0, 10],
428
+ [0, 10],
429
+ ],
430
+ box: [0, 0],
431
+ backgroundImage: {
432
+ url: "hint2-image-a",
433
+ width: 0,
434
+ height: 0,
435
+ },
436
+ labels: [],
437
+ alt: "",
438
+ caption:
439
+ "![hint2-image-caption-a](hint2-image-caption-a) ![hint2-image-caption-b](hint2-image-caption-b)",
440
+ },
441
+ version: {major: 0, minor: 0},
442
+ },
443
+ },
444
+ },
445
+ ],
446
+ };
447
+
448
+ // Article perseus format is very similar to exercises and should parse the
449
+ // same way, but should just be a list of renders. So we reuse the test data
450
+ // from exerciseImagesEverywhere, but include the question and hints as if they
451
+ // were paragraphs in the article.
452
+ const articleImagesEverywhere = [exerciseImagesEverywhere.question].concat(
453
+ exerciseImagesEverywhere.hints,
454
+ );
455
+
456
+ // All of the images that are in the `exerciseImagesEverywhere` item. Also the
457
+ // same list of images that are in the `articleImagesEverywhere` item.
458
+ const allImages = [
459
+ "question-a",
460
+ "question-b",
461
+ "category-category-a",
462
+ "category-category-b",
463
+ "category-item-a",
464
+ "category-item-b",
465
+ "group-a",
466
+ "group-b",
467
+ "group-image-title-a",
468
+ "group-image-title-b",
469
+ "group-image-a",
470
+ "group-image-caption-a",
471
+ "group-image-caption-b",
472
+ "image-title-a",
473
+ "image-title-b",
474
+ "image-a",
475
+ "image-caption-a",
476
+ "image-caption-b",
477
+ "matcher-label-a",
478
+ "matcher-label-b",
479
+ "matcher-left-a",
480
+ "matcher-left-b",
481
+ "matcher-right-a",
482
+ "matcher-right-b",
483
+ "matrix-prefix-a",
484
+ "matrix-prefix-b",
485
+ "matrix-suffix-a",
486
+ "matrix-suffix-b",
487
+ "orderer-correct-a",
488
+ "orderer-correct-b",
489
+ "orderer-other-a",
490
+ "orderer-other-b",
491
+ "passage-title-a",
492
+ "passage-title-b",
493
+ "radio-choice1-a",
494
+ "radio-choice1-b",
495
+ "radio-choice2-a",
496
+ "radio-choice2-b",
497
+ "sorter-correct-a",
498
+ "sorter-correct-b",
499
+ "sorter-correct-c",
500
+ "table-header-a",
501
+ "table-header-b",
502
+ "table-header-c",
503
+ "grapher-a",
504
+ "interactive-graph-a",
505
+ "measurer-a",
506
+ "plotter-a",
507
+ "transformer-a",
508
+ "hint1-a",
509
+ "hint1-a",
510
+ "hint1-image-title-a",
511
+ "hint1-image-title-b",
512
+ "hint1-image-a",
513
+ "hint1-image-caption-a",
514
+ "hint1-image-caption-b",
515
+ "hint2-a",
516
+ "hint2-a",
517
+ "hint2-image-title-a",
518
+ "hint2-image-title-b",
519
+ "hint2-image-a",
520
+ "hint2-image-caption-a",
521
+ "hint2-image-caption-b",
522
+ ];
523
+
524
+ describe("i18n", () => {
525
+ beforeAll(() => {
526
+ registerAllWidgetsAndEditorsForTesting();
527
+ });
528
+
529
+ beforeEach(() => {
530
+ jest.spyOn(Dependencies, "getDependencies").mockReturnValue(
531
+ testDependencies,
532
+ );
533
+ });
534
+
535
+ describe("Exercise image finding", () => {
536
+ it("should find all of the images in items", () => {
537
+ const foundImages = i18n.findImagesInItemData(
538
+ exerciseImagesEverywhere,
539
+ );
540
+
541
+ expect(foundImages.length <= allImages.length).toBeTruthy();
542
+
543
+ _.each(allImages, (image) => {
544
+ expect(foundImages.indexOf(image) !== -1).toBeTruthy();
545
+ });
546
+ });
547
+ });
548
+
549
+ describe("Article image finding", () => {
550
+ it("should find all of the images in items", () => {
551
+ const foundImages = i18n.findImagesInArticles(
552
+ articleImagesEverywhere,
553
+ );
554
+
555
+ expect(foundImages.length <= allImages.length).toBeTruthy();
556
+
557
+ _.each(allImages, (image) => {
558
+ expect(foundImages.indexOf(image) !== -1).toBeTruthy();
559
+ });
560
+ });
561
+ });
562
+
563
+ describe("Multi-item image finding", () => {
564
+ it("should find all of the images in each leaf node", () => {
565
+ const foundImages = i18n.findImagesInItemData({
566
+ _multi: {
567
+ question: {
568
+ __type: "content",
569
+ ...exerciseImagesEverywhere.question,
570
+ },
571
+ hints: exerciseImagesEverywhere.hints.map((hint) => ({
572
+ __type: "hint",
573
+ ...hint,
574
+ })),
575
+ },
576
+ });
577
+
578
+ expect(foundImages.length <= allImages.length).toBeTruthy();
579
+
580
+ _.each(allImages, (image) => {
581
+ expect(foundImages.indexOf(image) !== -1).toBeTruthy();
582
+ });
583
+ });
584
+ });
585
+ });