Skip to content

Commit 74c7e57

Browse files
committed
Improve organization of, and add comments to, CLI and functional tests.
1 parent 4d13bd5 commit 74c7e57

File tree

6 files changed

+95
-90
lines changed

6 files changed

+95
-90
lines changed

.appveyor.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ before_test:
2828
test_script:
2929
- npm run lint
3030
- npx mocha --reporter mocha-junit-reporter --reporter-options mochaFile=./tr-unit.xml index.spec.js
31-
- npx mocha --reporter mocha-junit-reporter --reporter-options mochaFile=./tr-func.xml test/functional/*
31+
- npx mocha --reporter mocha-junit-reporter --reporter-options mochaFile=./tr-func.xml test/functional/*.spec.js
3232

3333
after_test:
3434
- ps: |

bin/cli.js

+33-32
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
const path = require('path')
44
const fs = require('fs').promises
55
const log = console.log
6-
const validate = require('../index.js')
6+
const validateFn = require('../index.js')
77

88
/**
9-
* [validateStdIn description]
9+
* Returns the data piped into this process on stdin.
10+
*
1011
* @return {Promise}
1112
*/
12-
function validateStdIn () {
13+
function captureInputFromStdIn () {
1314
log('Validating XML from stdin...')
1415

1516
return new Promise((resolve, reject) => {
@@ -29,53 +30,52 @@ function validateStdIn () {
2930
})
3031

3132
process.stdin.on('end', () => {
32-
validate(input.join(''))
33-
.then(resolve)
33+
resolve(input.join(''))
3434
})
3535
})
3636
}
3737

