Skip to content

Commit e2b31c4

Browse files
committed
maint(web): re-add engine .js tests
PR #15093 merged multiple engine modules into one. However, in doing so we lost the .js tests and ran only the .ts ones. This change re-adds the .js tests and fixes them where the code diverged since then. Other changes: - rename `queryEngine.ts` to `cloudQueryEngine.ts` to match the class name - remove unused `keyboard-storage/cloud/index.ts` - expose `CLOUD_TIMEOUT_ERR` and `CLOUD_STUB_REGISTRATION_ERR` as `unitTestEndpoints` - add `test/resources` to exports in `web/package.json`. This was necessary because the compiled .ts test files are under `web/build` whereas the .js test files are under `web/src` and so the relative paths in imports no longer work. Also fix the imports in test files. - apply fix from #15477 if KEYMAN_ROOT is not set I'm not happy to put the compiled files under `web/src/test/auto/resources/build`, but that's the only way I got it to work. If I put the compiled files in `web/build/test/resources` it couldn't find the types for `promise-status-async`. Also, running the .js tests succeeded but then creating the coverage report failed. I was not able to find the reason or a fix for that. As a hack to work around this problem we check the number of failed tests instead of relying on the exit code of the test. Follows: #15093 Test-bot: skip
1 parent bfa6dfa commit e2b31c4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+262
-176
lines changed

