@longsightgroup/qti3-core 0.10.2 → 0.10.3

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 (119) hide show
  1. package/README.md +21 -2
  2. package/dist/attempt-state.d.ts.map +1 -1
  3. package/dist/attempt-state.js +18 -0
  4. package/dist/attempt-state.js.map +1 -1
  5. package/dist/content-text.d.ts +4 -0
  6. package/dist/content-text.d.ts.map +1 -1
  7. package/dist/content-text.js +112 -9
  8. package/dist/content-text.js.map +1 -1
  9. package/dist/index.d.ts +4 -0
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +4 -0
  12. package/dist/index.js.map +1 -1
  13. package/dist/media-definition.d.ts +55 -0
  14. package/dist/media-definition.d.ts.map +1 -0
  15. package/dist/media-definition.js +97 -0
  16. package/dist/media-definition.js.map +1 -0
  17. package/dist/parser-declarations.d.ts +4 -4
  18. package/dist/parser-declarations.d.ts.map +1 -1
  19. package/dist/parser-declarations.js +87 -46
  20. package/dist/parser-declarations.js.map +1 -1
  21. package/dist/parser-item-metadata.d.ts.map +1 -1
  22. package/dist/parser-item-metadata.js +4 -3
  23. package/dist/parser-item-metadata.js.map +1 -1
  24. package/dist/parser-processing.js +10 -9
  25. package/dist/parser-processing.js.map +1 -1
  26. package/dist/parser-values.d.ts +2 -0
  27. package/dist/parser-values.d.ts.map +1 -1
  28. package/dist/parser-values.js +7 -0
  29. package/dist/parser-values.js.map +1 -1
  30. package/dist/parser.js +16 -13
  31. package/dist/parser.js.map +1 -1
  32. package/dist/processing-evaluator-collection.d.ts.map +1 -1
  33. package/dist/processing-evaluator-collection.js +8 -2
  34. package/dist/processing-evaluator-collection.js.map +1 -1
  35. package/dist/processing-evaluator-comparison.d.ts.map +1 -1
  36. package/dist/processing-evaluator-comparison.js +6 -0
  37. package/dist/processing-evaluator-comparison.js.map +1 -1
  38. package/dist/processing-evaluator-numeric.d.ts.map +1 -1
  39. package/dist/processing-evaluator-numeric.js +8 -1
  40. package/dist/processing-evaluator-numeric.js.map +1 -1
  41. package/dist/processing-expression-children.d.ts.map +1 -1
  42. package/dist/processing-expression-children.js +2 -1
  43. package/dist/processing-expression-children.js.map +1 -1
  44. package/dist/processing-limits.d.ts +3 -0
  45. package/dist/processing-limits.d.ts.map +1 -0
  46. package/dist/processing-limits.js +3 -0
  47. package/dist/processing-limits.js.map +1 -0
  48. package/dist/processing-mapping.d.ts.map +1 -1
  49. package/dist/processing-mapping.js +13 -2
  50. package/dist/processing-mapping.js.map +1 -1
  51. package/dist/processing-operators.d.ts +2 -0
  52. package/dist/processing-operators.d.ts.map +1 -1
  53. package/dist/processing-operators.js +34 -5
  54. package/dist/processing-operators.js.map +1 -1
  55. package/dist/response-validation-policy.d.ts.map +1 -1
  56. package/dist/response-validation-policy.js +5 -6
  57. package/dist/response-validation-policy.js.map +1 -1
  58. package/dist/serializer-processing-expressions.js +1 -1
  59. package/dist/serializer-processing-expressions.js.map +1 -1
  60. package/dist/slider-definition.d.ts +59 -0
  61. package/dist/slider-definition.d.ts.map +1 -0
  62. package/dist/slider-definition.js +198 -0
  63. package/dist/slider-definition.js.map +1 -0
  64. package/dist/support-evidence.d.ts +6 -2
  65. package/dist/support-evidence.d.ts.map +1 -1
  66. package/dist/support-evidence.js +15 -11
  67. package/dist/support-evidence.js.map +1 -1
  68. package/dist/support.d.ts.map +1 -1
  69. package/dist/support.js +96 -100
  70. package/dist/support.js.map +1 -1
  71. package/dist/types.d.ts +3 -0
  72. package/dist/types.d.ts.map +1 -1
  73. package/dist/validation-declaration-entries.d.ts +13 -0
  74. package/dist/validation-declaration-entries.d.ts.map +1 -0
  75. package/dist/validation-declaration-entries.js +136 -0
  76. package/dist/validation-declaration-entries.js.map +1 -0
  77. package/dist/validation-interactions.d.ts.map +1 -1
  78. package/dist/validation-interactions.js +14 -46
  79. package/dist/validation-interactions.js.map +1 -1
  80. package/dist/validation-primitives.js +2 -2
  81. package/dist/validation-primitives.js.map +1 -1
  82. package/dist/validation-processing.d.ts.map +1 -1
  83. package/dist/validation-processing.js +125 -1
  84. package/dist/validation-processing.js.map +1 -1
  85. package/dist/validation.d.ts.map +1 -1
  86. package/dist/validation.js +8 -134
  87. package/dist/validation.js.map +1 -1
  88. package/dist/xml.d.ts.map +1 -1
  89. package/dist/xml.js +3 -2
  90. package/dist/xml.js.map +1 -1
  91. package/package.json +1 -1
  92. package/src/attempt-state.ts +20 -0
  93. package/src/content-text.ts +135 -11
  94. package/src/index.ts +25 -0
  95. package/src/media-definition.ts +174 -0
  96. package/src/parser-declarations.ts +134 -40
  97. package/src/parser-item-metadata.ts +4 -3
  98. package/src/parser-processing.ts +10 -9
  99. package/src/parser-values.ts +7 -0
  100. package/src/parser.ts +16 -13
  101. package/src/processing-evaluator-collection.ts +7 -2
  102. package/src/processing-evaluator-comparison.ts +6 -0
  103. package/src/processing-evaluator-numeric.ts +5 -1
  104. package/src/processing-expression-children.ts +2 -1
  105. package/src/processing-limits.ts +2 -0
  106. package/src/processing-mapping.ts +10 -2
  107. package/src/processing-operators.ts +38 -5
  108. package/src/response-validation-policy.ts +5 -5
  109. package/src/serializer-processing-expressions.ts +1 -1
  110. package/src/slider-definition.ts +363 -0
  111. package/src/support-evidence.ts +15 -17
  112. package/src/support.ts +106 -102
  113. package/src/types.ts +8 -1
  114. package/src/validation-declaration-entries.ts +162 -0
  115. package/src/validation-interactions.ts +14 -64
  116. package/src/validation-primitives.ts +2 -2
  117. package/src/validation-processing.ts +145 -1
  118. package/src/validation.ts +11 -151
  119. package/src/xml.ts +3 -4
