Skip to content

Commit e5129be

Browse files
authored
Merge pull request #837 from Speech-Rule-Engine/tests/work_tests
Tests/work tests
2 parents 2add0b1 + fd12dc3 commit e5129be

File tree

9 files changed

+243
-57
lines changed

9 files changed

+243
-57
lines changed

testsuite/expected/base/api_test.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@
400400
},
401401
"SpeechStructure_1": {
402402
"type": "toSpeechStructure",
403-
"input": "<math xmlns=\"http://www.w3.org/1998/Math/MathML\" display=\"block\"><msup data-semantic-type=\"superscript\" data-semantic-role=\"latinletter\" data-semantic-annotation=\"depth:1\" data-semantic-id=\"2\" data-semantic-children=\"0,1\"><mi data-semantic-type=\"identifier\" data-semantic-role=\"latinletter\" data-semantic-font=\"italic\" data-semantic-annotation=\"clearspeak:simple;nemeth:number;depth:2\" data-semantic-id=\"0\" data-semantic-parent=\"2\">x</mi><mn data-semantic-type=\"number\" data-semantic-role=\"integer\" data-semantic-font=\"normal\" data-semantic-annotation=\"clearspeak:simple;depth:2\" data-semantic-id=\"1\" data-semantic-parent=\"2\">2</mn></msup></math>",
403+
"input": "square",
404404
"expected": "{\"0\":{\"speech-none\":\"x\",\"prefix-none\":\"Base\",\"postfix-none\":\"\",\"summary-none\":\"identifier\",\"speech-ssml\":\"<say-as interpret-as=\\\"character\\\">x</say-as>\",\"prefix-ssml\":\"Base\",\"postfix-ssml\":\"\",\"summary-ssml\":\"identifier\"},\"1\":{\"speech-none\":\"2\",\"prefix-none\":\"Exponent\",\"postfix-none\":\"\",\"summary-none\":\"number\",\"speech-ssml\":\"2\",\"prefix-ssml\":\"Exponent\",\"postfix-ssml\":\"\",\"summary-ssml\":\"number\"},\"2\":{\"speech-none\":\"x squared\",\"prefix-none\":\"\",\"postfix-none\":\"\",\"summary-none\":\"power\",\"speech-ssml\":\"<say-as interpret-as=\\\"character\\\">x</say-as> squared\",\"prefix-ssml\":\"\",\"postfix-ssml\":\"\",\"summary-ssml\":\"power\"}}",
405405
"json": true
406406
}

testsuite/expected/base/worker_test.json

Lines changed: 61 additions & 0 deletions
Large diffs are not rendered by default.

testsuite/ts/classes/api_test.ts

Lines changed: 156 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,83 @@ import { Key } from './keycodes.js';
2929
import { AbstractJsonTest } from './abstract_test.js';
3030
import { jest, expect } from '@jest/globals';
3131

