Skip to content

Commit 4ec2949

Browse files
committed
New continueOnFail feature to support aborting with error
#6
1 parent 8e20597 commit 4ec2949

File tree

5 files changed

+79
-26
lines changed

5 files changed

+79
-26
lines changed

README.md

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,13 @@ $ html-validator docs/*.html flyer.html
4949

5050
### 3. CLI flags
5151
Command-line flags:
52-
| Flag | Description | Value |
53-
| ----------- | ------------------------------------------------------------ | ---------- |
54-
| `--exclude` | Comma separated list of strings to match in paths to skip. | **string** |
55-
| `--note` | Place to add a comment only for humans. | **string** |
56-
| `--quiet` | Suppress messages for successful validations. | N/A |
57-
| `--trim` | Truncate validation messages to not exceed a maximum length. | **number** |
52+
| Flag | Description | Value |
53+
| ------------ | --------------------------------------------------------------- | ---------- |
54+
| `--continue` | Report messages but do not throw an error if validation failed. | N/A |
55+
| `--exclude` | Comma separated list of strings to match in paths to skip. | **string** |
56+
| `--note` | Place to add a comment only for humans. | **string** |
57+
| `--quiet` | Suppress messages for successful validations. | N/A |
58+
| `--trim` | Truncate validation messages to not exceed a maximum length. | **number** |
5859

5960
### 4. Example CLI usage
6061
Examples:
@@ -66,8 +67,8 @@ Examples:
6667
Suppress "pass" messages.
6768
- `html-validator docs`<br>
6869
Validate HTML files in a folder.
69-
- `html-validator docs --trim=30`<br>
70-
Truncate messages to 30 characters.
70+
- `html-validator docs --trim=30 --continue`<br>
71+
Truncate messages to 30 characters and do not abort CI if validation fails.
7172

7273
## D) Application Code and Testing Frameworks
7374
In addition to the CLI interface, the **w3c-html-validator** package can also be imported and called directly in ESM and TypeScript projects.
@@ -107,11 +108,12 @@ $ node examples.js
107108
Option value `'warning'` also skips `'info'`.
108109

109110
#### w3cHtmlValidator.reporter(options)
110-
| Name (key) | Type | Default | Description |
111-
| :-------------- | :---------- | :------ | :------------------------------------------------------------- |
112-
| `maxMessageLen` | **number** | `null` | Trim validation messages to not exceed a maximum length. |
113-
| `quiet` | **boolean** | `false` | Suppress messages for successful validations. |
114-
| `title` | **string** | `null` | Override display title (useful for naming HTML string inputs). |
111+
| Name (key) | Type | Default | Description |
112+
| :--------------- | :---------- | :------ | :-------------------------------------------------------------- |
113+
| `continueOnFail` | **boolean** | `false` | Report messages but do not throw an error if validation failed. |
114+
| `maxMessageLen` | **number** | `null` | Trim validation messages to not exceed a maximum length. |
115+
| `quiet` | **boolean** | `false` | Suppress messages for successful validations. |
116+
| `title` | **string** | `null` | Override display title (useful for naming HTML string inputs). |
115117

116118
### 3. TypeScript declarations
117119
See the TypeScript declarations at the top of the

bin/cli.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
//
1818
// Contributors to this project:
1919
// $ cd w3c-html-validator
20-
// $ node bin/cli.js spec/**/*.html --quiet
20+
// $ node bin/cli.js spec/**/*.html --continue
2121

2222
// Imports
2323
import { cliArgvUtil } from 'cli-argv-util';
@@ -28,7 +28,7 @@ import glob from 'glob';
2828
import log from 'fancy-log';
2929

3030
// Parameters and flags
31-
const validFlags = ['exclude', 'note', 'quiet', 'trim'];
31+
const validFlags = ['continue', 'exclude', 'note', 'quiet', 'trim'];
3232
const cli = cliArgvUtil.parse(validFlags);
3333
const files = cli.params;
3434
const trim = parseInt(cli.flagMap.trim) || null;
@@ -51,8 +51,9 @@ if (error)
5151
if (filenames.length > 1 && !cli.flagOn.quiet)
5252
log(chalk.gray('w3c-html-validator'), chalk.magenta('files: ' + filenames.length));
5353
const reporterOptions = {
54-
quiet: cli.flagOn.quiet,
55-
maxMessageLen: trim,
54+
continueOnFail: cli.flagOn.continue,
55+
quiet: cli.flagOn.quiet,
56+
maxMessageLen: trim,
5657
};
5758
const handleReport = (report) => w3cHtmlValidator.reporter(report, reporterOptions);
5859
filenames.forEach(file => w3cHtmlValidator.validate({ filename: file }).then(handleReport));

examples.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
import { w3cHtmlValidator } from './dist/w3c-html-validator.js';
1111

