Skip to content

Commit 6eec528

Browse files
authoredMar 15, 2019
Merge pull request #1449 from UziTech/use-htmldiffer
Update tests to node 4 syntax
2 parents d069d0d + 0cd0333 commit 6eec528

File tree

5 files changed

+151
-185
lines changed

5 files changed

+151
-185
lines changed
 

‎jasmine.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"**/*-spec.js"
55
],
66
"helpers": [
7-
"helpers/**/*.js"
7+
"helpers/helpers.js"
88
],
99
"stopSpecOnExpectationFailure": false,
1010
"random": true

‎test/helpers/helpers.js

+4-22
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
const marked = require('../../');
2-
const HtmlDiffer = require('@markedjs/html-differ').HtmlDiffer;
3-
const htmlDiffer = new HtmlDiffer({ignoreSelfClosingSlash: true});
4-
5-
const EXCERPT_LENGTH = 30;
2+
const htmlDiffer = require('./html-differ.js');
63

74
beforeEach(() => {
85
marked.setOptions(marked.getDefaults());
@@ -16,25 +13,10 @@ beforeEach(() => {
1613
result.pass = htmlDiffer.isEqual(expected, actual);
1714

1815
if (result.pass) {
19-
result.message = spec.markdown + '\n------\n\nExpected: Should Fail';
16+
result.message = `${spec.markdown}\n------\n\nExpected: Should Fail`;
2017
} else {
21-
var expectedHtml = expected.replace(/\s/g, '');
22-
var actualHtml = actual.replace(/\s/g, '');
23-
24-
for (var i = 0; i < expectedHtml.length; i++) {
25-
if (actualHtml[i] !== expectedHtml[i]) {
26-
actualHtml = actualHtml.substring(
27-
Math.max(i - EXCERPT_LENGTH, 0),
28-
Math.min(i + EXCERPT_LENGTH, actualHtml.length));
29-
30-
expectedHtml = expectedHtml.substring(
31-
Math.max(i - EXCERPT_LENGTH, 0),
32-
Math.min(i + EXCERPT_LENGTH, expectedHtml.length));
33-
34-
break;
35-
}
36-
}
37-
result.message = 'Expected:\n' + expectedHtml + '\n\nActual:\n' + actualHtml;
18+
const diff = htmlDiffer.firstDiff(actual, expected);
19+
result.message = `Expected: ${diff.expected}\n Actual: ${diff.actual}`;
3820
}
3921
return result;
4022
}

‎test/helpers/html-differ.js

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
const HtmlDiffer = require('@markedjs/html-differ').HtmlDiffer;
2+
const htmlDiffer = new HtmlDiffer({ignoreSelfClosingSlash: true});
3+
4+
module.exports = {
5+
isEqual: htmlDiffer.isEqual.bind(htmlDiffer),
6+
firstDiff: (actual, expected, padding) => {
7+
padding = padding || 30;
8+
const result = htmlDiffer
9+
.diffHtml(actual, expected)
10+
.reduce((obj, diff) => {
11+
if (diff.added) {
12+
if (obj.firstIndex === null) {
13+
obj.firstIndex = obj.expected.length;
14+
}
15+
obj.expected += diff.value;
16+
} else if (diff.removed) {
17+
if (obj.firstIndex === null) {
18+
obj.firstIndex = obj.actual.length;
19+
}
20+
obj.actual += diff.value;
21+
} else {
22+
obj.actual += diff.value;
23+
obj.expected += diff.value;
24+
}
25+
26+
return obj;
27+
}, {
28+
firstIndex: null,
29+
actual: '',
30+
expected: ''
31+
});
32+
33+
return {
34+
actual: result.actual.substring(result.firstIndex - padding, result.firstIndex + padding),
35+
expected: result.expected.substring(result.firstIndex - padding, result.firstIndex + padding)
36+
};
37+
}
38+
};

‎test/index.js

+106-160
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,40 +245,33 @@ function runBench(options) {
289245
}
290246
bench('marked (pedantic)', files, marked);
291247

292-
// showdown
293248
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) {
249+
bench('commonmark', files, (() => {
250+
const commonmark = require('commonmark');
251+
const parser = new commonmark.Parser();
252+
const writer = new commonmark.HtmlRenderer();
253+
return function (text) {
299254
return writer.render(parser.parse(text));
300255
};
301256
})());
302257
} catch (e) {
303258
console.log('Could not bench commonmark. (Error: %s)', e.message);
304259
}
305260

306-
// markdown-it
307261
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-
};
262+
bench('markdown-it', files, (() => {
263+
const MarkdownIt = require('markdown-it');
264+
const md = new MarkdownIt();
265+
return md.render.bind(md);
314266
})());
315267
} catch (e) {
316268
console.log('Could not bench markdown-it. (Error: %s)', e.message);
317269
}
318270