web/common.inc.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
# compile engine/main
1818
# ```
1919
function compile() {
20-
if [ $# -lt 1 ]; then
20+
if [[ $# -lt 1 ]]; then
2121
builder_die "Scripting error: insufficient argument count!"
2222
fi
2323

@@ -27,10 +27,10 @@ function compile() {
2727
local SRC_DIR=${2:-"${KEYMAN_ROOT}/web/src"}
2828
local BUILD_DIR=${3:-"${KEYMAN_ROOT}/web/build"}
2929

30-
tsc -b "${SRC_DIR}/$COMPILE_TARGET"
30+
tsc -b "${SRC_DIR}/${COMPILE_TARGET}"
3131

3232
# So... tsc does declaration-bundling on its own pretty well, at least for local development.
33-
tsc --emitDeclarationOnly --outFile "${BUILD_DIR}/$COMPILE_TARGET/lib/index.d.ts" -p "${SRC_DIR}/$COMPILE_TARGET"
33+
tsc --emitDeclarationOnly --outFile "${BUILD_DIR}/${COMPILE_TARGET}/lib/index.d.ts" -p "${SRC_DIR}/${COMPILE_TARGET}"
3434
}
3535

3636
function _copy_dir_if_exists() {

web/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@
8181
"./tools/testing/test-utils": {
8282
"types": "./build/tools/testing/test-utils/obj/index.d.ts",
8383
"import": "./build/tools/testing/test-utils/obj/index.js"
84+
},
85+
"./test/resources": {
86+
"types": "./src/test/auto/resources/build/index.d.ts",
87+
"import": "./src/test/auto/resources/build/index.js"
8488
}
8589
},
8690
"imports": {

web/src/engine/build.sh

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,35 @@ do_build () {
6868
node src/osk/validate-gesture-specs.js
6969
}
7070

71-
builder_run_action clean rm -rf "$KEYMAN_ROOT/web/build/engine"
71+
run_tests() {
72+
local OUTPUT_FILE FAILURE_COUNT
73+
# Remove stale coverage data
74+
rm -rf "${KEYMAN_ROOT}/web/build/coverage/raw/engine"
75+
76+
# Unfortunately we get an error from the coverage report generation:
77+
# "TypeError [ERR_INVALID_URL_SCHEME]: The URL must be of scheme file"
78+
# The following lines ignore the exit code and instead check the number
79+
# of failed tests from the output.
80+
set +e
81+
OUTPUT_FILE=$(mktemp)
82+
test-headless engine "" 2>&1 | tee "${OUTPUT_FILE}"
83+
set -e
84+
85+
FAILURE_COUNT=$(grep ' failing' "${OUTPUT_FILE}" | xargs | cut -f 1 -d' ')
86+
rm "${OUTPUT_FILE}"
87+
builder_echo "(The 'TypeError [ERR_INVALID_URL_SCHEME]: The URL must be of scheme file' is expected)"
88+
if ((FAILURE_COUNT > 0)); then
89+
builder_die "Headless engine tests failed (.js tests)"
90+
fi
91+
92+
test-headless-typescript engine
93+
}
94+
95+
builder_run_action clean rm -rf "${KEYMAN_ROOT}/web/build/engine"
7296
builder_run_child_actions clean
7397
builder_run_action configure node_select_version_and_npm_ci
7498
builder_run_child_actions configure
7599
builder_run_child_actions build
76100
builder_run_action build do_build
77-
builder_run_action test test-headless-typescript engine
101+
builder_run_action test run_tests
78102
builder_run_child_actions test

web/src/engine/src/keyboard-storage/cloud/queryEngine.ts renamed to web/src/engine/src/keyboard-storage/cloud/cloudQueryEngine.ts

File renamed without changes.

web/src/engine/src/keyboard-storage/cloud/index.ts

Lines changed: 0 additions & 2 deletions
This file was deleted.

web/src/engine/src/keyboard-storage/domCloudRequester.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { ManagedPromise } from 'keyman/common/web-utils';
22
import { CloudRequesterInterface } from './cloud/requesterInterface.js';
3-
import { CLOUD_MALFORMED_OBJECT_ERR, CLOUD_TIMEOUT_ERR, CLOUD_STUB_REGISTRATION_ERR } from './cloud/queryEngine.js';
3+
import { CLOUD_MALFORMED_OBJECT_ERR, CLOUD_TIMEOUT_ERR, CLOUD_STUB_REGISTRATION_ERR } from './cloud/cloudQueryEngine.js';
44

55
export class DOMCloudRequester implements CloudRequesterInterface {
66
private readonly fileLocal: boolean;

web/src/engine/src/keyboard-storage/index.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,15 @@ export {
88
REGION_CODES
99
} from './keyboardStub.js';
1010
export { StubAndKeyboardCache, toPrefixedKeyboardId, toUnprefixedKeyboardId } from './stubAndKeyboardCache.js';
11-
export { CloudQueryResult, CloudQueryEngine } from './cloud/queryEngine.js';
11+
export { CloudQueryResult, CloudQueryEngine } from './cloud/cloudQueryEngine.js';
1212
export { CloudRequesterInterface } from './cloud/requesterInterface.js';
1313
export { KeyboardRequisitioner } from './keyboardRequisitioner.js';
1414
export { ModelCache } from './modelCache.js';
15-
export { DOMCloudRequester } from './domCloudRequester.js';
15+
export { DOMCloudRequester } from './domCloudRequester.js';
16+
17+
import { CLOUD_TIMEOUT_ERR, CLOUD_STUB_REGISTRATION_ERR } from './cloud/cloudQueryEngine.js';
18+
19+
export const unitTestEndpoints = {
20+
CLOUD_TIMEOUT_ERR,
21+
CLOUD_STUB_REGISTRATION_ERR
22+
};

web/src/test/auto/headless/engine/interfaces/prediction/predictionContext.tests.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import sinon from 'sinon';
33

44
import { LanguageProcessor, TranscriptionCache } from 'keyman/engine/main';
55
import { PredictionContext } from 'keyman/engine/interfaces';
6-
import { Worker as LMWorker } from "@keymanapp/lexical-model-layer/node";
7-
import { DeviceSpec, SyntheticTextStore } from 'keyman/engine/keyboard';
6+
import { NodeWorker } from "@keymanapp/lexical-model-layer/node";
7+
import { SyntheticTextStore } from 'keyman/engine/keyboard';
88

99
function compileDummyModel(suggestionSets) {
1010
return `
@@ -66,7 +66,7 @@ describe("PredictionContext", () => {
6666
let langProcessor;
6767

6868
beforeEach(function() {
69-
langProcessor = new LanguageProcessor(LMWorker, new TranscriptionCache());
69+
langProcessor = new LanguageProcessor(NodeWorker, new TranscriptionCache());
7070
});
7171

7272
afterEach(function() {
@@ -83,7 +83,7 @@ describe("PredictionContext", () => {
8383

8484
let textStore = new SyntheticTextStore("appl", 4); // "appl|", with '|' as the caret position.
8585
const initialTextStore = SyntheticTextStore.from(textStore);
86-
const promise = predictiveContext.setCurrentTarget(textStore);
86+
const promise = predictiveContext.setCurrentTextStore(textStore);
8787

8888
// Initial predictive state: no suggestions. context.initializeState() has not yet been called.
8989
assert.equal(updateFake.callCount, 1);
@@ -122,7 +122,7 @@ describe("PredictionContext", () => {
122122

123123
let textStore = new SyntheticTextStore("appl", 4); // "appl|", with '|' as the caret position.
124124
const initialTextStore = SyntheticTextStore.from(textStore);
125-
const promise = predictiveContext.setCurrentTarget(textStore);
125+
const promise = predictiveContext.setCurrentTextStore(textStore);
126126

127127
// Initial predictive state: no suggestions. context.initializeState() has not yet been called.
128128
assert.equal(updateFake.callCount, 1);
@@ -181,7 +181,7 @@ describe("PredictionContext", () => {
181181
const predictiveContext = new PredictionContext(langProcessor, dummiedGetLayer);
182182

183183
let textStore = new SyntheticTextStore("appl", 4); // "appl|", with '|' as the caret position.
184-
const initialSuggestions = await predictiveContext.setCurrentTarget(textStore);
184+
const initialSuggestions = await predictiveContext.setCurrentTextStore(textStore);
185185

186186
let updateFake = sinon.fake();
187187
predictiveContext.on('update', updateFake);
@@ -206,7 +206,7 @@ describe("PredictionContext", () => {
206206

207207
let textState = new SyntheticTextStore("appl", 4); // "appl|", with '|' as the caret position.
208208

209-
await predictiveContext.setCurrentTarget(textState);
209+
await predictiveContext.setCurrentTextStore(textState);
210210

211211
let updateFake = sinon.fake();
212212
predictiveContext.on('update', updateFake);
@@ -274,7 +274,7 @@ describe("PredictionContext", () => {
274274

275275
// Test setup - return to the state at the end of the prior-defined unit test ('suggestion application...')
276276

277-
await predictiveContext.setCurrentTarget(textState);
277+
await predictiveContext.setCurrentTextStore(textState);
278278

279279
// This is the point in time that a reversion operation will rewind the context to.
280280
const revertBaseTextState = SyntheticTextStore.from(textState);

web/src/test/auto/headless/engine/js-processor/basic-engine.tests.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,15 @@ const require = createRequire(import.meta.url);
77

88
import { MinimalKeymanGlobal } from 'keyman/engine/keyboard';
99
import { JSKeyboardInterface } from 'keyman/engine/js-processor';
10-
import { NodeKeyboardLoader } from '../../../resources/loader/nodeKeyboardLoader.js';
10+
import { NodeKeyboardLoader } from 'keyman/test/resources';
1111
import { KeyboardTest, NodeProctor } from '@keymanapp/recorder-core';
1212

1313
import { env } from 'node:process';
14-
const KEYMAN_ROOT = env.KEYMAN_ROOT;
14+
import { fileURLToPath } from 'node:url';
15+
import { dirname } from 'node:path';
16+
17+
const __dirname = dirname(fileURLToPath(import.meta.url));
18+
const KEYMAN_ROOT = env.KEYMAN_ROOT ?? (__dirname + '/../../../../../../../');
1519

1620
describe('Engine - Basic Simulation', function() {
1721
let testJSONtext = fs.readFileSync(require.resolve('@keymanapp/common-test-resources/json/engine_tests/basic_lao_simulation.json'));

web/src/test/auto/headless/engine/js-processor/basic-init.tests.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ import { createRequire } from 'module';
44
const require = createRequire(import.meta.url);
55

66
import { JSKeyboardProcessor } from 'keyman/engine/js-processor';
7-
import { NodeKeyboardLoader } from '../../../resources/loader/nodeKeyboardLoader.js';
8-
import { DEFAULT_PROCESSOR_INIT_OPTIONS } from '../../../resources/defaultProcessorInitOptions.js';
7+
import { DEFAULT_PROCESSOR_INIT_OPTIONS, NodeKeyboardLoader } from 'keyman/test/resources';
98

109
global.keyman = {}; // So that keyboard-based checks against the global `keyman` succeed.
1110
// 10.0+ dependent keyboards, like khmer_angkor, will otherwise fail to load.

0 commit comments

Comments
 (0)