mirror of
https://github.com/lancedikson/bowser
synced 2026-10-09 20:32:15 +00:00
Two follow-ups to the dual packaging change (#628), found while running a consumer-facing regression sweep against published 2.14.1. An exports map is a closed list. Before #628 bowser had no exports map, so every published file was reachable by subpath; afterwards LICENSE, README.md and index.d.ts resolved to ERR_PACKAGE_PATH_NOT_EXPORTED. Nothing in the documented API regressed, but `/// <reference types="bowser/index.d.ts" />` and tooling that resolves the license by specifier both did. Add the four non-code files to the map so the published surface matches 2.14.1 exactly, and assert it in the package smoke test (25 -> 29 checks). The acceptance suite asserted src/bowser.js and es5.js against the UA corpus but not bundled.js or bowser.mjs. bowser.mjs is what the `import` condition resolves to, so it is the file every modern ESM and bundler consumer runs, and a build regression confined to it would have kept CI green. Assert all four artifacts against the spec instead. Verified by injecting a Chrome-parsing regression into bowser.mjs and into bundled.js separately (each turns the suite red, labelled by artifact), and by running the new smoke assertions against a pre-fix tarball (exit 1) and this one (exit 0) on Node 12.16, 14, 18, 20 and 22.
55 lines
2.2 KiB
JavaScript
55 lines
2.2 KiB
JavaScript
import test from 'ava';
|
|
import yaml from 'yamljs';
|
|
import path from 'path';
|
|
import Bowser from '../../src/bowser';
|
|
import BowserEs5 from '../../es5';
|
|
import BowserBundled from '../../bundled';
|
|
import BowserMjs from '../../bowser.mjs';
|
|
|
|
/**
|
|
* Every published JS artifact is built from `src/` through a different
|
|
* pipeline — raw ES modules, babel + terser UMD, UMD with core-js baked in,
|
|
* and the rolldown ESM build. A regression in any one of them ships silently
|
|
* unless each is asserted against the spec independently.
|
|
*
|
|
* `bowser.mjs` matters most: it is what the `import` condition of the exports
|
|
* map resolves to, so it is the file every modern ESM and bundler consumer
|
|
* actually runs. Testing only `src/` and `es5.js` leaves it uncovered.
|
|
*
|
|
* These are build outputs, so `pnpm build` has to run before `pnpm test`.
|
|
* Importing `bowser.mjs` from this CommonJS test file relies on Node's
|
|
* require(esm) support (Node >= 22.12) — the build toolchain already requires
|
|
* a newer Node than that, so anything able to produce these files can load them.
|
|
*/
|
|
const artifacts = [
|
|
['src/bowser.js', Bowser],
|
|
['es5.js', BowserEs5],
|
|
['bundled.js', BowserBundled],
|
|
['bowser.mjs', BowserMjs],
|
|
];
|
|
|
|
// A missing build output fails at import with a plain "Cannot find module".
|
|
// This catches the quieter failure: an artifact that loads but is not the
|
|
// Bowser class — a broken UMD wrapper or a lost CJS interop unwrap would
|
|
// otherwise make every assertion below vacuous instead of failing.
|
|
artifacts.forEach(([name, artifact]) => {
|
|
if (typeof artifact !== 'function' || typeof artifact.parse !== 'function') {
|
|
throw new Error(`${name} did not load as the Bowser class — run \`pnpm build\` first`);
|
|
}
|
|
});
|
|
|
|
const listOfUA = yaml.load(path.join(__dirname, 'useragentstrings.yml'));
|
|
|
|
const browserNames = Object.keys(listOfUA);
|
|
|
|
browserNames.forEach((browserName) => {
|
|
listOfUA[browserName].forEach((browser, index) => {
|
|
test(`Test ${browserName} ${index}`, (t) => {
|
|
artifacts.forEach(([name, artifact]) => {
|
|
t.deepEqual(artifact.parse(browser.ua), browser.spec, `${name}: ${browser.ua}`);
|
|
});
|
|
t.is(Bowser.parse(browser.ua).browser.name, browserName, `${browser.ua}`);
|
|
});
|
|
});
|
|
});
|