1212
// Formatted output
13-
const customReporter = (results) => w3cHtmlValidator.reporter(results, { maxMessageLen: 80 });
13+
const options = { continueOnFail: true, maxMessageLen: 80 };
14+
const customReporter = (results) => w3cHtmlValidator.reporter(results, options);
1415
w3cHtmlValidator.validate({ website: 'https://pretty-print-json.js.org/' }).then(w3cHtmlValidator.reporter);
1516
w3cHtmlValidator.validate({ filename: 'spec/html/valid.html' }).then(w3cHtmlValidator.reporter);
1617
w3cHtmlValidator.validate({ filename: 'spec/html/invalid.html' }).then(customReporter);

spec/mocha.spec.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,3 +347,40 @@ describe('Network request failure', () => {
347347
});
348348

349349
});
350+
351+
////////////////////////////////////////////////////////////////////////////////
352+
describe('The reporter() function', () => {
353+
354+
it('passes through valid results', (done) => {
355+
const handleData = (data) => {
356+
const actual = data;
357+
const expected = {
358+
validates: true,
359+
mode: 'filename',
360+
title: 'spec/html/valid.html',
361+
html: validHtml,
362+
filename: 'spec/html/valid.html',
363+
website: null,
364+
output: 'json',
365+
status: 200,
366+
messages: [],
367+
display: null,
368+
};
369+
assertDeepStrictEqual(actual, expected, done);
370+
};
371+
w3cHtmlValidator.validate({ filename: 'spec/html/valid.html' })
372+
.then(w3cHtmlValidator.reporter)
373+
.then(handleData);
374+
});
375+
376+
it('throws the correct error when validation fails', () => {
377+
const options = { filename: 'spec/html/invalid.html' };
378+
const fail = () => w3cHtmlValidator.validate(options).then(w3cHtmlValidator.reporter);
379+
const expected = {
380+
name: 'Error',
381+
message: '[w3c-html-validator] Failed: spec/html/invalid.html -- warning line 9 column 4, error line 12 column 10',
382+
};
383+
return assert.rejects(fail, expected);
384+
});
385+
386+
});

w3c-html-validator.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,10 @@ export type ValidatorResults = {
5050
};
5151
export type ValidatorResultsOutput = ValidatorResults['output'];
5252
export type ReporterSettings = {
53-
maxMessageLen: number | null, //trim validation messages to not exceed a maximum length
54-
quiet: boolean, //suppress messages for successful validations
55-
title: string | null, //override display title (useful for naming HTML string inputs)
53+
continueOnFail: boolean, //report messages but do not throw an error if validation failed
54+
maxMessageLen: number | null, //trim validation messages to not exceed a maximum length
55+
quiet: boolean, //suppress messages for successful validations
56+
title: string | null, //override display title (useful for naming HTML string inputs)
5657
};
5758
export type ReporterOptions = Partial<ReporterSettings>;
5859

@@ -133,9 +134,10 @@ const w3cHtmlValidator = {
133134

134135
reporter(results: ValidatorResults, options?: ReporterOptions): ValidatorResults {
135136
const defaults = {
136-
maxMessageLen: null,
137-
quiet: false,
138-
title: null,
137+
continueOnFail: false,
138+
maxMessageLen: null,
139+
quiet: false,
140+
title: null,
139141
};
140142
const settings = { ...defaults, ...options };
141143
if (typeof results?.validates !== 'boolean')
@@ -152,8 +154,8 @@ const w3cHtmlValidator = {
152154
info: chalk.white.bold,
153155
};
154156
const logMessage = (message: ValidatorResultsMessage) => {
155-
const type = message.subType || message.type;
156-
const typeColor = typeColorMap[type] || chalk.redBright.bold;
157+
const type = message.subType ?? message.type;
158+
const typeColor = typeColorMap[type] ?? chalk.redBright.bold;
157159
const location = `line ${message.lastLine}, column ${message.firstColumn}:`;
158160
const lineText = message.extract?.replace(/\n/g, '\\n');
159161
const maxLen = settings.maxMessageLen ?? undefined;
@@ -162,6 +164,16 @@ const w3cHtmlValidator = {
162164
log(chalk.white(location), chalk.magenta(lineText));
163165
};
164166
messages.forEach(logMessage);
167+
const failDetails = () => {
168+
// Example: 'spec/html/invalid.html -- warning line 9 column 4, error line 12 column 10'
169+
const toString = (message: ValidatorResultsMessage) =>
170+
`${message.subType ?? message.type} line ${message.lastLine} column ${message.firstColumn}`;
171+
const fileDetails = () =>
172+
results.filename + ' -- ' + results.messages!.map(toString).join(', ');
173+
return !results.filename ? results.messages![0]!.message : fileDetails();
174+
};
175+
if (!settings.continueOnFail && !results.validates)
176+
throw Error('[w3c-html-validator] Failed: ' + failDetails());
165177
return results;
166178
},
167179

0 commit comments

Comments
 (0)