Skip to content

Commit

Permalink
test build: consistently sort everything the same way
Browse files Browse the repository at this point in the history
Fix: #891
  • Loading branch information
isaacs committed Sep 17, 2023
1 parent d5a7c8b commit ccc165e
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 44 deletions.
47 changes: 20 additions & 27 deletions src/test/scripts/build.mts
Expand Up @@ -20,6 +20,13 @@ let template = readFileSync(templateFile, 'utf8')

const defaultTarget = resolve(__dirname, '../test-built')

const sortedStrings = (s: string[]) =>
s.sort((a, b) => a.localeCompare(b, 'en'))
const sortedMapEntries = <T extends any>(m: Map<string, T>) =>
[...m.entries()].sort(([a], [b]) => a.localeCompare(b, 'en'))
const sortedMapValues = <T extends any>(m: Map<string, T>) =>
sortedMapEntries(m).map(([_, v]) => v)

// override in testing, otherwise always the default
/* c8 ignore start */
const dir = process.env._TESTING_TEST_BUILD_TARGET_ || defaultTarget
Expand All @@ -39,7 +46,7 @@ for (const f of copies) {
writeFileSync(resolve(dir, t), readFileSync(resolve(__dirname, f)))
}

const plugins = process.argv.slice(2)
const plugins = sortedStrings(process.argv.slice(2))
const seen = new Set<string>()

// If a plugin does not appear in hasConfig, hasPlugin, or hasLoader,
Expand All @@ -58,9 +65,7 @@ const preloaders = new Map<string, string>()
const preimports = new Map<string, string>()
const testFileExtensions = new Set<string>()

const signature = plugins
.sort((a, b) => a.localeCompare(b, 'en'))
.join('\n')
const signature = plugins.join('\n')
const signatureCode = `export const signature = \`${signature}\`
`
const configs = new Map<
Expand Down Expand Up @@ -100,7 +105,7 @@ const validPlugin = (p: any): p is PluginExport =>
typeof p.importLoader === 'string') &&
(p.preload === undefined || typeof p.preload === 'boolean')

