Skip to content

Commit

Permalink
resolves #86 exit process consistency
Browse files Browse the repository at this point in the history
  • Loading branch information
ggrossetie committed Feb 1, 2020
1 parent c1e3f2f commit 6115734
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 32 deletions.
53 changes: 23 additions & 30 deletions lib/invoker.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,28 @@ class Invoker {
this.showVersion()
process.exit(0)
}
if (files.length === 0 && !this.options.stdin) {
// nothing to do...
this.showHelp()
process.exit(0)
}
Invoker.prepareProcessor(args, asciidoctor)
const options = this.options.options
const failureLevel = options['failure_level']
if (this.options.stdin) {
await Invoker.convertFromStdin(options, args)
Invoker.exit(failureLevel)
} else if (files && files.length > 0) {
Invoker.processFiles(files, verbose, args['timings'], options)
try {
if (this.options.stdin) {
await Invoker.convertFromStdin(options, args)
} else if (files && files.length > 0) {
Invoker.convertFiles(files, verbose, args['timings'], options)
}
Invoker.exit(failureLevel)
} else {
this.showHelp()
process.exit(0)
} catch (e) {
if (e && e.name === 'NotImplementedError' && e.message === `asciidoctor: FAILED: missing converter for backend '${options.backend}'. Processing aborted.`) {
console.error(`> Error: missing converter for backend '${options.backend}'. Processing aborted.`)
console.error(`> You might want to require a Node.js package with --require option to support this backend.`)
process.exit(1)
}
throw e
}
}

Expand Down Expand Up @@ -69,42 +79,25 @@ CLI version ${pkg.version}`
if (args['timings']) {
const timings = asciidoctor.Timings.create()
const instanceOptions = Object.assign({}, options, { timings })
Invoker.convert(asciidoctor.convert, data, instanceOptions)
asciidoctor.convert(data, instanceOptions)
timings.printReport(process.stderr, '-')
} else {
Invoker.convert(asciidoctor.convert, data, options)
}
}

static convert (processorFn, input, options) {
try {
processorFn.apply(asciidoctor, [input, options])
} catch (e) {
if (e && e.name === 'NotImplementedError' && e.message === `asciidoctor: FAILED: missing converter for backend '${options.backend}'. Processing aborted.`) {
console.error(`> Error: missing converter for backend '${options.backend}'. Processing aborted.`)
console.error(`> You might want to require a Node.js package with --require option to support this backend.`)
process.exit(1)
}
throw e
asciidoctor.convert(data, options)
}
}

static convertFile (file, options) {
Invoker.convert(asciidoctor.convertFile, file, options)
}

static processFiles (files, verbose, timings, options) {
static convertFiles (files, verbose, timings, options) {
files.forEach((file) => {
if (verbose) {
console.log(`converting file ${file}`)
}
if (timings) {
const timings = asciidoctor.Timings.create()
const instanceOptions = Object.assign({}, options, { timings })
Invoker.convertFile(file, instanceOptions)
asciidoctor.convertFile(file, instanceOptions)
timings.printReport(process.stderr, file)
} else {
Invoker.convertFile(file, options)
asciidoctor.convertFile(file, options)
}
})
}
Expand Down
44 changes: 42 additions & 2 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ describe('Help', () => {
describe('Print timings report', () => {
it('should print timings report', () => {
sinon.stub(process.stderr, 'write')
sinon.stub(process.stdout, 'write')
sinon.stub(process, 'exit')
try {
new Invoker(new Options().parse(['node', 'asciidoctor', `${__dirname}/fixtures/sample.adoc`, '--timings', '-o', '-'])).invoke()
Expand All @@ -166,6 +167,43 @@ describe('Print timings report', () => {
expect(process.stderr.write.getCall(3).args[0]).to.include('Total time (read, parse and convert):')
} finally {
process.stderr.write.restore()
process.stdout.write.restore()
process.exit.restore()
}
})
})

describe('Write to stdout', () => {
it('should write to stdout', () => {
sinon.stub(process.stdout, 'write')
sinon.stub(process, 'exit')
try {
new Invoker(new Options().parse(['node', 'asciidoctor', `${__dirname}/fixtures/sample.adoc`, '-a', 'nofooter', '-o', '-'])).invoke()
expect(process.stdout.write.called).to.be.true()
expect(process.stdout.write.getCall(0).args[0]).to.include(`<body class="article">
<div id="header">
<h1>Title</h1>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>This is a sample document</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_first_section">First section</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This is a paragraph.</p>
</div>
</div>
</div>
</div>
</body>`)
} finally {
process.stdout.write.restore()
process.exit.restore()
}
})
Expand Down Expand Up @@ -227,8 +265,9 @@ describe('Process files', () => {
it('should exit with code 1 when failure level is lower than the maximum logging level', () => {
sinon.stub(process, 'exit')
try {
Invoker.processFiles([bookFilePath], false, false)
Invoker.convertFiles([bookFilePath], false, false)
Invoker.exit(3) // ERROR: 3
Invoker.exit(3)
expect(process.exit.called).to.be.true()
expect(process.exit.calledWith(1)).to.be.true()
} finally {
Expand All @@ -239,8 +278,9 @@ describe('Process files', () => {
it('should exit with code 0 when failure level is lower than the maximum logging level', () => {
sinon.stub(process, 'exit')
try {
Invoker.processFiles([bookFilePath], false, false)
Invoker.convertFiles([bookFilePath], false, false)
Invoker.exit(4) // FATAL: 4
Invoker.exit(4)
expect(process.exit.called).to.be.true()
expect(process.exit.calledWith(0)).to.be.true()
} finally {
Expand Down

0 comments on commit 6115734

Please sign in to comment.