32+
enum Expression {
33+
Quadratic = 'quadratic',
34+
Square = 'square',
35+
Maction = 'maction',
36+
Href = 'href'
37+
}
38+
39+
const Samples: Record<Expression, string> = {
40+
[Expression.Quadratic]:
41+
'<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">' +
42+
'<mi>x</mi>' +
43+
'<mo>=</mo>' +
44+
'<mfrac>' +
45+
'<mrow>' +
46+
'<mo>&#x2212;<!-- − --></mo>' +
47+
'<mi>b</mi>' +
48+
'<mo>&#x00B1;<!-- ± --></mo>' +
49+
'<msqrt>' +
50+
'<msup>' +
51+
'<mi>b</mi>' +
52+
'<mn>2</mn>' +
53+
'</msup>' +
54+
'<mo>&#x2212;<!-- − --></mo>' +
55+
'<mn>4</mn>' +
56+
'<mi>a</mi>' +
57+
'<mi>c</mi>' +
58+
'</msqrt>' +
59+
'</mrow>' +
60+
'<mrow>' +
61+
'<mn>2</mn>' +
62+
'<mi>a</mi>' +
63+
'</mrow>' +
64+
'</mfrac>' +
65+
'</math>',
66+
[Expression.Square]:
67+
'<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">' +
68+
'<msup>' +
69+
'<mi>x</mi>' +
70+
'<mn>2</mn>' +
71+
'</msup>' +
72+
'</math>',
73+
[Expression.Maction]:
74+
'<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">' +
75+
'<maction actiontype="toggle" selection="2" data-collapsible="true" id="mjx-collapse-0">' +
76+
'<mtext>&#x25C2;f()&#x25B8;</mtext>' +
77+
'<mrow>' +
78+
'<mi>f</mi>' +
79+
'<mo>&#x2061;</mo>' +
80+
'<maction actiontype="toggle" selection="2" data-collapsible="true" id="mjx-collapse-1">' +
81+
'<mtext>&#x25C2;()&#x25B8;</mtext>' +
82+
'<mrow>' +
83+
'<mo stretchy="false">(</mo>' +
84+
'<mrow>' +
85+
'<mi>a</mi>' +
86+
'<mo>+</mo>' +
87+
'<mi>b</mi>' +
88+
'<mo>+</mo>' +
89+
'<mi>c</mi>' +
90+
'<mo>+</mo>' +
91+
'<mi>d</mi>' +
92+
'</mrow>' +
93+
'<mo stretchy="false">)</mo>' +
94+
'</mrow>' +
95+
'</maction>' +
96+
'</mrow>' +
97+
'</maction>' +
98+
'</math>',
99+
[Expression.Href]:
100+
'<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">' +
101+
'<mrow href="c">' +
102+
'<mi href="a">a</mi>' +
103+
'<mo>+</mo>' +
104+
'<mi href="b">b</mi>' +
105+
'</mrow>' +
106+
'</math>'
107+
}
108+
32109
export class ApiTest extends AbstractJsonTest {
33110
/**
34111
* Feature vector for setting up the engine.
@@ -40,12 +117,6 @@ export class ApiTest extends AbstractJsonTest {
40117
speech: EngineConst.Speech.NONE
41118
};
42119

43-
/**
44-
* The quadratic equation as a MathML string. By default tests are run against
45-
* the quadratic equation unless a different input is provided.
46-
*/
47-
public static QUADRATIC: string;
48-
49120
/**
50121
* @override
51122
*/
@@ -66,6 +137,19 @@ export class ApiTest extends AbstractJsonTest {
66137
});
67138
}
68139

