Skip to content

Commit da57301

Browse files
committedMar 13, 2019
use htmldiffer in file tests & update to node 4
1 parent 621f649 commit da57301

File tree

1 file changed

+104
-155
lines changed

1 file changed

+104
-155
lines changed
 

‎test/index.js

+104-155
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#!/usr/bin/env node
2+
'use strict';
3+
// 'use strict' is here so we can use let and const in node 4
24

35
/**
46
* marked tests
@@ -10,57 +12,49 @@
1012
* Modules
1113
*/
1214

13-
var fs = require('fs'),
14-
path = require('path'),
15-
fm = require('front-matter'),
16-
g2r = require('glob-to-regexp'),
17-
marked = require('../'),
18-
markedMin = require('../marked.min.js');
15+
const fs = require('fs');
16+
const path = require('path');
17+
const fm = require('front-matter');
18+
const g2r = require('glob-to-regexp');
19+
let marked = require('../');
20+
const htmlDiffer = require('./helpers/html-differ.js');
1921

2022
/**
2123
* Load Tests
2224
*/
2325

2426
function load(options) {
2527
options = options || {};
26-
var dir = path.join(__dirname, 'compiled_tests'),
27-
files = {},
28-
list,
29-
file,
30-
name,
31-
content,
32-
glob = g2r(options.glob || '*', { extended: true }),
33-
i,
34-
l;
35-
36-
list = fs
28+
const dir = path.join(__dirname, 'compiled_tests');
29+
const glob = g2r(options.glob || '*', { extended: true });
30+
31+
const list = fs
3732
.readdirSync(dir)
38-
.filter(function(file) {
33+
.filter(file => {
3934
return path.extname(file) === '.md';
4035
})
4136
.sort();
4237

43-
l = list.length;
44-
45-
for (i = 0; i < l; i++) {
46-
name = path.basename(list[i], '.md');
38+
const files = list.reduce((obj, item) => {
39+
const name = path.basename(item, '.md');
4740
if (glob.test(name)) {
48-
file = path.join(dir, list[i]);
49-
content = fm(fs.readFileSync(file, 'utf8'));
41+
const file = path.join(dir, item);
42+
const content = fm(fs.readFileSync(file, 'utf8'));
5043

51-
files[name] = {
44+
obj[name] = {
5245
options: content.attributes,
5346
text: content.body,
5447
html: fs.readFileSync(file.replace(/[^.]+$/, 'html'), 'utf8')
5548
};
5649
}
57-
}
50+
return obj;
51+
}, {});
5852

5953
if (options.bench || options.time) {
6054
if (!options.glob) {
6155
// Change certain tests to allow
6256
// comparison to older benchmark times.
63-
fs.readdirSync(path.join(__dirname, 'new')).forEach(function(name) {
57+
fs.readdirSync(path.join(__dirname, 'new')).forEach(name => {
6458
if (path.extname(name) === '.html') return;
6559
if (name === 'main.md') return;
6660
delete files[name];
@@ -93,25 +87,21 @@ function runTests(engine, options) {
9387

9488
engine = engine || marked;
9589
options = options || {};
96-
var succeeded = 0,
97-
failed = 0,
98-
files = options.files || load(options),
99-
filenames = Object.keys(files),
100-
len = filenames.length,
101-
success,
102-
i,
103-
filename,
104-
file;
90+
91+
let succeeded = 0;
92+
let failed = 0;
93+
const files = options.files || load(options);
94+
const filenames = Object.keys(files);
10595

10696
if (options.marked) {
10797
marked.setOptions(options.marked);
10898
}
10999

110-
for (i = 0; i < len; i++) {
111-
filename = filenames[i];
112-
file = files[filename];
100+
for (let i = 0; i < filenames.length; i++) {
101+
const filename = filenames[i];
102+
const file = files[filename];
113103

114-
success = testFile(engine, file, filename, i + 1);
104+
const success = testFile(engine, file, filename, i + 1);
115105

116106
if (success) {
117107
succeeded++;
@@ -123,8 +113,8 @@ function runTests(engine, options) {
123113
}
124114
}
125115

126-
console.log('%d/%d tests completed successfully.', succeeded, len);
127-
if (failed) console.log('%d/%d tests failed.', failed, len);
116+
console.log('\n%d/%d tests completed successfully.', succeeded, filenames.length);
117+
if (failed) console.log('%d/%d tests failed.', failed, filenames.length);
128118

129119
return !failed;
130120
}
@@ -134,13 +124,7 @@ function runTests(engine, options) {
134124
*/
135125

136126
function testFile(engine, file, filename, index) {
137-
var opts = Object.keys(file.options),
138-
text,
139-
html,
140-
j,
141-
l,
142-
before,
143-
elapsed;
127+
const opts = Object.keys(file.options);
144128

145129
if (marked._original) {
146130
marked.defaults = marked._original;
@@ -152,91 +136,63 @@ function testFile(engine, file, filename, index) {
152136
if (opts.length) {
153137
marked._original = marked.defaults;
154138
marked.defaults = {};
155-
Object.keys(marked._original).forEach(function(key) {
139+
Object.keys(marked._original).forEach(key => {
156140
marked.defaults[key] = marked._original[key];
157141
});
158-
opts.forEach(function(key) {
142+
opts.forEach(key => {
159143
if (marked.defaults.hasOwnProperty(key)) {
160144
marked.defaults[key] = file.options[key];
161145
}
162146
});
163147
}
164148

165-
before = process.hrtime();
149+
const before = process.hrtime();
150+
151+
let text, html, elapsed;
166152
try {
167-
text = engine(file.text).replace(/\s/g, '');
168-
html = file.html.replace(/\s/g, '');
153+
text = engine(file.text);
154+
html = file.html;
169155
} catch (e) {
170156
elapsed = process.hrtime(before);
171-
console.log(' failed in %dms', prettyElapsedTime(elapsed));
157+
console.log('\n failed in %dms\n', prettyElapsedTime(elapsed));
172158
throw e;
173159
}
174160

175161
elapsed = process.hrtime(before);
176162

177-
l = html.length;
178-
179-
if (l === 0 && text.length > 0) {
180-
text = text.substring(0, Math.min(30, text.length));
181-
182-
console.log(' failed in %dms at offset %d. Near: "%s".\n', prettyElapsedTime(elapsed), 0, text);
183-
184-
console.log('\nActual:\n%s\n', text.trim() || text);
185-
console.log('\nExpected:\n\n');
186-
187-
return false;
188-
}
189-
190-
for (j = 0; j < l; j++) {
191-
if (text[j] !== html[j]) {
192-
text = text.substring(
193-
Math.max(j - 30, 0),
194-
Math.min(j + 30, text.length));
195-
196-
html = html.substring(
197-
Math.max(j - 30, 0),
198-
Math.min(j + 30, l));
199-
200-
console.log(' failed in %dms at offset %d. Near: "%s".\n', prettyElapsedTime(elapsed), j, text);
201-
202-
console.log('\nActual:\n%s\n', text.trim() || text);
203-
console.log('\nExpected:\n%s\n', html.trim() || html);
204-
163+
if (htmlDiffer.isEqual(text, html)) {
164+
if (elapsed[0] > 0) {
165+
console.log('\n failed because it took too long.\n\n passed in %dms\n', prettyElapsedTime(elapsed));
205166
return false;
206167
}
168+
console.log(' passed in %dms', prettyElapsedTime(elapsed));
169+
return true;
207170
}
208171

209-
if (elapsed[0] > 0) {
210-
console.log(' failed because it took too long.\n\n passed in %dms', prettyElapsedTime(elapsed));
211-
return false;
212-
}
172+
const diff = htmlDiffer.firstDiff(text, html);
213173

214-
console.log(' passed in %dms', prettyElapsedTime(elapsed));
215-
return true;
174+
console.log('\n failed in %dms', prettyElapsedTime(elapsed));
175+
console.log(' Expected: %s', diff.expected);
176+
console.log(' Actual: %s\n', diff.actual);
177+
return false;
216178
}
217179

218180
/**
219181
* Benchmark a function
220182
*/
221183

222-
function bench(name, files, func) {
223-
var start = Date.now(),
224-
times = 1000,
225-
keys = Object.keys(files),
226-
i,
227-
l = keys.length,
228-
filename,
229-
file;
230-
231-
while (times--) {
232-
for (i = 0; i < l; i++) {
233-
filename = keys[i];
234-
file = files[filename];
235-
func(file.text);
184+
function bench(name, files, engine) {
185+
const start = Date.now();
186+
187+
for (let i = 0; i < 1000; i++) {
188+
for (const filename in files) {
189+
engine(files[filename].text);
236190
}
237191
}
238192

239-
console.log('%s completed in %dms.', name, Date.now() - start);
193+
const end = Date.now();
194+
195+
console.log('%s completed in %dms.', name, end - start);
240196
}
241197

242198
/**
@@ -245,7 +201,7 @@ function bench(name, files, func) {
245201

246202
function runBench(options) {
247203
options = options || {};
248-
var files = load(options);
204+
const files = load(options);
249205

250206
// Non-GFM, Non-pedantic
251207
marked.setOptions({
@@ -289,13 +245,13 @@ function runBench(options) {
289245
}
290246
bench('marked (pedantic)', files, marked);
291247

292-
// showdown
248+
// commonmark
293249
try {
294-
bench('commonmark', files, (function() {
295-
var commonmark = require('commonmark'),
296-
parser = new commonmark.Parser(),
297-
writer = new commonmark.HtmlRenderer();
298-
return function(text) {
250+
bench('commonmark', files, (() => {
251+
const commonmark = require('commonmark');
252+
const parser = new commonmark.Parser();
253+
const writer = new commonmark.HtmlRenderer();
254+
return function (text) {
299255
return writer.render(parser.parse(text));
300256
};
301257
})());
@@ -305,24 +261,20 @@ function runBench(options) {
305261

306262
// markdown-it
307263
try {
308-
bench('markdown-it', files, (function() {
309-
var MarkdownIt = require('markdown-it');
310-
var md = new MarkdownIt();
311-
return function(text) {
312-
return md.render(text);
313-
};
264+
bench('markdown-it', files, (() => {
265+
const MarkdownIt = require('markdown-it');
266+
const md = new MarkdownIt();
267+
return md.render.bind(md);
314268
})());
315269
} catch (e) {
316270
console.log('Could not bench markdown-it. (Error: %s)', e.message);
317271
}
318272

319273
// markdown.js
320274
try {
321-
bench('markdown.js', files, (function() {
322-
var markdown = require('markdown').markdown;
323-
return function(text) {
324-
return markdown.toHTML(text);
325-
};
275+
bench('markdown.js', files, (() => {
276+
const markdown = require('markdown').markdown;
277+
return markdown.toHTML.bind(markdown);
326278
})());
327279
} catch (e) {
328280
console.log('Could not bench markdown.js. (Error: %s)', e.message);
@@ -337,7 +289,7 @@ function runBench(options) {
337289

338290
function time(options) {
339291
options = options || {};
340-
var files = load(options);
292+
const files = load(options);
341293
if (options.marked) {
342294
marked.setOptions(options.marked);
343295
}
@@ -357,7 +309,7 @@ function time(options) {
357309
*/
358310

359311
function fix() {
360-
['compiled_tests', 'original', 'new', 'redos'].forEach(function(dir) {
312+
['compiled_tests', 'original', 'new', 'redos'].forEach(dir => {
361313
try {
362314
fs.mkdirSync(path.resolve(__dirname, dir));
363315
} catch (e) {
@@ -366,13 +318,13 @@ function fix() {
366318
});
367319

368320
// rm -rf tests
369-
fs.readdirSync(path.resolve(__dirname, 'compiled_tests')).forEach(function(file) {
321+
fs.readdirSync(path.resolve(__dirname, 'compiled_tests')).forEach(file => {
370322
fs.unlinkSync(path.resolve(__dirname, 'compiled_tests', file));
371323
});
372324

373325
// cp -r original tests
374-
fs.readdirSync(path.resolve(__dirname, 'original')).forEach(function(file) {
375-
var text = fs.readFileSync(path.resolve(__dirname, 'original', file), 'utf8');
326+
fs.readdirSync(path.resolve(__dirname, 'original')).forEach(file => {
327+
let text = fs.readFileSync(path.resolve(__dirname, 'original', file), 'utf8');
376328

377329
if (path.extname(file) === '.md') {
378330
if (fm.test(text)) {
@@ -387,13 +339,13 @@ function fix() {
387339
});
388340

389341
// node fix.js
390-
var dir = path.join(__dirname, 'compiled_tests');
342+
const dir = path.join(__dirname, 'compiled_tests');
391343

392-
fs.readdirSync(dir).filter(function(file) {
344+
fs.readdirSync(dir).filter(file => {
393345
return path.extname(file) === '.html';
394-
}).forEach(function(file) {
346+
}).forEach(file => {
395347
file = path.join(dir, file);
396-
var html = fs.readFileSync(file, 'utf8');
348+
let html = fs.readFileSync(file, 'utf8');
397349

398350
// fix unencoded quotes
399351
html = html
@@ -408,9 +360,9 @@ function fix() {
408360
});
409361

410362
// turn <hr /> into <hr>
411-
fs.readdirSync(dir).forEach(function(file) {
363+
fs.readdirSync(dir).forEach(file => {
412364
file = path.join(dir, file);
413-
var text = fs.readFileSync(file, 'utf8');
365+
let text = fs.readFileSync(file, 'utf8');
414366

415367
text = text.replace(/(<|&lt;)hr\s*\/(>|&gt;)/g, '$1hr$2');
416368

@@ -419,22 +371,22 @@ function fix() {
419371

420372
// markdown does some strange things.
421373
// it does not encode naked `>`, marked does.
422-
(function() {
423-
var file = dir + '/amps_and_angles_encoding.html';
424-
var html = fs.readFileSync(file, 'utf8')
374+
{
375+
const file = dir + '/amps_and_angles_encoding.html';
376+
const html = fs.readFileSync(file, 'utf8')
425377
.replace('6 > 5.', '6 &gt; 5.');
426378

427379
fs.writeFileSync(file, html);
428-
})();
380+
}
429381

430382
// cp new/* tests/
431-
fs.readdirSync(path.resolve(__dirname, 'new')).forEach(function(file) {
383+
fs.readdirSync(path.resolve(__dirname, 'new')).forEach(file => {
432384
fs.writeFileSync(path.resolve(__dirname, 'compiled_tests', file),
433385
fs.readFileSync(path.resolve(__dirname, 'new', file)));
434386
});
435387

436388
// cp redos/* tests/
437-
fs.readdirSync(path.resolve(__dirname, 'redos')).forEach(function(file) {
389+
fs.readdirSync(path.resolve(__dirname, 'redos')).forEach(file => {
438390
fs.writeFileSync(path.resolve(__dirname, 'compiled_tests', file),
439391
fs.readFileSync(path.resolve(__dirname, 'redos', file)));
440392
});
@@ -445,14 +397,13 @@ function fix() {
445397
*/
446398

447399
function parseArg(argv) {
448-
var options = {},
449-
opt = '',
450-
orphans = [],
451-
arg;
452-
453400
argv = argv.slice(2);
401+
402+
const options = {};
403+
const orphans = [];
404+
454405
function getarg() {
455-
var arg = argv.shift();
406+
let arg = argv.shift();
456407

457408
if (arg.indexOf('--') === 0) {
458409
// e.g. --opt
@@ -465,7 +416,7 @@ function parseArg(argv) {
465416
} else if (arg[0] === '-') {
466417
if (arg.length > 2) {
467418
// e.g. -abc
468-
argv = arg.substring(1).split('').map(function(ch) {
419+
argv = arg.substring(1).split('').map(ch => {
469420
return '-' + ch;
470421
}).concat(argv);
471422
arg = argv.shift();
@@ -480,7 +431,7 @@ function parseArg(argv) {
480431
}
481432

482433
while (argv.length) {
483-
arg = getarg();
434+
let arg = getarg();
484435
switch (arg) {
485436
case '-f':
486437
case '--fix':
@@ -515,7 +466,7 @@ function parseArg(argv) {
515466
break;
516467
default:
517468
if (arg.indexOf('--') === 0) {
518-
opt = camelize(arg.replace(/^--(no-)?/, ''));
469+
const opt = camelize(arg.replace(/^--(no-)?/, ''));
519470
if (!marked.defaults.hasOwnProperty(opt)) {
520471
continue;
521472
}
@@ -544,17 +495,15 @@ function parseArg(argv) {
544495
*/
545496

546497
function camelize(text) {
547-
return text.replace(/(\w)-(\w)/g, function(_, a, b) {
548-
return a + b.toUpperCase();
549-
});
498+
return text.replace(/(\w)-(\w)/g, (_, a, b) => a + b.toUpperCase());
550499
}
551500

552501
/**
553502
* Main
554503
*/
555504

556505
function main(argv) {
557-
var opt = parseArg(argv);
506+
const opt = parseArg(argv);
558507

559508
if (opt.fix !== false) {
560509
fix();
@@ -574,7 +523,7 @@ function main(argv) {
574523
}
575524

576525
if (opt.minified) {
577-
marked = markedMin;
526+
marked = require('../marked.min.js');
578527
}
579528
return runTests(opt);
580529
}
@@ -599,7 +548,7 @@ if (!module.parent) {
599548

600549
// returns time to millisecond granularity
601550
function prettyElapsedTime(hrtimeElapsed) {
602-
var seconds = hrtimeElapsed[0];
603-
var frac = Math.round(hrtimeElapsed[1] / 1e3) / 1e3;
551+
const seconds = hrtimeElapsed[0];
552+
const frac = Math.round(hrtimeElapsed[1] / 1e3) / 1e3;
604553
return seconds * 1e3 + frac;
605554
}

0 commit comments

Comments
 (0)
Please sign in to comment.