@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,512 +0,0 @@
|
|
|
1
|
-
import test from 'ava'
|
|
2
|
-
import sinon from 'sinon'
|
|
3
|
-
import esmock from 'esmock'
|
|
4
|
-
|
|
5
|
-
test.beforeEach((t) => {
|
|
6
|
-
// Create sinon sandbox for mocking
|
|
7
|
-
t.context.sandbox = sinon.createSandbox()
|
|
8
|
-
|
|
9
|
-
// Create mock logger
|
|
10
|
-
t.context.mockLogger = {
|
|
11
|
-
info: t.context.sandbox.stub(),
|
|
12
|
-
error: t.context.sandbox.stub(),
|
|
13
|
-
debug: t.context.sandbox.stub(),
|
|
14
|
-
log: t.context.sandbox.stub(),
|
|
15
|
-
warn: t.context.sandbox.stub()
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// Mock config
|
|
19
|
-
t.context.mockConfig = {
|
|
20
|
-
get: t.context.sandbox.stub().returns('./.quire-version')
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// Mock testcwd helper
|
|
24
|
-
t.context.mockTestcwd = t.context.sandbox.stub()
|
|
25
|
-
|
|
26
|
-
// Mock packageConfig binPath
|
|
27
|
-
t.context.mockBinPath = t.context.sandbox.stub().returns('/usr/local/bin/quire')
|
|
28
|
-
|
|
29
|
-
// Mock fs module
|
|
30
|
-
t.context.mockFs = {
|
|
31
|
-
readFileSync: t.context.sandbox.stub(),
|
|
32
|
-
writeFileSync: t.context.sandbox.stub(),
|
|
33
|
-
existsSync: t.context.sandbox.stub().returns(true)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Default version file content
|
|
37
|
-
t.context.versionFileContent = JSON.stringify({
|
|
38
|
-
cli: '1.0.0-rc.33',
|
|
39
|
-
starter: 'https://github.com/thegetty/quire-starter-default'
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
// Default package.json content
|
|
43
|
-
t.context.packageJsonContent = JSON.stringify({
|
|
44
|
-
name: 'test-project',
|
|
45
|
-
version: '1.0.0'
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
// Setup default readFileSync behavior - stub returns different content based on file path
|
|
49
|
-
t.context.mockFs.readFileSync.callsFake((filePath, options) => {
|
|
50
|
-
if (filePath === './.quire-version') {
|
|
51
|
-
return t.context.versionFileContent
|
|
52
|
-
}
|
|
53
|
-
if (filePath === './package.json') {
|
|
54
|
-
return t.context.packageJsonContent
|
|
55
|
-
}
|
|
56
|
-
// For any other file, return empty string
|
|
57
|
-
return ''
|
|
58
|
-
})
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
test.afterEach.always((t) => {
|
|
62
|
-
// Restore all mocks
|
|
63
|
-
t.context.sandbox.restore()
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
test('info command should validate Quire project in preAction', async (t) => {
|
|
67
|
-
const { sandbox, mockLogger, mockTestcwd, mockConfig, mockBinPath, mockFs } = t.context
|
|
68
|
-
|
|
69
|
-
const { default: InfoCommand } = await esmock('./info.js', {
|
|
70
|
-
'#helpers/test-cwd.js': {
|
|
71
|
-
default: mockTestcwd
|
|
72
|
-
},
|
|
73
|
-
'#src/packageConfig.js': {
|
|
74
|
-
binPath: mockBinPath
|
|
75
|
-
},
|
|
76
|
-
'node:fs': mockFs
|
|
77
|
-
}, {
|
|
78
|
-
'#lib/logger/index.js': {
|
|
79
|
-
default: () => mockLogger
|
|
80
|
-
}
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
const command = new InfoCommand()
|
|
84
|
-
command.config = mockConfig
|
|
85
|
-
command.logger = mockLogger
|
|
86
|
-
command.debug = sandbox.stub()
|
|
87
|
-
|
|
88
|
-
// Mock Commander.js command object
|
|
89
|
-
const mockCommand = {
|
|
90
|
-
name: () => 'info',
|
|
91
|
-
opts: () => ({})
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Call preAction
|
|
95
|
-
command.preAction(mockCommand)
|
|
96
|
-
|
|
97
|
-
t.true(mockTestcwd.called, 'testcwd should be called in preAction')
|
|
98
|
-
t.true(mockTestcwd.calledWith(mockCommand), 'testcwd should be called with command')
|
|
99
|
-
})
|
|
100
|
-
|
|
101
|
-
test('info command should display project version information', async (t) => {
|
|
102
|
-
const { sandbox, mockLogger, mockConfig, mockTestcwd, mockBinPath, mockFs } = t.context
|
|
103
|
-
|
|
104
|
-
const { default: InfoCommand } = await esmock('./info.js', {
|
|
105
|
-
'#helpers/test-cwd.js': {
|
|
106
|
-
default: mockTestcwd
|
|
107
|
-
},
|
|
108
|
-
'#src/packageConfig.js': {
|
|
109
|
-
binPath: mockBinPath
|
|
110
|
-
},
|
|
111
|
-
'node:fs': mockFs
|
|
112
|
-
}, {
|
|
113
|
-
'#lib/logger/index.js': {
|
|
114
|
-
default: () => mockLogger
|
|
115
|
-
}
|
|
116
|
-
})
|
|
117
|
-
|
|
118
|
-
const command = new InfoCommand()
|
|
119
|
-
command.config = mockConfig
|
|
120
|
-
command.logger = mockLogger
|
|
121
|
-
command.debug = sandbox.stub()
|
|
122
|
-
|
|
123
|
-
await command.action({}, {})
|
|
124
|
-
|
|
125
|
-
// Verify logger.info was called with project information
|
|
126
|
-
t.true(mockLogger.info.called, 'logger.info should be called')
|
|
127
|
-
|
|
128
|
-
// Check for project header
|
|
129
|
-
const calls = mockLogger.info.getCalls()
|
|
130
|
-
const hasProjectInfo = calls.some((call) =>
|
|
131
|
-
call.args[0] && call.args[0].includes('Project:')
|
|
132
|
-
)
|
|
133
|
-
t.true(hasProjectInfo, 'should display project header')
|
|
134
|
-
|
|
135
|
-
// Check for quire-cli version in output
|
|
136
|
-
const hasCliVersion = calls.some((call) =>
|
|
137
|
-
call.args[0] && call.args[0].includes('quire-cli') && call.args[0].includes('1.0.0-rc.33')
|
|
138
|
-
)
|
|
139
|
-
t.true(hasCliVersion, 'should display quire-cli version')
|
|
140
|
-
|
|
141
|
-
// Check for quire-11ty version in output
|
|
142
|
-
const has11tyVersion = calls.some((call) =>
|
|
143
|
-
call.args[0] && call.args[0].includes('quire-11ty')
|
|
144
|
-
)
|
|
145
|
-
t.true(has11tyVersion, 'should display quire-11ty version')
|
|
146
|
-
|
|
147
|
-
// Check for doctor tip
|
|
148
|
-
const hasDoctorTip = calls.some((call) =>
|
|
149
|
-
call.args[0] && call.args[0].includes('quire doctor')
|
|
150
|
-
)
|
|
151
|
-
t.true(hasDoctorTip, 'should display doctor tip')
|
|
152
|
-
})
|
|
153
|
-
|
|
154
|
-
test('info command should display starter version when available', async (t) => {
|
|
155
|
-
const { sandbox, mockLogger, mockConfig, mockTestcwd, mockBinPath, mockFs } = t.context
|
|
156
|
-
|
|
157
|
-
const { default: InfoCommand } = await esmock('./info.js', {
|
|
158
|
-
'#helpers/test-cwd.js': {
|
|
159
|
-
default: mockTestcwd
|
|
160
|
-
},
|
|
161
|
-
'#src/packageConfig.js': {
|
|
162
|
-
binPath: mockBinPath
|
|
163
|
-
},
|
|
164
|
-
'node:fs': mockFs
|
|
165
|
-
}, {
|
|
166
|
-
'#lib/logger/index.js': {
|
|
167
|
-
default: () => mockLogger
|
|
168
|
-
}
|
|
169
|
-
})
|
|
170
|
-
|
|
171
|
-
const command = new InfoCommand()
|
|
172
|
-
command.config = mockConfig
|
|
173
|
-
command.logger = mockLogger
|
|
174
|
-
command.debug = sandbox.stub()
|
|
175
|
-
|
|
176
|
-
await command.action({}, {})
|
|
177
|
-
|
|
178
|
-
// Verify logger.info was called
|
|
179
|
-
t.true(mockLogger.info.called, 'logger.info should be called')
|
|
180
|
-
|
|
181
|
-
// Check for starter version in output (from version file)
|
|
182
|
-
const calls = mockLogger.info.getCalls()
|
|
183
|
-
const hasStarterVersion = calls.some((call) =>
|
|
184
|
-
call.args[0] && call.args[0].includes('starter')
|
|
185
|
-
)
|
|
186
|
-
t.true(hasStarterVersion, 'should display starter version when available')
|
|
187
|
-
})
|
|
188
|
-
|
|
189
|
-
test('info command --debug shows installation paths', async (t) => {
|
|
190
|
-
const { sandbox, mockLogger, mockConfig, mockTestcwd, mockBinPath, mockFs } = t.context
|
|
191
|
-
|
|
192
|
-
const { default: InfoCommand } = await esmock('./info.js', {
|
|
193
|
-
'#helpers/test-cwd.js': {
|
|
194
|
-
default: mockTestcwd
|
|
195
|
-
},
|
|
196
|
-
'#src/packageConfig.js': {
|
|
197
|
-
binPath: mockBinPath
|
|
198
|
-
},
|
|
199
|
-
'node:fs': mockFs
|
|
200
|
-
}, {
|
|
201
|
-
'#lib/logger/index.js': {
|
|
202
|
-
default: () => mockLogger
|
|
203
|
-
}
|
|
204
|
-
})
|
|
205
|
-
|
|
206
|
-
const command = new InfoCommand()
|
|
207
|
-
command.config = mockConfig
|
|
208
|
-
command.logger = mockLogger
|
|
209
|
-
command.debug = sandbox.stub()
|
|
210
|
-
|
|
211
|
-
await command.action({ debug: true }, {})
|
|
212
|
-
|
|
213
|
-
const calls = mockLogger.info.getCalls()
|
|
214
|
-
const output = calls.map((call) => call.args[0]).join('\n')
|
|
215
|
-
|
|
216
|
-
// Check for quire-cli path
|
|
217
|
-
t.true(output.includes('/usr/local/bin/quire'), 'should display quire-cli path')
|
|
218
|
-
})
|
|
219
|
-
|
|
220
|
-
test('info command --debug handles missing quire-cli in PATH', async (t) => {
|
|
221
|
-
const { sandbox, mockLogger, mockConfig, mockTestcwd, mockFs } = t.context
|
|
222
|
-
|
|
223
|
-
// binPath returns null when executable is not found
|
|
224
|
-
const mockBinPathNotFound = sandbox.stub().returns(null)
|
|
225
|
-
|
|
226
|
-
const { default: InfoCommand } = await esmock('./info.js', {
|
|
227
|
-
'#helpers/test-cwd.js': {
|
|
228
|
-
default: mockTestcwd
|
|
229
|
-
},
|
|
230
|
-
'#src/packageConfig.js': {
|
|
231
|
-
binPath: mockBinPathNotFound
|
|
232
|
-
},
|
|
233
|
-
'node:fs': mockFs
|
|
234
|
-
}, {
|
|
235
|
-
'#lib/logger/index.js': {
|
|
236
|
-
default: () => mockLogger
|
|
237
|
-
}
|
|
238
|
-
})
|
|
239
|
-
|
|
240
|
-
const command = new InfoCommand()
|
|
241
|
-
command.config = mockConfig
|
|
242
|
-
command.logger = mockLogger
|
|
243
|
-
command.debug = sandbox.stub()
|
|
244
|
-
|
|
245
|
-
await command.action({ debug: true }, {})
|
|
246
|
-
|
|
247
|
-
const calls = mockLogger.info.getCalls()
|
|
248
|
-
const output = calls.map((call) => call.args[0]).join('\n')
|
|
249
|
-
|
|
250
|
-
t.true(output.includes('not found in PATH'), 'should show not found message for quire-cli')
|
|
251
|
-
})
|
|
252
|
-
|
|
253
|
-
test('info command should handle missing version file', async (t) => {
|
|
254
|
-
const { sandbox, mockLogger, mockConfig, mockTestcwd, mockBinPath, mockFs } = t.context
|
|
255
|
-
|
|
256
|
-
// Setup mockFs to throw error for missing version file (simulating file not found)
|
|
257
|
-
mockFs.readFileSync.callsFake((filePath, options) => {
|
|
258
|
-
if (filePath === './.quire-version') {
|
|
259
|
-
throw new Error('ENOENT: no such file')
|
|
260
|
-
}
|
|
261
|
-
if (filePath === './package.json') {
|
|
262
|
-
return t.context.packageJsonContent
|
|
263
|
-
}
|
|
264
|
-
return ''
|
|
265
|
-
})
|
|
266
|
-
|
|
267
|
-
const { default: InfoCommand } = await esmock('./info.js', {
|
|
268
|
-
'#helpers/test-cwd.js': {
|
|
269
|
-
default: mockTestcwd
|
|
270
|
-
},
|
|
271
|
-
'#src/packageConfig.js': {
|
|
272
|
-
binPath: mockBinPath
|
|
273
|
-
},
|
|
274
|
-
'node:fs': mockFs
|
|
275
|
-
}, {
|
|
276
|
-
'#lib/logger/index.js': {
|
|
277
|
-
default: () => mockLogger
|
|
278
|
-
}
|
|
279
|
-
})
|
|
280
|
-
|
|
281
|
-
const command = new InfoCommand()
|
|
282
|
-
command.config = mockConfig
|
|
283
|
-
command.logger = mockLogger
|
|
284
|
-
command.debug = sandbox.stub()
|
|
285
|
-
|
|
286
|
-
await command.action({}, {})
|
|
287
|
-
|
|
288
|
-
// Verify warning was logged about old version
|
|
289
|
-
t.true(mockLogger.warn.called, 'logger.warn should be called for missing version file')
|
|
290
|
-
t.true(
|
|
291
|
-
mockLogger.warn.calledWith(sinon.match(/prior to version 1.0.0.rc-8/)),
|
|
292
|
-
'should warn about old project version'
|
|
293
|
-
)
|
|
294
|
-
|
|
295
|
-
// Verify version file was created
|
|
296
|
-
t.true(mockFs.writeFileSync.called, 'writeFileSync should be called to create version file')
|
|
297
|
-
})
|
|
298
|
-
|
|
299
|
-
test('info command should handle malformed version file', async (t) => {
|
|
300
|
-
const { sandbox, mockLogger, mockConfig, mockTestcwd, mockBinPath, mockFs } = t.context
|
|
301
|
-
|
|
302
|
-
// Setup mockFs to return malformed JSON (simulating corrupted file)
|
|
303
|
-
mockFs.readFileSync.callsFake((filePath, options) => {
|
|
304
|
-
if (filePath === './.quire-version') {
|
|
305
|
-
return 'invalid json{'
|
|
306
|
-
}
|
|
307
|
-
if (filePath === './package.json') {
|
|
308
|
-
return t.context.packageJsonContent
|
|
309
|
-
}
|
|
310
|
-
return ''
|
|
311
|
-
})
|
|
312
|
-
|
|
313
|
-
const { default: InfoCommand } = await esmock('./info.js', {
|
|
314
|
-
'#helpers/test-cwd.js': {
|
|
315
|
-
default: mockTestcwd
|
|
316
|
-
},
|
|
317
|
-
'#src/packageConfig.js': {
|
|
318
|
-
binPath: mockBinPath
|
|
319
|
-
},
|
|
320
|
-
'node:fs': mockFs
|
|
321
|
-
}, {
|
|
322
|
-
'#lib/logger/index.js': {
|
|
323
|
-
default: () => mockLogger
|
|
324
|
-
}
|
|
325
|
-
})
|
|
326
|
-
|
|
327
|
-
const command = new InfoCommand()
|
|
328
|
-
command.config = mockConfig
|
|
329
|
-
command.logger = mockLogger
|
|
330
|
-
command.debug = sandbox.stub()
|
|
331
|
-
|
|
332
|
-
await command.action({}, {})
|
|
333
|
-
|
|
334
|
-
// Verify warning was logged
|
|
335
|
-
t.true(mockLogger.warn.called, 'logger.warn should be called for malformed version file')
|
|
336
|
-
|
|
337
|
-
// Verify version file was overwritten with valid JSON
|
|
338
|
-
t.true(mockFs.writeFileSync.called, 'writeFileSync should be called to fix malformed version file')
|
|
339
|
-
|
|
340
|
-
// Check that the content written is valid JSON
|
|
341
|
-
const writeCall = mockFs.writeFileSync.getCall(0)
|
|
342
|
-
if (writeCall) {
|
|
343
|
-
const writtenContent = writeCall.args[1]
|
|
344
|
-
t.notThrows(() => JSON.parse(writtenContent), 'written content should be valid JSON')
|
|
345
|
-
}
|
|
346
|
-
})
|
|
347
|
-
|
|
348
|
-
test('info command should read quire-11ty version from package.json', async (t) => {
|
|
349
|
-
const { sandbox, mockLogger, mockConfig, mockTestcwd, mockBinPath, mockFs } = t.context
|
|
350
|
-
|
|
351
|
-
// Override package.json to have specific version
|
|
352
|
-
mockFs.readFileSync.callsFake((filePath, options) => {
|
|
353
|
-
if (filePath === './.quire-version') {
|
|
354
|
-
return t.context.versionFileContent
|
|
355
|
-
}
|
|
356
|
-
if (filePath === './package.json') {
|
|
357
|
-
return JSON.stringify({
|
|
358
|
-
name: 'test-project',
|
|
359
|
-
version: '2.5.3'
|
|
360
|
-
})
|
|
361
|
-
}
|
|
362
|
-
return ''
|
|
363
|
-
})
|
|
364
|
-
|
|
365
|
-
const { default: InfoCommand } = await esmock('./info.js', {
|
|
366
|
-
'#helpers/test-cwd.js': {
|
|
367
|
-
default: mockTestcwd
|
|
368
|
-
},
|
|
369
|
-
'#src/packageConfig.js': {
|
|
370
|
-
binPath: mockBinPath
|
|
371
|
-
},
|
|
372
|
-
'node:fs': mockFs
|
|
373
|
-
}, {
|
|
374
|
-
'#lib/logger/index.js': {
|
|
375
|
-
default: () => mockLogger
|
|
376
|
-
}
|
|
377
|
-
})
|
|
378
|
-
|
|
379
|
-
const command = new InfoCommand()
|
|
380
|
-
command.config = mockConfig
|
|
381
|
-
command.logger = mockLogger
|
|
382
|
-
command.debug = sandbox.stub()
|
|
383
|
-
|
|
384
|
-
await command.action({}, {})
|
|
385
|
-
|
|
386
|
-
// Verify logger.info was called
|
|
387
|
-
t.true(mockLogger.info.called, 'logger.info should be called')
|
|
388
|
-
|
|
389
|
-
// Check for quire-11ty version from package.json
|
|
390
|
-
const calls = mockLogger.info.getCalls()
|
|
391
|
-
const hasEleventyVersion = calls.some((call) =>
|
|
392
|
-
call.args[0] && call.args[0].includes('quire-11ty') && call.args[0].includes('2.5.3')
|
|
393
|
-
)
|
|
394
|
-
t.true(hasEleventyVersion, 'should display quire-11ty version from package.json')
|
|
395
|
-
})
|
|
396
|
-
|
|
397
|
-
test('info command should log debug information', async (t) => {
|
|
398
|
-
const { sandbox, mockLogger, mockConfig, mockTestcwd, mockBinPath, mockFs } = t.context
|
|
399
|
-
|
|
400
|
-
const mockDebug = sandbox.stub()
|
|
401
|
-
|
|
402
|
-
const { default: InfoCommand } = await esmock('./info.js', {
|
|
403
|
-
'#helpers/test-cwd.js': {
|
|
404
|
-
default: mockTestcwd
|
|
405
|
-
},
|
|
406
|
-
'#src/packageConfig.js': {
|
|
407
|
-
binPath: mockBinPath
|
|
408
|
-
},
|
|
409
|
-
'node:fs': mockFs
|
|
410
|
-
}, {
|
|
411
|
-
'#lib/logger/index.js': {
|
|
412
|
-
default: () => mockLogger
|
|
413
|
-
}
|
|
414
|
-
})
|
|
415
|
-
|
|
416
|
-
const command = new InfoCommand()
|
|
417
|
-
command.config = mockConfig
|
|
418
|
-
command.logger = mockLogger
|
|
419
|
-
command.debug = mockDebug
|
|
420
|
-
|
|
421
|
-
await command.action({}, {})
|
|
422
|
-
|
|
423
|
-
// Verify debug was called
|
|
424
|
-
t.true(mockDebug.called, 'debug should be called')
|
|
425
|
-
t.true(mockDebug.calledWith('called with options %O', {}))
|
|
426
|
-
})
|
|
427
|
-
|
|
428
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
429
|
-
// JSON output tests
|
|
430
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
431
|
-
|
|
432
|
-
test.serial('info --json should output valid JSON with project versions', async (t) => {
|
|
433
|
-
const { sandbox, mockLogger, mockConfig, mockTestcwd, mockBinPath, mockFs } = t.context
|
|
434
|
-
const consoleLogStub = sandbox.stub(console, 'log')
|
|
435
|
-
|
|
436
|
-
const { default: InfoCommand } = await esmock('./info.js', {
|
|
437
|
-
'#helpers/test-cwd.js': {
|
|
438
|
-
default: mockTestcwd
|
|
439
|
-
},
|
|
440
|
-
'#src/packageConfig.js': {
|
|
441
|
-
binPath: mockBinPath
|
|
442
|
-
},
|
|
443
|
-
'node:fs': mockFs
|
|
444
|
-
}, {
|
|
445
|
-
'#lib/logger/index.js': {
|
|
446
|
-
default: () => mockLogger
|
|
447
|
-
}
|
|
448
|
-
})
|
|
449
|
-
|
|
450
|
-
const command = new InfoCommand()
|
|
451
|
-
command.config = mockConfig
|
|
452
|
-
command.logger = mockLogger
|
|
453
|
-
command.debug = sandbox.stub()
|
|
454
|
-
|
|
455
|
-
await command.action({ json: true }, {})
|
|
456
|
-
|
|
457
|
-
// Should output via console.log, not logger.info
|
|
458
|
-
t.true(consoleLogStub.calledOnce, 'console.log should be called once')
|
|
459
|
-
t.false(mockLogger.info.called, 'logger.info should not be called in JSON mode')
|
|
460
|
-
|
|
461
|
-
// Parse and validate the JSON structure
|
|
462
|
-
const output = JSON.parse(consoleLogStub.firstCall.args[0])
|
|
463
|
-
|
|
464
|
-
t.truthy(output.project, 'JSON should have project section')
|
|
465
|
-
|
|
466
|
-
// Project section
|
|
467
|
-
t.is(output.project.cli, '1.0.0-rc.33')
|
|
468
|
-
t.is(output.project.quire11ty, '1.0.0')
|
|
469
|
-
t.is(output.project.starter, 'https://github.com/thegetty/quire-starter-default')
|
|
470
|
-
t.is(typeof output.project.directory, 'string')
|
|
471
|
-
})
|
|
472
|
-
|
|
473
|
-
test.serial('info --json should set starter to null when not available', async (t) => {
|
|
474
|
-
const { sandbox, mockLogger, mockConfig, mockTestcwd, mockBinPath, mockFs } = t.context
|
|
475
|
-
const consoleLogStub = sandbox.stub(console, 'log')
|
|
476
|
-
|
|
477
|
-
// Version file without starter
|
|
478
|
-
t.context.mockFs.readFileSync.callsFake((filePath, options) => {
|
|
479
|
-
if (filePath === './.quire-version') {
|
|
480
|
-
return JSON.stringify({ cli: '1.0.0-rc.33' })
|
|
481
|
-
}
|
|
482
|
-
if (filePath === './package.json') {
|
|
483
|
-
return t.context.packageJsonContent
|
|
484
|
-
}
|
|
485
|
-
return ''
|
|
486
|
-
})
|
|
487
|
-
|
|
488
|
-
const { default: InfoCommand } = await esmock('./info.js', {
|
|
489
|
-
'#helpers/test-cwd.js': {
|
|
490
|
-
default: mockTestcwd
|
|
491
|
-
},
|
|
492
|
-
'#src/packageConfig.js': {
|
|
493
|
-
binPath: mockBinPath
|
|
494
|
-
},
|
|
495
|
-
'node:fs': mockFs
|
|
496
|
-
}, {
|
|
497
|
-
'#lib/logger/index.js': {
|
|
498
|
-
default: () => mockLogger
|
|
499
|
-
}
|
|
500
|
-
})
|
|
501
|
-
|
|
502
|
-
const command = new InfoCommand()
|
|
503
|
-
command.config = mockConfig
|
|
504
|
-
command.logger = mockLogger
|
|
505
|
-
command.debug = sandbox.stub()
|
|
506
|
-
|
|
507
|
-
await command.action({ json: true }, {})
|
|
508
|
-
|
|
509
|
-
const output = JSON.parse(consoleLogStub.firstCall.args[0])
|
|
510
|
-
|
|
511
|
-
t.is(output.project.starter, null, 'starter should be null when not in version file')
|
|
512
|
-
})
|
package/src/commands/pdf.spec.js
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import { Command, Option } from 'commander'
|
|
2
|
-
import program from '#src/main.js'
|
|
3
|
-
import test from 'ava'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Command Contract/Interface Tests
|
|
7
|
-
*
|
|
8
|
-
* Verifies the command's public API and Commander.js integration.
|
|
9
|
-
* @see docs/testing-commands.md
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
test.before((t) => {
|
|
13
|
-
// Get the registered command (from program.commands) once and share across all tests
|
|
14
|
-
t.context.command = program.commands.find((cmd) => cmd.name() === 'pdf')
|
|
15
|
-
})
|
|
16
|
-
|
|
17
|
-
test('command is registered in CLI program', (t) => {
|
|
18
|
-
const { command } = t.context
|
|
19
|
-
|
|
20
|
-
t.truthy(command, 'command "pdf" should be registered in program')
|
|
21
|
-
t.true(command instanceof Command, 'registered command should be Commander.js Command instance')
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
test('registered command has correct metadata', (t) => {
|
|
25
|
-
const { command } = t.context
|
|
26
|
-
|
|
27
|
-
t.is(command.name(), 'pdf')
|
|
28
|
-
t.truthy(command.description())
|
|
29
|
-
t.is(typeof command._actionHandler, 'function', 'command should have action handler')
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
test('registered command has no arguments', (t) => {
|
|
33
|
-
const { command } = t.context
|
|
34
|
-
const registeredArguments = command.registeredArguments
|
|
35
|
-
|
|
36
|
-
t.is(registeredArguments.length, 0, 'pdf command should have no arguments')
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
test('registered command has correct options', (t) => {
|
|
40
|
-
const { command } = t.context
|
|
41
|
-
|
|
42
|
-
// Get all options
|
|
43
|
-
const engineOption = command.options.find((opt) => opt.long === '--engine')
|
|
44
|
-
const libOption = command.options.find((opt) => opt.long === '--lib')
|
|
45
|
-
const buildOption = command.options.find((opt) => opt.long === '--build')
|
|
46
|
-
const openOption = command.options.find((opt) => opt.long === '--open')
|
|
47
|
-
const quietOption = command.options.find((opt) => opt.long === '--quiet')
|
|
48
|
-
const verboseOption = command.options.find((opt) => opt.long === '--verbose')
|
|
49
|
-
const debugOption = command.options.find((opt) => opt.long === '--debug')
|
|
50
|
-
|
|
51
|
-
// Verify all options exist
|
|
52
|
-
t.truthy(engineOption, '--engine option should exist')
|
|
53
|
-
t.truthy(libOption, '--lib option should exist (deprecated alias)')
|
|
54
|
-
t.truthy(buildOption, '--build option should exist')
|
|
55
|
-
t.truthy(openOption, '--open option should exist')
|
|
56
|
-
t.truthy(quietOption, '--quiet option should exist')
|
|
57
|
-
t.truthy(verboseOption, '--verbose option should exist')
|
|
58
|
-
t.truthy(debugOption, '--debug option should exist')
|
|
59
|
-
|
|
60
|
-
// Verify they are Option instances
|
|
61
|
-
t.true(engineOption instanceof Option, '--engine should be Option instance')
|
|
62
|
-
t.true(libOption instanceof Option, '--lib should be Option instance')
|
|
63
|
-
t.true(buildOption instanceof Option, '--build should be Option instance')
|
|
64
|
-
t.true(openOption instanceof Option, '--open should be Option instance')
|
|
65
|
-
t.true(quietOption instanceof Option, '--quiet should be Option instance')
|
|
66
|
-
t.true(verboseOption instanceof Option, '--verbose should be Option instance')
|
|
67
|
-
t.true(debugOption instanceof Option, '--debug should be Option instance')
|
|
68
|
-
|
|
69
|
-
// Verify --engine option properties
|
|
70
|
-
t.is(engineOption.long, '--engine')
|
|
71
|
-
t.truthy(engineOption.description)
|
|
72
|
-
t.true(engineOption.required, '--engine should require a value')
|
|
73
|
-
|
|
74
|
-
// Verify --lib is hidden (deprecated alias)
|
|
75
|
-
t.is(libOption.long, '--lib')
|
|
76
|
-
t.true(libOption.hidden, '--lib should be hidden (deprecated)')
|
|
77
|
-
|
|
78
|
-
t.is(buildOption.long, '--build')
|
|
79
|
-
t.truthy(buildOption.description)
|
|
80
|
-
t.false(buildOption.required, '--build should not require a value')
|
|
81
|
-
|
|
82
|
-
t.is(openOption.long, '--open')
|
|
83
|
-
t.truthy(openOption.description)
|
|
84
|
-
t.false(openOption.required, '--open should not require a value')
|
|
85
|
-
|
|
86
|
-
t.is(quietOption.long, '--quiet')
|
|
87
|
-
t.is(quietOption.short, '-q', '--quiet should have -q short flag')
|
|
88
|
-
t.truthy(quietOption.description)
|
|
89
|
-
t.false(quietOption.required, '--quiet should not require a value')
|
|
90
|
-
|
|
91
|
-
t.is(verboseOption.long, '--verbose')
|
|
92
|
-
t.is(verboseOption.short, '-v', '--verbose should have -v short flag')
|
|
93
|
-
t.truthy(verboseOption.description)
|
|
94
|
-
t.false(verboseOption.required, '--verbose should not require a value')
|
|
95
|
-
|
|
96
|
-
t.is(debugOption.long, '--debug')
|
|
97
|
-
t.truthy(debugOption.description)
|
|
98
|
-
t.false(debugOption.required, '--debug should not require a value')
|
|
99
|
-
})
|
|
100
|
-
|
|
101
|
-
test('command options are accessible via public API', (t) => {
|
|
102
|
-
const { command } = t.context
|
|
103
|
-
|
|
104
|
-
// Test that options can be accessed the way Commander.js does
|
|
105
|
-
const optionNames = command.options.map((opt) => opt.long)
|
|
106
|
-
|
|
107
|
-
t.true(optionNames.includes('--engine'))
|
|
108
|
-
t.true(optionNames.includes('--lib')) // deprecated alias still exists
|
|
109
|
-
t.true(optionNames.includes('--build'))
|
|
110
|
-
t.true(optionNames.includes('--open'))
|
|
111
|
-
t.true(optionNames.includes('--quiet'))
|
|
112
|
-
t.true(optionNames.includes('--verbose'))
|
|
113
|
-
t.true(optionNames.includes('--debug'))
|
|
114
|
-
})
|