Skip to content

Commit 0b9a57f

Browse files
committed
feat: add test command
1 parent 28000df commit 0b9a57f

File tree

7 files changed

+643
-0
lines changed

7 files changed

+643
-0
lines changed

commands/Test.ts

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*
2+
* @adonisjs/assembler
3+
*
4+
* (c) Harminder Virk <[email protected]>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
import { BaseCommand, flags } from '@adonisjs/core/build/standalone'
11+
import { JapaFlags } from '../src/Contracts'
12+
13+
/**
14+
* Run tests
15+
*/
16+
export default class Test extends BaseCommand {
17+
public static commandName = 'test'
18+
public static description = 'Run AdonisJS tests'
19+
public static settings = {
20+
stayAlive: true,
21+
}
22+
23+
/**
24+
* Allows watching for file changes
25+
*/
26+
@flags.boolean({
27+
description: 'Watch for file changes and re-run tests on file change',
28+
alias: 'w',
29+
})
30+
public watch: boolean
31+
32+
/**
33+
* Detect changes by polling files
34+
*/
35+
@flags.boolean({
36+
description: 'Detect file changes by polling files instead of listening to filesystem events',
37+
alias: 'p',
38+
})
39+
public poll: boolean
40+
41+
/**
42+
* Arguments to pass to the `node` binary
43+
*/
44+
@flags.array({ description: 'CLI options to pass to the node command line' })
45+
public nodeArgs: string[] = []
46+
47+
@flags.array({ description: 'Run tests for only specified tags' })
48+
public tags: string[]
49+
50+
@flags.array({ description: 'Run all the tests except the tests using specified tags' })
51+
public ignoreTags: string[]
52+
53+
@flags.number({ description: 'Define timeout for tests' })
54+
public timeout: number
55+
56+
@flags.array({ description: 'Run tests for only the specified suites' })
57+
public suites: string[]
58+
59+
@flags.array({ description: 'Run tests for only the specified groups' })
60+
public groups: string[]
61+
62+
@flags.array({ description: 'Run tests with the specified titles' })
63+
public tests: string[]
64+
65+
@flags.boolean({ description: 'Force exit the tests runner process' })
66+
public forceExit: boolean
67+
68+
/**
69+
* Convert command flags to test filters
70+
*/
71+
private getTestFilters() {
72+
const filters: JapaFlags = {}
73+
if (this.forceExit) {
74+
filters['--force-exit'] = true
75+
}
76+
77+
if (this.timeout !== undefined) {
78+
filters['--timeout'] = this.timeout
79+
}
80+
81+
if (this.tests) {
82+
filters['--tests'] = this.tests
83+
}
84+
85+
if (this.groups) {
86+
filters['--groups'] = this.groups
87+
}
88+
89+
if (this.suites) {
90+
filters['--suites'] = this.suites
91+
}
92+
93+
if (this.tags) {
94+
filters['--tags'] = this.tags
95+
}
96+
97+
if (this.ignoreTags) {
98+
filters['--ignore-tags'] = this.ignoreTags
99+
}
100+
101+
return filters
102+
}
103+
104+
public async run() {
105+
const { TestsServer } = await import('../src/Test')
106+
107+
try {
108+
if (this.watch) {
109+
await new TestsServer(
110+
this.application.appRoot,
111+
this.getTestFilters(),
112+
this.nodeArgs,
113+
this.logger
114+
).watch()
115+
} else {
116+
await new TestsServer(
117+
this.application.appRoot,
118+
this.getTestFilters(),
119+
this.nodeArgs,
120+
this.logger
121+
).run()
122+
}
123+
} catch (error) {
124+
this.exitCode = 1
125+
this.logger.fatal(error)
126+
}
127+
}
128+
}

config/paths.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ export const DEFAULT_BUILD_DIR = 'build'
1212
export const RCFILE_NAME = '.adonisrc.json'
1313
export const ENV_FILES = ['.env', '.env.testing']
1414
export const SERVER_ENTRY_FILE = 'server.ts'
15+
export const TESTS_ENTRY_FILE = 'tests.ts'
1516
export const TSCONFIG_FILE_NAME = 'tsconfig.json'

src/Contracts/index.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
* @adonisjs/assembler
3+
*
4+
* (c) Harminder Virk <[email protected]>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
export type JapaFlags = Partial<{
11+
'--tests': string[]
12+
'--tags': string[]
13+
'--groups': string[]
14+
'--ignore-tags': string[]
15+
'--files': string[]
16+
'--timeout': number
17+
'--suites': string[]
18+
'--force-exit': boolean
19+
}>

src/RcFile/index.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ export class RcFile {
3838
*/
3939
public isMetaFile: (filePath: string) => boolean = picomatch(this.getMetaFilesGlob())
4040

41+
/**
42+
* A matcher to know if file is a test file or not
43+
*/
44+
public isTestsFile: (filePath: string) => boolean = picomatch(this.getTestsFileGlob())
45+
4146
/**
4247
* A matcher to know if a file is part of the restart server files globs
4348
*/
@@ -99,6 +104,19 @@ export class RcFile {
99104
.concat([ACE_FILE_NAME])
100105
}
101106

107+
/**
108+
* Returns an array of globs for the test files
109+
*/
110+
public getTestsFileGlob(): string[] {
111+
return this.application.rcFile.tests.suites.reduce((result, suite) => {
112+
if (suite.files) {
113+
result = result.concat(suite.files)
114+
}
115+
116+
return result
117+
}, [] as string[])
118+
}
119+
102120
/**
103121
* Reloads the rcfile.json
104122
*/
@@ -119,6 +137,7 @@ export class RcFile {
119137
reload: true,
120138
rcFile: true,
121139
metaFile: true,
140+
testFile: false,
122141
}
123142
}
124143

@@ -130,6 +149,7 @@ export class RcFile {
130149
reload: true,
131150
rcFile: false,
132151
metaFile: true,
152+
testFile: false,
133153
}
134154
}
135155

@@ -141,6 +161,19 @@ export class RcFile {
141161
reload: false,
142162
rcFile: false,
143163
metaFile: true,
164+
testFile: false,
165+
}
166+
}
167+
168+
/**
169+
* File is part of one of the tests suite
170+
*/
171+
if (this.isTestsFile(filePath)) {
172+
return {
173+
reload: false,
174+
rcFile: false,
175+
metaFile: false,
176+
testFile: true,
144177
}
145178
}
146179

@@ -151,6 +184,7 @@ export class RcFile {
151184
reload: false,
152185
rcFile: false,
153186
metaFile: false,
187+
testFile: false,
154188
}
155189
}
156190
}

0 commit comments

Comments
 (0)