| // Copyright 2026 The Chromium Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| import {assert} from 'chai'; | |
| import {describe, it} from 'mocha'; | |
| import { | |
| checkForDuplicateTests, | |
| createTestIdMap, | |
| duplicateTests, | |
| listContainsTestOrSuite, | |
| pruneSuite, | |
| } from './MochaHelpers.js'; | |
| interface MockTestOptions { | |
| file?: string; | |
| titlePath: string[]; | |
| pending?: boolean; | |
| } | |
| function createMockTest(options: MockTestOptions): Mocha.Test { | |
| return { | |
| file: options.file, | |
| titlePath: () => options.titlePath, | |
| pending: options.pending ?? false, | |
| } as unknown as Mocha.Test; | |
| } | |
| describe('MochaHelpers', () => { | |
| describe('createTestIdMap', () => { | |
| it('creates a map of Mocha.Test to computed test ID for all tests in suites', () => { | |
| const test1 = createMockTest({file: 'base/test.ts', titlePath: ['Suite', 'test 1']}); | |
| const test2 = createMockTest({file: 'base/test.ts', titlePath: ['Suite', 'sub suite', 'test 2']}); | |
| const subSuite: Mocha.Suite = { | |
| tests: [test2], | |
| suites: [], | |
| } as unknown as Mocha.Suite; | |
| const rootSuite: Mocha.Suite = { | |
| tests: [test1], | |
| suites: [subSuite], | |
| } as unknown as Mocha.Suite; | |
| const map = createTestIdMap(rootSuite); | |
| assert.strictEqual(map.get(test1), 'base/test.ts:suite:test_1'); | |
| assert.strictEqual(map.get(test2), 'base/test.ts:suite:sub_suite:test_2'); | |
| assert.strictEqual(map.size, 2); | |
| }); | |
| it('throws an error if test does not have a file', () => { | |
| const test = createMockTest({titlePath: ['Suite', 'test 1']}); | |
| const suite: Mocha.Suite = { | |
| tests: [test], | |
| suites: [], | |
| } as unknown as Mocha.Suite; | |
| assert.throws(() => createTestIdMap(suite), /Test Suite,test 1 does not have a file\./); | |
| }); | |
| }); | |
| describe('checkForDuplicateTests', () => { | |
| it('passes when there are no duplicates', () => { | |
| const test1 = createMockTest({file: 'base/test.ts', titlePath: ['Suite', 'test 1']}); | |
| const test2 = createMockTest({file: 'base/test.ts', titlePath: ['Suite', 'test 2']}); | |
| const map = new Map<Mocha.Test, string>([ | |
| [test1, 'base/test.ts:suite:test_1'], | |
| [test2, 'base/test.ts:suite:test_2'], | |
| ]); | |
| assert.doesNotThrow(() => checkForDuplicateTests(map)); | |
| }); | |
| it('throws when duplicate tests are found', () => { | |
| const test1 = createMockTest({file: 'base/test.ts', titlePath: ['Suite', 'test 1']}); | |
| const test2 = createMockTest({file: 'base/test.ts', titlePath: ['Suite', 'test 1']}); | |
| const map = new Map<Mocha.Test, string>([ | |
| [test1, 'base/test.ts:suite:test_1'], | |
| [test2, 'base/test.ts:suite:test_1'], | |
| ]); | |
| assert.throws(() => checkForDuplicateTests(map), /Duplicate test base\/test\.ts:suite:test_1/); | |
| }); | |
| }); | |
| describe('pruneSuite', () => { | |
| it('recursively filters tests in suites using testIds', () => { | |
| const test1 = createMockTest({file: 'base/test.ts', titlePath: ['Suite', 'test 1']}); | |
| const test2 = createMockTest({file: 'base/test.ts', titlePath: ['Suite', 'sub suite', 'test 2']}); | |
| const test3 = createMockTest({file: 'base/test.ts', titlePath: ['Suite', 'sub suite', 'test 3']}); | |
| const subSuite: Mocha.Suite = { | |
| tests: [test2, test3], | |
| suites: [], | |
| } as unknown as Mocha.Suite; | |
| const rootSuite: Mocha.Suite = { | |
| tests: [test1], | |
| suites: [subSuite], | |
| } as unknown as Mocha.Suite; | |
| const map = createTestIdMap(rootSuite); | |
| pruneSuite(rootSuite, map, { | |
| testIds: new Set(['base/test.ts:suite:sub_suite:test_2']), | |
| }); | |
| assert.deepEqual(rootSuite.tests, []); | |
| assert.deepEqual(subSuite.tests, [test2]); | |
| }); | |
| it('marks skipped tests as pending (by exact match or prefix)', () => { | |
| const test1 = createMockTest({file: 'base/test.ts', titlePath: ['Suite', 'test 1']}); | |
| const test2 = createMockTest({file: 'base/test.ts', titlePath: ['Suite', 'sub suite', 'test 2']}); | |
| const subSuite: Mocha.Suite = { | |
| tests: [test2], | |
| suites: [], | |
| } as unknown as Mocha.Suite; | |
| const rootSuite: Mocha.Suite = { | |
| tests: [test1], | |
| suites: [subSuite], | |
| } as unknown as Mocha.Suite; | |
| const map = createTestIdMap(rootSuite); | |
| pruneSuite(rootSuite, map, { | |
| skippedTests: ['base/test.ts:suite:test_1', 'base/test.ts:suite:sub_suite'], | |
| }); | |
| assert.isTrue(test1.pending); | |
| assert.isTrue(test2.pending); | |
| assert.deepEqual(rootSuite.tests, [test1]); | |
| assert.deepEqual(subSuite.tests, [test2]); | |
| }); | |
| it('keeps all tests when testIds is empty', () => { | |
| const test1 = createMockTest({file: 'base/test.ts', titlePath: ['Suite', 'test 1']}); | |
| const suite: Mocha.Suite = { | |
| tests: [test1], | |
| suites: [], | |
| } as unknown as Mocha.Suite; | |
| const map = createTestIdMap(suite); | |
| pruneSuite(suite, map, {testIds: new Set()}); | |
| assert.deepEqual(suite.tests, [test1]); | |
| }); | |
| }); | |
| describe('duplicateTests', () => { | |
| it('duplicates tests in suites according to repetitions', () => { | |
| const originalTest = { | |
| pending: false, | |
| clone(): {pending: boolean} { | |
| return {pending: originalTest.pending}; | |
| }, | |
| } as unknown as Mocha.Test; | |
| const suite: Mocha.Suite = { | |
| tests: [originalTest], | |
| suites: [], | |
| _onlyTests: [] as Mocha.Test[], | |
| addTest(test: Mocha.Test) { | |
| suite.tests.push(test); | |
| }, | |
| } as unknown as Mocha.Suite; | |
| duplicateTests(suite, 3); | |
| assert.lengthOf(suite.tests, 3); | |
| }); | |
| }); | |
| describe('listContainsTestOrSuite', () => { | |
| it('returns true when exact test ID is present in an array', () => { | |
| const list = ['base/test.ts:suite:test_1', 'base/test.ts:suite:test_2']; | |
| assert.isTrue(listContainsTestOrSuite(list, 'base/test.ts:suite:test_1')); | |
| }); | |
| it('returns true when exact test ID is present in a set', () => { | |
| const set = new Set(['base/test.ts:suite:test_1', 'base/test.ts:suite:test_2']); | |
| assert.isTrue(listContainsTestOrSuite(set, 'base/test.ts:suite:test_1')); | |
| }); | |
| it('returns true when a suite prefix of test ID is present', () => { | |
| const list = ['base/test.ts:suite']; | |
| assert.isTrue(listContainsTestOrSuite(list, 'base/test.ts:suite:test_1')); | |
| assert.isTrue(listContainsTestOrSuite(list, 'base/test.ts:suite:sub_suite:test_2')); | |
| }); | |
| it('returns false when test ID is not present and no suite prefix matches', () => { | |
| const list = ['base/test.ts:suite:test_2', 'base/other.ts:suite']; | |
| assert.isFalse(listContainsTestOrSuite(list, 'base/test.ts:suite:test_1')); | |
| }); | |
| it('returns false when item in list is only a prefix without colon separator', () => { | |
| const list = ['base/test.ts:suite']; | |
| assert.isFalse(listContainsTestOrSuite(list, 'base/test.ts:suite_extra:test_1')); | |
| }); | |
| it('returns false when list is empty', () => { | |
| assert.isFalse(listContainsTestOrSuite([], 'base/test.ts:suite:test_1')); | |
| assert.isFalse(listContainsTestOrSuite(new Set(), 'base/test.ts:suite:test_1')); | |
| }); | |
| }); | |
| }); |