@thegetty/quire-cli 1.0.0-rc.44 → 1.0.0-rc.46
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.
- package/CHANGELOG.md +0 -36
- package/README.md +0 -9
- package/bin/cli.js +1 -46
- package/package.json +9 -25
- package/src/Command.js +6 -26
- package/src/commands/README.md +122 -213
- package/src/commands/build.js +37 -45
- package/src/commands/clean.js +19 -33
- package/src/commands/conf.js +43 -0
- package/src/commands/create.js +14 -42
- package/src/commands/epub.js +31 -67
- package/src/commands/index.js +2 -9
- package/src/commands/info.js +86 -88
- package/src/commands/pdf.js +82 -63
- package/src/commands/preview.js +31 -32
- package/src/commands/validate.js +20 -64
- package/src/commands/version.js +43 -0
- package/src/errors/validation/validation-error.js +11 -20
- package/src/helpers/clean.js +1 -1
- package/src/helpers/is-quire.js +31 -0
- package/src/helpers/test-cwd.js +6 -5
- package/src/helpers/which.js +4 -10
- package/src/lib/11ty/README.md +19 -135
- package/src/lib/11ty/api.js +93 -235
- package/src/lib/11ty/cli.js +37 -112
- package/src/lib/11ty/index.js +5 -64
- package/src/lib/11ty/paths.js +103 -0
- package/src/lib/README.md +0 -330
- package/src/lib/conf/README.md +69 -86
- package/src/lib/conf/config.js +3 -5
- package/src/lib/conf/defaults.js +0 -65
- package/src/lib/conf/schema.js +9 -103
- package/src/lib/epub/README.md +2 -133
- package/src/lib/epub/epub.js +11 -36
- package/src/lib/epub/index.js +21 -111
- package/src/lib/epub/pandoc.js +4 -33
- package/src/lib/git/README.md +2 -151
- package/src/lib/git/index.js +13 -217
- package/src/lib/i18n/README.md +3 -0
- package/src/lib/i18n/config.js +53 -0
- package/src/lib/i18n/index.js +43 -0
- package/src/lib/i18n/localeService.js +58 -0
- package/src/lib/pdf/README.md +0 -131
- package/src/lib/pdf/index.js +21 -124
- package/src/lib/pdf/paged.js +52 -100
- package/src/lib/pdf/prince.js +37 -115
- package/src/lib/pdf/split.js +33 -61
- package/src/lib/quire/README.md +19 -0
- package/src/lib/quire/index.js +353 -0
- package/src/lib/reporter/README.md +2 -211
- package/src/lib/reporter/index.js +0 -607
- package/src/main.js +48 -221
- package/src/packageConfig.js +0 -17
- package/src/validators/utils.js +1 -2
- package/schemas/config.schema.json +0 -194
- package/schemas/figures.schema.json +0 -56
- package/schemas/layout.schema.json +0 -5
- package/schemas/objects.schema.json +0 -62
- package/schemas/publication.schema.json +0 -140
- package/schemas/references.schema.json +0 -29
- package/src/Command.spec.js +0 -99
- package/src/commands/build.spec.js +0 -113
- package/src/commands/build.test.js +0 -397
- package/src/commands/clean.spec.js +0 -118
- package/src/commands/clean.test.js +0 -382
- package/src/commands/config.js +0 -238
- package/src/commands/config.spec.js +0 -107
- package/src/commands/config.test.js +0 -845
- package/src/commands/create.spec.js +0 -112
- package/src/commands/create.test.js +0 -415
- package/src/commands/doctor.js +0 -251
- package/src/commands/doctor.spec.js +0 -115
- package/src/commands/doctor.test.js +0 -1409
- package/src/commands/epub.spec.js +0 -114
- package/src/commands/epub.test.js +0 -503
- package/src/commands/help.js +0 -60
- package/src/commands/help.test.js +0 -132
- package/src/commands/info.spec.js +0 -72
- package/src/commands/info.test.js +0 -512
- package/src/commands/pdf.spec.js +0 -114
- package/src/commands/pdf.test.js +0 -464
- package/src/commands/preview.spec.js +0 -97
- package/src/commands/preview.test.js +0 -250
- package/src/commands/use.js +0 -56
- package/src/commands/use.spec.js +0 -61
- package/src/commands/use.test.js +0 -280
- package/src/commands/validate.spec.js +0 -90
- package/src/commands/validate.test.js +0 -378
- package/src/commands/workflows.js +0 -70
- package/src/errors/build/build-failed-error.js +0 -19
- package/src/errors/build/config-field-missing-error.js +0 -20
- package/src/errors/build/config-file-not-found-error.js +0 -20
- package/src/errors/build/index.js +0 -11
- package/src/errors/help/help-topic-not-found-error.js +0 -30
- package/src/errors/help/index.js +0 -8
- package/src/errors/index.js +0 -58
- package/src/errors/input/index.js +0 -8
- package/src/errors/input/invalid-input-error.js +0 -21
- package/src/errors/install/dependency-install-error.js +0 -19
- package/src/errors/install/directory-not-empty-error.js +0 -25
- package/src/errors/install/index.js +0 -12
- package/src/errors/install/invalid-path-error.js +0 -31
- package/src/errors/install/invalid-starter-error.js +0 -27
- package/src/errors/install/version-not-found-error.js +0 -35
- package/src/errors/output/epub-generation-error.js +0 -19
- package/src/errors/output/index.js +0 -14
- package/src/errors/output/invalid-epub-library-error.js +0 -20
- package/src/errors/output/invalid-pdf-library-error.js +0 -20
- package/src/errors/output/missing-build-output-error.js +0 -21
- package/src/errors/output/pdf-generation-error.js +0 -24
- package/src/errors/output/tool-not-found-error.js +0 -37
- package/src/errors/project/index.js +0 -10
- package/src/errors/project/not-in-project-error.js +0 -20
- package/src/errors/project/project-create-error.js +0 -21
- package/src/errors/quire-error.js +0 -27
- package/src/errors/validation/index.js +0 -3
- package/src/errors/validation/unknown-config-key-error.js +0 -27
- package/src/errors/validation/unknown-config-operation-error.js +0 -24
- package/src/helpers/docs-url.js +0 -32
- package/src/helpers/pager.js +0 -59
- package/src/helpers/pager.test.js +0 -85
- package/src/helpers/suggest-similar.js +0 -124
- package/src/helpers/suggest-similar.test.js +0 -108
- package/src/helpers/test-cwd.test.js +0 -192
- package/src/lib/11ty/index.test.js +0 -655
- package/src/lib/commander/index.js +0 -103
- package/src/lib/commander/index.test.js +0 -86
- package/src/lib/commander/options.js +0 -237
- package/src/lib/commander/options.test.js +0 -205
- package/src/lib/conf/build-status.js +0 -103
- package/src/lib/conf/build-status.test.js +0 -247
- package/src/lib/conf/config.test.js +0 -281
- package/src/lib/conf/format.js +0 -60
- package/src/lib/conf/format.test.js +0 -106
- package/src/lib/conf/helpers.js +0 -91
- package/src/lib/conf/helpers.test.js +0 -136
- package/src/lib/conf/index.js +0 -22
- package/src/lib/constants.js +0 -28
- package/src/lib/doctor/README.md +0 -667
- package/src/lib/doctor/checks/environment/cli-version.js +0 -62
- package/src/lib/doctor/checks/environment/cli-version.test.js +0 -132
- package/src/lib/doctor/checks/environment/git-available.js +0 -77
- package/src/lib/doctor/checks/environment/git-available.test.js +0 -52
- package/src/lib/doctor/checks/environment/index.js +0 -13
- package/src/lib/doctor/checks/environment/node-version.js +0 -66
- package/src/lib/doctor/checks/environment/node-version.test.js +0 -17
- package/src/lib/doctor/checks/environment/npm-available.js +0 -66
- package/src/lib/doctor/checks/environment/npm-available.test.js +0 -52
- package/src/lib/doctor/checks/environment/os-info.js +0 -48
- package/src/lib/doctor/checks/environment/os-info.test.js +0 -81
- package/src/lib/doctor/checks/environment/runtime-info.js +0 -51
- package/src/lib/doctor/checks/environment/runtime-info.test.js +0 -132
- package/src/lib/doctor/checks/outputs/epub-output.js +0 -119
- package/src/lib/doctor/checks/outputs/epub-output.test.js +0 -277
- package/src/lib/doctor/checks/outputs/index.js +0 -10
- package/src/lib/doctor/checks/outputs/pdf-output.js +0 -144
- package/src/lib/doctor/checks/outputs/pdf-output.test.js +0 -377
- package/src/lib/doctor/checks/outputs/stale-build.js +0 -122
- package/src/lib/doctor/checks/outputs/stale-build.test.js +0 -282
- package/src/lib/doctor/checks/project/data-files.js +0 -56
- package/src/lib/doctor/checks/project/data-files.test.js +0 -125
- package/src/lib/doctor/checks/project/dependencies.js +0 -53
- package/src/lib/doctor/checks/project/dependencies.test.js +0 -71
- package/src/lib/doctor/checks/project/index.js +0 -11
- package/src/lib/doctor/checks/project/quire-11ty.js +0 -98
- package/src/lib/doctor/checks/project/quire-11ty.test.js +0 -170
- package/src/lib/doctor/checks/project/quire-project.js +0 -38
- package/src/lib/doctor/checks/project/quire-project.test.js +0 -47
- package/src/lib/doctor/checks/tools/index.js +0 -10
- package/src/lib/doctor/checks/tools/pandoc-available.js +0 -82
- package/src/lib/doctor/checks/tools/pandoc-available.test.js +0 -73
- package/src/lib/doctor/checks/tools/prince-available.js +0 -81
- package/src/lib/doctor/checks/tools/prince-available.test.js +0 -73
- package/src/lib/doctor/constants.js +0 -39
- package/src/lib/doctor/formatDuration.js +0 -108
- package/src/lib/doctor/formatDuration.test.js +0 -76
- package/src/lib/doctor/formatters/human.js +0 -257
- package/src/lib/doctor/formatters/human.test.js +0 -463
- package/src/lib/doctor/formatters/index.js +0 -8
- package/src/lib/doctor/formatters/json.js +0 -78
- package/src/lib/doctor/formatters/json.test.js +0 -174
- package/src/lib/doctor/formatters/shared.js +0 -129
- package/src/lib/doctor/formatters/shared.test.js +0 -194
- package/src/lib/doctor/index.js +0 -271
- package/src/lib/doctor/index.test.js +0 -797
- package/src/lib/epub/engines.js +0 -46
- package/src/lib/epub/index.test.js +0 -518
- package/src/lib/epub/pandoc.test.js +0 -122
- package/src/lib/epub/schema.js +0 -21
- package/src/lib/error/README.md +0 -170
- package/src/lib/error/handler.js +0 -107
- package/src/lib/git/index.spec.js +0 -80
- package/src/lib/git/index.test.js +0 -453
- package/src/lib/help/frontmatter.js +0 -77
- package/src/lib/help/frontmatter.test.js +0 -139
- package/src/lib/help/index.js +0 -146
- package/src/lib/help/index.test.js +0 -188
- package/src/lib/help/topics/configuration.md +0 -77
- package/src/lib/help/topics/debugging.md +0 -69
- package/src/lib/help/topics/epub.md +0 -74
- package/src/lib/help/topics/pdf.md +0 -74
- package/src/lib/help/topics/publishing.md +0 -80
- package/src/lib/help/topics/workflows.md +0 -50
- package/src/lib/installer/index.js +0 -309
- package/src/lib/installer/index.spec.js +0 -83
- package/src/lib/installer/index.test.js +0 -545
- package/src/lib/logger/README.md +0 -424
- package/src/lib/logger/debug.js +0 -132
- package/src/lib/logger/debug.spec.js +0 -130
- package/src/lib/logger/debug.test.js +0 -128
- package/src/lib/logger/index.js +0 -228
- package/src/lib/logger/index.spec.js +0 -131
- package/src/lib/logger/index.test.js +0 -578
- package/src/lib/npm/README.md +0 -127
- package/src/lib/npm/index.js +0 -198
- package/src/lib/npm/index.spec.js +0 -60
- package/src/lib/npm/index.test.js +0 -355
- package/src/lib/pdf/engines.js +0 -46
- package/src/lib/pdf/index.test.js +0 -708
- package/src/lib/pdf/paged.test.js +0 -366
- package/src/lib/pdf/prince.test.js +0 -202
- package/src/lib/pdf/schema.js +0 -21
- package/src/lib/pdf/split.test.js +0 -445
- package/src/lib/platform.js +0 -95
- package/src/lib/process/manager.js +0 -110
- package/src/lib/process/manager.test.js +0 -55
- package/src/lib/project/build.js +0 -162
- package/src/lib/project/build.test.js +0 -275
- package/src/lib/project/config.js +0 -48
- package/src/lib/project/config.test.js +0 -134
- package/src/lib/project/detect.js +0 -47
- package/src/lib/project/detect.test.js +0 -157
- package/src/lib/project/index.js +0 -56
- package/src/lib/project/output-paths.js +0 -87
- package/src/lib/project/output-paths.test.js +0 -66
- package/src/lib/project/paths.js +0 -272
- package/src/lib/project/version.js +0 -110
- package/src/lib/project/version.test.js +0 -350
- package/src/lib/reporter/index.test.js +0 -862
- package/src/main.spec.js +0 -61
- package/src/main.test.js +0 -347
- package/src/validators/validate-data-files.js +0 -154
- package/src/validators/validate-data-files.test.js +0 -217
|
@@ -1,845 +0,0 @@
|
|
|
1
|
-
import test from 'ava'
|
|
2
|
-
import { Volume, createFsFromVolume } from 'memfs'
|
|
3
|
-
import sinon from 'sinon'
|
|
4
|
-
import esmock from 'esmock'
|
|
5
|
-
|
|
6
|
-
test.beforeEach((t) => {
|
|
7
|
-
// Create sinon sandbox for mocking
|
|
8
|
-
t.context.sandbox = sinon.createSandbox()
|
|
9
|
-
|
|
10
|
-
// Create in-memory file system
|
|
11
|
-
t.context.vol = new Volume()
|
|
12
|
-
t.context.fs = createFsFromVolume(t.context.vol)
|
|
13
|
-
|
|
14
|
-
// Create mock logger (no global console stubbing needed!)
|
|
15
|
-
t.context.mockLogger = {
|
|
16
|
-
info: t.context.sandbox.stub(),
|
|
17
|
-
error: t.context.sandbox.stub(),
|
|
18
|
-
debug: t.context.sandbox.stub(),
|
|
19
|
-
log: t.context.sandbox.stub(),
|
|
20
|
-
warn: t.context.sandbox.stub()
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// Mock config store
|
|
24
|
-
t.context.mockConfig = {
|
|
25
|
-
path: '/mock/config/path',
|
|
26
|
-
store: {
|
|
27
|
-
logLevel: 'info',
|
|
28
|
-
logShowLevel: false,
|
|
29
|
-
projectTemplate: 'https://github.com/thegetty/quire-starter-default',
|
|
30
|
-
quireVersion: '1.0.0',
|
|
31
|
-
__internal__secretKey: 'hidden-value',
|
|
32
|
-
projects: { abc123: { projectPath: '/test', buildStatus: { build: { status: 'ok', timestamp: 1000 } } } }
|
|
33
|
-
},
|
|
34
|
-
get: (key) => t.context.mockConfig.store[key],
|
|
35
|
-
set: t.context.sandbox.stub(),
|
|
36
|
-
delete: t.context.sandbox.stub(),
|
|
37
|
-
reset: t.context.sandbox.stub(),
|
|
38
|
-
clear: t.context.sandbox.stub()
|
|
39
|
-
}
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
test.afterEach.always((t) => {
|
|
43
|
-
// Restore all mocks
|
|
44
|
-
t.context.sandbox.restore()
|
|
45
|
-
|
|
46
|
-
// Clear in-memory file system
|
|
47
|
-
t.context.vol.reset()
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
// =============================================================================
|
|
51
|
-
// Show all (no operation)
|
|
52
|
-
// =============================================================================
|
|
53
|
-
|
|
54
|
-
test('conf command should display all config when no operation provided', async (t) => {
|
|
55
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
56
|
-
|
|
57
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
58
|
-
'#lib/logger/index.js': {
|
|
59
|
-
default: () => mockLogger
|
|
60
|
-
}
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
const command = new ConfCommand()
|
|
64
|
-
command.config = mockConfig
|
|
65
|
-
command.logger = mockLogger
|
|
66
|
-
command.debug = sandbox.stub()
|
|
67
|
-
|
|
68
|
-
await command.action(undefined, undefined, undefined, {})
|
|
69
|
-
|
|
70
|
-
// Should be called once with all output joined
|
|
71
|
-
t.true(mockLogger.info.calledOnce)
|
|
72
|
-
|
|
73
|
-
const output = mockLogger.info.firstCall.args[0]
|
|
74
|
-
t.true(output.includes('quire-cli configuration /mock/config/path'))
|
|
75
|
-
t.true(output.includes('logLevel: "info"'))
|
|
76
|
-
t.true(output.includes('quireVersion: "1.0.0"'))
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
test('conf command should hide internal config values by default', async (t) => {
|
|
80
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
81
|
-
|
|
82
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
83
|
-
'#lib/logger/index.js': {
|
|
84
|
-
default: () => mockLogger
|
|
85
|
-
}
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
const command = new ConfCommand()
|
|
89
|
-
command.config = mockConfig
|
|
90
|
-
command.logger = mockLogger
|
|
91
|
-
command.debug = sandbox.stub()
|
|
92
|
-
|
|
93
|
-
await command.action(undefined, undefined, undefined, {})
|
|
94
|
-
|
|
95
|
-
const output = mockLogger.info.firstCall.args[0]
|
|
96
|
-
t.false(output.includes('__internal__secretKey'))
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
test('conf command should show internal config values with debug flag', async (t) => {
|
|
100
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
101
|
-
|
|
102
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
103
|
-
'#lib/logger/index.js': {
|
|
104
|
-
default: () => mockLogger
|
|
105
|
-
}
|
|
106
|
-
})
|
|
107
|
-
|
|
108
|
-
const command = new ConfCommand()
|
|
109
|
-
command.config = mockConfig
|
|
110
|
-
command.logger = mockLogger
|
|
111
|
-
command.debug = sandbox.stub()
|
|
112
|
-
|
|
113
|
-
await command.action(undefined, undefined, undefined, { debug: true })
|
|
114
|
-
|
|
115
|
-
const output = mockLogger.info.firstCall.args[0]
|
|
116
|
-
t.true(output.includes('__internal__secretKey: "hidden-value"'))
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
test('conf command should hide projects by default', async (t) => {
|
|
120
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
121
|
-
|
|
122
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
123
|
-
'#lib/logger/index.js': {
|
|
124
|
-
default: () => mockLogger
|
|
125
|
-
}
|
|
126
|
-
})
|
|
127
|
-
|
|
128
|
-
const command = new ConfCommand()
|
|
129
|
-
command.config = mockConfig
|
|
130
|
-
command.logger = mockLogger
|
|
131
|
-
command.debug = sandbox.stub()
|
|
132
|
-
|
|
133
|
-
await command.action(undefined, undefined, undefined, {})
|
|
134
|
-
|
|
135
|
-
const output = mockLogger.info.firstCall.args[0]
|
|
136
|
-
t.false(output.includes('projects'))
|
|
137
|
-
})
|
|
138
|
-
|
|
139
|
-
test('conf command should show projects with debug flag', async (t) => {
|
|
140
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
141
|
-
|
|
142
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
143
|
-
'#lib/logger/index.js': {
|
|
144
|
-
default: () => mockLogger
|
|
145
|
-
}
|
|
146
|
-
})
|
|
147
|
-
|
|
148
|
-
const command = new ConfCommand()
|
|
149
|
-
command.config = mockConfig
|
|
150
|
-
command.logger = mockLogger
|
|
151
|
-
command.debug = sandbox.stub()
|
|
152
|
-
|
|
153
|
-
await command.action(undefined, undefined, undefined, { debug: true })
|
|
154
|
-
|
|
155
|
-
const output = mockLogger.info.firstCall.args[0]
|
|
156
|
-
t.true(output.includes('projects'))
|
|
157
|
-
})
|
|
158
|
-
|
|
159
|
-
// =============================================================================
|
|
160
|
-
// Get operation
|
|
161
|
-
// =============================================================================
|
|
162
|
-
|
|
163
|
-
test('conf get should return a single value', async (t) => {
|
|
164
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
165
|
-
|
|
166
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
167
|
-
'#lib/logger/index.js': {
|
|
168
|
-
default: () => mockLogger
|
|
169
|
-
}
|
|
170
|
-
})
|
|
171
|
-
|
|
172
|
-
const command = new ConfCommand()
|
|
173
|
-
command.config = mockConfig
|
|
174
|
-
command.logger = mockLogger
|
|
175
|
-
command.debug = sandbox.stub()
|
|
176
|
-
|
|
177
|
-
await command.action('get', 'logLevel', undefined, {})
|
|
178
|
-
|
|
179
|
-
t.true(mockLogger.info.calledOnce)
|
|
180
|
-
t.true(mockLogger.info.calledWith('logLevel: "info"'))
|
|
181
|
-
})
|
|
182
|
-
|
|
183
|
-
test('conf get should show error when key is missing', async (t) => {
|
|
184
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
185
|
-
|
|
186
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
187
|
-
'#lib/logger/index.js': {
|
|
188
|
-
default: () => mockLogger
|
|
189
|
-
}
|
|
190
|
-
})
|
|
191
|
-
|
|
192
|
-
const command = new ConfCommand()
|
|
193
|
-
command.config = mockConfig
|
|
194
|
-
command.logger = mockLogger
|
|
195
|
-
command.debug = sandbox.stub()
|
|
196
|
-
|
|
197
|
-
await command.action('get', undefined, undefined, {})
|
|
198
|
-
|
|
199
|
-
t.true(mockLogger.error.calledOnce)
|
|
200
|
-
t.true(mockLogger.error.calledWith('Usage: quire conf get <key>'))
|
|
201
|
-
})
|
|
202
|
-
|
|
203
|
-
test('conf get should throw UnknownConfigKeyError for unknown key', async (t) => {
|
|
204
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
205
|
-
|
|
206
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
207
|
-
'#lib/logger/index.js': {
|
|
208
|
-
default: () => mockLogger
|
|
209
|
-
}
|
|
210
|
-
})
|
|
211
|
-
|
|
212
|
-
const command = new ConfCommand()
|
|
213
|
-
command.config = mockConfig
|
|
214
|
-
command.logger = mockLogger
|
|
215
|
-
command.debug = sandbox.stub()
|
|
216
|
-
|
|
217
|
-
const error = await t.throwsAsync(
|
|
218
|
-
() => command.action('get', 'unknownKey', undefined, {}),
|
|
219
|
-
{ code: 'UNKNOWN_CONFIG_KEY' }
|
|
220
|
-
)
|
|
221
|
-
t.true(error.message.includes('Unknown configuration key: unknownKey'))
|
|
222
|
-
t.true(error.suggestion.includes('Valid keys:'))
|
|
223
|
-
})
|
|
224
|
-
|
|
225
|
-
test('conf get should suggest similar key for close misspelling', async (t) => {
|
|
226
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
227
|
-
|
|
228
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
229
|
-
'#lib/logger/index.js': {
|
|
230
|
-
default: () => mockLogger
|
|
231
|
-
}
|
|
232
|
-
})
|
|
233
|
-
|
|
234
|
-
const command = new ConfCommand()
|
|
235
|
-
command.config = mockConfig
|
|
236
|
-
command.logger = mockLogger
|
|
237
|
-
command.debug = sandbox.stub()
|
|
238
|
-
|
|
239
|
-
const error = await t.throwsAsync(
|
|
240
|
-
() => command.action('get', 'logLeve', undefined, {}),
|
|
241
|
-
{ code: 'UNKNOWN_CONFIG_KEY' }
|
|
242
|
-
)
|
|
243
|
-
t.true(error.message.includes('Unknown configuration key: logLeve'))
|
|
244
|
-
t.true(error.suggestion.includes('Did you mean: logLevel?'))
|
|
245
|
-
})
|
|
246
|
-
|
|
247
|
-
test('conf get should suggest similar key for case difference', async (t) => {
|
|
248
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
249
|
-
|
|
250
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
251
|
-
'#lib/logger/index.js': {
|
|
252
|
-
default: () => mockLogger
|
|
253
|
-
}
|
|
254
|
-
})
|
|
255
|
-
|
|
256
|
-
const command = new ConfCommand()
|
|
257
|
-
command.config = mockConfig
|
|
258
|
-
command.logger = mockLogger
|
|
259
|
-
command.debug = sandbox.stub()
|
|
260
|
-
|
|
261
|
-
const error = await t.throwsAsync(
|
|
262
|
-
() => command.action('get', 'loglevel', undefined, {}),
|
|
263
|
-
{ code: 'UNKNOWN_CONFIG_KEY' }
|
|
264
|
-
)
|
|
265
|
-
t.true(error.suggestion.includes('Did you mean: logLevel?'))
|
|
266
|
-
})
|
|
267
|
-
|
|
268
|
-
// =============================================================================
|
|
269
|
-
// Set operation
|
|
270
|
-
// =============================================================================
|
|
271
|
-
|
|
272
|
-
test('conf set should set a value', async (t) => {
|
|
273
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
274
|
-
|
|
275
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
276
|
-
'#lib/logger/index.js': {
|
|
277
|
-
default: () => mockLogger
|
|
278
|
-
}
|
|
279
|
-
})
|
|
280
|
-
|
|
281
|
-
const command = new ConfCommand()
|
|
282
|
-
command.config = mockConfig
|
|
283
|
-
command.logger = mockLogger
|
|
284
|
-
command.debug = sandbox.stub()
|
|
285
|
-
|
|
286
|
-
await command.action('set', 'logLevel', 'debug', {})
|
|
287
|
-
|
|
288
|
-
t.true(mockConfig.set.calledOnce)
|
|
289
|
-
t.true(mockConfig.set.calledWith('logLevel', 'debug'))
|
|
290
|
-
t.true(mockLogger.info.calledWith('logLevel: "debug"'))
|
|
291
|
-
})
|
|
292
|
-
|
|
293
|
-
test('conf set should show error when key is missing', async (t) => {
|
|
294
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
295
|
-
|
|
296
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
297
|
-
'#lib/logger/index.js': {
|
|
298
|
-
default: () => mockLogger
|
|
299
|
-
}
|
|
300
|
-
})
|
|
301
|
-
|
|
302
|
-
const command = new ConfCommand()
|
|
303
|
-
command.config = mockConfig
|
|
304
|
-
command.logger = mockLogger
|
|
305
|
-
command.debug = sandbox.stub()
|
|
306
|
-
|
|
307
|
-
await command.action('set', undefined, undefined, {})
|
|
308
|
-
|
|
309
|
-
t.true(mockLogger.error.calledOnce)
|
|
310
|
-
t.true(mockLogger.error.calledWith('Usage: quire conf set <key> <value>'))
|
|
311
|
-
})
|
|
312
|
-
|
|
313
|
-
test('conf set should show error when value is missing', async (t) => {
|
|
314
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
315
|
-
|
|
316
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
317
|
-
'#lib/logger/index.js': {
|
|
318
|
-
default: () => mockLogger
|
|
319
|
-
}
|
|
320
|
-
})
|
|
321
|
-
|
|
322
|
-
const command = new ConfCommand()
|
|
323
|
-
command.config = mockConfig
|
|
324
|
-
command.logger = mockLogger
|
|
325
|
-
command.debug = sandbox.stub()
|
|
326
|
-
|
|
327
|
-
await command.action('set', 'logLevel', undefined, {})
|
|
328
|
-
|
|
329
|
-
t.true(mockLogger.error.calledOnce)
|
|
330
|
-
t.true(mockLogger.error.calledWith('Usage: quire conf set <key> <value>'))
|
|
331
|
-
})
|
|
332
|
-
|
|
333
|
-
test('conf set should coerce boolean true values', async (t) => {
|
|
334
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
335
|
-
|
|
336
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
337
|
-
'#lib/logger/index.js': {
|
|
338
|
-
default: () => mockLogger
|
|
339
|
-
}
|
|
340
|
-
})
|
|
341
|
-
|
|
342
|
-
const command = new ConfCommand()
|
|
343
|
-
command.config = mockConfig
|
|
344
|
-
command.logger = mockLogger
|
|
345
|
-
command.debug = sandbox.stub()
|
|
346
|
-
|
|
347
|
-
await command.action('set', 'logShowLevel', 'true', {})
|
|
348
|
-
|
|
349
|
-
t.true(mockConfig.set.calledWith('logShowLevel', true))
|
|
350
|
-
})
|
|
351
|
-
|
|
352
|
-
test('conf set should coerce boolean false values', async (t) => {
|
|
353
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
354
|
-
|
|
355
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
356
|
-
'#lib/logger/index.js': {
|
|
357
|
-
default: () => mockLogger
|
|
358
|
-
}
|
|
359
|
-
})
|
|
360
|
-
|
|
361
|
-
const command = new ConfCommand()
|
|
362
|
-
command.config = mockConfig
|
|
363
|
-
command.logger = mockLogger
|
|
364
|
-
command.debug = sandbox.stub()
|
|
365
|
-
|
|
366
|
-
await command.action('set', 'logShowLevel', 'false', {})
|
|
367
|
-
|
|
368
|
-
t.true(mockConfig.set.calledWith('logShowLevel', false))
|
|
369
|
-
})
|
|
370
|
-
|
|
371
|
-
test('conf set should coerce numeric boolean values', async (t) => {
|
|
372
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
373
|
-
|
|
374
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
375
|
-
'#lib/logger/index.js': {
|
|
376
|
-
default: () => mockLogger
|
|
377
|
-
}
|
|
378
|
-
})
|
|
379
|
-
|
|
380
|
-
const command = new ConfCommand()
|
|
381
|
-
command.config = mockConfig
|
|
382
|
-
command.logger = mockLogger
|
|
383
|
-
command.debug = sandbox.stub()
|
|
384
|
-
|
|
385
|
-
await command.action('set', 'logShowLevel', '1', {})
|
|
386
|
-
t.true(mockConfig.set.calledWith('logShowLevel', true))
|
|
387
|
-
|
|
388
|
-
mockConfig.set.resetHistory()
|
|
389
|
-
|
|
390
|
-
await command.action('set', 'logShowLevel', '0', {})
|
|
391
|
-
t.true(mockConfig.set.calledWith('logShowLevel', false))
|
|
392
|
-
})
|
|
393
|
-
|
|
394
|
-
test('conf set should show validation error for invalid enum value', async (t) => {
|
|
395
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
396
|
-
|
|
397
|
-
// Make config.set throw an error for invalid values
|
|
398
|
-
mockConfig.set.throws(new Error('Schema validation failed'))
|
|
399
|
-
|
|
400
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
401
|
-
'#lib/logger/index.js': {
|
|
402
|
-
default: () => mockLogger
|
|
403
|
-
}
|
|
404
|
-
})
|
|
405
|
-
|
|
406
|
-
const command = new ConfCommand()
|
|
407
|
-
command.config = mockConfig
|
|
408
|
-
command.logger = mockLogger
|
|
409
|
-
command.debug = sandbox.stub()
|
|
410
|
-
|
|
411
|
-
await command.action('set', 'logLevel', 'invalid', {})
|
|
412
|
-
|
|
413
|
-
t.true(mockLogger.error.calledOnce)
|
|
414
|
-
const errorOutput = mockLogger.error.firstCall.args[0]
|
|
415
|
-
t.true(errorOutput.includes('Invalid value'))
|
|
416
|
-
t.true(errorOutput.includes('Valid values:'))
|
|
417
|
-
})
|
|
418
|
-
|
|
419
|
-
// =============================================================================
|
|
420
|
-
// Delete operation
|
|
421
|
-
// =============================================================================
|
|
422
|
-
|
|
423
|
-
test('conf delete should delete a key', async (t) => {
|
|
424
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
425
|
-
|
|
426
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
427
|
-
'#lib/logger/index.js': {
|
|
428
|
-
default: () => mockLogger
|
|
429
|
-
}
|
|
430
|
-
})
|
|
431
|
-
|
|
432
|
-
const command = new ConfCommand()
|
|
433
|
-
command.config = mockConfig
|
|
434
|
-
command.logger = mockLogger
|
|
435
|
-
command.debug = sandbox.stub()
|
|
436
|
-
|
|
437
|
-
await command.action('delete', 'logLevel', undefined, {})
|
|
438
|
-
|
|
439
|
-
t.true(mockConfig.delete.calledOnce)
|
|
440
|
-
t.true(mockConfig.delete.calledWith('logLevel'))
|
|
441
|
-
t.true(mockLogger.info.calledOnce)
|
|
442
|
-
t.true(mockLogger.info.firstCall.args[0].includes('reset to'))
|
|
443
|
-
})
|
|
444
|
-
|
|
445
|
-
test('conf delete should show error when key is missing', async (t) => {
|
|
446
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
447
|
-
|
|
448
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
449
|
-
'#lib/logger/index.js': {
|
|
450
|
-
default: () => mockLogger
|
|
451
|
-
}
|
|
452
|
-
})
|
|
453
|
-
|
|
454
|
-
const command = new ConfCommand()
|
|
455
|
-
command.config = mockConfig
|
|
456
|
-
command.logger = mockLogger
|
|
457
|
-
command.debug = sandbox.stub()
|
|
458
|
-
|
|
459
|
-
await command.action('delete', undefined, undefined, {})
|
|
460
|
-
|
|
461
|
-
t.true(mockLogger.error.calledOnce)
|
|
462
|
-
t.true(mockLogger.error.calledWith('Usage: quire conf delete <key>'))
|
|
463
|
-
t.false(mockConfig.delete.called)
|
|
464
|
-
})
|
|
465
|
-
|
|
466
|
-
test('conf delete should throw UnknownConfigKeyError for unknown key', async (t) => {
|
|
467
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
468
|
-
|
|
469
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
470
|
-
'#lib/logger/index.js': {
|
|
471
|
-
default: () => mockLogger
|
|
472
|
-
}
|
|
473
|
-
})
|
|
474
|
-
|
|
475
|
-
const command = new ConfCommand()
|
|
476
|
-
command.config = mockConfig
|
|
477
|
-
command.logger = mockLogger
|
|
478
|
-
command.debug = sandbox.stub()
|
|
479
|
-
|
|
480
|
-
await t.throwsAsync(
|
|
481
|
-
() => command.action('delete', 'unknownKey', undefined, {}),
|
|
482
|
-
{ code: 'UNKNOWN_CONFIG_KEY' }
|
|
483
|
-
)
|
|
484
|
-
t.false(mockConfig.delete.called)
|
|
485
|
-
})
|
|
486
|
-
|
|
487
|
-
// =============================================================================
|
|
488
|
-
// Reset operation
|
|
489
|
-
// =============================================================================
|
|
490
|
-
|
|
491
|
-
test('conf reset should reset a single key', async (t) => {
|
|
492
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
493
|
-
|
|
494
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
495
|
-
'#lib/logger/index.js': {
|
|
496
|
-
default: () => mockLogger
|
|
497
|
-
}
|
|
498
|
-
})
|
|
499
|
-
|
|
500
|
-
const command = new ConfCommand()
|
|
501
|
-
command.config = mockConfig
|
|
502
|
-
command.logger = mockLogger
|
|
503
|
-
command.debug = sandbox.stub()
|
|
504
|
-
|
|
505
|
-
await command.action('reset', 'logLevel', undefined, {})
|
|
506
|
-
|
|
507
|
-
t.true(mockConfig.reset.calledOnce)
|
|
508
|
-
t.true(mockConfig.reset.calledWith('logLevel'))
|
|
509
|
-
t.true(mockLogger.info.firstCall.args[0].includes('reset to'))
|
|
510
|
-
})
|
|
511
|
-
|
|
512
|
-
test('conf reset should reset all config when no key provided', async (t) => {
|
|
513
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
514
|
-
|
|
515
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
516
|
-
'#lib/logger/index.js': {
|
|
517
|
-
default: () => mockLogger
|
|
518
|
-
}
|
|
519
|
-
})
|
|
520
|
-
|
|
521
|
-
const command = new ConfCommand()
|
|
522
|
-
command.config = mockConfig
|
|
523
|
-
command.logger = mockLogger
|
|
524
|
-
command.debug = sandbox.stub()
|
|
525
|
-
|
|
526
|
-
await command.action('reset', undefined, undefined, {})
|
|
527
|
-
|
|
528
|
-
t.true(mockConfig.clear.calledOnce)
|
|
529
|
-
t.true(mockLogger.info.calledWith('Configuration reset to defaults'))
|
|
530
|
-
})
|
|
531
|
-
|
|
532
|
-
test('conf reset should throw UnknownConfigKeyError for unknown key', async (t) => {
|
|
533
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
534
|
-
|
|
535
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
536
|
-
'#lib/logger/index.js': {
|
|
537
|
-
default: () => mockLogger
|
|
538
|
-
}
|
|
539
|
-
})
|
|
540
|
-
|
|
541
|
-
const command = new ConfCommand()
|
|
542
|
-
command.config = mockConfig
|
|
543
|
-
command.logger = mockLogger
|
|
544
|
-
command.debug = sandbox.stub()
|
|
545
|
-
|
|
546
|
-
await t.throwsAsync(
|
|
547
|
-
() => command.action('reset', 'unknownKey', undefined, {}),
|
|
548
|
-
{ code: 'UNKNOWN_CONFIG_KEY' }
|
|
549
|
-
)
|
|
550
|
-
t.false(mockConfig.reset.called)
|
|
551
|
-
})
|
|
552
|
-
|
|
553
|
-
// =============================================================================
|
|
554
|
-
// Path operation
|
|
555
|
-
// =============================================================================
|
|
556
|
-
|
|
557
|
-
test('conf path should show config file path', async (t) => {
|
|
558
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
559
|
-
|
|
560
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
561
|
-
'#lib/logger/index.js': {
|
|
562
|
-
default: () => mockLogger
|
|
563
|
-
}
|
|
564
|
-
})
|
|
565
|
-
|
|
566
|
-
const command = new ConfCommand()
|
|
567
|
-
command.config = mockConfig
|
|
568
|
-
command.logger = mockLogger
|
|
569
|
-
command.debug = sandbox.stub()
|
|
570
|
-
|
|
571
|
-
await command.action('path', undefined, undefined, {})
|
|
572
|
-
|
|
573
|
-
t.true(mockLogger.info.calledOnce)
|
|
574
|
-
t.true(mockLogger.info.calledWith('/mock/config/path'))
|
|
575
|
-
})
|
|
576
|
-
|
|
577
|
-
// =============================================================================
|
|
578
|
-
// Invalid operation
|
|
579
|
-
// =============================================================================
|
|
580
|
-
|
|
581
|
-
test('conf should throw UnknownConfigOperationError for unknown operation', async (t) => {
|
|
582
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
583
|
-
|
|
584
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
585
|
-
'#lib/logger/index.js': {
|
|
586
|
-
default: () => mockLogger
|
|
587
|
-
}
|
|
588
|
-
})
|
|
589
|
-
|
|
590
|
-
const command = new ConfCommand()
|
|
591
|
-
command.config = mockConfig
|
|
592
|
-
command.logger = mockLogger
|
|
593
|
-
command.debug = sandbox.stub()
|
|
594
|
-
|
|
595
|
-
const error = await t.throwsAsync(
|
|
596
|
-
() => command.action('unknownOp', undefined, undefined, {}),
|
|
597
|
-
{ code: 'UNKNOWN_CONFIG_OPERATION' }
|
|
598
|
-
)
|
|
599
|
-
t.true(error.message.includes('Unknown operation: unknownOp'))
|
|
600
|
-
t.true(error.suggestion.includes('Valid operations:'))
|
|
601
|
-
})
|
|
602
|
-
|
|
603
|
-
test('conf should suggest similar operation for close misspelling', async (t) => {
|
|
604
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
605
|
-
|
|
606
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
607
|
-
'#lib/logger/index.js': {
|
|
608
|
-
default: () => mockLogger
|
|
609
|
-
}
|
|
610
|
-
})
|
|
611
|
-
|
|
612
|
-
const command = new ConfCommand()
|
|
613
|
-
command.config = mockConfig
|
|
614
|
-
command.logger = mockLogger
|
|
615
|
-
command.debug = sandbox.stub()
|
|
616
|
-
|
|
617
|
-
const error = await t.throwsAsync(
|
|
618
|
-
() => command.action('gt', undefined, undefined, {}),
|
|
619
|
-
{ code: 'UNKNOWN_CONFIG_OPERATION' }
|
|
620
|
-
)
|
|
621
|
-
t.true(error.message.includes('Unknown operation: gt'))
|
|
622
|
-
t.true(error.suggestion.includes('Did you mean: get?'))
|
|
623
|
-
})
|
|
624
|
-
|
|
625
|
-
test('conf should suggest similar operation for transposition', async (t) => {
|
|
626
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
627
|
-
|
|
628
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
629
|
-
'#lib/logger/index.js': {
|
|
630
|
-
default: () => mockLogger
|
|
631
|
-
}
|
|
632
|
-
})
|
|
633
|
-
|
|
634
|
-
const command = new ConfCommand()
|
|
635
|
-
command.config = mockConfig
|
|
636
|
-
command.logger = mockLogger
|
|
637
|
-
command.debug = sandbox.stub()
|
|
638
|
-
|
|
639
|
-
const error = await t.throwsAsync(
|
|
640
|
-
() => command.action('ste', undefined, undefined, {}),
|
|
641
|
-
{ code: 'UNKNOWN_CONFIG_OPERATION' }
|
|
642
|
-
)
|
|
643
|
-
t.true(error.message.includes('Unknown operation: ste'))
|
|
644
|
-
t.true(error.suggestion.includes('Did you mean: set?'))
|
|
645
|
-
})
|
|
646
|
-
|
|
647
|
-
// =============================================================================
|
|
648
|
-
// JSON output
|
|
649
|
-
// =============================================================================
|
|
650
|
-
|
|
651
|
-
test.serial('conf --json should output raw JSON of all config', async (t) => {
|
|
652
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
653
|
-
|
|
654
|
-
const consoleLogStub = sandbox.stub(console, 'log')
|
|
655
|
-
|
|
656
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
657
|
-
'#lib/logger/index.js': {
|
|
658
|
-
default: () => mockLogger
|
|
659
|
-
}
|
|
660
|
-
})
|
|
661
|
-
|
|
662
|
-
const command = new ConfCommand()
|
|
663
|
-
command.config = mockConfig
|
|
664
|
-
command.logger = mockLogger
|
|
665
|
-
command.debug = sandbox.stub()
|
|
666
|
-
|
|
667
|
-
await command.action(undefined, undefined, undefined, { json: true })
|
|
668
|
-
|
|
669
|
-
t.true(consoleLogStub.calledOnce)
|
|
670
|
-
const output = JSON.parse(consoleLogStub.firstCall.args[0])
|
|
671
|
-
t.is(output.logLevel, 'info')
|
|
672
|
-
t.is(output.quireVersion, '1.0.0')
|
|
673
|
-
t.false(mockLogger.info.called, 'logger.info should not be called in JSON mode')
|
|
674
|
-
})
|
|
675
|
-
|
|
676
|
-
test.serial('conf --json should not include descriptions or headers', async (t) => {
|
|
677
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
678
|
-
|
|
679
|
-
const consoleLogStub = sandbox.stub(console, 'log')
|
|
680
|
-
|
|
681
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
682
|
-
'#lib/logger/index.js': {
|
|
683
|
-
default: () => mockLogger
|
|
684
|
-
}
|
|
685
|
-
})
|
|
686
|
-
|
|
687
|
-
const command = new ConfCommand()
|
|
688
|
-
command.config = mockConfig
|
|
689
|
-
command.logger = mockLogger
|
|
690
|
-
command.debug = sandbox.stub()
|
|
691
|
-
|
|
692
|
-
await command.action(undefined, undefined, undefined, { json: true })
|
|
693
|
-
|
|
694
|
-
const raw = consoleLogStub.firstCall.args[0]
|
|
695
|
-
t.false(raw.includes('quire-cli configuration'), 'JSON output should not contain header text')
|
|
696
|
-
t.false(raw.includes('Use "quire settings'), 'JSON output should not contain help hint')
|
|
697
|
-
})
|
|
698
|
-
|
|
699
|
-
test.serial('conf --json should exclude __internal__ keys by default', async (t) => {
|
|
700
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
701
|
-
|
|
702
|
-
const consoleLogStub = sandbox.stub(console, 'log')
|
|
703
|
-
|
|
704
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
705
|
-
'#lib/logger/index.js': {
|
|
706
|
-
default: () => mockLogger
|
|
707
|
-
}
|
|
708
|
-
})
|
|
709
|
-
|
|
710
|
-
const command = new ConfCommand()
|
|
711
|
-
command.config = mockConfig
|
|
712
|
-
command.logger = mockLogger
|
|
713
|
-
command.debug = sandbox.stub()
|
|
714
|
-
|
|
715
|
-
await command.action(undefined, undefined, undefined, { json: true })
|
|
716
|
-
|
|
717
|
-
const output = JSON.parse(consoleLogStub.firstCall.args[0])
|
|
718
|
-
t.false('__internal__secretKey' in output, 'JSON output should not include __internal__ keys')
|
|
719
|
-
t.is(output.logLevel, 'info', 'non-internal keys should still be present')
|
|
720
|
-
})
|
|
721
|
-
|
|
722
|
-
test.serial('conf --json --debug should include __internal__ keys', async (t) => {
|
|
723
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
724
|
-
|
|
725
|
-
const consoleLogStub = sandbox.stub(console, 'log')
|
|
726
|
-
|
|
727
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
728
|
-
'#lib/logger/index.js': {
|
|
729
|
-
default: () => mockLogger
|
|
730
|
-
}
|
|
731
|
-
})
|
|
732
|
-
|
|
733
|
-
const command = new ConfCommand()
|
|
734
|
-
command.config = mockConfig
|
|
735
|
-
command.logger = mockLogger
|
|
736
|
-
command.debug = sandbox.stub()
|
|
737
|
-
|
|
738
|
-
await command.action(undefined, undefined, undefined, { json: true, debug: true })
|
|
739
|
-
|
|
740
|
-
const output = JSON.parse(consoleLogStub.firstCall.args[0])
|
|
741
|
-
t.is(output.__internal__secretKey, 'hidden-value', '__internal__ keys should be included with --debug')
|
|
742
|
-
t.is(output.logLevel, 'info')
|
|
743
|
-
})
|
|
744
|
-
|
|
745
|
-
test.serial('conf get --json should output single value as JSON', async (t) => {
|
|
746
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
747
|
-
|
|
748
|
-
const consoleLogStub = sandbox.stub(console, 'log')
|
|
749
|
-
|
|
750
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
751
|
-
'#lib/logger/index.js': {
|
|
752
|
-
default: () => mockLogger
|
|
753
|
-
}
|
|
754
|
-
})
|
|
755
|
-
|
|
756
|
-
const command = new ConfCommand()
|
|
757
|
-
command.config = mockConfig
|
|
758
|
-
command.logger = mockLogger
|
|
759
|
-
command.debug = sandbox.stub()
|
|
760
|
-
|
|
761
|
-
await command.action('get', 'logLevel', undefined, { json: true })
|
|
762
|
-
|
|
763
|
-
t.true(consoleLogStub.calledOnce)
|
|
764
|
-
t.is(consoleLogStub.firstCall.args[0], '"info"')
|
|
765
|
-
t.false(mockLogger.info.called, 'logger.info should not be called in JSON mode')
|
|
766
|
-
})
|
|
767
|
-
|
|
768
|
-
test.serial('conf get --json should output boolean value as JSON', async (t) => {
|
|
769
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
770
|
-
|
|
771
|
-
const consoleLogStub = sandbox.stub(console, 'log')
|
|
772
|
-
|
|
773
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
774
|
-
'#lib/logger/index.js': {
|
|
775
|
-
default: () => mockLogger
|
|
776
|
-
}
|
|
777
|
-
})
|
|
778
|
-
|
|
779
|
-
const command = new ConfCommand()
|
|
780
|
-
command.config = mockConfig
|
|
781
|
-
command.logger = mockLogger
|
|
782
|
-
command.debug = sandbox.stub()
|
|
783
|
-
|
|
784
|
-
await command.action('get', 'logShowLevel', undefined, { json: true })
|
|
785
|
-
|
|
786
|
-
t.true(consoleLogStub.calledOnce)
|
|
787
|
-
t.is(consoleLogStub.firstCall.args[0], 'false')
|
|
788
|
-
})
|
|
789
|
-
|
|
790
|
-
test.serial('conf get --json should output undefined as JSON for unset key', async (t) => {
|
|
791
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
792
|
-
|
|
793
|
-
const consoleLogStub = sandbox.stub(console, 'log')
|
|
794
|
-
|
|
795
|
-
// Add a key that returns undefined
|
|
796
|
-
mockConfig.store.missingKey = undefined
|
|
797
|
-
mockConfig.get = (key) => mockConfig.store[key]
|
|
798
|
-
|
|
799
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
800
|
-
'#lib/logger/index.js': {
|
|
801
|
-
default: () => mockLogger
|
|
802
|
-
}
|
|
803
|
-
})
|
|
804
|
-
|
|
805
|
-
const command = new ConfCommand()
|
|
806
|
-
command.config = mockConfig
|
|
807
|
-
command.logger = mockLogger
|
|
808
|
-
command.debug = sandbox.stub()
|
|
809
|
-
|
|
810
|
-
await command.action('get', 'logLevel', undefined, { json: true })
|
|
811
|
-
|
|
812
|
-
t.true(consoleLogStub.calledOnce)
|
|
813
|
-
})
|
|
814
|
-
|
|
815
|
-
// =============================================================================
|
|
816
|
-
// Debug output
|
|
817
|
-
// =============================================================================
|
|
818
|
-
|
|
819
|
-
test('conf command logs debug info with operation, key, value, and options', async (t) => {
|
|
820
|
-
const { sandbox, mockLogger, mockConfig } = t.context
|
|
821
|
-
|
|
822
|
-
const mockDebug = sandbox.stub()
|
|
823
|
-
|
|
824
|
-
const { default: ConfCommand } = await esmock('./config.js', {}, {
|
|
825
|
-
'#lib/logger/index.js': {
|
|
826
|
-
default: () => mockLogger
|
|
827
|
-
}
|
|
828
|
-
})
|
|
829
|
-
|
|
830
|
-
const command = new ConfCommand()
|
|
831
|
-
command.config = mockConfig
|
|
832
|
-
command.logger = mockLogger
|
|
833
|
-
command.debug = mockDebug
|
|
834
|
-
|
|
835
|
-
await command.action('set', 'logLevel', 'debug', { someOption: true })
|
|
836
|
-
|
|
837
|
-
t.true(mockDebug.called)
|
|
838
|
-
t.true(mockDebug.calledWith(
|
|
839
|
-
'called with operation=%s key=%s value=%s options=%O',
|
|
840
|
-
'set',
|
|
841
|
-
'logLevel',
|
|
842
|
-
'debug',
|
|
843
|
-
{ someOption: true }
|
|
844
|
-
))
|
|
845
|
-
})
|