Skip to content

Commit

Permalink
chore: upgrade testing environment
Browse files Browse the repository at this point in the history
  • Loading branch information
ph-fritsche committed Dec 27, 2023
1 parent 6a3c896 commit c4b4629
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 193 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ node_modules
coverage
dist
.DS_Store
.swc

# these cause more harm than good
# when working with contributors
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,18 @@
"validate": "kcd-scripts typecheck"
},
"devDependencies": {
"@esbuild-plugins/node-modules-polyfill": "^0.2.2",
"@ph.fritsche/scripts-config": "^2.4.0",
"@ph.fritsche/toolbox": "^1.0.0-alpha.1",
"@ph.fritsche/toolbox": "^1.0.0-alpha.11",
"@testing-library/dom": "^8.19.0",
"@testing-library/jest-dom": "^5.16.3",
"@testing-library/react": "^13.4.0",
"@types/jest-in-case": "^1.0.3",
"@types/react": "^18.0.25",
"@types/sinonjs__fake-timers": "^8.1.2",
"css.escape": "^1.5.1",
"esbuild": "^0.19.10",
"esbuild-plugin-globals": "^0.2.0",
"eslint-import-resolver-typescript": "^3.5.2",
"eslint-plugin-local-rules": "^1.3.2",
"expect": "^28.1.3",
Expand Down
71 changes: 20 additions & 51 deletions scripts/setup.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import fs from 'fs/promises'
import path from 'path'
import {createBundleBuilder} from '@ph.fritsche/toolbox/dist/builder/index.js'
import {spawn} from 'child_process'
import esbuild from 'esbuild'
import pluginGlobals from 'esbuild-plugin-globals'
import {NodeModulesPolyfillPlugin} from '@esbuild-plugins/node-modules-polyfill'

const dirname = path.dirname(new URL(import.meta.url).pathname)
const indexDirLib = path.join(dirname, '../testenv/libs')
Expand Down Expand Up @@ -92,61 +94,28 @@ async function buildLib(name, dir) {

process.stdout.write(`Bundling library "${name}" at ${dir}/index.js\n`)

const builder = createBundleBuilder({
basePath: `${dir}/`,
globals,
await esbuild.build({
entryPoints: [`${dir}/index.js`],
outfile: `${dir}/index.bundle.js`,
bundle: true,
plugins: [
pluginGlobals(globals),
],
})
builder.inputFiles.set(`${dir}/index.js`, undefined)

builder.emitter.addListener('complete', e => {
const content = String(e.outputFiles.get('index.js')?.content)
fs.writeFile(`${dir}/index.bundle.js`, content).then(() =>
process.stdout.write(
[
'<<<',
`Wrote ${dir}/index.bundle.js`,
`[${content.length} bytes]`,
...(globals && Object.keys(globals).length
? [
` Depending on:`,
...Object.entries(globals).map(
([module, name]) => ` ${name} => ${module}`,
),
]
: []),
'>>>',
'',
].join('\n'),
),
)
})

builder.build()
}

async function buildEnv(name, file) {
process.stdout.write(`Bundling environment "${name}" at ${file}\n`)

const builder = createBundleBuilder({
basePath: `${indexDirEnv}/`,
})
const basename = path.basename(file, '.js')
builder.inputFiles.set(file, undefined)

builder.emitter.addListener('complete', e => {
const content = String(e.outputFiles.get(`${basename}.js`)?.content)
fs.writeFile(`${indexDirEnv}/${basename}.bundle.js`, content).then(() =>
process.stdout.write(
[
'<<<',
`Wrote ${indexDirEnv}/${basename}.bundle.js`,
`[${content.length} bytes]`,
'>>>',
'',
].join('\n'),
),
)
})
const base = path.basename(file, '.js')

builder.build()
await esbuild.build({
entryPoints: [file],
outfile: `${indexDirEnv}/${base}.bundle.js`,
bundle: true,
sourcemap: 'inline',
plugins: [
NodeModulesPolyfillPlugin(),
],
})
}
195 changes: 54 additions & 141 deletions scripts/test.js
Original file line number Diff line number Diff line change
@@ -1,153 +1,66 @@
import {
createProjectBuildProvider,
serveDir,
serveToolboxRunner,
} from '@ph.fritsche/toolbox'
import {NodeTestConductor} from '@ph.fritsche/toolbox/dist/conductor/NodeTestConductor.js'
import {ChromeTestConductor} from '@ph.fritsche/toolbox/dist/conductor/ChromeTestConductor.js'
import {ConsoleReporter} from '@ph.fritsche/toolbox/dist/reporter/ConsoleReporter.js'
import {ReporterServer} from '@ph.fritsche/toolbox/dist/reporter/ReporterServer.js'
import {TestRunStack} from '@ph.fritsche/toolbox/dist/reporter/TestRunStack.js'

import IstanbulLibCoverage from 'istanbul-lib-coverage'
import IstanbulLibReport from 'istanbul-lib-report'
import IstanbulLibSourceMaps from 'istanbul-lib-source-maps'
import IstanbulReports from 'istanbul-reports'
import { serveDir, setupChromeConductor, setupNodeConductor, setupSourceModuleLoader, setupToolboxTester } from '@ph.fritsche/toolbox'

const tsConfigFile = './tests/tsconfig.json'

const toolbox = await serveToolboxRunner()
const env = await serveDir('testenv')

const {buildProvider, fileProvider, fileServer, onBuildDone} =
createProjectBuildProvider(['src', 'tests'], {
tsConfigFile,
globals: {
'@testing-library/dom': 'DomTestingLibrary',
'@testing-library/react': 'ReactTestingLibrary',
react: 'React',
'react-dom': 'ReactDom',
},
})

for (const {builder} of buildProvider.builders) {
builder.emitter.addListener('start', ({type, buildId, inputFiles}) =>
console.log(builder.id, {type, buildId, inputFiles: inputFiles.size}),
)
builder.emitter.addListener(
'complete',
({type, buildId, inputFiles, outputFiles}) =>
console.log(builder.id, {
type,
buildId,
inputFiles: inputFiles.size,
outputFiles: outputFiles.size,
}),
)
builder.emitter.addListener('error', ({type, buildId, error}) =>
console.log(builder.id, {type, buildId, error}),
)
builder.emitter.addListener('done', ({type, buildId}) =>
console.log(builder.id, {type, buildId}),
)
}
buildProvider
.getBuilder('dependencies')
.builder.emitter.addListener('start', ({inputFiles}) =>
console.log('dependencies', inputFiles.keys()),
)

const filter = f =>
f.startsWith('tests') &&
/(?<!\.json)\.js$/.test(f) &&
!/\/_.+(?<!\.test)\.[jt]sx?$/.test(f)

const reporterServer = new ReporterServer()
await reporterServer.registerFileServer(toolbox.server)
await reporterServer.registerFileServer(env.server)
await reporterServer.registerFileServer(fileServer)

const consoleReporter = new ConsoleReporter()
consoleReporter.config.result = !!process.env.CI
consoleReporter.connect(reporterServer)

const conductors = [
new ChromeTestConductor(
reporterServer,
toolbox.url,
'Chrome, DTL8, React18',
const tester = await setupToolboxTester(
[
'src',
'tests',
],
[
setupNodeConductor('Node, DTL8, React18', [
new URL('../testenv/node.js', import.meta.url),
new URL('./libs/dom8/index.bundle.js', env.url),
new URL('./libs/react18/index.bundle.js', env.url),
]),
setupNodeConductor('Node, DTL8, React17', [
new URL('../testenv/node.js', import.meta.url),
new URL('./libs/dom8/index.bundle.js', env.url),
new URL('./libs/react17/index.bundle.js', env.url),
]),
setupChromeConductor('Chrome, DTL8, React18', [
new URL('./browser.bundle.js', env.url),
new URL('./libs/dom8/index.bundle.js', env.url),
new URL('./libs/react18/index.bundle.js', env.url),
])
],
[
{server: env.url, paths: ['browser.bundle.js']},
{
server: env.url,
paths: ['libs/dom8/index.bundle.js', 'libs/react18/index.bundle.js'],
},
await setupSourceModuleLoader({
globals: {
'@testing-library/dom': 'DomTestingLibrary',
'@testing-library/react': 'ReactTestingLibrary',
'react': 'React',
'react-dom': 'ReactDom',
},
}),
],
),
new NodeTestConductor(reporterServer, toolbox.url, 'Node, DTL8, React18', [
{server: new URL(`file://${env.provider.origin}`), paths: ['node.js']},
{
server: env.url,
paths: ['libs/dom8/index.bundle.js', 'libs/react18/index.bundle.js'],
},
]),
]

if (process.env.CI) {
conductors.push(
new NodeTestConductor(reporterServer, toolbox.url, 'Node, DTL8, React17', [
{server: new URL(`file://${env.provider.origin}`), paths: ['node.js']},
{
server: env.url,
paths: ['libs/dom8/index.bundle.js', 'libs/react17/index.bundle.js'],
},
]),
)
}

onBuildDone(async () => {
const files = {
server: await fileServer.url,
paths: Array.from(fileProvider.files.keys()).filter(filter),
}
const runs = conductors.map(c => c.createTestRun(files))
const stack = new TestRunStack(runs.map(r => r.run))

for (const r of runs) {
await r.exec()
}

await stack.then()

const coverageMap = IstanbulLibCoverage.createCoverageMap()
for (const run of stack.runs) {
for (const coverage of run.coverage.values()) {
coverageMap.merge(coverage)
setExitCode: false,
}
}

const sourceStore = IstanbulLibSourceMaps.createSourceMapStore()
const reportContext = IstanbulLibReport.createContext({
coverageMap: await sourceStore.transformCoverage(coverageMap),
dir: fileProvider.origin,
sourceFinder: sourceStore.sourceFinder,
defaultSummarizer: 'nested',
watermarks: {
branches: [80, 100],
functions: [80, 100],
lines: [80, 100],
statements: [80, 100],
},
})
)

tester.connectCoverageReporter(async map => {
const sourceStore = IstanbulLibSourceMaps.createSourceMapStore()
const reportContext = IstanbulLibReport.createContext({
coverageMap: await sourceStore.transformCoverage(map),
sourceFinder: sourceStore.sourceFinder,
defaultSummarizer: 'nested',
watermarks: {
branches: [80, 100],
functions: [80, 100],
lines: [80, 100],
statements: [80, 100],
},
})

IstanbulReports.create('text').execute(reportContext)
})

IstanbulReports.create('text').execute(reportContext)
await tester.start()

if (process.env.CI) {
toolbox.server.close()
env.server.close()
fileServer.close()
buildProvider.close()
reporterServer.close()
conductors.forEach(c => c.close())
}
})
if (process.env.CI) {
await env.server.close()
}

0 comments on commit c4b4629

Please sign in to comment.