import path from 'node:path'; import {fileURLToPath} from 'node:url'; import tap from 'tap'; import * as globs from '../lib/globs.js'; const {test} = tap; const __dirname = fileURLToPath(new URL('.', import.meta.url)); tap.afterEach(() => { // We changed the CWD in some of the tests process.chdir(path.resolve(__dirname, '..')); }); function fixture(...args) { args.unshift(__dirname, 'fixture', 'globs'); return path.join(...args); } test('ignores relativeness in patterns', t => { const {filePatterns} = globs.normalizeGlobs({files: ['./foo.js', '!./bar'], extensions: ['js'], providers: []}); t.same(filePatterns, ['foo.js', '!bar']); t.end(); }); test('ignores trailing slashes in (simple) patterns', t => { const {filePatterns} = globs.normalizeGlobs({files: ['foo/', '!bar/', 'foo/{bar/,baz/}'], extensions: ['js'], providers: []}); t.same(filePatterns, ['foo', '!bar', 'foo/{bar/,baz/}']); t.end(); }); test('isTest with defaults', t => { const options = { ...globs.normalizeGlobs({ extensions: ['js'], providers: [], }), cwd: fixture(), }; function isTest(file) { t.ok(globs.classify(fixture(file), options).isTest, `${file} should be a test`); } function notTest(file) { t.notOk(globs.classify(fixture(file), options).isTest, `${file} should not be a test`); } isTest('__tests__/foo.js'); isTest('__tests__/foo/bar.js'); isTest('foo.spec.js'); isTest('foo.test.js'); isTest('test-foo.js'); isTest('test.js'); notTest('foo/test.js'); isTest('test/foo.js'); isTest('tests/foo.js'); notTest('foo-bar.js'); notTest('foo.js'); notTest('foo/blah.js'); notTest('bar/foo.js'); notTest('bar/foo-bar/baz/buz.js'); notTest('bar/baz/buz.js'); notTest('bar.js'); notTest('bar/bar.js'); notTest('_foo-bar.js'); notTest('foo/_foo-bar.js'); notTest('foo-bar.txt'); notTest('node_modules/foo.js'); notTest('fixtures/foo.js'); notTest('helpers/foo.js'); notTest('_foo/bar.js'); notTest('__tests__/__helper__/foo.js'); notTest('__tests__/__helper__/test.js'); notTest('__tests__/__helpers__/foo.js'); notTest('__tests__/__helpers__/test.js'); notTest('__tests__/__fixture__/foo.js'); notTest('__tests__/__fixture__/test.js'); notTest('__tests__/__fixtures__/foo.js'); notTest('__tests__/__fixtures__/test.js'); isTest('__tests__/helper/foo.js'); isTest('__tests__/fixtures/foo.js'); isTest('test/foo.js'); notTest('test/_foo/bar.js'); notTest('test/helper/foo.js'); notTest('test/helper/test.js'); notTest('test/helpers/foo.js'); notTest('test/helpers/test.js'); notTest('test/fixture/foo.js'); notTest('test/fixture/test.js'); notTest('test/fixtures/foo.js'); notTest('test/fixtures/test.js'); notTest('tests/helper/foo.js'); notTest('tests/helper/test.js'); notTest('tests/helpers/foo.js'); notTest('tests/helpers/test.js'); notTest('tests/fixture/foo.js'); notTest('tests/fixture/test.js'); notTest('tests/fixtures/foo.js'); notTest('tests/fixtures/test.js'); isTest('tests/__helper__/test.js'); isTest('tests/__fixtures__/test.js'); t.end(); }); test('isTest with patterns', t => { const options = { ...globs.normalizeGlobs({ files: ['**/foo*.js', '**/foo*/**/*.js', '!**/fixtures', '!**/helpers'], extensions: ['js'], providers: [], }), cwd: fixture(), }; function isTest(file) { t.ok(globs.classify(fixture(file), options).isTest, `${file} should be a test`); } function notTest(file) { t.notOk(globs.classify(fixture(file), options).isTest, `${file} should not be a test`); } isTest('foo-bar.js'); isTest('foo.js'); isTest('foo/blah.js'); isTest('bar/foo.js'); isTest('bar/foo-bar/baz/buz.js'); notTest('bar/baz/buz.js'); notTest('bar.js'); notTest('bar/bar.js'); notTest('_foo-bar.js'); notTest('foo/_foo-bar.js'); notTest('foo-bar.txt'); notTest('node_modules/foo.js'); notTest('fixtures/foo.js'); notTest('helpers/foo.js'); t.end(); }); test('isTest (pattern starts with directory)', t => { const options = { ...globs.normalizeGlobs({ files: ['bar/**/*'], extensions: ['js'], providers: [], }), cwd: fixture(), }; function isTest(file) { t.ok(globs.classify(fixture(file), options).isTest, `${file} should be a test`); } function notTest(file) { t.notOk(globs.classify(fixture(file), options).isTest, `${file} should not be a test`); } notTest('foo-bar.js'); notTest('foo.js'); notTest('foo/blah.js'); isTest('bar/foo.js'); isTest('bar/foo-bar/baz/buz.js'); isTest('bar/baz/buz.js'); notTest('bar.js'); isTest('bar/bar.js'); notTest('bar/_foo-bar.js'); notTest('foo/_foo-bar.js'); notTest('foo-bar.txt'); notTest('node_modules/foo.js'); notTest('fixtures/foo.js'); notTest('helpers/foo.js'); t.end(); }); test('isTest after provider modifications', t => { const options = { ...globs.normalizeGlobs({ extensions: ['js'], providers: [{ level: 2, main: { updateGlobs({filePatterns, ignoredByWatcherPatterns}) { t.ok(filePatterns.length > 0); t.ok(ignoredByWatcherPatterns.length > 0); return { filePatterns: ['foo.js'], ignoredByWatcherPatterns, }; }, }, }], }), cwd: fixture(), }; t.ok(globs.classify(fixture('foo.js'), options).isTest); t.notOk(globs.classify(fixture('bar.js'), options).isTest); t.end(); }); test('findFiles finds non-ignored files (just .cjs)', async t => { const fixtureDir = fixture('default-patterns'); process.chdir(fixtureDir); const expected = [ 'sub/directory/__tests__/_foo.cjs', 'sub/directory/__tests__/foo.cjs', 'sub/directory/bar.spec.cjs', 'sub/directory/bar.test.cjs', 'test-foo.cjs', 'test.cjs', 'test/_foo-help.cjs', 'test/baz.cjs', 'test/deep/deep.cjs', 'tests/baz.cjs', 'tests/deep/deep.cjs', 'tests/_foo-help.cjs', ].map(file => path.join(fixtureDir, file)).sort(); const actual = await globs.findFiles({ cwd: fixtureDir, ...globs.normalizeGlobs({files: ['!**/fixtures/*.*', '!**/helpers/*.*'], extensions: ['cjs'], providers: []}), }); actual.sort(); t.same(actual, expected); }); test('findFiles finds non-ignored files (.cjs, .jsx)', async t => { const fixtureDir = fixture('custom-extension'); process.chdir(fixtureDir); const expected = [ 'test/do-not-compile.cjs', 'test/foo.jsx', 'test/sub/_helper.jsx', 'test/sub/bar.jsx', ].sort().map(file => path.join(fixtureDir, file)); const actual = await globs.findFiles({ cwd: fixtureDir, ...globs.normalizeGlobs({files: ['!**/fixtures/*', '!**/helpers/*'], extensions: ['cjs', 'jsx'], providers: []}), }); actual.sort(); t.same(actual, expected); });