const pluginNames = (
const pluginNames = sortedStrings(
await Promise.all(
plugins.map(async p => {
// this also verifies that all plugins can be loaded, or it'll blow
Expand Down Expand Up @@ -172,26 +177,21 @@ const pluginNames = (
name = ni
}
seen.add(name)
let isPlugin = false
if (imp.config) {
hasConfig.set(p, name)
configs.set(p, imp.config)
isPlugin = true
}
if (typeof imp.plugin === 'function') {
hasPlugin.set(p, name)
isPlugin = true
}
if (typeof imp.importLoader === 'string') {
if (imp.preload === true) preimports.set(p, imp.importLoader)
hasImport.set(p, imp.importLoader)
isPlugin = true
}
if (typeof imp.loader === 'string') {
if (imp.preload === true) preloaders.set(p, imp.loader)
if (!imp.importLoader) hasLoader.set(p, imp.loader)
else hasLoaderFallback.set(p, imp.loader)
isPlugin = true
}

// we can't reasonably add more file types if we didn't add some
Expand All @@ -217,7 +217,7 @@ const pluginNames = (
return name
})
)
).sort((a, b) => a.localeCompare(b))
)

const pluginImport = plugins
.map(
Expand All @@ -231,9 +231,7 @@ const pluginsConfig = (() => {
if (!hasConfig.size) return code + 'jack\n'

code += '{\n'
const hasConfigEntries = [...hasConfig.entries()].sort(([a], [b]) =>
a.localeCompare(b, 'en')
)
const hasConfigEntries = sortedMapEntries(hasConfig)
for (const [p, name] of hasConfigEntries) {
let c = 0
for (const [field, cfg] of Object.entries(configs.get(p) || {})) {
Expand Down Expand Up @@ -281,8 +279,7 @@ const pluginsConfig = (() => {
const pluginsCode = `export type PluginSet = ${
hasPlugin.size
? `[
${[...hasPlugin.values()]
.sort((a, b) => a.localeCompare(b, 'en'))
${sortedMapValues(hasPlugin)
.map(name => ` typeof ${name}.plugin,\n`)
.join('')}]`
: '(TapPlugin<any> | TapPlugin<any, TestBaseOpts>)[]'
Expand All @@ -291,21 +288,20 @@ ${[...hasPlugin.values()]
const plugins = () => {
if (plugins_) return plugins_
return (plugins_ = [
${[...hasPlugin.values()]
.sort((a, b) => a.localeCompare(b, 'en'))
${sortedMapValues(hasPlugin)
.map(name => ` ${name}.plugin,\n`)
.join('')} ])
}
`

const pluginLoaders = `const preloaders = new Set<string>(${JSON.stringify(
[...preloaders.values()].sort((a, b) => a.localeCompare(b, 'en')),
sortedMapValues(preloaders),
null,
2
)})
const preimports = new Set<string>(${JSON.stringify(
[...preimports.values()].sort((a, b) => a.localeCompare(b, 'en')),
sortedMapValues(preimports),
null,
2
)})
Expand All @@ -316,7 +312,7 @@ const preimports = new Set<string>(${JSON.stringify(
* that Node loads it before other loaders.
*/
export const loaders: string[] = ${JSON.stringify(
[...hasLoader.values()].sort((a, b) => a.localeCompare(b, 'en')),
sortedMapValues(hasLoader),
null,
2
)}.sort(
Expand All @@ -330,7 +326,7 @@ export const loaders: string[] = ${JSON.stringify(
* \`Module.register\` in node v20.6 and higher.
*/
export const importLoaders: string[] = ${JSON.stringify(
[...hasImport.values()].sort((a, b) => a.localeCompare(b, 'en')),
sortedMapValues(hasImport),
null,
2
)}.sort(
Expand All @@ -344,9 +340,7 @@ export const importLoaders: string[] = ${JSON.stringify(
* for those that also export an \`importLoader\`
*/
export const loaderFallbacks: string[] = ${JSON.stringify(
[...hasLoaderFallback.values()]
.concat([...hasLoader.values()])
.sort((a, b) => a.localeCompare(b, 'en')),
sortedMapValues(new Map([...hasLoaderFallback, ...hasLoader])),
null,
2
)}.sort(
Expand All @@ -357,8 +351,7 @@ export const loaderFallbacks: string[] = ${JSON.stringify(
`

const testFileExtensionsCode = [...testFileExtensions]
.sort((a, b) => a.localeCompare(b, 'en'))
const testFileExtensionsCode = sortedStrings([...testFileExtensions])
.map(ext => `testFileExtensions.add(${JSON.stringify(ext)})\n`)
.join('')

Expand Down
71 changes: 54 additions & 17 deletions src/test/test/build.ts
Expand Up @@ -10,6 +10,7 @@ const buildScriptURL = await resolveImport(
if (!buildScriptURL) throw new Error('could not load build script')
const buildScript = fileURLToPath(buildScriptURL)

import { readFileSync } from 'node:fs'
import os from 'node:os'
import { fileURLToPath } from 'node:url'
const p = os.availableParallelism
Expand Down Expand Up @@ -62,25 +63,62 @@ const build = async (
})
}

t.test('good plugins', async t => {
const dir = t.testdir()
const res = await build(dir, [
'@tapjs/asserts',
'@tapjs/dummy-plugin',
])
t.same(res, {
target: dir,
plugins: ['@tapjs/asserts', '@tapjs/dummy-plugin'],
code: 0,
signal: null,
stderr: '',
stdout: `
t.test(
'good plugins, sort order tests',
{ saveFixture: true },
async t => {
const dir = t.testdir()
const plugins = [
// intentionally unsorted
'@tapjs/typescript',
'@tapjs/dummy-plugin',
'@tapjs/worker',
'@tapjs/asserts',
]
const res = await build(dir, plugins)
t.same(res, {
target: dir,
plugins,
code: 0,
signal: null,
stderr: '',
stdout: `
> @tapjs/test-built@0.0.0 prepare
> tshy
`,
})
})
})
const built = readFileSync(resolve(dir, 'src/index.ts'), 'utf8')
const sorted = plugins.sort((a, b) => a.localeCompare(b, 'en'))
t.same(await build(dir, sorted), {
target: dir,
plugins: sorted,
code: 0,
signal: null,
stderr: '',
stdout: `
> @tapjs/test-built@0.0.0 prepare
> tshy
`,
})
t.equal(readFileSync(resolve(dir, 'src/index.ts'), 'utf8'), built)
const rsorted = plugins.sort((a, b) => a.localeCompare(b, 'en'))
t.same(await build(dir, rsorted), {
target: dir,
plugins: rsorted,
code: 0,
signal: null,
stderr: '',
stdout: `
> @tapjs/test-built@0.0.0 prepare
> tshy
`,
})
t.equal(readFileSync(resolve(dir, 'src/index.ts'), 'utf8'), built)
}
)

t.test('missing plugin', async t => {
const dir = t.testdir()
Expand Down Expand Up @@ -126,8 +164,7 @@ t.test('invalid plugin', async t => {
plugins: [plugin],
code: 1,
signal: null,
stderr:
`'${plugin}' does not appear to be a tap plugin. `,
stderr: `'${plugin}' does not appear to be a tap plugin. `,
stdout: '',
})
})
Expand Down

0 comments on commit ccc165e

Please sign in to comment.