@oclif/test 3.0.3 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +230 -3
  2. package/package.json +4 -4
package/README.md CHANGED
@@ -1,9 +1,236 @@
1
- @oclif/test
2
- ============
1
+ # @oclif/test
3
2
 
4
- test helpers for oclif components
3
+ test helpers for oclif CLIs
5
4
 
6
5
  [![Version](https://img.shields.io/npm/v/@oclif/test.svg)](https://npmjs.org/package/@oclif/test)
7
6
  [![Known Vulnerabilities](https://snyk.io/test/npm/@oclif/test/badge.svg)](https://snyk.io/test/npm/@oclif/test)
8
7
  [![Downloads/week](https://img.shields.io/npm/dw/@oclif/test.svg)](https://npmjs.org/package/@oclif/test)
9
8
  [![License](https://img.shields.io/npm/l/@oclif/test.svg)](https://github.com/oclif/test/blob/main/package.json)
9
+
10
+ ## Usage
11
+
12
+ `@oclif/test` is an extension of [fancy-test](https://github.com/oclif/fancy-test). Please see the [fancy-test documentation](https://github.com/oclif/fancy-test#fancy-test) for all the features that are available.
13
+
14
+ The following are the features that `@oclif/test` adds to `fancy-test`.
15
+
16
+ ### `.loadConfig()`
17
+
18
+ `.loadConfig()` creates and returns a new [`Config`](https://github.com/oclif/core/blob/main/src/config/config.ts) instance. This instance will be available on the `ctx` variable that's provided in the callback.
19
+
20
+ ```typescript
21
+ import {join} from 'node:path'
22
+ import {expect, test} from '@oclif/test'
23
+
24
+ const root = join(__dirname, 'fixtures/test-cli')
25
+ test
26
+ .loadConfig({root})
27
+ .stdout()
28
+ .command(['foo:bar'])
29
+ .it('should run the command from the given directory', (ctx) => {
30
+ expect(ctx.stdout).to.equal('hello world!\n')
31
+ expect(ctx.config.root).to.equal(root)
32
+ const {name} = ctx.returned as {name: string}
33
+ expect(name).to.equal('world')
34
+ })
35
+ ```
36
+
37
+ If you would like to run the same test without using `@oclif/test`:
38
+
39
+ ```typescript
40
+ import {Config, ux} from '@oclif/core'
41
+ import {expect} from 'chai'
42
+ import {join} from 'node:path'
43
+ import {SinonSandbox, SinonStub, createSandbox} from 'sinon'
44
+
45
+ const root = join(__dirname, 'fixtures/test-cli')
46
+ describe('non-fancy test', () => {
47
+ let sandbox: SinonSandbox
48
+ let config: Config
49
+ let stdoutStub: SinonStub
50
+
51
+ beforeEach(async () => {
52
+ sandbox = createSandbox()
53
+ stdoutStub = sandbox.stub(ux.write, 'stdout')
54
+ config = await Config.load({root})
55
+ })
56
+
57
+ afterEach(async () => {
58
+ sandbox.restore()
59
+ })
60
+
61
+ it('should run command from the given directory', async () => {
62
+ const {name} = await config.runCommand<{name: string}>('foo:bar')
63
+ expect(stdoutStub.calledWith('hello world!\n')).to.be.true
64
+ expect(config.root).to.equal(root)
65
+ expect(name).to.equal('world')
66
+ })
67
+ })
68
+ ```
69
+
70
+ ### `.command()`
71
+
72
+ `.command()` let's you run a command from your CLI.
73
+
74
+ ```typescript
75
+ import {expect, test} from '@oclif/test'
76
+
77
+ describe('hello world', () => {
78
+ test
79
+ .stdout()
80
+ .command(['hello:world'])
81
+ .it('runs hello world cmd', (ctx) => {
82
+ expect(ctx.stdout).to.contain('hello world!')
83
+ })
84
+ })
85
+ ```
86
+
87
+ For a [single command cli](https://oclif.io/docs/single_command_cli) you would provide `'.'` as the command. For instance:
88
+
89
+ ```typescript
90
+ import {expect, test} from '@oclif/test'
91
+
92
+ describe('hello world', () => {
93
+ test
94
+ .stdout()
95
+ .command(['.'])
96
+ .it('runs hello world cmd', (ctx) => {
97
+ expect(ctx.stdout).to.contain('hello world!')
98
+ })
99
+ })
100
+ ```
101
+
102
+ If you would like to run the same test without using `@oclif/test`:
103
+
104
+ ```typescript
105
+ import {Config, ux} from '@oclif/core'
106
+ import {expect} from 'chai'
107
+ import {SinonSandbox, SinonStub, createSandbox} from 'sinon'
108
+
109
+ describe('non-fancy test', () => {
110
+ let sandbox: SinonSandbox
111
+ let config: Config
112
+ let stdoutStub: SinonStub
113
+
114
+ beforeEach(async () => {
115
+ sandbox = createSandbox()
116
+ stdoutStub = sandbox.stub(ux.write, 'stdout')
117
+ config = await Config.load({root: process.cwd()})
118
+ })
119
+
120
+ afterEach(async () => {
121
+ sandbox.restore()
122
+ })
123
+
124
+ it('should run command', async () => {
125
+ // use '.' for a single command CLI
126
+ const {name} = await config.runCommand<{name: string}>('hello:world')
127
+ expect(stdoutStub.calledWith('hello world!\n')).to.be.true
128
+ expect(name).to.equal('world')
129
+ })
130
+ })
131
+ ```
132
+
133
+ ### `.exit()`
134
+
135
+ `.exit()` let's you test that a command exited with a certain exit code.
136
+
137
+ ```typescript
138
+ import {join} from 'node:path'
139
+ import {expect, test} from '@oclif/test'
140
+
141
+ describe('exit', () => {
142
+ test
143
+ .loadConfig()
144
+ .stdout()
145
+ .command(['hello:world', '--code=101'])
146
+ .exit(101)
147
+ .do((output) => expect(output.stdout).to.equal('exiting with code 101\n'))
148
+ .it('should exit with code 101')
149
+ })
150
+ ```
151
+
152
+ If you would like to run the same test without using `@oclif/test`:
153
+
154
+ ```typescript
155
+ import {Config, Errors, ux} from '@oclif/core'
156
+ import {expect} from 'chai'
157
+ import {SinonSandbox, createSandbox} from 'sinon'
158
+
159
+ describe('non-fancy test', () => {
160
+ let sandbox: SinonSandbox
161
+ let config: Config
162
+
163
+ beforeEach(async () => {
164
+ sandbox = createSandbox()
165
+ sandbox.stub(ux.write, 'stdout')
166
+ config = await Config.load({root: process.cwd()})
167
+ })
168
+
169
+ afterEach(async () => {
170
+ sandbox.restore()
171
+ })
172
+
173
+ it('should run command from the given directory', async () => {
174
+ try {
175
+ await config.runCommand('.')
176
+ throw new Error('Expected CLIError to be thrown')
177
+ } catch (error) {
178
+ if (error instanceof Errors.CLIError) {
179
+ expect(error.oclif.exit).to.equal(101)
180
+ } else {
181
+ throw error
182
+ }
183
+ }
184
+ })
185
+ })
186
+ ```
187
+
188
+ ### `.hook()`
189
+
190
+ `.hook()` let's you test a hook in your CLI.
191
+
192
+ ```typescript
193
+ import {join} from 'node:path'
194
+
195
+ import {expect, test} from '@oclif/test'
196
+
197
+ const root = join(__dirname, 'fixtures/test-cli')
198
+
199
+ describe('hooks', () => {
200
+ test
201
+ .loadConfig({root})
202
+ .stdout()
203
+ .hook('foo', {argv: ['arg']}, {root})
204
+ .do((output) => expect(output.stdout).to.equal('foo hook args: arg\n'))
205
+ .it('should run hook')
206
+ })
207
+ ```
208
+
209
+ If you would like to run the same test without using `@oclif/test`:
210
+
211
+ ```typescript
212
+ import {Config, ux} from '@oclif/core'
213
+ import {expect} from 'chai'
214
+ import {SinonSandbox, SinonStub, createSandbox} from 'sinon'
215
+
216
+ describe('non-fancy test', () => {
217
+ let sandbox: SinonSandbox
218
+ let config: Config
219
+ let stdoutStub: SinonStub
220
+
221
+ beforeEach(async () => {
222
+ sandbox = createSandbox()
223
+ stdoutStub = sandbox.stub(ux.write, 'stdout')
224
+ config = await Config.load({root: process.cwd()})
225
+ })
226
+
227
+ afterEach(async () => {
228
+ sandbox.restore()
229
+ })
230
+
231
+ it('should run hook', async () => {
232
+ const {name} = await config.runHook('foo', {argv: ['arg']})
233
+ expect(stdoutStub.calledWith('foo hook args: arg\n')).to.be.true
234
+ })
235
+ })
236
+ ```
package/package.json CHANGED
@@ -1,21 +1,21 @@
1
1
  {
2
2
  "name": "@oclif/test",
3
3
  "description": "test helpers for oclif components",
4
- "version": "3.0.3",
4
+ "version": "3.1.0",
5
5
  "author": "Salesforce",
6
6
  "bugs": "https://github.com/oclif/test/issues",
7
7
  "dependencies": {
8
- "@oclif/core": "^3.6.0",
8
+ "@oclif/core": "^3.9.1",
9
9
  "chai": "^4.3.10",
10
10
  "fancy-test": "^3.0.1"
11
11
  },
12
12
  "devDependencies": {
13
- "@commitlint/config-conventional": "^18.0.0",
13
+ "@commitlint/config-conventional": "^18.1.0",
14
14
  "@oclif/prettier-config": "^0.2.1",
15
15
  "@types/cli-progress": "^3.11.4",
16
16
  "@types/mocha": "^10",
17
17
  "@types/node": "^18",
18
- "commitlint": "^18.0.0",
18
+ "commitlint": "^18.2.0",
19
19
  "eslint": "^8.52.0",
20
20
  "eslint-config-oclif": "^5.0.0",
21
21
  "eslint-config-oclif-typescript": "^3.0.8",