@@ -0,0 +1,363 @@
1
+ import { parseXmlBoolean } from "./parser-values.js";
2
+ import type { QtiDiagnostic, QtiInteraction } from "./types.js";
3
+
4
+ declare const qtiSliderDefinitionBrand: unique symbol;
5
+
6
+ /** The axis used to present a refined QTI slider interaction. */
7
+ export type QtiSliderOrientation = "horizontal" | "vertical";
8
+
9
+ /** The movement policy and interval shape for a refined QTI slider interaction. */
10
+ export type QtiSliderStep =
11
+ | { readonly kind: "continuous" }
12
+ | {
13
+ readonly kind: "aligned";
14
+ readonly value: number;
15
+ readonly intervalCount: number;
16
+ }
17
+ | {
18
+ readonly kind: "detachedUpper";
19
+ readonly value: number;
20
+ readonly regularIntervalCount: number;
21
+ };
22
+
23
+ /** A validated slider value domain and presentation policy. */
24
+ export interface QtiSliderDefinition {
25
+ readonly [qtiSliderDefinitionBrand]: true;
26
+ readonly lowerBound: number;
27
+ readonly upperBound: number;
28
+ readonly step: QtiSliderStep;
29
+ readonly orientation: QtiSliderOrientation;
30
+ readonly reverse: boolean;
31
+ readonly stepLabels: boolean;
32
+ readonly responseBaseType: "integer" | "float";
33
+ }
34
+
35
+ /** The typed result of refining raw slider interaction attributes. */
36
+ export type QtiSliderDefinitionResult =
37
+ | { readonly ok: true; readonly value: QtiSliderDefinition }
38
+ | { readonly ok: false; readonly diagnostics: readonly QtiDiagnostic[] };
39
+
40
+ /** The reason a candidate value does not belong to a refined slider domain. */
41
+ export type QtiSliderValueFailureReason =
42
+ | "notNumeric"
43
+ | "notInteger"
44
+ | "outsideBounds"
45
+ | "outsideStepSequence";
46
+
47
+ /** The typed result of parsing a candidate value against a refined slider domain. */
48
+ export type QtiSliderValueResult =
49
+ | { readonly ok: true; readonly value: number }
50
+ | { readonly ok: false; readonly reason: QtiSliderValueFailureReason };
51
+
52
+ type ParsedSliderStep =
53
+ | { readonly kind: "continuous" }
54
+ | { readonly kind: "discrete"; readonly value: number };
55
+
56
+ const MAX_REGULAR_INTERVAL_COUNT = Number.MAX_SAFE_INTEGER - 2;
57
+
58
+ function diagnostic(interaction: QtiInteraction, code: string, message: string): QtiDiagnostic {
59
+ return {
60
+ code,
61
+ severity: "error",
62
+ message,
63
+ path: interaction.source?.path,
64
+ source: interaction.source,
65
+ };
66
+ }
67
+
68
+ function clamp(value: number, minimum: number, maximum: number): number {
69
+ return Math.max(minimum, Math.min(maximum, value));
70
+ }
71
+
72
+ function decimalPlaces(value: number): number {
73
+ const [coefficient = "", exponentText] = String(value).toLowerCase().split("e");
74
+ const fractionLength = coefficient.split(".")[1]?.length ?? 0;
75
+ const exponent = Number(exponentText ?? "0");
76
+ return Math.max(0, fractionLength - exponent);
77
+ }
78
+
79
+ function steppedValue(lowerBound: number, step: number, index: number): number {
80
+ const value = lowerBound + index * step;
81
+ if (value === 0) return 0;
82
+ const decimalPrecision = Math.max(decimalPlaces(lowerBound), decimalPlaces(step));
83
+ const integerDigits = Math.floor(Math.log10(Math.abs(value))) + 1;
84
+ const significantDigits = Math.min(100, Math.max(1, integerDigits + decimalPrecision));
85
+ return Number(value.toPrecision(significantDigits));
86
+ }
87
+
88
+ function discreteStep(
89
+ interaction: QtiInteraction,
90
+ lowerBound: number,
91
+ upperBound: number,
92
+ step: number,
93
+ diagnostics: QtiDiagnostic[],
94
+ ): QtiSliderStep | undefined {
95
+ const intervalRatio = (upperBound - lowerBound) / step;
96
+ const nearestInteger = Math.round(intervalRatio);
97
+ const canTestAlignedUpper =
98
+ Number.isSafeInteger(nearestInteger) && nearestInteger <= MAX_REGULAR_INTERVAL_COUNT;
99
+ const alignedUpper =
100
+ canTestAlignedUpper && steppedValue(lowerBound, step, nearestInteger) === upperBound;
101
+ const regularIntervalCount = alignedUpper ? nearestInteger : Math.floor(intervalRatio);
102
+ if (
103
+ !Number.isSafeInteger(regularIntervalCount) ||
104
+ regularIntervalCount > MAX_REGULAR_INTERVAL_COUNT ||
105
+ (regularIntervalCount > 0 && steppedValue(lowerBound, step, 1) === lowerBound)
106
+ ) {
107
+ diagnostics.push(
108
+ diagnostic(
109
+ interaction,
110
+ "interaction.slider.resolution",
111
+ `${interaction.qtiName} step ${step} cannot be represented safely across bounds ${lowerBound} to ${upperBound}.`,
112
+ ),
113
+ );
114
+ return undefined;
115
+ }
116
+ if (alignedUpper) {
117
+ return { kind: "aligned", value: step, intervalCount: regularIntervalCount };
118
+ }
119
+ return { kind: "detachedUpper", value: step, regularIntervalCount };
120
+ }
121
+
122
+ function requiredNumber(
123
+ interaction: QtiInteraction,
124
+ attribute: "lower-bound" | "upper-bound",
125
+ missingCode: string,
126
+ diagnostics: QtiDiagnostic[],
127
+ ): number | undefined {
128
+ const raw = interaction.attributes[attribute];
129
+ if (raw === undefined || raw.trim() === "") {
130
+ diagnostics.push(
131
+ diagnostic(interaction, missingCode, `${interaction.qtiName} requires ${attribute}.`),
132
+ );
133
+ return undefined;
134
+ }
135
+
136
+ const value = Number(raw);
137
+ if (!Number.isFinite(value) || value < 0) {
138
+ diagnostics.push(
139
+ diagnostic(
140
+ interaction,
141
+ "interaction.numericAttribute",
142
+ `${interaction.qtiName} requires non-negative numeric ${attribute}, got ${raw}.`,
143
+ ),
144
+ );
145
+ return undefined;
146
+ }
147
+ return value;
148
+ }
149
+
150
+ function optionalBoolean(
151
+ interaction: QtiInteraction,
152
+ attribute: "reverse" | "step-label",
153
+ diagnostics: QtiDiagnostic[],
154
+ ): boolean {
155
+ const raw = interaction.attributes[attribute];
156
+ if (raw === undefined) return false;
157
+ const value = parseXmlBoolean(raw);
158
+ if (value !== undefined) return value;
159
+ diagnostics.push(
160
+ diagnostic(
161
+ interaction,
162
+ "interaction.booleanAttribute",
163
+ `${interaction.qtiName} requires boolean ${attribute}, got ${raw}.`,
164
+ ),
165
+ );
166
+ return false;
167
+ }
168
+
169
+ function sliderOrientation(
170
+ interaction: QtiInteraction,
171
+ diagnostics: QtiDiagnostic[],
172
+ ): QtiSliderOrientation {
173
+ const raw = interaction.attributes.orientation;
174
+ if (raw === undefined || raw === "horizontal") return "horizontal";
175
+ if (raw === "vertical") return "vertical";
176
+ diagnostics.push(
177
+ diagnostic(
178
+ interaction,
179
+ "interaction.slider.orientation",
180
+ `${interaction.qtiName} requires horizontal or vertical orientation, got ${raw}.`,
181
+ ),
182
+ );
183
+ return "horizontal";
184
+ }
185
+
186
+ function sliderStep(
187
+ interaction: QtiInteraction,
188
+ responseBaseType: "integer" | "float" | undefined,
189
+ diagnostics: QtiDiagnostic[],
190
+ ): ParsedSliderStep | undefined {
191
+ const raw = interaction.attributes.step;
192
+ if (raw === undefined) {
193
+ if (responseBaseType === "float") return { kind: "continuous" };
194
+ if (responseBaseType === "integer") return { kind: "discrete", value: 1 };
195
+ return undefined;
196
+ }
197
+
198
+ const value = Number(raw);
199
+ if (!Number.isFinite(value) || value <= 0) {
200
+ diagnostics.push(
201
+ diagnostic(
202
+ interaction,
203
+ "interaction.numericAttribute",
204
+ `${interaction.qtiName} requires positive numeric step, got ${raw}.`,
205
+ ),
206
+ );
207
+ return undefined;
208
+ }
209
+ if (responseBaseType === "integer" && !Number.isInteger(value)) {
210
+ diagnostics.push(
211
+ diagnostic(
212
+ interaction,
213
+ "interaction.slider.integerStep",
214
+ `${interaction.qtiName} requires an integer step when its response has integer base type, got ${raw}.`,
215
+ ),
216
+ );
217
+ }
218
+ return { kind: "discrete", value };
219
+ }
220
+
221
+ function sliderResponseBaseType(
222
+ interaction: QtiInteraction,
223
+ diagnostics: QtiDiagnostic[],
224
+ ): "integer" | "float" | undefined {
225
+ const baseType = interaction.responseBaseType;
226
+ if (baseType === "integer" || baseType === "float") return baseType;
227
+ diagnostics.push(
228
+ diagnostic(
229
+ interaction,
230
+ "interaction.baseType",
231
+ baseType === undefined
232
+ ? `${interaction.qtiName} requires an integer or float response base type.`
233
+ : `${interaction.qtiName} expects integer or float base type, got ${baseType}.`,
234
+ ),
235
+ );
236
+ return undefined;
237
+ }
238
+
239
+ /**
240
+ * Refines raw QTI slider attributes into the single value model shared by validation and players.
241
+ */
242
+ export function parseQtiSliderDefinition(interaction: QtiInteraction): QtiSliderDefinitionResult {
243
+ const diagnostics: QtiDiagnostic[] = [];
244
+ const lower = requiredNumber(
245
+ interaction,
246
+ "lower-bound",
247
+ "interaction.slider.lowerBound",
248
+ diagnostics,
249
+ );
250
+ const upper = requiredNumber(
251
+ interaction,
252
+ "upper-bound",
253
+ "interaction.slider.upperBound",
254
+ diagnostics,
255
+ );
256
+ const orientation = sliderOrientation(interaction, diagnostics);
257
+ const reverse = optionalBoolean(interaction, "reverse", diagnostics);
258
+ const stepLabels = optionalBoolean(interaction, "step-label", diagnostics);
259
+ const sliderBaseType = sliderResponseBaseType(interaction, diagnostics);
260
+ const parsedStep = sliderStep(interaction, sliderBaseType, diagnostics);
261
+
262
+ if (lower !== undefined && upper !== undefined && lower >= upper) {
263
+ diagnostics.push(
264
+ diagnostic(
265
+ interaction,
266
+ "interaction.slider.bounds",
267
+ `${interaction.qtiName} requires lower-bound to be less than upper-bound.`,
268
+ ),
269
+ );
270
+ }
271
+ if (
272
+ diagnostics.length > 0 ||
273
+ lower === undefined ||
274
+ upper === undefined ||
275
+ parsedStep === undefined ||
276
+ sliderBaseType === undefined
277
+ ) {
278
+ return { ok: false, diagnostics };
279
+ }
280
+
281
+ const lowerBound = sliderBaseType === "integer" ? Math.floor(lower) : lower;
282
+ const upperBound = sliderBaseType === "integer" ? Math.ceil(upper) : upper;
283
+ const step =
284
+ parsedStep.kind === "continuous"
285
+ ? parsedStep
286
+ : discreteStep(interaction, lowerBound, upperBound, parsedStep.value, diagnostics);
287
+ if (step === undefined) return { ok: false, diagnostics };
288
+ const definition = {
289
+ lowerBound,
290
+ upperBound,
291
+ step,
292
+ orientation,
293
+ reverse,
294
+ stepLabels,
295
+ responseBaseType: sliderBaseType,
296
+ };
297
+ // SAFETY: every slider invariant is established above before the definition is branded.
298
+ // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- SAFETY: callers cannot create the brand directly.
299
+ return { ok: true, value: definition as QtiSliderDefinition };
300
+ }
301
+
302
+ /** Returns the normalized position of a slider value between the authored bounds. */
303
+ export function qtiSliderRatio(value: number, definition: QtiSliderDefinition): number {
304
+ return clamp(
305
+ (value - definition.lowerBound) / (definition.upperBound - definition.lowerBound),
306
+ 0,
307
+ 1,
308
+ );
309
+ }
310
+
311
+ /** Returns the discrete value at a regular step index, or the lower bound for a continuous slider. */
312
+ export function qtiSliderDiscreteValue(definition: QtiSliderDefinition, index: number): number {
313
+ if (definition.step.kind === "continuous") return definition.lowerBound;
314
+ if (definition.step.kind === "aligned" && index === definition.step.intervalCount) {
315
+ return definition.upperBound;
316
+ }
317
+ return steppedValue(definition.lowerBound, definition.step.value, index);
318
+ }
319
+
320
+ /** Snaps a raw value to the closest authored slider value. */
321
+ export function snapQtiSliderValue(value: number, definition: QtiSliderDefinition): number {
322
+ const clampedValue = clamp(value, definition.lowerBound, definition.upperBound);
323
+ if (definition.step.kind === "continuous") return clampedValue;
324
+
325
+ const regularIntervalCount =
326
+ definition.step.kind === "aligned"
327
+ ? definition.step.intervalCount
328
+ : definition.step.regularIntervalCount;
329
+ const regularIndex = clamp(
330
+ Math.round((clampedValue - definition.lowerBound) / definition.step.value),
331
+ 0,
332
+ regularIntervalCount,
333
+ );
334
+ const regularValue = qtiSliderDiscreteValue(definition, regularIndex);
335
+ if (definition.step.kind === "aligned") return regularValue;
336
+ return Math.abs(definition.upperBound - clampedValue) < Math.abs(regularValue - clampedValue)
337
+ ? definition.upperBound
338
+ : regularValue;
339
+ }
340
+
341
+ /** Parses an unknown candidate value against a refined QTI slider domain. */
342
+ export function parseQtiSliderValue(
343
+ input: unknown,
344
+ definition: QtiSliderDefinition,
345
+ ): QtiSliderValueResult {
346
+ const value =
347
+ typeof input === "number"
348
+ ? input
349
+ : typeof input === "string" && input.trim() !== ""
350
+ ? Number(input)
351
+ : Number.NaN;
352
+ if (!Number.isFinite(value)) return { ok: false, reason: "notNumeric" };
353
+ if (definition.responseBaseType === "integer" && !Number.isInteger(value)) {
354
+ return { ok: false, reason: "notInteger" };
355
+ }
356
+ if (value < definition.lowerBound || value > definition.upperBound) {
357
+ return { ok: false, reason: "outsideBounds" };
358
+ }
359
+ if (definition.step.kind !== "continuous" && snapQtiSliderValue(value, definition) !== value) {
360
+ return { ok: false, reason: "outsideStepSequence" };
361
+ }
362
+ return { ok: true, value };
363
+ }
@@ -1,6 +1,11 @@
1
1
  import type { QtiInteractionType } from "./types.js";
