maint(web): re-add engine .js tests 🎼#15497
Conversation
User Test ResultsTest specification and instructions User tests are not required Test Artifacts
|
39763fc to
677ca5f
Compare
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
677ca5f to
e2b31c4
Compare
mcdurdin
left a comment
There was a problem hiding this comment.
I think we should have another go at sorting the locations of files. And a few more changes requested. Happy to rubber-ducky if that makes it easier.
| import { CLOUD_TIMEOUT_ERR, CLOUD_STUB_REGISTRATION_ERR } from './cloud/cloudQueryEngine.js'; | ||
|
|
||
| export const unitTestEndpoints = { | ||
| CLOUD_TIMEOUT_ERR, | ||
| CLOUD_STUB_REGISTRATION_ERR | ||
| }; |
There was a problem hiding this comment.
This doesn't feel right. unitTestEndpoints are intended for targets for unit tests, not for sharing variables. There's no need for these to be exported for their usages in unit tests -- they are both used just one time in nodeCloudeRequester.ts (tests):
keyman/web/src/test/auto/resources/loader/nodeCloudRequester.ts
Lines 35 to 38 in 9930a8c
keyman/web/src/test/auto/resources/loader/nodeCloudRequester.ts
Lines 58 to 60 in 9930a8c
IMHO, those errors should just be plain strings in the unit testing code -- it's not deployed, there's no localization need, etc, etc. Just KISS. We can then eliminate the messiness of exporting these two constants.
| import { CLOUD_TIMEOUT_ERR, CLOUD_STUB_REGISTRATION_ERR } from './cloud/cloudQueryEngine.js'; | |
| export const unitTestEndpoints = { | |
| CLOUD_TIMEOUT_ERR, | |
| CLOUD_STUB_REGISTRATION_ERR | |
| }; |
There was a problem hiding this comment.
ok, inlined those consts.
| # Unfortunately we get an error from the coverage report generation: | ||
| # "TypeError [ERR_INVALID_URL_SCHEME]: The URL must be of scheme file" | ||
| # The following lines ignore the exit code and instead check the number | ||
| # of failed tests from the output. | ||
| set +e | ||
| OUTPUT_FILE=$(mktemp) | ||
| test-headless engine "" 2>&1 | tee "${OUTPUT_FILE}" | ||
| set -e | ||
|
|
||
| FAILURE_COUNT=$(grep ' failing' "${OUTPUT_FILE}" | xargs | cut -f 1 -d' ') | ||
| rm "${OUTPUT_FILE}" | ||
| builder_echo "(The 'TypeError [ERR_INVALID_URL_SCHEME]: The URL must be of scheme file' is expected)" | ||
| if ((FAILURE_COUNT > 0)); then | ||
| builder_die "Headless engine tests failed (.js tests)" | ||
| fi |
There was a problem hiding this comment.
This doesn't seem right. We are running code coverage tests elsewhere just fine.
There was a problem hiding this comment.
Turns out previously we didn't run the tests with coverage for engine/main. The reason c8 coverage report generation fails is a data:text/javascript URL coming from web/src/engine/predictive-text/worker-main/src/node/mappedWorker.ts. I changed it so that languageProcessor.tests.js which imports mappedWorker runs without test coverage.
| import { env } from 'node:process'; | ||
| const KEYMAN_ROOT = env.KEYMAN_ROOT; | ||
| import { fileURLToPath } from 'node:url'; | ||
| import { dirname } from 'node:path'; | ||
|
|
||
| const __dirname = dirname(fileURLToPath(import.meta.url)); | ||
| const KEYMAN_ROOT = env.KEYMAN_ROOT ?? (__dirname + '/../../../../../../../../'); |
There was a problem hiding this comment.
Can we put this into a helper module in keyman/test/resources and avoid repeating it?
- inline consts so that we don't have to export them for unit testing - create `getKeymanRoot` and `getWebTestResourcesPath` helper functions to DRY out the code - run `languageProcessortests.js` without coverage to prevent a failure creating the coverage report.
6ac2b79 to
745fa36
Compare
| // Set callback timer | ||
| const timeoutID = window.setTimeout(() => { | ||
| promise.reject(new Error(CLOUD_TIMEOUT_ERR)); | ||
| promise.reject(new Error('The Cloud API request timed out.')); |
There was a problem hiding this comment.
Not sure why you are removing the constants?
| import { PathConfiguration } from 'keyman/engine/interfaces'; | ||
| import NodeCloudRequester from '../../../resources/loader/nodeCloudRequester.js'; | ||
|
|
||
| import path from 'path'; |
There was a problem hiding this comment.
| import path from 'path'; | |
| import path from 'node:path'; |
Trying to make this more consistent over time
| @@ -2,20 +2,13 @@ import { assert } from 'chai'; | |||
| import sinon from 'sinon'; | |||
| import fs from 'fs'; | |||
There was a problem hiding this comment.
| import fs from 'fs'; | |
| import fs from 'node:fs'; |
Also see our import order at https://github.com/keymanapp/keyman/wiki/Keyman-Code-Style-Guide#imports-typescript-nodejs-etc
| @@ -1,5 +1,6 @@ | |||
| import { assert } from 'chai'; | |||
|
|
|||
| import path from 'path'; | |||
There was a problem hiding this comment.
| import path from 'path'; | |
| import path from 'mode:path'; |
|
|
||
| export function getKeymanRoot(): string { | ||
| const __dirname = dirname(fileURLToPath(import.meta.url)); | ||
| return process.env['KEYMAN_ROOT'] ?? (__dirname + '/../../../../../../'); |
There was a problem hiding this comment.
Should we just use:
| return process.env['KEYMAN_ROOT'] ?? (__dirname + '/../../../../../../'); | |
| return __dirname + '/../../../../../../'; |
And never reference the KEYMAN_ROOT variable at all? I don't see any benefit to having both methods here.
Co-authored-by: Marc Durdin <marc@durdin.net>
For the files touched in this PR: - fix the order of the imports according to style guide - use `node:` prefix for node modules - add header
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:
queryEngine.tstocloudQueryEngine.tsto match the class namekeyboard-storage/cloud/index.tsCLOUD_TIMEOUT_ERRandCLOUD_STUB_REGISTRATION_ERRasunitTestEndpointstest/resourcesto exports inweb/package.json. This was necessary because the compiled .ts test files are underweb/buildwhereas the .js test files are underweb/srcand so the relative paths in imports no longer work. Also fix the imports in test files.node-keyboard-loader.tswhich was just a wrapper aroundNodeKeyboardLoader.specialized-backspace.tests.jstospecialized-backspace.tests.tsand fixed resulting issues/warnings.getKeymanRootandgetWebTestResourcesPathhelper functions to DRY out the codelanguageProcessortests.jswithout coverage to prevent a failure creating the coverage reportI'm not happy to put the compiled files for
test/auto/resourcesunderweb/src/test/auto/resources/build, but that's the only way I got it to work. If I put the compiled files inweb/build/test/resourcesit couldn't find the types forpromise-status-async.Follows: #15093
Test-bot: skip