1
1
#!/usr/bin/env node
2
+ 'use strict' ;
3
+ // 'use strict' is here so we can use let and const in node 4
2
4
3
5
/**
4
6
* marked tests
10
12
* Modules
11
13
*/
12
14
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' ) ;
19
21
20
22
/**
21
23
* Load Tests
22
24
*/
23
25
24
26
function load ( options ) {
25
27
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
37
32
. readdirSync ( dir )
38
- . filter ( function ( file ) {
33
+ . filter ( file => {
39
34
return path . extname ( file ) === '.md' ;
40
35
} )
41
36
. sort ( ) ;
42
37
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' ) ;
47
40
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' ) ) ;
50
43
51
- files [ name ] = {
44
+ obj [ name ] = {
52
45
options : content . attributes ,
53
46
text : content . body ,
54
47
html : fs . readFileSync ( file . replace ( / [ ^ . ] + $ / , 'html' ) , 'utf8' )
55
48
} ;
56
49
}
57
- }
50
+ return obj ;
51
+ } , { } ) ;
58
52
59
53
if ( options . bench || options . time ) {
60
54
if ( ! options . glob ) {
61
55
// Change certain tests to allow
62
56
// comparison to older benchmark times.
63
- fs . readdirSync ( path . join ( __dirname , 'new' ) ) . forEach ( function ( name ) {
57
+ fs . readdirSync ( path . join ( __dirname , 'new' ) ) . forEach ( name => {
64
58
if ( path . extname ( name ) === '.html' ) return ;
65
59
if ( name === 'main.md' ) return ;
66
60
delete files [ name ] ;
@@ -93,25 +87,21 @@ function runTests(engine, options) {
93
87
94
88
engine = engine || marked ;
95
89
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 ) ;
105
95
106
96
if ( options . marked ) {
107
97
marked . setOptions ( options . marked ) ;
108
98
}
109
99
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 ] ;
113
103
114
- success = testFile ( engine , file , filename , i + 1 ) ;
104
+ const success = testFile ( engine , file , filename , i + 1 ) ;
115
105
116
106
if ( success ) {
117
107
succeeded ++ ;
@@ -123,8 +113,8 @@ function runTests(engine, options) {
123
113
}
124
114
}
125
115
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 ) ;
128
118
129
119
return ! failed ;
130
120
}
@@ -134,13 +124,7 @@ function runTests(engine, options) {
134
124
*/
135
125
136
126
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 ) ;
144
128
145
129
if ( marked . _original ) {
146
130
marked . defaults = marked . _original ;
@@ -152,91 +136,63 @@ function testFile(engine, file, filename, index) {
152
136
if ( opts . length ) {
153
137
marked . _original = marked . defaults ;
154
138
marked . defaults = { } ;
155
- Object . keys ( marked . _original ) . forEach ( function ( key ) {
139
+ Object . keys ( marked . _original ) . forEach ( key => {
156
140
marked . defaults [ key ] = marked . _original [ key ] ;
157
141
} ) ;
158
- opts . forEach ( function ( key ) {
142
+ opts . forEach ( key => {
159
143
if ( marked . defaults . hasOwnProperty ( key ) ) {
160
144
marked . defaults [ key ] = file . options [ key ] ;
161
145
}
162
146
} ) ;
163
147
}
164
148
165
- before = process . hrtime ( ) ;
149
+ const before = process . hrtime ( ) ;
150
+
151
+ let text , html , elapsed ;
166
152
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 ;
169
155
} catch ( e ) {
170
156
elapsed = process . hrtime ( before ) ;
171
- console . log ( ' failed in %dms' , prettyElapsedTime ( elapsed ) ) ;
157
+ console . log ( '\n failed in %dms\n ' , prettyElapsedTime ( elapsed ) ) ;
172
158
throw e ;
173
159
}
174
160
175
161
elapsed = process . hrtime ( before ) ;
176
162
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 ) ) ;
205
166
return false ;
206
167
}
168
+ console . log ( ' passed in %dms' , prettyElapsedTime ( elapsed ) ) ;
169
+ return true ;
207
170
}
208
171
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 ) ;
213
173
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 ;
216
178
}
217
179
218
180
/**
219
181
* Benchmark a function
220
182
*/
221
183
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 ) ;
236
190
}
237
191
}
238
192
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 ) ;
240
196
}
241
197
242
198
/**
@@ -245,7 +201,7 @@ function bench(name, files, func) {
245
201
246
202
function runBench ( options ) {
247
203
options = options || { } ;
248
- var files = load ( options ) ;
204
+ const files = load ( options ) ;
249
205
250
206
// Non-GFM, Non-pedantic
251
207
marked . setOptions ( {
@@ -289,13 +245,13 @@ function runBench(options) {
289
245
}
290
246
bench ( 'marked (pedantic)' , files , marked ) ;
291
247
292
- // showdown
248
+ // commonmark
293
249
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 ) {
299
255
return writer . render ( parser . parse ( text ) ) ;
300
256
} ;
301
257
} ) ( ) ) ;
@@ -305,24 +261,20 @@ function runBench(options) {
305
261
306
262
// markdown-it
307
263
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 ) ;
314
268
} ) ( ) ) ;
315
269
} catch ( e ) {
316
270
console . log ( 'Could not bench markdown-it. (Error: %s)' , e . message ) ;
317
271
}
318
272
319
273
// markdown.js
320
274
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 ) ;
326
278
} ) ( ) ) ;
327
279
} catch ( e ) {
328
280
console . log ( 'Could not bench markdown.js. (Error: %s)' , e . message ) ;
@@ -337,7 +289,7 @@ function runBench(options) {
337
289
338
290
function time ( options ) {
339
291
options = options || { } ;
340
- var files = load ( options ) ;
292
+ const files = load ( options ) ;
341
293
if ( options . marked ) {
342
294
marked . setOptions ( options . marked ) ;
343
295
}
@@ -357,7 +309,7 @@ function time(options) {
357
309
*/
358
310
359
311
function fix ( ) {
360
- [ 'compiled_tests' , 'original' , 'new' , 'redos' ] . forEach ( function ( dir ) {
312
+ [ 'compiled_tests' , 'original' , 'new' , 'redos' ] . forEach ( dir => {
361
313
try {
362
314
fs . mkdirSync ( path . resolve ( __dirname , dir ) ) ;
363
315
} catch ( e ) {
@@ -366,13 +318,13 @@ function fix() {
366
318
} ) ;
367
319
368
320
// rm -rf tests
369
- fs . readdirSync ( path . resolve ( __dirname , 'compiled_tests' ) ) . forEach ( function ( file ) {
321
+ fs . readdirSync ( path . resolve ( __dirname , 'compiled_tests' ) ) . forEach ( file => {
370
322
fs . unlinkSync ( path . resolve ( __dirname , 'compiled_tests' , file ) ) ;
371
323
} ) ;
372
324
373
325
// 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' ) ;
376
328
377
329
if ( path . extname ( file ) === '.md' ) {
378
330
if ( fm . test ( text ) ) {
@@ -387,13 +339,13 @@ function fix() {
387
339
} ) ;
388
340
389
341
// node fix.js
390
- var dir = path . join ( __dirname , 'compiled_tests' ) ;
342
+ const dir = path . join ( __dirname , 'compiled_tests' ) ;
391
343
392
- fs . readdirSync ( dir ) . filter ( function ( file ) {
344
+ fs . readdirSync ( dir ) . filter ( file => {
393
345
return path . extname ( file ) === '.html' ;
394
- } ) . forEach ( function ( file ) {
346
+ } ) . forEach ( file => {
395
347
file = path . join ( dir , file ) ;
396
- var html = fs . readFileSync ( file , 'utf8' ) ;
348
+ let html = fs . readFileSync ( file , 'utf8' ) ;
397
349
398
350
// fix unencoded quotes
399
351
html = html
@@ -408,9 +360,9 @@ function fix() {
408
360
} ) ;
409
361
410
362
// turn <hr /> into <hr>
411
- fs . readdirSync ( dir ) . forEach ( function ( file ) {
363
+ fs . readdirSync ( dir ) . forEach ( file => {
412
364
file = path . join ( dir , file ) ;
413
- var text = fs . readFileSync ( file , 'utf8' ) ;
365
+ let text = fs . readFileSync ( file , 'utf8' ) ;
414
366
415
367
text = text . replace ( / ( < | & l t ; ) h r \s * \/ ( > | & g t ; ) / g, '$1hr$2' ) ;
416
368
@@ -419,22 +371,22 @@ function fix() {
419
371
420
372
// markdown does some strange things.
421
373
// 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' )
425
377
. replace ( '6 > 5.' , '6 > 5.' ) ;
426
378
427
379
fs . writeFileSync ( file , html ) ;
428
- } ) ( ) ;
380
+ }
429
381
430
382
// cp new/* tests/
431
- fs . readdirSync ( path . resolve ( __dirname , 'new' ) ) . forEach ( function ( file ) {
383
+ fs . readdirSync ( path . resolve ( __dirname , 'new' ) ) . forEach ( file => {
432
384
fs . writeFileSync ( path . resolve ( __dirname , 'compiled_tests' , file ) ,
433
385
fs . readFileSync ( path . resolve ( __dirname , 'new' , file ) ) ) ;
434
386
} ) ;
435
387
436
388
// cp redos/* tests/
437
- fs . readdirSync ( path . resolve ( __dirname , 'redos' ) ) . forEach ( function ( file ) {
389
+ fs . readdirSync ( path . resolve ( __dirname , 'redos' ) ) . forEach ( file => {
438
390
fs . writeFileSync ( path . resolve ( __dirname , 'compiled_tests' , file ) ,
439
391
fs . readFileSync ( path . resolve ( __dirname , 'redos' , file ) ) ) ;
440
392
} ) ;
@@ -445,14 +397,13 @@ function fix() {
445
397
*/
446
398
447
399
function parseArg ( argv ) {
448
- var options = { } ,
449
- opt = '' ,
450
- orphans = [ ] ,
451
- arg ;
452
-
453
400
argv = argv . slice ( 2 ) ;
401
+
402
+ const options = { } ;
403
+ const orphans = [ ] ;
404
+
454
405
function getarg ( ) {
455
- var arg = argv . shift ( ) ;
406
+ let arg = argv . shift ( ) ;
456
407
457
408
if ( arg . indexOf ( '--' ) === 0 ) {
458
409
// e.g. --opt
@@ -465,7 +416,7 @@ function parseArg(argv) {
465
416
} else if ( arg [ 0 ] === '-' ) {
466
417
if ( arg . length > 2 ) {
467
418
// e.g. -abc
468
- argv = arg . substring ( 1 ) . split ( '' ) . map ( function ( ch ) {
419
+ argv = arg . substring ( 1 ) . split ( '' ) . map ( ch => {
469
420
return '-' + ch ;
470
421
} ) . concat ( argv ) ;
471
422
arg = argv . shift ( ) ;
@@ -480,7 +431,7 @@ function parseArg(argv) {
480
431
}
481
432
482
433
while ( argv . length ) {
483
- arg = getarg ( ) ;
434
+ let arg = getarg ( ) ;
484
435
switch ( arg ) {
485
436
case '-f' :
486
437
case '--fix' :
@@ -515,7 +466,7 @@ function parseArg(argv) {
515
466
break ;
516
467
default :
517
468
if ( arg . indexOf ( '--' ) === 0 ) {
518
- opt = camelize ( arg . replace ( / ^ - - ( n o - ) ? / , '' ) ) ;
469
+ const opt = camelize ( arg . replace ( / ^ - - ( n o - ) ? / , '' ) ) ;
519
470
if ( ! marked . defaults . hasOwnProperty ( opt ) ) {
520
471
continue ;
521
472
}
@@ -544,17 +495,15 @@ function parseArg(argv) {
544
495
*/
545
496
546
497
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 ( ) ) ;
550
499
}
551
500
552
501
/**
553
502
* Main
554
503
*/
555
504
556
505
function main ( argv ) {
557
- var opt = parseArg ( argv ) ;
506
+ const opt = parseArg ( argv ) ;
558
507
559
508
if ( opt . fix !== false ) {
560
509
fix ( ) ;
@@ -574,7 +523,7 @@ function main(argv) {
574
523
}
575
524
576
525
if ( opt . minified ) {
577
- marked = markedMin ;
526
+ marked = require ( '../marked.min.js' ) ;
578
527
}
579
528
return runTests ( opt ) ;
580
529
}
@@ -599,7 +548,7 @@ if (!module.parent) {
599
548
600
549
// returns time to millisecond granularity
601
550
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 ;
604
553
return seconds * 1e3 + frac ;
605
554
}
0 commit comments