3838
/**
39-
* [validateFile description]
40-
* @param {[type]} resolvedPath [description]
39+
* Returns the contents of the specified file.
40+
*
41+
* @param {String} p The path to the file.
42+
*
4143
* @return {Promise}
4244
*/
43-
function validateFile (resolvedPath) {
44-
log('Validating XML from path "%s"...', resolvedPath)
45+
function captureInputFromFile (p) {
46+
const resolvedPath = path.resolve(p)
4547

48+
log('Validating the file at "%s"...', resolvedPath)
4649
return fs.readFile(resolvedPath)
47-
.then((contents) => {
48-
return validate(contents)
49-
})
5050
}
5151

5252
/**
53-
* [displayResult description]
54-
* @param {[type]} result [description]
53+
* Outputs the results of the XML validation to the log.
54+
*
5555
* @return {undefined}
5656
*/
57-
function logStatusOfValidation (status) {
57+
function logResultOfXmlValidation (dtd, warnings, errors) {
5858
log('')
5959

60-
if (status.errors.length === 0) {
61-
log('Congratulations, the provided XML is well-formed and valid, according to the DTD at "%s"', status.dtd)
60+
if (errors.length === 0) {
61+
log('Congratulations, the provided XML is well-formed and valid, according to the DTD at "%s"', dtd)
6262

63-
if (status.warnings.length > 0) {
63+
if (warnings.length > 0) {
6464
log('')
6565
log('However, please note the following warnings:')
66-
status.warnings.forEach((msg) => { log(' -', msg) })
66+
warnings.forEach((msg) => { log(' -', msg) })
6767
}
6868
} else {
69-
log('Unfortunately, the provided XML does not validate according to the DTD at "%s"', status.dtd)
69+
log('Unfortunately, the provided XML does not validate according to the DTD at "%s"', dtd)
7070
log('')
7171
log('The following errors were reported:')
7272

73-
status.errors.forEach((msg) => { log(' ✘', msg) })
73+
errors.forEach((msg) => { log(' ✘', msg) })
7474

75-
if (status.warnings.length > 0) {
75+
if (warnings.length > 0) {
7676
log('')
7777
log('Also, please note the following warnings:')
78-
status.warnings.forEach((msg) => { log(' -', msg) })
78+
warnings.forEach((msg) => { log(' -', msg) })
7979
}
8080
}
8181
}
@@ -85,22 +85,23 @@ function logStatusOfValidation (status) {
8585
* @return {undefined}
8686
*/
8787
async function main () {
88-
let validationResult = null
88+
let xml = ''
8989
const args = process.argv.slice(2)
9090

9191
try {
9292
if (args.length === 0) {
93-
validationResult = await validateStdIn()
93+
xml = await captureInputFromStdIn()
9494
} else {
95-
const resolvedPath = path.resolve(args[0])
96-
validationResult = await validateFile(resolvedPath)
95+
xml = await captureInputFromFile(args[0])
9796
}
9897

99-
logStatusOfValidation({
100-
dtd: validationResult.doctype,
101-
errors: validationResult.errors,
102-
warnings: validationResult.warnings
103-
})
98+
const validationResult = await validateFn(xml)
99+
100+
logResultOfXmlValidation(
101+
validationResult.doctype,
102+
validationResult.warnings,
103+
validationResult.errors
104+
)
104105

105106
if (validationResult.errors.length > 0) {
106107
process.exit(1)

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
},
99
"scripts": {
1010
"test:unit": "mocha index.spec.js",
11-
"test:func": "mocha test/functional/*",
11+
"test:func": "mocha test/functional/*.spec.js",
1212
"test": "npm run lint && npm run check-coverage && npm run test:func",
1313
"lint": "standard",
1414
"check-coverage": "nyc npm run test:unit",

test/functional/cli-runner.js

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
const childProcess = require('child_process')
2+
3+
/**
4+
* Spawns a child process to run the given CLI command. The return code, and
5+
* outputs of `stdout` and `stderr`, are captured for later analysis.
6+
*
7+
* @param {String} cmd The command to run, which will be executed in a
8+
* shell context.
9+
*
10+
* @return {Promise} Resolving to an object with properties `code`,
11+
* `stdin` and `stderr`.
12+
*/
13+
function exported (cmd) {
14+
return new Promise((resolve, reject) => {
15+
const output = {
16+
stdout: [],
17+
stderr: []
18+
}
19+
20+
const proc = childProcess.spawn(cmd, { cwd: process.cwd(), shell: true })
21+
22+
proc.stdout.on('data', (data) => {
23+
const stringValue = data.toString()
24+
console.log(stringValue) // this is to indicate actual progress as the tests are running
25+
output.stdout.push(stringValue)
26+
})
27+
28+
proc.stderr.on('data', (data) => {
29+
const stringValue = data.toString()
30+
console.error(stringValue) // (same)
31+
output.stderr.push(stringValue)
32+
})
33+
34+
proc.on('error', (err) => {
35+
reject(err)
36+
})
37+
38+
proc.on('exit', (code, signal) => {
39+
output.code = code
40+
resolve(output)
41+
})
42+
})
43+
}
44+
45+
module.exports = exported

test/functional/submission-to-w3c.js test/functional/submission-to-w3c.spec.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ const path = require('path')
77
* Code under test.
88
* @type {any}
99
*/
10-
const T = require(path.join(__dirname, '../../index.js'))
10+
const T = require(path.resolve('./index.js'))
1111

12-
const VALID_XML = fs.readFileSync(path.join(__dirname, '../samples/valid.xml'))
13-
const INVALID_XML = fs.readFileSync(path.join(__dirname, '../samples/invalid.xml'))
12+
const VALID_XML = fs.readFileSync(path.resolve('./test/samples/valid.xml'))
13+
const INVALID_XML = fs.readFileSync(path.resolve('./test/samples/invalid.xml'))
1414

1515
describe('an actual submission to W3C', function () {
1616
context('with a valid document', function () {

test/functional/test-cli.js test/functional/test-cli.spec.js

+12-53
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,24 @@
11
/* eslint-env mocha */
22

3-
const childProcess = require('child_process')
43
const path = require('path')
4+
const cliRunner = require('./cli-runner.js')
55

66
/**
7-
* [isWindowsPlatform description]
7+
* A flag indicating whether the current OS is based on MS Windows.
88
* @type {Boolean}
99
*/
10-
const isWindowsPlatform = (require('os').platform() === 'win32')
10+
const isWindowsOS = require('os').platform().startsWith('win')
1111

1212
/**
13-
* [command description]
13+
* The appropriate way to call the CLI, depending on the detected OS type.
1414
* @type {String}
1515
*/
16-
const callee = (
17-
isWindowsPlatform
16+
const cli = (
17+
isWindowsOS
1818
? 'node .\\bin\\cli.js'
1919
: './bin/cli.js'
2020
)
2121

22-
/**
23-
* Spawns a child process to run the CLI command given. The return code, and
24-
* output of `stdout` and `stderr` are captured for later analysis by the tests.
25-
*
26-
* @param {String} cmd The command to run, which will be executed in a
27-
* shell context.
28-
*
29-
* @return {Promise}
30-
*/
31-
function runChildProcess (cmd) {
32-
return new Promise((resolve, reject) => {
33-
const output = {
34-
stdout: [],
35-
stderr: []
36-
}
37-
38-
const proc = childProcess.spawn(
39-
cmd,
40-
{
41-
cwd: process.cwd(),
42-
shell: true
43-
}
44-
)
45-
46-
proc.stdout.on('data', (data) => {
47-
console.log(data.toString()) // this is to indicate actual progress as the tests are running
48-
output.stdout.push(data)
49-
})
50-
51-
proc.stderr.on('data', (data) => {
52-
console.error(data.toString()) // (same)
53-
output.stderr.push(data)
54-
})
55-
56-
proc.on('exit', (code, signal) => {
57-
output.code = code
58-
resolve(output)
59-
})
60-
})
61-
}
62-
6322
const pathToValidSampleXmlFile = path.resolve('./test/samples/valid.xml')
6423
const pathToInvalidSampleXmlFile = path.resolve('./test/samples/invalid.xml')
6524

@@ -71,12 +30,12 @@ describe('the command-line interface', function () {
7130
this.timeout(8000) // sometimes the request to W3C takes a bit longer than the default timeout of 2 sec
7231

7332
const cmd = (
74-
isWindowsPlatform
75-
? `type ${pathToValidSampleXmlFile} | ${callee}`
76-
: `cat ${pathToValidSampleXmlFile} | ${callee}`
33+
isWindowsOS
34+
? `type ${pathToValidSampleXmlFile} | ${cli}`
35+
: `cat ${pathToValidSampleXmlFile} | ${cli}`
7736
)
7837

79-
return runChildProcess(cmd)
38+
return cliRunner(cmd)
8039
.then(function (output) {
8140
result = output
8241
})
@@ -109,7 +68,7 @@ However, please note the following warnings:
10968
before(function () {
11069
this.timeout(8000)
11170

112-
return runChildProcess(`${callee} ${pathToInvalidSampleXmlFile}`)
71+
return cliRunner(`${cli} ${pathToInvalidSampleXmlFile}`)
11372
.then(function (output) {
11473
result = output
11574
})
@@ -123,7 +82,7 @@ However, please note the following warnings:
12382
})
12483

12584
it('must output the expected text', function () {
126-
const expected = `Validating XML from path "${pathToInvalidSampleXmlFile}"...
85+
const expected = `Validating the file at "${pathToInvalidSampleXmlFile}"...
12786
12887
Unfortunately, the provided XML does not validate according to the DTD at "http://xml.cxml.org/schemas/cXML/1.2.014/cXML.dtd"
12988

0 commit comments

Comments
 (0)