140+
/**
141+
* The sample equations.
142+
*/
143+
protected static SAMPLES: Record<Expression, string> = Samples;
144+
145+
/*
146+
* Quadratic equation as a MathML string. By default tests are run against
147+
* the quadratic equation unless a different input is provided.
148+
*/
149+
protected getSample(expr: Expression) {
150+
return ApiTest.SAMPLES[expr] || ApiTest.SAMPLES[Expression.Quadratic];
151+
}
152+
69153
/**
70154
* Executes single API tests.
71155
*
@@ -78,14 +162,14 @@ export class ApiTest extends AbstractJsonTest {
78162
*/
79163
public executeTest(
80164
func: string,
81-
expr: any,
165+
input: any,
82166
result: string | null,
83167
feature: { [key: string]: string },
84168
json: boolean,
85169
move: boolean
86170
) {
87171
System.setupEngine(feature || ApiTest.SETUP);
88-
expr = move ? Key.get(expr) : expr || ApiTest.QUADRATIC;
172+
const expr = move ? Key.get(input) : this.getSample(input);
89173
let output = (System as any)[func](expr);
90174
output = output
91175
? json
@@ -98,8 +182,8 @@ export class ApiTest extends AbstractJsonTest {
98182
/**
99183
* @override
100184
*/
101-
public method() {
102-
this.executeTest(
185+
public async method() {
186+
await this.executeTest(
103187
this.field('type'),
104188
this.field('input'),
105189
this.field('expected'),
@@ -110,32 +194,53 @@ export class ApiTest extends AbstractJsonTest {
110194
}
111195
}
112196

113-
ApiTest.QUADRATIC =
114-
'<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">' +
115-
'<mi>x</mi>' +
116-
'<mo>=</mo>' +
117-
'<mfrac>' +
118-
'<mrow>' +
119-
'<mo>&#x2212;<!-- − --></mo>' +
120-
'<mi>b</mi>' +
121-
'<mo>&#x00B1;<!-- ± --></mo>' +
122-
'<msqrt>' +
123-
'<msup>' +
124-
'<mi>b</mi>' +
125-
'<mn>2</mn>' +
126-
'</msup>' +
127-
'<mo>&#x2212;<!-- − --></mo>' +
128-
'<mn>4</mn>' +
129-
'<mi>a</mi>' +
130-
'<mi>c</mi>' +
131-
'</msqrt>' +
132-
'</mrow>' +
133-
'<mrow>' +
134-
'<mn>2</mn>' +
135-
'<mi>a</mi>' +
136-
'</mrow>' +
137-
'</mfrac>' +
138-
'</math>';
197+
import { semanticMathmlSync } from '#js/enrich_mathml/enrich.js';
198+
199+
export class WorkerTest extends ApiTest {
200+
201+
/**
202+
* Executes single API tests.
203+
*
204+
* @param func The API function to test.
205+
* @param expr The input expression.
206+
* @param result The expected result.
207+
* @param feature Feature vector for engine setup.
208+
* @param json Json output expected?
209+
* @param move Is this a move with some keyboard input?
210+
*/
211+
public async executeTest(
212+
func: string,
213+
input: Expression,
214+
result: string | null,
215+
feature: { [key: string]: string },
216+
json: boolean,
217+
_move: boolean
218+
) {
219+
const sample = this.getSample(input);
220+
const options = Object.assign({}, feature, ApiTest.SETUP);
221+
await System.setupEngine(options);
222+
const sxml = semanticMathmlSync(sample, options as any);
223+
let promise = (System as any)[func](sxml.toString(), options);
224+
promise.catch((err: Error) => console.log(`THIS PROMISE ERROR: ${err}`));
225+
let output = await promise;
226+
output = output
227+
? json
228+
? JSON.stringify(output)
229+
: output.toString()
230+
: output;
231+
this.assert.equal(output, result);
232+
}
233+
234+
/**
235+
* @override
236+
*/
237+
public async setUpTest() {
238+
ApiTest.SETUP['locale'] = 'en';
239+
ApiTest.SETUP['braille'] = 'nemeth';
240+
return super.setUpTest();
241+
}
242+
243+
}
139244

140245

141246
export class DebugTest extends ApiTest {
@@ -145,16 +250,18 @@ export class DebugTest extends ApiTest {
145250
*/
146251
public information = 'Debugger test.';
147252

148-
253+
private oldDebug: boolean | string = null;
254+
149255
constructor() {
150256
super();
151257
this.pickFields.push('strings');
152258
}
153-
259+
154260
/**
155261
* @override
156262
*/
157263
public async setUpTest() {
264+
this.oldDebug = ApiTest.SETUP['debug'] ?? null;
158265
ApiTest.SETUP['debug'] = true;
159266
jest.clearAllMocks();
160267
return super.setUpTest();
@@ -164,7 +271,11 @@ export class DebugTest extends ApiTest {
164271
* @override
165272
*/
166273
public async tearDownTest(): Promise<string> {
167-
ApiTest.SETUP['debug'] = false;
274+
if (this.oldDebug === null) {
275+
delete ApiTest.SETUP['debug'];
276+
} else {
277+
ApiTest.SETUP['debug'] = this.oldDebug;
278+
}
168279
jest.clearAllMocks();
169280
return super.tearDownTest();
170281
}
@@ -174,21 +285,21 @@ export class DebugTest extends ApiTest {
174285
*/
175286
public async executeTest(
176287
func: string,
177-
expr: any,
288+
input: string,
178289
result: string,
179290
feature: { [key: string]: string },
180291
_json: boolean,
181-
move: boolean
292+
_move: boolean
182293
) {
183294
await System.setupEngine(feature || ApiTest.SETUP);
184-
expr = move ? Key.get(expr) : expr || ApiTest.QUADRATIC;
185295
console.info = jest.fn();
186-
await (System as any)[func](expr);
296+
await (System as any)[func](input);
187297
expect(console.info).toHaveBeenCalledTimes(parseInt(result, 10));
188298
const strings = Object.entries(this.field('strings') as null | { [key: string]: string[]});
189299
for (let [index, res] of strings) {
190-
expect(console.info).toHaveBeenNthCalledWith(parseInt(index, 10), "Speech Rule Engine Debugger:", ...res);
300+
expect(console.info).
301+
toHaveBeenNthCalledWith(parseInt(index, 10), "Speech Rule Engine Debugger:", ...res);
191302
}
192-
}
303+
}
193304

194305
}

testsuite/ts/classes/test_factory.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
import { TestError, TestPath, TestUtil } from '../base/test_util.js';
2323
import { AbstractJsonTest } from './abstract_test.js';
2424

25-
import { ApiTest, DebugTest } from './api_test.js';
25+
import * as api from './api_test.js';
2626
import * as cs from './clearspeak_annotation_test.js';
2727
import { BrailleLayoutTest, ClearspeakTest, SpeechMarkupTest } from './clearspeak_test.js';
2828
import { CollapseTest } from './collapse_test.js';
@@ -39,9 +39,9 @@ import { SymbolTest } from './symbol_test.js';
3939
import { ExplorationTest, WalkerTest, SemanticSkeletonTest } from './walker_test.js';
4040

4141
const map = new Map<string, any>([
42-
['api', ApiTest],
42+
['api', api.ApiTest],
4343
['braille2D', BrailleLayoutTest],
44-
['debug', DebugTest],
44+
['debug', api.DebugTest],
4545
['deepSpeech', st.DeepSpeechTest],
4646
['category', st.CategoryTest],
4747
['clearspeak', ClearspeakTest],
@@ -75,6 +75,7 @@ const map = new Map<string, any>([
7575
['summarySpeech', SummarySpeechTest],
7676
['symbol', SymbolTest],
7777
['walker', WalkerTest],
78+
['worker', api.WorkerTest],
7879
['xpath', XpathTest]
7980
]);
8081

testsuite/ts/jest.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ export function runJsonTest(file: string) {
2828
if (!testcase.test) {
2929
continue;
3030
}
31-
test(testcase.name, () => {
31+
test(testcase.name, async () => {
3232
AnalyticsTest.currentTestcase = testcase.name;
33-
testcases.method.bind(testcases).apply(null, testcases.pick(testcase));
33+
await testcases.method.bind(testcases).apply(null, testcases.pick(testcase));
3434
});
3535
}
3636
});

ts/common/dom_util.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export function parseInput(input: string): Element {
6464
const allValues = clean_input.match(/&(?!lt|gt|amp|quot|apos)\w+;/g);
6565
const html = !!allValues;
6666
if (!clean_input) {
67-
throw new Error('Empty input!');
67+
throw new SREError('Empty input!');
6868
}
6969
try {
7070
const doc = dp.parseFromString(

ts/common/processor_factory.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,11 @@ export function process<T>(name: string, expr: string): T {
7676
const processor = get(name);
7777
try {
7878
return processor.processor(expr) as T;
79-
} catch (_e) {
80-
throw new SREError('Processing error for expression ' + expr);
79+
} catch (error) {
80+
if (error instanceof SREError) {
81+
throw error;
82+
}
83+
throw new SREError(`Processing error for expression\n ${expr}`);
8184
}
8285
}
8386

@@ -110,8 +113,11 @@ export function output(name: string, expr: string): string {
110113
return Engine.getInstance().options.pprint
111114
? processor.pprint(data)
112115
: processor.print(data);
113-
} catch (_e) {
114-
throw new SREError('Processing error for expression ' + expr);
116+
} catch (error) {
117+
if (error instanceof SREError) {
118+
throw error;
119+
}
120+
throw new SREError(`Processing error for expression\n ${expr}`);
115121
}
116122
}
117123

@@ -527,6 +533,9 @@ export function assembleSpeechStructure(
527533
) {
528534
json.options = options;
529535
json.mactions = SpeechGeneratorUtil.connectMactionSelections(mml, sxml);
536+
if ((options as any).enableSpeech === false) {
537+
return;
538+
}
530539
json.speech = SpeechGeneratorUtil.computeSpeechStructure(sxml);
531540
const root = (sxml.childNodes[0] as Element)?.getAttribute('id');
532541
// Here we have to add the postfix correctly and then ensure that it is also

ts/common/system.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ async function assembleWorkerStructure(
535535
Engine.getInstance().options.automark = true;
536536
const json: WorkerStructure = {};
537537
ProcessorFactory.assembleSpeechStructure(json, mml, sxml, options);
538-
if (options.braille === 'none') {
538+
if ((options as any).enableBraille === false) {
539539
return json;
540540
}
541541
await setupEngine({

0 commit comments

Comments
 (0)