319-
// markdown.js
320271
try {
321-
bench('markdown.js', files, (function() {
322-
var markdown = require('markdown').markdown;
323-
return function(text) {
324-
return markdown.toHTML(text);
325-
};
272+
bench('markdown.js', files, (() => {
273+
const markdown = require('markdown').markdown;
274+
return markdown.toHTML.bind(markdown);
326275
})());
327276
} catch (e) {
328277
console.log('Could not bench markdown.js. (Error: %s)', e.message);
@@ -337,7 +286,7 @@ function runBench(options) {
337286

338287
function time(options) {
339288
options = options || {};
340-
var files = load(options);
289+
const files = load(options);
341290
if (options.marked) {
342291
marked.setOptions(options.marked);
343292
}
@@ -357,7 +306,7 @@ function time(options) {
357306
*/
358307

359308
function fix() {
360-
['compiled_tests', 'original', 'new', 'redos'].forEach(function(dir) {
309+
['compiled_tests', 'original', 'new', 'redos'].forEach(dir => {
361310
try {
362311
fs.mkdirSync(path.resolve(__dirname, dir));
363312
} catch (e) {
@@ -366,34 +315,34 @@ function fix() {
366315
});
367316

368317
// rm -rf tests
369-
fs.readdirSync(path.resolve(__dirname, 'compiled_tests')).forEach(function(file) {
318+
fs.readdirSync(path.resolve(__dirname, 'compiled_tests')).forEach(file => {
370319
fs.unlinkSync(path.resolve(__dirname, 'compiled_tests', file));
371320
});
372321

373322
// 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');
323+
fs.readdirSync(path.resolve(__dirname, 'original')).forEach(file => {
324+
let text = fs.readFileSync(path.resolve(__dirname, 'original', file), 'utf8');
376325

377326
if (path.extname(file) === '.md') {
378327
if (fm.test(text)) {
379328
text = fm(text);
380-
text = '---\n' + text.frontmatter + '\ngfm: false\n---\n' + text.body;
329+
text = `---\n${text.frontmatter}\ngfm: false\n---\n${text.body}`;
381330
} else {
382-
text = '---\ngfm: false\n---\n' + text;
331+
text = `---\ngfm: false\n---\n${text}`;
383332
}
384333
}
385334

386335
fs.writeFileSync(path.resolve(__dirname, 'compiled_tests', file), text);
387336
});
388337

389338
// node fix.js
390-
var dir = path.join(__dirname, 'compiled_tests');
339+
const dir = path.join(__dirname, 'compiled_tests');
391340

392-
fs.readdirSync(dir).filter(function(file) {
341+
fs.readdirSync(dir).filter(file => {
393342
return path.extname(file) === '.html';
394-
}).forEach(function(file) {
343+
}).forEach(file => {
395344
file = path.join(dir, file);
396-
var html = fs.readFileSync(file, 'utf8');
345+
let html = fs.readFileSync(file, 'utf8');
397346

398347
// fix unencoded quotes
399348
html = html
@@ -408,9 +357,9 @@ function fix() {
408357
});
409358

410359
// turn <hr /> into <hr>
411-
fs.readdirSync(dir).forEach(function(file) {
360+
fs.readdirSync(dir).forEach(file => {
412361
file = path.join(dir, file);
413-
var text = fs.readFileSync(file, 'utf8');
362+
let text = fs.readFileSync(file, 'utf8');
414363

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

@@ -419,22 +368,22 @@ function fix() {
419368

420369
// markdown does some strange things.
421370
// 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')
371+
{
372+
const file = `${dir}/amps_and_angles_encoding.html`;
373+
const html = fs.readFileSync(file, 'utf8')
425374
.replace('6 > 5.', '6 &gt; 5.');
426375

427376
fs.writeFileSync(file, html);
428-
})();
377+
}
429378

430379
// cp new/* tests/
431-
fs.readdirSync(path.resolve(__dirname, 'new')).forEach(function(file) {
380+
fs.readdirSync(path.resolve(__dirname, 'new')).forEach(file => {
432381
fs.writeFileSync(path.resolve(__dirname, 'compiled_tests', file),
433382
fs.readFileSync(path.resolve(__dirname, 'new', file)));
434383
});
435384

436385
// cp redos/* tests/
437-
fs.readdirSync(path.resolve(__dirname, 'redos')).forEach(function(file) {
386+
fs.readdirSync(path.resolve(__dirname, 'redos')).forEach(file => {
438387
fs.writeFileSync(path.resolve(__dirname, 'compiled_tests', file),
439388
fs.readFileSync(path.resolve(__dirname, 'redos', file)));
440389
});
@@ -445,14 +394,13 @@ function fix() {
445394
*/
446395

447396
function parseArg(argv) {
448-
var options = {},
449-
opt = '',
450-
orphans = [],
451-
arg;
452-
453397
argv = argv.slice(2);
398+
399+
const options = {};
400+
const orphans = [];
401+
454402
function getarg() {
455-
var arg = argv.shift();
403+
let arg = argv.shift();
456404

457405
if (arg.indexOf('--') === 0) {
458406
// e.g. --opt
@@ -465,8 +413,8 @@ function parseArg(argv) {
465413
} else if (arg[0] === '-') {
466414
if (arg.length > 2) {
467415
// e.g. -abc
468-
argv = arg.substring(1).split('').map(function(ch) {
469-
return '-' + ch;
416+
argv = arg.substring(1).split('').map(ch => {
417+
return `-${ch}`;
470418
}).concat(argv);
471419
arg = argv.shift();
472420
} else {
@@ -480,7 +428,7 @@ function parseArg(argv) {
480428
}
481429

482430
while (argv.length) {
483-
arg = getarg();
431+
let arg = getarg();
484432
switch (arg) {
485433
case '-f':
486434
case '--fix':
@@ -515,7 +463,7 @@ function parseArg(argv) {
515463
break;
516464
default:
517465
if (arg.indexOf('--') === 0) {
518-
opt = camelize(arg.replace(/^--(no-)?/, ''));
466+
const opt = camelize(arg.replace(/^--(no-)?/, ''));
519467
if (!marked.defaults.hasOwnProperty(opt)) {
520468
continue;
521469
}
@@ -544,17 +492,15 @@ function parseArg(argv) {
544492
*/
545493

546494
function camelize(text) {
547-
return text.replace(/(\w)-(\w)/g, function(_, a, b) {
548-
return a + b.toUpperCase();
549-
});
495+
return text.replace(/(\w)-(\w)/g, (_, a, b) => a + b.toUpperCase());
550496
}
551497

552498
/**
553499
* Main
554500
*/
555501

556502
function main(argv) {
557-
var opt = parseArg(argv);
503+
const opt = parseArg(argv);
558504

559505
if (opt.fix !== false) {
560506
fix();
@@ -574,7 +520,7 @@ function main(argv) {
574520
}
575521

576522
if (opt.minified) {
577-
marked = markedMin;
523+
marked = require('../marked.min.js');
578524
}
579525
return runTests(opt);
580526
}
@@ -599,7 +545,7 @@ if (!module.parent) {
599545

600546
// returns time to millisecond granularity
601547
function prettyElapsedTime(hrtimeElapsed) {
602-
var seconds = hrtimeElapsed[0];
603-
var frac = Math.round(hrtimeElapsed[1] / 1e3) / 1e3;
548+
const seconds = hrtimeElapsed[0];
549+
const frac = Math.round(hrtimeElapsed[1] / 1e3) / 1e3;
604550
return seconds * 1e3 + frac;
605551
}

‎test/new/uppercase_hex.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
<p>lowerclickmelower
2-
upperclickmeupper</p>
1+
<p>lowerclick melower
2+
upperclick meupper</p>

0 commit comments

Comments
 (0)
Please sign in to comment.