Files
compiler-explorer/static/tests
Luan Taraschi 070896a011 Key LibsWidget consistently, so the conformance view keeps its libraries (#9027)
Fixes #9007.

`LibsWidget` buckets `availableLibs` by compiler id, and it had two
disagreeing ways of deciding that key.

The constructor read `compiler.id`. `setNewLangId` took a plain id
string. The compiler and executor panes pass a `CompilerInfo`, so they
matched the constructor. The conformance view passes
`compilerIds.join('|')`, because the libraries it offers are the
intersection across every compiler in the pane, so it matched
`setNewLangId` instead. The parameter was typed `any`, so nothing
complained.

Reading `.id` off a string gives `undefined`. So a conformance view
restored from a link:

1. builds the widget with the joined id and keys itself on `undefined`,
2. loads the saved libs into `availableLibs[langId][undefined]`,
3. gets a real compiler-change event once the picker resolves, which
calls `updateLibraries` and then `setNewLangId` with the same joined
string,
4. is now keyed on `"g142|clang1500"`, where nothing was ever recorded.

`listUsedLibs` reads the new bucket, finds nothing, and the libraries
are gone. Re-adding one through the green button writes it into the new
bucket, which is why that workaround sticks, exactly as the reporter
describes.

Both paths now go through one `toCompilerKey`, so the key cannot change
shape mid-life. The parameter is typed instead of `any`, which is what
let the two conventions coexist.

One deliberate behavior change beyond the bug: a compiler whose `id` is
the empty string now falls into `_default_` from the constructor too.
`setNewLangId` already treated it that way through its falsy check, so
this makes the two agree rather than inventing a third rule.

The local `c_default_compiler_non_id` becomes the exported
`DEFAULT_COMPILER_KEY`, and the two places that spelled the same value
as a bare `'_default_'` literal now use it. Same value throughout, one
name.

## What I ran

`npm run check` passes: ts-check on both projects, biome over 826 files,
frontend imports, license headers, and the test run.

New test file `static/tests/widgets/libs-widget-tests.ts`, 5 cases over
`toCompilerKey`, covering both call shapes, that they agree for the same
compiler, every empty shape landing on the default, and that no shape
can yield a non-string. All 5 fail before the change and pass after.

The one failure in the suite, `test/build-systems-tests.ts > Maven build
system > builds Kotlin ...`, also fails on a clean `main` on my machine.
It is a symlink `realpath` comparison and I am on Windows.

I did not reproduce the symptom in a browser: I cannot run the server
locally, since it needs at least one compiler on POSIX paths. The chain
above is read off the code and pinned by the unit test at the point
where the two conventions met. If you would rather see a test that
drives the whole widget through construct then `setNewLangId`, say so
and I will add it.
2026-08-24 19:57:45 -05:00
..
2025-06-19 08:46:57 -05:00

Front-end unit tests

Tests here are super simple and use jsdom with a fake document to do quick checks on the front-end code.

For anything requiring a real browser, use the cypress tests in the cypress directory.