test(unit-tests): make the harness runnable again - #194
Conversation
test/unit-tests/common/index.html could not run at all. Every path in it, and in
the two test files it loads, pointed into a "web-apps — копия" directory that is
not in this repository, and requirejs aborts the whole run on the first 404. The
suite has been dead long enough for the rest of it to rot behind that.
Working outwards from there:
- Paths now resolve inside this checkout. baseUrl was '../../apps/', which from
test/unit-tests/common/ is test/apps/ -- a directory that has never existed.
- mocha.setup() no longer passes ignoreLeaks. Removed in mocha 4, and setup()
calls every key as a method, so an unknown one throws "self[opt] is not a
function" before a single test registers.
- chai 5 is ESM only ("type": "module", no UMD build), so requirejs' classic
script tag dies on `export`. The page imports it as a module and registers it
under the id the test files already use, leaving define(['chai']) and
require('chai') untouched.
- jquery, underscore and backbone load before the tests, and are published to
window. The components read them as globals without declaring them as
dependencies, and underscore's UMD build registers as AMD without leaving a
global behind, so requirejs was free to evaluate a component first.
- Module ids ending in .js resolve against the page rather than baseUrl, so the
ids inside the test files lost their extension and the ones in index.html
kept theirs.
That leaves the Button suite, which was failing on its own terms:
- .andSelf() was removed in jQuery 3; it is .addBack() now.
- Common.UI.Scaling.currentRatio(), Common.Locale.isCurrentLanguageRtl() and
Common.NotificationCenter are read at render time. The real modules pull in
'core' and the whole application bootstrap, which is the opposite of a unit
test, so common.js stubs the three.
12 tests, no failures. Serve the repository over http and open
test/unit-tests/common/index.html -- requirejs cannot load modules from file://,
where Chrome gives every URL its own opaque origin.
No product code is touched.
The runner also registers the SmartPicker unit test, whose module and test file
arrive with #130. Until that merges, requirejs 404s on it and
aborts the run, so this has to land second.
Assisted-by: ClaudeCode:claude-opus-5
Signed-off-by: Christoph Schaefer <christoph.schaefer@nextcloud.com>
|
TL;DR: Request changes — one real, previously-unreported bug (a module load-order race that can blank out the whole suite), plus a disclosed-but-technically-unenforced dependency on #130. Everything else in the PR checks out, verified by actually running the harness in a real browser, not just reading the diff. Full review — verified by cloning, checking out the branch, and running the harness in headless Chrome1. Real bug: module load-order race in The test-setup module ( require([
'../test/unit-tests/common',
'./main/lib/util/utils.js',
'./main/lib/component/Button.js',
'./main/lib/util/SmartPicker.js'
], runMocha);RequireJS does not guarantee array-order execution — it resolves whichever module's fetch completes first. This currently "works" only because the setup file is small and fast on localhost. Proof: I wrote a small proxy that delays serving Fix — nest the require so the setup module is guaranteed to finish first (verified: 26/26 pass even under the same 2s injected delay once nested): require(['../test/unit-tests/common'], function () {
require([
'./main/lib/util/utils.js',
'./main/lib/component/Button.js',
'./main/lib/util/SmartPicker.js'
], runMocha);
});This is the same pattern the PR already uses correctly for 2. Confirmed as described, but not technically enforced: the PR depends on #130. Reproduced directly: this branch's diff, merged alone (before #130 lands), 404s on 3. Everything else checks out — verified live, not just read:
(Review assisted by Claude Code — findings verified by actually running the test harness in headless Chrome, including a live repro of the race condition, not inferred from the diff or the PR description.) |
The suite file arrives with this branch, so its registration belongs here too rather than in the harness fix (#194), which now stands on its own. Note that the runner itself only works once #194 lands -- every path in this file still points at a directory that is not in the repository. Assisted-by: ClaudeCode:claude-opus-5
|
TL;DR: Both findings from the previous review are genuinely fixed — verified by re-running, not just reading the diff. One new, small blocker: the fix commit is missing DCO sign-off. Re-verification1. Race condition — fixed, confirmed. 2. #130 dependency — genuinely removed. The 3. New blocker: DCO. Commit Nothing else regressed — the jQuery/chai/mocha mechanics I verified live in the previous pass are untouched. (Re-reviewed by re-cloning, checking out the updated branch, and re-running the harness — including repeating the delay-injection repro — rather than trusting the commit message.) |
The setup module publishes assert/expect and stubs the ambient Common.* state, and it sat in the same flat require array as the suites that read them. RequireJS makes no promise about the order of independent siblings in one array, so nest the call and let the setup resolve first -- the same pattern the vendor globals above already use. The SmartPicker suite registration moves to #130, which is where the module and its test file come from. This branch now stands on its own: 12 tests, no failures. Assisted-by: ClaudeCode:claude-opus-5 Signed-off-by: Christoph Schaefer <christoph.schaefer@nextcloud.com>
The suite file arrives with this branch, so its registration belongs here too rather than in the harness fix (#194), which now stands on its own. Note that the runner itself only works once #194 lands -- every path in this file still points at a directory that is not in the repository. Assisted-by: ClaudeCode:claude-opus-5 Signed-off-by: Christoph Schaefer <christoph.schaefer@nextcloud.com>
96e788e to
d0fddf0
Compare
The suite file arrives with this branch, so its registration belongs here too rather than in the harness fix (#194), which now stands on its own. Note that the runner itself only works once #194 lands -- every path in this file still points at a directory that is not in the repository. Assisted-by: ClaudeCode:claude-opus-5 Signed-off-by: Christoph Schaefer <christoph.schaefer@nextcloud.com>
Make the unit-test harness runnable again
test/unit-tests/common/index.htmlcould not run at all. Every path in it, and inthe two test files it loads, pointed into a
web-apps — копияdirectory that is notin this repository. RequireJS aborts the whole run on the first 404, so the suite has
been dead long enough for the rest of it to rot behind that.
Fixed
baseUrlwas'../../apps/', which fromtest/unit-tests/common/istest/apps/— a directory that has never existed.mocha.setup()no longer passesignoreLeaks. Removed in mocha 4, andsetup()calls every key as a method, so an unknown one throwsself[opt] is not a functionbefore a single test registers."type": "module", no UMD build), so RequireJS's classicscript tag dies on
export. The page imports it as a module and registers it underthe id the test files already use, leaving
define(['chai'])andrequire('chai')untouched.
window. The components read them as globals without declaring them asdependencies, and underscore's UMD build registers as AMD without leaving a global
behind, so RequireJS was free to evaluate a component first.
.js-suffixed module ids resolve against the page rather thanbaseUrl— theids inside the test files lost their extension, the ones in
index.htmlkept theirs.assert/expectand stubs the ambient
Common.*state, and it sat in the same flatrequirearrayas the suites that read them. RequireJS documents no ordering guarantee for
independent siblings in one array, so the call is nested — the same pattern already
used for the vendor globals one level up.
And the Button suite, which was failing on its own terms
.andSelf()was removed in jQuery 3; it is.addBack()now.Common.UI.Scaling.currentRatio(),Common.Locale.isCurrentLanguageRtl()andCommon.NotificationCenterare read at render time. The real modules pull incoreand the whole application bootstrap, which is the opposite of a unit test, so
common.jsstubs the three.Result
12 tests, no failures. Serve the repository over http and open
test/unit-tests/common/index.html— RequireJS cannot load modules fromfile://,where Chrome gives every URL its own opaque origin.
No product code is touched.
No longer depends on #130
The SmartPicker suite registration moved to #130, which is where the module
(
apps/common/main/lib/util/SmartPicker.js) and its test file come from. This branchnow stands on its own and the two can merge in either order; whichever lands second
resolves a one-line conflict in the
requirearray.Assisted-by: ClaudeCode:claude-opus-5