diff --git a/tests/components-test.ts b/tests/components-test.ts index f8314d7688..7c4cd50ced 100644 --- a/tests/components-test.ts +++ b/tests/components-test.ts @@ -1,9 +1,11 @@ -import { assert } from 'chai'; import { readFileSync } from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; -import { forEach, noop, toArray } from '../src/shared/util'; +import { assert } from 'chai'; +import { noop } from '../src/shared/util'; +import { forEach, toArray } from '../src/util/iterables'; import { getComponent, getComponentIds, getLanguageIds } from './helper/prism-loader'; +import type { LanguageProto } from '../src/types'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -41,7 +43,7 @@ describe('Components', () => { for (const id of getComponentIds()) { const proto = await getComponent(id).catch(noop); add(id, 'a component id'); - forEach(proto?.alias, a => add(a, `an alias of ${id}`)); + forEach((proto as LanguageProto)?.alias, a => add(a, `an alias of ${id}`)); } }); }); @@ -100,7 +102,7 @@ describe('components.json', () => { describe('- should have valid alias titles', () => { for (const lang of getLanguageIds()) { it(`- ${lang} should have all alias titles registered as alias`, async () => { - const aliases = new Set(toArray((await getComponent(lang)).alias)); + const aliases = new Set(toArray(((await getComponent(lang)) as LanguageProto)?.alias)); const aliasTitles = (components.languages[lang] as ComponentEntry | undefined)?.aliasTitles ?? {}; @@ -123,7 +125,6 @@ describe('components.json', () => { .map((key): { id: string; title: string } => { return { id: key, - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion title: (components.languages[key] as ComponentEntry).title!, }; }); diff --git a/tests/core/registry.ts b/tests/core/registry.ts index d2afb7a9cd..6dae213aa1 100644 --- a/tests/core/registry.ts +++ b/tests/core/registry.ts @@ -1,60 +1,34 @@ import { assert } from 'chai'; import { Prism } from '../../src/core/prism'; +import type { Grammar } from '../../src/types'; describe('Registry', () => { it('should resolve aliases', () => { - const { components } = new Prism(); + const { languageRegistry } = new Prism(); - const grammar = {}; - components.add({ id: 'a', alias: 'b', grammar }); + const grammar = {} as Grammar; + languageRegistry.add({ id: 'a', alias: 'b', grammar }); - assert.isTrue(components.has('a')); - assert.isTrue(components.has('b')); + assert.equal(languageRegistry.resolveRef('a').id, 'a'); + assert.equal(languageRegistry.resolveRef('b').id, 'a'); - assert.strictEqual(components.resolveAlias('a'), 'a'); - assert.strictEqual(components.resolveAlias('b'), 'a'); + assert.strictEqual(languageRegistry.aliases['b'], 'a'); - assert.strictEqual(components.getLanguage('a'), grammar); - assert.strictEqual(components.getLanguage('b'), grammar); + assert.deepStrictEqual(languageRegistry.getLanguage('a')?.resolvedGrammar, grammar); + assert.deepStrictEqual(languageRegistry.getLanguage('b')?.resolvedGrammar, grammar); }); it('should resolve aliases in optional dependencies', () => { - const { components } = new Prism(); + const { languageRegistry } = new Prism(); - const grammar = {}; - components.add({ id: 'a', alias: 'b', grammar }); - components.add({ + const grammar = {} as Grammar; + languageRegistry.add({ id: 'a', alias: 'b', grammar }); + languageRegistry.add({ id: 'c', optional: 'b', - grammar ({ getOptionalLanguage }) { - return getOptionalLanguage('b') ?? {}; - }, + grammar: ({ getLanguage }) => getLanguage('b') ?? {}, }); - assert.strictEqual(components.getLanguage('c'), grammar); - }); - - it('should throw on circular dependencies', () => { - assert.throws(() => { - const { components } = new Prism(); - - components.add({ id: 'a', optional: 'b', grammar: {} }); - components.add({ id: 'b', optional: 'a', grammar: {} }); - }, /Circular dependency a -> b -> a not allowed/); - - assert.throws(() => { - const { components } = new Prism(); - - components.add( - { id: 'a', optional: 'b', grammar: {} }, - { id: 'b', optional: 'a', grammar: {} } - ); - }, /Circular dependency a -> b -> a not allowed/); - - assert.throws(() => { - const { components } = new Prism(); - - components.add({ id: 'a', optional: 'a', grammar: {} }); - }, /Circular dependency a -> a not allowed/); + assert.deepStrictEqual(languageRegistry.getLanguage('c')?.resolvedGrammar, grammar); }); }); diff --git a/tests/coverage.ts b/tests/coverage.ts index 2738a52c2d..872da0d341 100644 --- a/tests/coverage.ts +++ b/tests/coverage.ts @@ -17,14 +17,13 @@ describe('Pattern test coverage', () => { const Prism = await PrismLoader.createInstance(languages); const root = Object.fromEntries( - [...Prism.components['entries'].keys()].map(id => [ + Object.keys(Prism.languageRegistry.cache).map(id => [ id, - Prism.components.getLanguage(id), + Prism.languageRegistry.getLanguage(id)?.resolvedGrammar, ]) ); BFS(root, (path, object) => { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const { key, value } = path[path.length - 1]; const tokenPath = BFSPathToPrismTokenPath(path); @@ -78,8 +77,8 @@ describe('Pattern test coverage', () => { try { await runTestCase(languageIdentifier, filePath, 'none', createInstance); } - catch (error) { - // we don't case about whether the test succeeds, + catch (error) { // eslint-disable-line @typescript-eslint/no-unused-vars + // we don't care about whether the test succeeds, // we just want to gather usage data } } @@ -112,7 +111,7 @@ describe('Pattern test coverage', () => { }); it(`- should exhaustively cover all keywords in keyword lists`, () => { - const problems = []; + const problems: string[] = []; for (const data of getAllOf(language)) { if (data.matches.length === 0) { diff --git a/tests/helper/prism-loader.ts b/tests/helper/prism-loader.ts index 71b40503cc..9abd069e07 100644 --- a/tests/helper/prism-loader.ts +++ b/tests/helper/prism-loader.ts @@ -63,7 +63,9 @@ export async function createInstance (languages?: string | string[]) { const instance = new Prism(); const protos = await Promise.all(toArray(languages).map(getComponent)); - instance.components.add(...protos); + protos.filter(Boolean).forEach(proto => { + instance.languageRegistry.add(proto as LanguageProto); + }); return instance; } @@ -142,7 +144,14 @@ export function createPrismDOM (): PrismDOM<{}> { const load = async (languagesOrPlugins: string | string[]) => { const protos = await Promise.all(toArray(languagesOrPlugins).map(getComponent)); withGlobals(() => { - instance.components.add(...protos); + protos.filter(Boolean).forEach(proto => { + if (proto.grammar) { + instance.languageRegistry.add(proto); + } + else { + instance.pluginRegistry.add(proto); + } + }); }); }; diff --git a/tests/helper/test-case.ts b/tests/helper/test-case.ts index 173a56ec0c..fdd59a9922 100644 --- a/tests/helper/test-case.ts +++ b/tests/helper/test-case.ts @@ -3,8 +3,8 @@ import fs from 'fs'; import { createInstance } from './prism-loader'; import * as TokenStreamTransformer from './token-stream-transformer'; import { formatHtml, getLeadingSpaces } from './util'; -import type { Prism } from '../../src/core'; -import type { TokenStream } from '../../src/core/token'; +import type { Prism } from '../../src/types'; +import type { TokenStream } from '../../src/types'; const defaultCreateInstance = createInstance; @@ -134,7 +134,7 @@ interface Runner { } const jsonRunner: Runner = { run (Prism, code, language) { - const grammar = Prism.components.getLanguage(language); + const grammar = Prism.languageRegistry.getLanguage(language)?.resolvedGrammar; return Prism.tokenize(code, grammar ?? {}); }, print (actual) { diff --git a/tests/identifier-test.ts b/tests/identifier-test.ts index 969cf62c87..7b65af2729 100644 --- a/tests/identifier-test.ts +++ b/tests/identifier-test.ts @@ -3,7 +3,7 @@ import { toArray } from '../src/util/iterables'; import { createInstance, getComponent, getLanguageIds } from './helper/prism-loader'; import { prettyprint } from './helper/token-stream-transformer'; import type { Prism, Token } from '../src/core'; -import type { TokenStream } from '../src/core/token'; +import type { TokenStream } from '../src/types'; // This is where you can exclude a language from the identifier test. // @@ -89,7 +89,7 @@ for (const lang of getLanguageIds()) { describe(`Patterns of '${lang}' with optional dependencies`, () => { const getPrism = async () => { const component = await getComponent(lang); - const optional = toArray(component.optional); + const optional = toArray(component?.optional); const Prism = await createInstance([lang, ...optional]); return Prism; }; @@ -122,8 +122,8 @@ function testLiterals (getPrism: Promise, lang: string) { identifierType: keyof IdentifierTestOptions ) { const Prism = await getPrism; - for (const id of Prism.components['entries'].keys()) { - const grammar = Prism.components.getLanguage(id); + for (const id of Object.keys(Prism.languageRegistry.cache)) { + const grammar = Prism.languageRegistry.getLanguage(id)?.resolvedGrammar; if (!grammar) { continue; } diff --git a/tests/pattern-tests.ts b/tests/pattern-tests.ts index 38c77fadf9..65cd6457be 100644 --- a/tests/pattern-tests.ts +++ b/tests/pattern-tests.ts @@ -108,7 +108,6 @@ function testPatterns (getPrism: () => Promise, mainLanguage: visited.add(grammar); BFS(grammar, path => { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const { key, value } = path[path.length - 1]; const tokenPath = BFSPathToPrismTokenPath(path, rootStr); visited.add(value); @@ -125,9 +124,7 @@ function testPatterns (getPrism: () => Promise, mainLanguage: ); } - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const parent = path.length > 1 ? path[path.length - 2].value : undefined; - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const lookbehind = key === 'pattern' && !!parent && !!(parent as GrammarToken).lookbehind; const lookbehindGroup = lookbehind @@ -138,7 +135,6 @@ function testPatterns (getPrism: () => Promise, mainLanguage: ast, tokenPath, name: key, - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment parent, path, lookbehind, @@ -159,8 +155,8 @@ function testPatterns (getPrism: () => Promise, mainLanguage: } // static analysis - for (const id of Prism.components['entries'].keys()) { - const grammar = Prism.components.getLanguage(id); + for (const id of Object.keys(Prism.languageRegistry.cache)) { + const grammar = Prism.languageRegistry.getLanguage(id)?.resolvedGrammar; if (grammar) { traverse(grammar, id); } @@ -169,7 +165,7 @@ function testPatterns (getPrism: () => Promise, mainLanguage: // dynamic analysis for (const lang of getRelevantLanguages()) { const snippets = testSnippets.get(lang); - const grammar = Prism.components.getLanguage(lang); + const grammar = Prism.languageRegistry.getLanguage(lang)?.resolvedGrammar; // eslint-disable-next-line @typescript-eslint/unbound-method const oldTokenize = Prism.tokenize; @@ -282,7 +278,7 @@ function testPatterns (getPrism: () => Promise, mainLanguage: forEachCapturingGroup(ast.pattern, ({ group, number }) => { const isLookbehindGroup = group === lookbehindGroup; if (group.references.length === 0 && !isLookbehindGroup) { - const fixes = []; + const fixes: string[] = []; fixes.push( `Make this group a non-capturing group ('(?:...)' instead of '(...)'). (It's usually this option.)` ); @@ -406,7 +402,7 @@ function testPatterns (getPrism: () => Promise, mainLanguage: * Returns the first capturing group in the given pattern. */ function getFirstCapturingGroup (pattern: Pattern): CapturingGroup | undefined { - let cap = undefined; + let cap: CapturingGroup | undefined = undefined; try { visitRegExpAST(pattern, { @@ -416,7 +412,7 @@ function getFirstCapturingGroup (pattern: Pattern): CapturingGroup | undefined { }, }); } - catch (error) { + catch (error) { // eslint-disable-line @typescript-eslint/no-unused-vars // ignore errors } @@ -784,9 +780,9 @@ interface Highlight { function highlight (highlights: Highlight[], offset = 0) { highlights.sort((a, b) => a.start - b.start); - const lines = []; + const lines: string[] = []; while (highlights.length > 0) { - const newHighlights = []; + const newHighlights: Highlight[] = []; let l = ''; for (const highlight of highlights) { const start = highlight.start + offset;