2
2
 
3
- const coreProcessingTest = "packages/core/src/core.test.ts";
3
+ export const coreIntegrationTest = "packages/core/src/core.test.ts";
4
+ export const coreSessionStateTest = "packages/core/src/core-session-state.test.ts";
5
+ export const processingResponseTest = "packages/core/src/processing-response.test.ts";
6
+ export const processingTemplateTest = "packages/core/src/processing-template.test.ts";
7
+ export const processingOperatorsTest = "packages/core/src/processing-operators.test.ts";
8
+ export const processingMappingTest = "packages/core/src/processing-mapping.test.ts";
4
9
 
5
10
  export const browserProcessingTests = ["tests/browser/player-processing.spec.ts"];
6
11
  export const browserFeedbackTests = ["tests/browser/player-feedback.spec.ts"];
@@ -30,8 +35,6 @@ export const processingBrowserEvidence = {
30
35
  "qti-random-integer": randomIntegerBrowserEvidence,
31
36
  } as const satisfies Record<string, readonly string[]>;
32
37
 
33
- export type ProcessingBrowserEvidenceName = keyof typeof processingBrowserEvidence;
34
-
35
38
  export const interactionExtraFixtures: Partial<Record<QtiInteractionType, readonly string[]>> = {
36
39
  extendedText: [
37
40
  "packages/fixtures/packages/sv-matrix/items/extended-text-pattern-mask.xml",
@@ -72,7 +75,12 @@ export function browserTestsFor(interactionType: QtiInteractionType): string[] {
72
75
  portableCustom: ["tests/browser/player-portable-custom.spec.ts"],
73
76
  positionObject: ["tests/browser/player-graphic.spec.ts", ...browserKeyboardA11yTests],
74
77
  selectPoint: ["tests/browser/player-graphic.spec.ts"],
75
- slider: browserKeyboardA11yTests,
78
+ slider: [
79
+ "tests/browser/player-dom-behavior.spec.ts",
80
+ "tests/browser/player-slider.spec.ts",
81
+ "tests/browser/player-slider-cross-browser.spec.ts",
82
+ ...browserKeyboardA11yTests,
83
+ ],
76
84
  textEntry: ["tests/browser/player-dom-behavior.spec.ts"],
77
85
  upload: ["tests/browser/player-dom-behavior.spec.ts"],
78
86
  };
@@ -90,18 +98,8 @@ export function interactionSupportTests(interactionType: QtiInteractionType): st
90
98
  if (interactionType === "extendedText" || interactionType === "textEntry") {
91
99
  return [...browserTestsFor(interactionType), "packages/core/src/pattern-mask.test.ts"];
92
100
  }
93
- return browserTestsFor(interactionType);
94
- }
95
-
96
- function isProcessingBrowserEvidenceName(
97
- qtiName: string,
98
- ): qtiName is ProcessingBrowserEvidenceName {
99
- return Object.hasOwn(processingBrowserEvidence, qtiName);
100
- }
101
-
102
- export function processingSupportTests(qtiName: string): string[] {
103
- if (!isProcessingBrowserEvidenceName(qtiName)) {
104
- return [coreProcessingTest];
101
+ if (interactionType === "media") {
102
+ return [...browserTestsFor(interactionType), "packages/core/src/media-definition.test.ts"];
105
103
  }
106
- return [coreProcessingTest, ...processingBrowserEvidence[qtiName]];
104
+ return browserTestsFor(interactionType);
107
105
  }