Skip to content

Commit 3ec0508

Browse files
committed
fix: test result, support run all projects
1 parent 4983d35 commit 3ec0508

File tree

4 files changed

+78
-100
lines changed

4 files changed

+78
-100
lines changed

packages/tester/ts/app.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { cli, z } from 'clibuilder'
2+
import { dirSync } from 'find'
23
import { compile } from 'handlebars'
34
import { parse } from 'json5'
45
import fs from 'node:fs'
56
import path from 'node:path'
67
import { context, forEachKey } from 'type-plus'
78
import { getProjectPath, getTestSubjects, readPackageJson } from './logic/project'
8-
import { extractRuntimeErrorMessage, genTestResults, runCompile, runCompileAndRuntimeTests, runRuntime } from './testResults'
9-
import { dirSync } from 'find'
9+
import { extractRuntimeErrorMessage, genTestResults, runCompile, runRuntime } from './testResults'
1010

1111
const projectArg = { name: 'project' as const, description: 'project name', type: z.optional(z.string()) }
1212
const moduleTypesOption = {
@@ -22,20 +22,22 @@ export const app = cli({ name: 'tester', version: '0.0.1' })
2222
async run({ project, moduleTypes }) {
2323
const projects = project ? [project] : getProjects()
2424
await Promise.all(projects.map(async project => {
25+
this.ui.info(`building demo: ${project}`)
2526
const ctx = context({ project, moduleTypes })
2627
.extend(getProjectPath)
2728
.extend(readPackageJson)
2829
.extend(getTypeScriptInfo)
2930
.extend(getTestSubjects)
30-
.extend(runCompileAndRuntimeTests)
31+
.extend(runCompile)
32+
.extend(runRuntime)
3133
.build()
3234

3335
fs.writeFileSync(
3436
path.join(ctx.projectPath, `test-result.${ctx.tsVersion}.md`),
3537
[genTestConfiguration(ctx),
3638
genTestSubjects(ctx),
3739
genLegends(),
38-
genTestResults({ ...ctx, results: await ctx.results })].join('\n')
40+
await genTestResults(ctx)].join('\n')
3941
)
4042
}))
4143
}
@@ -47,6 +49,7 @@ export const app = cli({ name: 'tester', version: '0.0.1' })
4749
async run({ project, moduleTypes }) {
4850
const projects = project ? [project] : getProjects()
4951
await Promise.all(projects.map(async project => {
52+
this.ui.info(`compile: ${project}`)
5053
const ctx = context({ project, moduleTypes })
5154
.extend(getProjectPath)
5255
.extend(runCompile)
@@ -76,6 +79,7 @@ export const app = cli({ name: 'tester', version: '0.0.1' })
7679
async run({ project, moduleTypes }) {
7780
const projects = project ? [project] : getProjects()
7881
await Promise.all(projects.map(async project => {
82+
this.ui.info(`runtime: ${project}`)
7983
const ctx = context({ project, moduleTypes })
8084
.extend(getProjectPath)
8185
.extend(readPackageJson)
@@ -90,7 +94,7 @@ export const app = cli({ name: 'tester', version: '0.0.1' })
9094
const moduleType = moduleResult.moduleType
9195
const results = await moduleResult.results
9296
results.forEach(subjectResult => {
93-
const subject = subjectResult.name
97+
const subject = subjectResult.subject
9498
subjectResult.results.forEach(result => {
9599
lines.push([moduleType.padEnd(8), subject.padEnd(10), result.importType.padEnd(10), extractRuntimeErrorMessage(result.error)])
96100
})
@@ -103,7 +107,7 @@ export const app = cli({ name: 'tester', version: '0.0.1' })
103107
})
104108

105109
function getProjects() {
106-
return dirSync('tests')
110+
return fs.readdirSync('tests')
107111
}
108112

109113
function getTypeScriptInfo(ctx: { packageJson: any, projectPath: string }) {

packages/tester/ts/logic/project.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ export function getTestSubjects({
3131
}
3232
}
3333

34+
export type TestSubjectsContext = ReturnType<typeof getTestSubjects>
35+
3436
export function readPackageJson(ctx: { projectPath: string }) {
3537
const packageJsonPath = path.join(ctx.projectPath, 'package.json')
3638
return { packageJson: parse(readFileSync(packageJsonPath, 'utf8')) }
3739
}
3840

39-
40-
4141
function getTestFiles(projectPath: string, dependencyName: string) {
4242
const base = path.join(projectPath, 'ts')
4343
// the `.` at the end makes sure it match the exact package name.

packages/tester/ts/logic/runtime.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import path from 'node:path'
44
import { getTestSubjects } from './project'
55

66
export type RuntimeResult = {
7-
name: string
7+
subject: string
88
results: {
99
filename: string
1010
importType: string
@@ -37,7 +37,7 @@ export async function runProject(ctx: {
3737
})
3838
})))
3939
return {
40-
name: testSubject.name,
40+
subject: testSubject.name,
4141
results
4242
}
4343
})).then(r => r.filter(r => r.results.length > 0))

packages/tester/ts/testResults.ts

Lines changed: 64 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { compile } from 'handlebars'
22
import fs from 'node:fs'
33
import path from 'node:path'
4-
import { AwaitedProp, record } from 'type-plus'
4+
import { forEachKey, record } from 'type-plus'
55
import { CompileResult, PackageCompileResults, compileProject } from './logic/compile'
6-
import { getTestSubjects, toImportMap } from './logic/project'
6+
import { TestSubjectsContext, getTestSubjects, toImportMap } from './logic/project'
77
import { RuntimeResult, runProject } from './logic/runtime'
88
import { reduceFlatMessage } from './logic/utils'
99

@@ -16,123 +16,97 @@ export function runCompile(ctx: {
1616
}
1717
}
1818

19+
type RunCompileContext = ReturnType<typeof runCompile>
20+
1921
export function runRuntime(ctx: {
2022
project: string,
2123
moduleTypes: string[],
2224
projectPath: string,
2325
packageJson: any
2426
} & ReturnType<typeof getTestSubjects>) {
2527
return {
26-
runtime: Promise.all(ctx.moduleTypes.map(moduleType => ({
28+
runtime: ctx.moduleTypes.map(moduleType => ({
2729
moduleType,
2830
results: runProject(ctx, moduleType)
29-
})))
30-
}
31-
}
32-
33-
export function runCompileAndRuntimeTests(ctx: {
34-
project: string,
35-
moduleTypes: string[],
36-
projectPath: string,
37-
packageJson: any
38-
} & ReturnType<typeof getTestSubjects>) {
39-
return {
40-
results: compileProject(ctx)
41-
.then(compileResults => Promise.all(
42-
ctx.moduleTypes.map(moduleType =>
43-
runProject(ctx, moduleType).then(runtimeResults => ({
44-
moduleType,
45-
compileResults: compileResults[moduleType],
46-
runtimeResults
47-
}))))
48-
)
31+
}))
4932
}
5033
}
5134

52-
type TestSubjectsContext = ReturnType<typeof getTestSubjects>
53-
type TestResultsContext = AwaitedProp<ReturnType<typeof runCompileAndRuntimeTests>, 'results'>
35+
type RunRuntimeContext = ReturnType<typeof runRuntime>
5436

55-
export function genTestResults(
56-
ctx: TestSubjectsContext & TestResultsContext) {
57-
const results = collectTestResults(ctx)
37+
export async function genTestResults(
38+
ctx: { moduleTypes: string[] } & TestSubjectsContext & RunCompileContext & RunRuntimeContext) {
39+
const results = await collectTestResults(ctx)
5840
const template = compile(fs.readFileSync(path.join(__dirname, '../templates/test-results.hbs'), 'utf8'))
5941
return template(results)
6042
}
6143

62-
function collectTestResults({ subjects, results }: TestSubjectsContext & TestResultsContext) {
44+
async function collectTestResults({ moduleTypes, subjects, compile, runtime }: { moduleTypes: string[] } & TestSubjectsContext & RunCompileContext & RunRuntimeContext) {
45+
const compileResults = await compile
46+
const runtimeResults = await Promise.all(runtime.map(async r => ({
47+
moduleType: r.moduleType,
48+
results: await r.results
49+
})))
50+
const results = moduleTypes.map(moduleType => ({
51+
moduleType,
52+
compileResults: compileResults[moduleType],
53+
runtimeResults: runtimeResults.find(r => r.moduleType === moduleType)!.results
54+
}))
6355
const errors = toErrorRecord(results)
56+
// console.log('runtime errors', errors.runtime)
6457
return {
6558
results: results.flatMap(({ moduleType, compileResults, runtimeResults }) => {
59+
// console.log(moduleType, runtimeResults.map(r => ([r.subject, ...r.results.map(r => ([r.importType, extractRuntimeErrorMessage(r.error)]))])))
6660
return subjects.flatMap((s, i) => {
67-
const compileResult = compileResults[s.name]
68-
const runtimeResult = runtimeResults.find(r => r.name === s.name)
61+
const compileResult: Array<CompileResult> = compileResults[s.name]
62+
const runtimeResult = runtimeResults.find(r => r.subject === s.name)
63+
const compileImportMap = toImportMap(compileResult ? compileResult.map(c => {
64+
const error = errors.compile.find(e => e.message === c.messageText)
65+
return {
66+
importType: c.importType,
67+
transient: c.transient,
68+
value: error?.key ?? ''
69+
}
70+
}) : (s.files.length === 0 ? [
71+
{ importType: 'default', notApply: true },
72+
{ importType: 'default-as', notApply: true },
73+
{ importType: 'star', notApply: true },
74+
] : [
75+
{ importType: 'default', },
76+
{ importType: 'default-as' },
77+
{ importType: 'star' },
78+
]))// TypeError: m.default is not a function
79+
const runtimeImportMap = toImportMap(runtimeResult ? runtimeResult.results.map((r, i) => {
80+
const error = errors.runtime.find(e => e.message === extractRuntimeErrorMessage(r.error))
81+
return {
82+
importType: r.importType,
83+
transient: false,
84+
value: error?.key ?? ''
85+
}
86+
}) : (s.files.length === 0 ? [
87+
{ importType: 'default', notApply: true },
88+
{ importType: 'default-as', notApply: true },
89+
{ importType: 'star', notApply: true },
90+
] : [
91+
{ importType: 'default', },
92+
{ importType: 'default-as' },
93+
{ importType: 'star' },
94+
]))
95+
forEachKey(runtimeImportMap, (k) => {
96+
if (!compileImportMap[k].value && runtimeImportMap[k].value) {
97+
runtimeImportMap[k].icon = '❌'
98+
}
99+
})
69100
return [{
70101
moduleType: i === 0 ? moduleType : undefined,
71102
package: s.name,
72103
type: '💻 compile',
73-
...toImportMap(compileResult ? compileResult.map(c => {
74-
const error = errors.compile.find(e => e.message === c.messageText)
75-
return {
76-
importType: c.importType,
77-
transient: c.transient,
78-
value: error?.key ?? ''
79-
}
80-
}) : (s.files.length === 0 ? [
81-
{ importType: 'default', notApply: true },
82-
{ importType: 'default-as', notApply: true },
83-
{ importType: 'star', notApply: true },
84-
] : [
85-
{ importType: 'default', },
86-
{ importType: 'default-as' },
87-
{ importType: 'star' },
88-
]))
104+
...compileImportMap
89105
}, {
90106
type: '🏃 runtime',
91-
...toImportMap(runtimeResult ? runtimeResult.results.map(r => {
92-
const error = errors.runtime.find(e => e.message === extractRuntimeErrorMessage(r.error))
93-
return {
94-
importType: r.importType,
95-
transient: false,
96-
value: error?.key ?? ''
97-
}
98-
}) : (s.files.length === 0 ? [
99-
{ importType: 'default', notApply: true },
100-
{ importType: 'default-as', notApply: true },
101-
{ importType: 'star', notApply: true },
102-
] : [
103-
{ importType: 'default', },
104-
{ importType: 'default-as' },
105-
{ importType: 'star' },
106-
]))
107+
...runtimeImportMap
107108
}]
108109
})
109-
// return runtimeResults.flatMap((r, i) => {
110-
// return [{
111-
// moduleType: i === 0 ? moduleType : undefined,
112-
// package: r.name,
113-
// type: '💻 compile',
114-
// ...toImportMap(compileResults[r.name]?.map(c => {
115-
// const error = errors.compile.find(e => e.message === c.messageText)
116-
// return {
117-
// importType: c.importType,
118-
// transient: c.transient,
119-
// value: error?.key ?? ''
120-
// }
121-
// }))
122-
// }, {
123-
// moduleType: undefined,
124-
// package: r.name,
125-
// type: '🏃 runtime',
126-
// ...toImportMap(r.results.map(r => {
127-
// const error = errors.runtime.find(e => e.message === extractRuntimeErrorMessage(r.error))
128-
// return {
129-
// importType: r.importType,
130-
// transient: false,
131-
// value: error?.key ?? ''
132-
// }
133-
// }))
134-
// }]
135-
// })
136110
}),
137111
errors: [...errors.compile, ...errors.runtime]
138112
}

0 commit comments

Comments
 (0)