diff --git a/test/css/all.js b/test/css/all.js index c082949a22ec..30fde3ee687e 100644 --- a/test/css/all.js +++ b/test/css/all.js @@ -7,7 +7,7 @@ * data because that view is a strict subset of the curated view. */ -import { describe, it, before } from 'node:test'; +import { describe, it } from 'node:test'; import { strict as assert } from 'node:assert'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; @@ -28,158 +28,158 @@ const cssValues = [ { type: 'value space', prop: 'values', value: 'value' } ]; -describe(`The curated view of CSS extracts`, () => { - before(async () => { - const all = await css.listAll({ folder: curatedFolder }); - const baseProperties = {}; - const basePropertiesInDeltaSpecs = {}; - const extendedProperties = {}; - const selectors = {}; - const valuespaces = {}; +describe(`The curated view of CSS extracts`, async () => { + let all; + try { + all = await css.listAll({ folder: curatedFolder }); + } catch (err) { + it('contains valid JSON data', () => {throw err;}); + } + const baseProperties = {}; + const basePropertiesInDeltaSpecs = {}; + const extendedProperties = {}; + const selectors = {}; + const valuespaces = {}; - for (const [shortname, data] of Object.entries(all)) { - describe(`The CSS extract for ${shortname} in the curated view`, () => { - it('contains a link to the underlying spec', async () => { - assert(data); - assert(data.spec); - assert(data.spec.title); - }); + for (const [shortname, data] of Object.entries(all)) { + describe(`The CSS extract for ${shortname} in the curated view`, () => { + it('contains a link to the underlying spec', async () => { + assert(data); + assert(data.spec); + assert(data.spec.title); + }); - const spec = index.results.find(s => s.nightly?.url === data.spec.url); - for (const { type, prop, value } of cssValues) { - for (const desc of data[prop]) { - const name = desc.name; - if ((type === 'property') && (spec.seriesComposition !== 'delta') && !desc.newValues) { - if (!baseProperties[name]) { - baseProperties[name] = []; - } - baseProperties[name].push({ spec: data.spec, dfn: desc }); - } - else if ((type === 'property') && (spec.seriesComposition === 'delta') && !desc.newValues) { - if (!basePropertiesInDeltaSpecs[name]) { - basePropertiesInDeltaSpecs[name] = []; - } - basePropertiesInDeltaSpecs[name].push({ spec: data.spec, dfn: desc }); - } - else if ((type === 'extended property') && desc[value]) { - if (!extendedProperties[name]) { - extendedProperties[name] = []; - } - extendedProperties[name].push({ spec: data.spec, dfn: desc }); + const spec = index.results.find(s => s.nightly?.url === data.spec.url); + for (const { type, prop, value } of cssValues) { + for (const desc of data[prop]) { + const name = desc.name; + if ((type === 'property') && (spec.seriesComposition !== 'delta') && !desc.newValues) { + if (!baseProperties[name]) { + baseProperties[name] = []; } - else if ((type === 'selector') && (spec.seriesComposition !== 'delta')) { - if (!selectors[name]) { - selectors[name] = []; - } - selectors[name].push({ spec: data.spec, dfn: desc }); + baseProperties[name].push({ spec: data.spec, dfn: desc }); + } + else if ((type === 'property') && (spec.seriesComposition === 'delta') && !desc.newValues) { + if (!basePropertiesInDeltaSpecs[name]) { + basePropertiesInDeltaSpecs[name] = []; } - else if ((type === 'value space') && (spec.seriesComposition !== 'delta')) { - if (!valuespaces[name]) { - valuespaces[name] = []; - } - valuespaces[name].push({ spec: data.spec, dfn: desc }); + basePropertiesInDeltaSpecs[name].push({ spec: data.spec, dfn: desc }); + } + else if ((type === 'extended property') && desc[value]) { + if (!extendedProperties[name]) { + extendedProperties[name] = []; } - if (!desc[value]) { - continue; + extendedProperties[name].push({ spec: data.spec, dfn: desc }); + } + else if ((type === 'selector') && (spec.seriesComposition !== 'delta')) { + if (!selectors[name]) { + selectors[name] = []; } - if (type === 'descriptor') { - for (const dfn of desc[value]) { - it(`defines a valid ${type} "${dfn.name}" for at-rule "${name}"`, () => { - assert.strictEqual(dfn.for, name); - assert.doesNotThrow(() => { - const ast = definitionSyntax.parse(dfn.value); - assert(ast.type); - }, `Invalid definition value: ${dfn.value}`); - }); - } + selectors[name].push({ spec: data.spec, dfn: desc }); + } + else if ((type === 'value space') && (spec.seriesComposition !== 'delta')) { + if (!valuespaces[name]) { + valuespaces[name] = []; } - else { - it(`defines a valid ${type} "${name}"`, () => { + valuespaces[name].push({ spec: data.spec, dfn: desc }); + } + if (!desc[value]) { + continue; + } + if (type === 'descriptor') { + for (const dfn of desc[value]) { + it(`defines a valid ${type} "${dfn.name}" for at-rule "${name}"`, () => { + assert.strictEqual(dfn.for, name); assert.doesNotThrow(() => { - const ast = definitionSyntax.parse(desc[value]); + const ast = definitionSyntax.parse(dfn.value); assert(ast.type); - }, `Invalid definition value: ${desc[value]}`); - }); - }; - - // All CSS values should link back to the spec, except: - // - properties that extend a base property - // - at-rulesdefined elsewhere (and present only because the spec - // defines new descriptors for them) - // - properties in delta specs that completely override the base - // definition - currently enforced more restrictively as - // "the 'contain' property in css-contain-3", to better track such - // occurrences that should remain an exception to the exception rule! - if (!desc.newValues && - (prop !== 'atrules' || desc.value || desc.prose) && - !(prop === 'properties' && name === 'contain' && spec.shortname === 'css-contain-3')) { - it(`has a link back to the spec for ${type} "${name}"`, () => { - assert(desc.href); - assert(desc.href.includes('#')); + }, `Invalid definition value: ${dfn.value}`); }); } + } + else { + it(`defines a valid ${type} "${name}"`, () => { + assert.doesNotThrow(() => { + const ast = definitionSyntax.parse(desc[value]); + assert(ast.type); + }, `Invalid definition value: ${desc[value]}`); + }); + }; - if (desc.values) { - for (const value of desc.values) { - if (!value.value) { - continue; - } - it(`defines a valid value "${value.name}" for ${type} "${name}"`, () => { - assert.doesNotThrow(() => { - const ast = definitionSyntax.parse(value.value); - assert(ast.type); - }, `Invalid definition value: ${value.value}`); - }); + // All CSS values should link back to the spec, except: + // - properties that extend a base property + // - at-rulesdefined elsewhere (and present only because the spec + // defines new descriptors for them) + // - properties in delta specs that completely override the base + // definition - currently enforced more restrictively as + // "the 'contain' property in css-contain-3", to better track such + // occurrences that should remain an exception to the exception rule! + if (!desc.newValues && + (prop !== 'atrules' || desc.value || desc.prose) && + !(prop === 'properties' && name === 'contain' && spec.shortname === 'css-contain-3')) { + it(`has a link back to the spec for ${type} "${name}"`, () => { + assert(desc.href); + assert(desc.href.includes('#')); + }); + } - it(`has a link back to the spec for value "${value.name}" for ${type} "${name}"`, () => { - assert(value.href); - assert(value.href.includes('#')); - }); + if (desc.values) { + for (const value of desc.values) { + if (!value.value) { + continue; } + it(`defines a valid value "${value.name}" for ${type} "${name}"`, () => { + assert.doesNotThrow(() => { + const ast = definitionSyntax.parse(value.value); + assert(ast.type); + }, `Invalid definition value: ${value.value}`); + }); + + it(`has a link back to the spec for value "${value.name}" for ${type} "${name}"`, () => { + assert(value.href); + assert(value.href.includes('#')); + }); } } } - }); - } - - describe(`Looking at CSS properties, the curated view`, () => { - for (const [name, dfns] of Object.entries(baseProperties)) { - it(`contains only one "${name}" property definition`, () => { - assert.strictEqual(dfns.length, 1, - `defined in ${dfns.map(d => d.spec.title).join(', ')} (${dfns.map(d => d.spec.url).join(', ')})`); - }); } }); + } - describe(`Looking at CSS selectors, the curated view`, () => { - for (const [name, dfns] of Object.entries(selectors)) { - it(`contains only one "${name}" selector definition`, () => { - assert.strictEqual(dfns.length, 1, - `defined in ${dfns.map(d => d.spec.title).join(', ')} (${dfns.map(d => d.spec.url).join(', ')})`); - }); - } - }); + describe(`Looking at CSS properties, the curated view`, () => { + for (const [name, dfns] of Object.entries(baseProperties)) { + it(`contains only one "${name}" property definition`, () => { + assert.strictEqual(dfns.length, 1, + `defined in ${dfns.map(d => d.spec.title).join(', ')} (${dfns.map(d => d.spec.url).join(', ')})`); + }); + } + }); + + describe(`Looking at CSS selectors, the curated view`, () => { + for (const [name, dfns] of Object.entries(selectors)) { + it(`contains only one "${name}" selector definition`, () => { + assert.strictEqual(dfns.length, 1, + `defined in ${dfns.map(d => d.spec.title).join(', ')} (${dfns.map(d => d.spec.url).join(', ')})`); + }); + } + }); - describe(`Looking at extended CSS properties, the curated view`, () => { - for (const [name, dfns] of Object.entries(extendedProperties)) { - it(`contains a base definition for the "${name}" property`, () => { - assert(baseProperties[name] || basePropertiesInDeltaSpecs[name], 'no base definition found'); - }); - } - }); + describe(`Looking at extended CSS properties, the curated view`, () => { + for (const [name, dfns] of Object.entries(extendedProperties)) { + it(`contains a base definition for the "${name}" property`, () => { + assert(baseProperties[name] || basePropertiesInDeltaSpecs[name], 'no base definition found'); + }); + } + }); - describe(`Looking at CSS valuespaces, the curated view`, () => { - for (const [name, dfns] of Object.entries(valuespaces)) { - it(`contains only one "${name}" valuespace definition`, () => { - assert.strictEqual(dfns.length, 1, - `defined in ${dfns.map(d => d.spec.title).join(', ')} (${dfns.map(d => d.spec.url).join(', ')})`); - }); - } - }); + describe(`Looking at CSS valuespaces, the curated view`, () => { + for (const [name, dfns] of Object.entries(valuespaces)) { + it(`contains only one "${name}" valuespace definition`, () => { + assert.strictEqual(dfns.length, 1, + `defined in ${dfns.map(d => d.spec.title).join(', ')} (${dfns.map(d => d.spec.url).join(', ')})`); + }); + } }); - // Dummy test needed for "before" to run and register late tests - // (test will fail if before function throws, e.g. because data is invalid) - it('contains valid JSON data', () => {}); }); diff --git a/test/elements/consistency.js b/test/elements/consistency.js index 576a8724c38f..e9641b7c8a48 100644 --- a/test/elements/consistency.js +++ b/test/elements/consistency.js @@ -1,12 +1,12 @@ /** * Test the consistency of elements extracts with IDL extracts. - * + * * The tests run against the curated and package views of the data. An extract * that passes a test in the curated view may fail the same test in the package * view because of some missing IDL definition in that view. */ -import { describe, it, before } from 'node:test'; +import { describe, it } from 'node:test'; import { strict as assert } from 'node:assert'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; @@ -26,37 +26,36 @@ const views = [ ]; views.forEach(({ name, folder }) => { - describe(`The ${name} view of elements extracts`, () => { - before(async () => { - // Create a set of well-known interfaces - const allIdl = await idl.parseAll({ folder: path.join(folder, 'idl') }); - const interfaces = new Set(); - for (const [shortname, ast] of Object.entries(allIdl)) { - for (const dfn of ast) { - if (dfn.name) { - interfaces.add(dfn.name); - } + describe(`The ${name} view of elements extracts`, async () => { + let allIdl; + try { + allIdl = await idl.parseAll({ folder: path.join(folder, 'idl') }); + } catch (err) { + it('contains valid JSON data', () => {throw err;}); + } + const interfaces = new Set(); + for (const [shortname, ast] of Object.entries(allIdl)) { + for (const dfn of ast) { + if (dfn.name) { + interfaces.add(dfn.name); } } + } - const allElements = await elements.listAll({ folder: path.join(folder, 'elements') }); - for (const [shortname, data] of Object.entries(allElements)) { - describe(`The elements extract for ${shortname} in the ${name} view`, () => { - for (const el of data.elements) { - if (!el.interface) { - continue; - } - it(`links to a well-known interface for "${el.name}"`, () => { - assert(interfaces.has(el.interface), `Unknown interface "${el.interface}"`); - }); + const allElements = await elements.listAll({ folder: path.join(folder, 'elements') }); + for (const [shortname, data] of Object.entries(allElements)) { + describe(`The elements extract for ${shortname} in the ${name} view`, () => { + for (const el of data.elements) { + if (!el.interface) { + continue; } - }); - } - }); - - // Dummy test needed for "before" to run and register late tests - // (test will fail if before function throws, e.g. because data is invalid) - it('contains valid JSON data', () => {}); + it(`links to a well-known interface for "${el.name}"`, () => { + assert(interfaces.has(el.interface), `Unknown interface "${el.interface}"`); + }); + } + }); + } }); + }); diff --git a/test/events/all.js b/test/events/all.js index 53bb97d3955d..984eb15c6716 100644 --- a/test/events/all.js +++ b/test/events/all.js @@ -1,13 +1,13 @@ /** * Test individual events extracts. - * + * * The tests run against the curated view of the extracts. - * + * * Note: the tests are not run against the `@webref/events` package view of * the data because that view is a strict subset of the curated view. */ -import { describe, it, before } from 'node:test'; +import { describe, it } from 'node:test'; import { strict as assert } from 'node:assert'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; @@ -30,9 +30,14 @@ function report(msg, event) { (event.href ? ` href=${event.href}` : ''); } -before(async () => { +describe("the events data", async () => { // Create a set of well-known interfaces and an inheritance chain - const allIdl = await idl.parseAll({ folder: path.join(curatedFolder, 'idl') }); + let allIdl; + try { + allIdl = await idl.parseAll({ folder: path.join(curatedFolder, 'idl') }); + } catch (err) { + it('contains data that can be parsed with webidl2.js', () => {throw err;}); + } const parsedInterfaces = []; const mixins = new Set(); for (const [shortname, ast] of Object.entries(allIdl)) {