@jslint-org/jslint 2022.3.30 → 2022.5.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/jslint.mjs CHANGED
@@ -1,14 +1,15 @@
1
1
  // #!/usr/bin/env node
2
2
  // JSLint
3
- // Original Author: Douglas Crockford (https://www.jslint.com).
4
3
 
4
+ // The Unlicense
5
+ //
5
6
  // This is free and unencumbered software released into the public domain.
6
-
7
+ //
7
8
  // Anyone is free to copy, modify, publish, use, compile, sell, or
8
9
  // distribute this software, either in source code form or as a compiled
9
10
  // binary, for any purpose, commercial or non-commercial, and by any
10
11
  // means.
11
-
12
+ //
12
13
  // In jurisdictions that recognize copyright laws, the author or authors
13
14
  // of this software dedicate any and all copyright interest in the
14
15
  // software to the public domain. We make this dedication for the benefit
@@ -16,7 +17,7 @@
16
17
  // successors. We intend this dedication to be an overt act of
17
18
  // relinquishment in perpetuity of all present and future rights to this
18
19
  // software under copyright law.
19
-
20
+ //
20
21
  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
22
  // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
23
  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
@@ -24,7 +25,7 @@
24
25
  // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25
26
  // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26
27
  // OTHER DEALINGS IN THE SOFTWARE.
27
-
28
+ //
28
29
  // For more information, please refer to <https://unlicense.org/>
29
30
 
30
31
 
@@ -92,52 +93,52 @@
92
93
  // WARNING: JSLint will hurt your feelings.
93
94
 
94
95
  /*jslint beta, node*/
95
-
96
96
  /*property
97
- fud_stmt,
98
- is_fart,
99
- mode_conditional,
97
+ excludeList,
98
+ globExclude,
99
+ import_meta_url, includeList,
100
+ pathnameList,
100
101
  JSLINT_BETA, NODE_V8_COVERAGE, a, all, argv, arity, artifact,
101
102
  assertErrorThrownAsync, assertJsonEqual, assertOrThrow, assign, async, b,
102
103
  beta, bitwise, block, body, browser, c, calls, catch, catch_list,
103
- catch_stack, causes, char, children, clear, closer,
104
- closure, code, column, concat, consoleError, console_error, console_log,
105
- constant, context, convert, count, coverageDir, create, cwd, d, dead,
106
- debugInline, default, delta, devel, directive, directive_list,
107
- directive_quiet, directives, dirname, disrupt, dot, edition, elem_list,
108
- ellipsis, else, end, endOffset, endsWith, entries, env, error, eval, every,
109
- example_list, exec, execArgv, exit, export_dict, exports, expression, extra,
110
- file, fileList, fileURLToPath, filter, finally, flag, floor, for, forEach,
111
- formatted_message, free, freeze, from, froms,
112
- fsWriteFileWithParents, functionName, function_list, function_stack,
113
- functions, get, getset, github_repo, global, global_dict, global_list,
114
- holeList, htmlEscape, id, identifier, import, import_list, inc, indent2,
115
- index, indexOf, init, initial, isArray, isBlockCoverage, isHole, isNaN,
116
- is_equal, is_weird, join, jslint, jslint_apidoc, jslint_assert,
117
- jslint_charset_ascii, jslint_cli, jslint_edition, jslint_phase1_split,
118
- jslint_phase2_lex, jslint_phase3_parse, jslint_phase4_walk,
119
- jslint_phase5_whitage, jslint_report, json, jstestDescribe, jstestIt,
120
- jstestOnExit, keys, label, lbp, led_infix, length, level, line, lineList,
121
- line_list, line_offset, line_source, lines, linesCovered, linesTotal, live,
122
- log, long, loop, m, main, map, margin, match, max, message, meta, min,
123
- mkdir, modeCoverageIgnoreFile, modeIndex, mode_cli, mode_json, mode_module,
124
- mode_noop, mode_property, mode_shebang, mode_stop, module, moduleFsInit,
125
- moduleName, module_list, name, names, node, noop, now,
126
- nr, nud_prefix, objectDeepCopyWithKeysSorted, ok, on, open, opening, option,
127
- option_dict, order, package_name, padEnd, padStart, parameters, parent,
128
- parentIi, parse, pathname, platform, pop, processArgv, process_argv,
129
- process_env, process_exit, process_version, promises, property,
130
- property_dict, push, quote, ranges, readFile, readdir, readonly, recursive,
131
- reduce, repeat, replace, resolve, result, reverse, rm, rmdir, role, round,
132
- scriptId, search, set, shebang, shift, signature, single, slice, some, sort,
133
- source, spawn, splice, split, stack, stack_trace, start, startOffset,
134
- startsWith, statement, statement_prv, stdio, stop, stop_at, stringify,
135
- switch, syntax_dict, tenure, test, test_cause, test_internal_error, this,
136
- thru, toString, token, token_global, token_list, token_nxt, token_tree,
137
- tokens, trace, tree, trim, trimEnd, trimRight, try, type, unlink, unordered,
138
- unshift, url, used, v8CoverageListMerge, v8CoverageReportCreate, value,
139
- variable, version, versions, warn, warn_at, warning, warning_list, warnings,
140
- white, wrapped, writeFile
104
+ catch_stack, causes, char, children, clear, closer, closure, code, column,
105
+ concat, consoleError, console_error, console_log, constant, context,
106
+ convert, count, coverageDir, create, cwd, d, dead, debugInline, default,
107
+ delta, devel, directive, directive_list, directive_quiet, directives,
108
+ dirname, disrupt, dot, edition, elem_list, ellipsis, else, end, endOffset,
109
+ endsWith, entries, env, error, eval, every, example_list, exec, execArgv,
110
+ exit, exitCode, export_dict, exports, expression, extra, file, fileList,
111
+ fileURLToPath, filter, finally, flag, floor, for, forEach,
112
+ formatted_message, free, freeze, from, froms, fsWriteFileWithParents,
113
+ fud_stmt, functionName, function_list, function_stack, functions, get,
114
+ getset, github_repo, global, global_dict, global_list, holeList, htmlEscape,
115
+ id, identifier, import, import_list, inc, indent2, index, indexOf, init,
116
+ initial, isArray, isBlockCoverage, isHole, isNaN, is_equal, is_fart,
117
+ is_weird, join, jslint, jslint_apidoc, jslint_assert, jslint_charset_ascii,
118
+ jslint_cli, jslint_edition, jslint_phase1_split, jslint_phase2_lex,
119
+ jslint_phase3_parse, jslint_phase4_walk, jslint_phase5_whitage,
120
+ jslint_report, json, jstestDescribe, jstestIt, jstestOnExit, keys, label,
121
+ lbp, led_infix, length, level, line, lineList, line_list, line_offset,
122
+ line_source, lines, linesCovered, linesTotal, live, log, long, loop, m, map,
123
+ margin, match, max, message, meta, min, mkdir, modeCoverageIgnoreFile,
124
+ modeIndex, mode_cli, mode_conditional, mode_json, mode_module, mode_noop,
125
+ mode_property, mode_shebang, mode_stop, module, moduleFsInit, moduleName,
126
+ module_list, name, names, node, noop, now, nr, nud_prefix,
127
+ objectDeepCopyWithKeysSorted, ok, on, open, opening, option, option_dict,
128
+ order, package_name, padEnd, padStart, parameters, parent, parentIi, parse,
129
+ pathname, platform, pop, processArgv, process_argv, process_env,
130
+ process_exit, promises, property, property_dict, push, quote, ranges,
131
+ readFile, readdir, readonly, recursive, reduce, repeat, replace, resolve,
132
+ result, reverse, role, round, scriptId, search, set, shebang, shift,
133
+ signature, single, slice, some, sort, source, spawn, splice, split, stack,
134
+ stack_trace, start, startOffset, startsWith, statement, statement_prv,
135
+ stdio, stop, stop_at, stringify, switch, syntax_dict, tenure, test,
136
+ test_cause, test_internal_error, this, thru, toString, token, token_global,
137
+ token_list, token_nxt, token_tree, tokens, trace, tree, trim, trimEnd,
138
+ trimRight, try, type, unlink, unordered, unshift, url, used,
139
+ v8CoverageListMerge, v8CoverageReportCreate, value, variable, version,
140
+ versions, warn, warn_at, warning, warning_list, warnings, white, wrapped,
141
+ writeFile
141
142
  */
142
143
 
143
144
  // init debugInline
@@ -167,7 +168,7 @@ let jslint_charset_ascii = (
167
168
  + "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
168
169
  + "`abcdefghijklmnopqrstuvwxyz{|}~\u007f"
169
170
  );
170
- let jslint_edition = "v2022.3.30";
171
+ let jslint_edition = "v2022.5.20";
171
172
  let jslint_export; // The jslint object to be exported.
172
173
  let jslint_fudge = 1; // Fudge starting line and starting
173
174
  // ... column to 1.
@@ -254,6 +255,9 @@ let jslint_rgx_token = new RegExp(
254
255
  + ")"
255
256
  + "(.*)$"
256
257
  );
258
+ let jslint_rgx_url_search_window_jslint = (
259
+ /[&?]window_jslint=1(?:$|&)/m
260
+ );
257
261
  let jslint_rgx_weird_property = (
258
262
  /^_|\$|Sync$|_$/m
259
263
  );
@@ -352,6 +356,224 @@ async function fsWriteFileWithParents(pathname, data) {
352
356
  console.error("wrote file " + pathname);
353
357
  }
354
358
 
359
+ function globExclude({
360
+ excludeList = [],
361
+ includeList = [],
362
+ pathnameList = []
363
+ }) {
364
+
365
+ // This function will
366
+ // 1. Exclude pathnames in <pathnameList> that don't match glob-patterns in
367
+ // <includeList>.
368
+ // 2. Exclude pathnames in <pathnameList> that match glob-patterns in
369
+ // <excludeList>.
370
+
371
+ function globAssertNotWeird(list, name) {
372
+
373
+ // This function will check if <list> of strings contain weird characters.
374
+
375
+ [
376
+ [
377
+ "\n", (
378
+ /^.*?([\u0000-\u0007\r]).*/gm
379
+ )
380
+ ],
381
+ [
382
+ "\r", (
383
+ /^.*?([\n]).*/gm
384
+ )
385
+ ]
386
+ ].forEach(function ([
387
+ separator, rgx
388
+ ]) {
389
+ list.join(separator).replace(rgx, function (match0, char) {
390
+ throw new Error(
391
+ "Weird character "
392
+ + JSON.stringify(char)
393
+ + " found in " + name + " "
394
+ + JSON.stringify(match0)
395
+ );
396
+ });
397
+ });
398
+ }
399
+
400
+ function globToRegexp(pattern) {
401
+
402
+ // This function will translate glob <pattern> to javascript-regexp,
403
+ // which javascript can then use to "glob" pathnames.
404
+
405
+ let ii = 0;
406
+ let isClass = false;
407
+ let strClass = "";
408
+ let strRegex = "";
409
+ pattern = pattern.replace((
410
+ /\/\/+/g
411
+ ), "/");
412
+ pattern = pattern.replace((
413
+ /\*\*\*+/g
414
+ ), "**");
415
+ pattern.replace((
416
+ /\\\\|\\\[|\\\]|\[|\]|./g
417
+ ), function (match0) {
418
+ switch (match0) {
419
+ case "[":
420
+ if (isClass) {
421
+ strClass += "[";
422
+ return;
423
+ }
424
+ strClass += "\u0000";
425
+ strRegex += "\u0000";
426
+ isClass = true;
427
+ return;
428
+ case "]":
429
+ if (isClass) {
430
+ isClass = false;
431
+ return;
432
+ }
433
+ strRegex += "]";
434
+ return;
435
+ default:
436
+ if (isClass) {
437
+ strClass += match0;
438
+ return;
439
+ }
440
+ strRegex += match0;
441
+ }
442
+ return "";
443
+ });
444
+ strClass += "\u0000";
445
+
446
+ // An expression "[!...]" matches a single character, namely any character that
447
+ // is not matched by the expression obtained by removing the first '!' from it.
448
+ // (Thus, "[!a-]" matches any single character except 'a', and '-'.)
449
+
450
+ strClass = strClass.replace((
451
+ /\u0000!/g
452
+ ), "\u0000^");
453
+
454
+ // One may include '-' in its literal meaning by making it the first or last
455
+ // character between the brackets.
456
+
457
+ strClass = strClass.replace((
458
+ /\u0000-/g
459
+ ), "\u0000\\-");
460
+ strClass = strClass.replace((
461
+ /-\u0000/g
462
+ ), "\\-\u0000");
463
+
464
+ // Escape brackets '[', ']' in character class.
465
+
466
+ strClass = strClass.replace((
467
+ /[\[\]]/g
468
+ ), "\\$&");
469
+
470
+ // https://stackoverflow.com/questions/3561493
471
+ // /is-there-a-regexp-escape-function-in-javascript
472
+ // $()*+-./?[\]^{|}
473
+
474
+ strRegex = strRegex.replace((
475
+ // ignore [-/]
476
+ /[$()*+.?\[\\\]\^{|}]/g
477
+ ), "\\$&");
478
+
479
+ // Expand wildcard '**/*'.
480
+
481
+ strRegex = strRegex.replace((
482
+ /\\\*\\\*\/(?:\\\*)+/g
483
+ ), ".*?");
484
+
485
+ // Expand wildcard '**'.
486
+
487
+ strRegex = strRegex.replace((
488
+ /(^|\/)\\\*\\\*(\/|$)/gm
489
+ ), "$1.*?$2");
490
+
491
+ // Expand wildcard '*'.
492
+
493
+ strRegex = strRegex.replace((
494
+ /(?:\\\*)+/g
495
+ ), "[^\\/]*?");
496
+
497
+ // Expand wildcard '?'.
498
+
499
+ strRegex = strRegex.replace((
500
+ /\\\?/g
501
+ ), "[^\\/]");
502
+
503
+ // Expand directory-with-trailing-slash '.../'.
504
+
505
+ strRegex = strRegex.replace((
506
+ /\/$/gm
507
+ ), "\\/.*?");
508
+
509
+ // Merge strClass into strRegex.
510
+
511
+ ii = 0;
512
+ strClass = strClass.split("\u0000");
513
+ strRegex = strRegex.replace((
514
+ /\u0000/g
515
+ ), function () {
516
+ ii += 1;
517
+ if (strClass[ii] === "") {
518
+ return "";
519
+ }
520
+ return "[" + strClass[ii] + "]";
521
+ });
522
+
523
+ // Change strRegex from string to regexp.
524
+
525
+ strRegex = new RegExp("^" + strRegex + "$", "gm");
526
+ return strRegex;
527
+ }
528
+
529
+ // Validate excludeList, includeList, pathnameList.
530
+
531
+ globAssertNotWeird(excludeList, "pattern");
532
+ globAssertNotWeird(includeList, "pattern");
533
+ globAssertNotWeird(pathnameList, "pathname");
534
+
535
+ // Optimization
536
+ // Concat pathnames into a single, newline-separated string,
537
+ // whose pathnames can all be filtered with a single, regexp-pass.
538
+
539
+ pathnameList = pathnameList.join("\n");
540
+
541
+ // 1. Exclude pathnames in <pathnameList> that don't match glob-patterns in
542
+ // <includeList>.
543
+
544
+ if (includeList.length > 0) {
545
+ includeList = includeList.map(globToRegexp);
546
+ includeList.forEach(function (pattern) {
547
+ pathnameList = pathnameList.replace(pattern, "\u0000$&");
548
+ });
549
+ pathnameList = pathnameList.replace((
550
+ /^[^\u0000].*/gm
551
+ ), "");
552
+ pathnameList = pathnameList.replace((
553
+ /^\u0000+/gm
554
+ ), "");
555
+ }
556
+
557
+ // 2. Exclude pathnames in <pathnameList> that match glob-patterns in
558
+ // <excludeList>.
559
+
560
+ excludeList = excludeList.map(globToRegexp);
561
+ excludeList.forEach(function (pattern) {
562
+ pathnameList = pathnameList.replace(pattern, "");
563
+ });
564
+
565
+ // Split newline-separated pathnames back to list.
566
+
567
+ pathnameList = pathnameList.split("\n").filter(function (elem) {
568
+ return elem;
569
+ });
570
+ return {
571
+ excludeList,
572
+ includeList,
573
+ pathnameList
574
+ };
575
+ }
576
+
355
577
  function htmlEscape(str) {
356
578
 
357
579
  // This function will make <str> html-safe by escaping & < >.
@@ -437,8 +659,6 @@ function jslint(
437
659
  }
438
660
 
439
661
  function is_equal(aa, bb) {
440
- let aa_value;
441
- let bb_value;
442
662
 
443
663
  // test_cause:
444
664
  // ["0&&0", "is_equal", "", "", 0]
@@ -459,6 +679,7 @@ function jslint(
459
679
 
460
680
  // test_cause:
461
681
  // ["`${0}`&&`${0}`", "is_equal", "recurse_isArray", "", 0]
682
+ // ["`${0}`&&`${1}`", "is_equal", "recurse_isArray", "", 0]
462
683
 
463
684
  test_cause("recurse_isArray");
464
685
  return is_equal(value, bb[index]);
@@ -472,21 +693,19 @@ function jslint(
472
693
  // }
473
694
 
474
695
  jslint_assert(!Array.isArray(bb), `Expected !Array.isArray(bb).`);
475
- if (aa.id === "(number)" && bb.id === "(number)") {
696
+ switch (aa.id === bb.id && aa.id) {
697
+ case "(number)":
698
+ case "(string)":
476
699
  return aa.value === bb.value;
477
- }
478
- if (aa.id === "(string)") {
479
- aa_value = aa.value;
480
- } else if (aa.id === "`" && aa.constant) {
481
- aa_value = aa.value[0];
482
- }
483
- if (bb.id === "(string)") {
484
- bb_value = bb.value;
485
- } else if (bb.id === "`" && bb.constant) {
486
- bb_value = bb.value[0];
487
- }
488
- if (typeof aa_value === "string") {
489
- return aa_value === bb_value;
700
+
701
+ // PR-394 - Bugfix
702
+ // Fix jslint falsely believing megastring literals `0` and `1` are similar.
703
+
704
+ case "`":
705
+ if (!is_equal(aa.value, bb.value)) {
706
+ return false;
707
+ }
708
+ break;
490
709
  }
491
710
  if (is_weird(aa) || is_weird(bb)) {
492
711
 
@@ -1543,6 +1762,7 @@ async function jslint_cli({
1543
1762
  console_error,
1544
1763
  console_log,
1545
1764
  file,
1765
+ import_meta_url,
1546
1766
  mode_cli,
1547
1767
  mode_noop,
1548
1768
  option,
@@ -1711,11 +1931,26 @@ async function jslint_cli({
1711
1931
  return count;
1712
1932
  }
1713
1933
 
1934
+ // PR-396 - window.jslint
1935
+ // Check import.meta.url for directive to export jslint to window-object.
1936
+ // Useful for ES5-era browser-scripts that rely on window.jslint,
1937
+ // like CodeMirror.
1938
+ //
1939
+ // Example usage:
1940
+ // <script type="module" src="./jslint.mjs?window_jslint=1"></script>
1941
+
1942
+ import_meta_url = import_meta_url || jslint_import_meta_url;
1943
+ if (
1944
+ jslint_rgx_url_search_window_jslint.test(import_meta_url)
1945
+ && (typeof globalThis === "object" && globalThis)
1946
+ ) {
1947
+ globalThis.jslint = jslint;
1948
+ }
1949
+
1714
1950
  // Feature-detect nodejs.
1715
1951
 
1716
1952
  if (!(
1717
- typeof process === "object"
1718
- && process
1953
+ (typeof process === "object" && process)
1719
1954
  && process.versions
1720
1955
  && typeof process.versions.node === "string"
1721
1956
  && !mode_noop
@@ -1741,7 +1976,7 @@ async function jslint_cli({
1741
1976
  ).test(process_argv[1])
1742
1977
  || mode_cli
1743
1978
  )
1744
- && moduleUrl.fileURLToPath(jslint_import_meta_url)
1979
+ && moduleUrl.fileURLToPath(import_meta_url)
1745
1980
  === modulePath.resolve(process_argv[1])
1746
1981
  )
1747
1982
  && !mode_cli
@@ -1887,7 +2122,9 @@ async function jslint_cli({
1887
2122
  option
1888
2123
  });
1889
2124
  if (mode_report) {
1890
- await fsWriteFileWithParents(mode_report, jslint_report(result));
2125
+ result = jslint.jslint_report(result);
2126
+ result = `<body class="JSLINT_ JSLINT_REPORT_">\n${result}</body>\n`;
2127
+ await fsWriteFileWithParents(mode_report, result);
1891
2128
  }
1892
2129
  process_exit(exit_code);
1893
2130
  return exit_code;
@@ -7751,6 +7988,11 @@ function jslint_phase4_walk(state) {
7751
7988
  || thing.expression[0].constant === true
7752
7989
  || is_equal(thing.expression[1], thing.expression[2])
7753
7990
  ) {
7991
+
7992
+ // test_cause:
7993
+ // ["let aa=(aa?`${0}`:`${0}`);", "post_t", "unexpected_a", "?", 11]
7994
+ // ["let aa=(aa?`0`:`0`);", "post_t", "unexpected_a", "?", 11]
7995
+
7754
7996
  warn("unexpected_a", thing);
7755
7997
  } else if (is_equal(thing.expression[0], thing.expression[1])) {
7756
7998
 
@@ -8970,6 +9212,7 @@ function jslint_report({
8970
9212
 
8971
9213
  // This function will create human-readable, html-report
8972
9214
  // for warnings, properties, and functions from jslint-result-object.
9215
+ //
8973
9216
  // Example usage:
8974
9217
  // let result = jslint("console.log('hello world')");
8975
9218
  // let html = jslint_report(result);
@@ -9002,7 +9245,6 @@ function jslint_report({
9002
9245
  );
9003
9246
  }
9004
9247
 
9005
- html += "<div class=\"JSLINT_\" id=\"JSLINT_REPORT_HTML\">\n";
9006
9248
  html += String(`
9007
9249
  <style class="JSLINT_REPORT_STYLE">
9008
9250
  /* jslint utility2:true */
@@ -9151,19 +9393,38 @@ pyNj+JctcQLXenBOCms46aMkenIx45WpXqxxVJQLz/vgpmAVa0fmDv6Pue9xVTBPfVxCUGfj\
9151
9393
  /7xoEqvL+2E8VOyCTuT/7j269Zy4jUtN+g4="
9152
9394
  ) format("woff2");
9153
9395
  }
9154
- *,
9155
- *:after,
9156
- *:before {
9396
+ .JSLINT_,
9397
+ .JSLINT_ address,
9398
+ .JSLINT_ button,
9399
+ .JSLINT_ cite,
9400
+ .JSLINT_ dd,
9401
+ .JSLINT_ dfn,
9402
+ .JSLINT_ dl,
9403
+ .JSLINT_ dt,
9404
+ .JSLINT_ fieldset,
9405
+ .JSLINT_ fieldset > div,
9406
+ .JSLINT_ input,
9407
+ .JSLINT_ label,
9408
+ .JSLINT_ legend,
9409
+ .JSLINT_ ol,
9410
+ .JSLINT_ samp,
9411
+ .JSLINT_ style,
9412
+ .JSLINT_ textarea,
9413
+ .JSLINT_ ul {
9157
9414
  border: 0;
9158
9415
  box-sizing: border-box;
9159
9416
  margin: 0;
9160
9417
  padding: 0;
9161
9418
  }
9419
+ /* disable text inflation algorithm used on some smartphones and tablets */
9162
9420
  .JSLINT_ {
9163
9421
  -ms-text-size-adjust: none;
9164
9422
  -webkit-text-size-adjust: none;
9165
9423
  text-size-adjust: none;
9166
9424
  }
9425
+ .JSLINT_REPORT_ div {
9426
+ box-sizing: border-box;
9427
+ }
9167
9428
  /*csslint ignore:end*/
9168
9429
 
9169
9430
  /* css - jslint_report - font */
@@ -9197,7 +9458,7 @@ pyNj+JctcQLXenBOCms46aMkenIx45WpXqxxVJQLz/vgpmAVa0fmDv6Pue9xVTBPfVxCUGfj\
9197
9458
  }
9198
9459
 
9199
9460
  /* css - jslint_report - general */
9200
- body {
9461
+ .JSLINT_ {
9201
9462
  background: antiquewhite;
9202
9463
  }
9203
9464
  .JSLINT_ fieldset {
@@ -9534,7 +9795,6 @@ body {
9534
9795
  });
9535
9796
  html += "</div>\n";
9536
9797
  html += "</fieldset>\n";
9537
- html += "</div>\n";
9538
9798
  return html;
9539
9799
  }
9540
9800
 
@@ -9610,14 +9870,14 @@ function jstestIt(description, testFunction, mode) {
9610
9870
  }));
9611
9871
  }
9612
9872
 
9613
- function jstestOnExit(exitCode, processExit, countFailed) {
9873
+ function jstestOnExit(exitCode, mode) {
9614
9874
 
9615
9875
  // This function will on process-exit, print test-report
9616
9876
  // and exit with non-zero exit-code if any test failed.
9617
9877
 
9618
9878
  let message = (
9619
9879
  (
9620
- (jstestCountFailed || countFailed)
9880
+ (jstestCountFailed || mode === "testsFailed")
9621
9881
  ? "\n\u001b[31m"
9622
9882
  : "\n\u001b[32m"
9623
9883
  )
@@ -9625,11 +9885,10 @@ function jstestOnExit(exitCode, processExit, countFailed) {
9625
9885
  + " tests failed - " + jstestCountFailed + "\n"
9626
9886
  + "\u001b[39m"
9627
9887
  );
9628
- if (!processExit) {
9888
+ if (mode !== "testsFailed") {
9629
9889
  console.error(message);
9630
- processExit = process.exit;
9631
9890
  }
9632
- processExit(exitCode || jstestCountFailed);
9891
+ process.exitCode = exitCode || jstestCountFailed;
9633
9892
  return message;
9634
9893
  }
9635
9894
 
@@ -10351,11 +10610,11 @@ async function v8CoverageReportCreate({
10351
10610
  // 3. Create html-coverage-reports in <coverageDir>.
10352
10611
 
10353
10612
  let cwd;
10613
+ let excludeList = [];
10354
10614
  let exitCode = 0;
10355
10615
  let fileDict;
10356
- let fileExcludeList = [];
10357
- let fileIncludeList = [];
10358
- let fileIncludeNodeModules;
10616
+ let includeList = [];
10617
+ let modeIncludeNodeModules;
10359
10618
  let processArgElem;
10360
10619
  let promiseList = [];
10361
10620
  let v8CoverageObj;
@@ -10380,9 +10639,19 @@ async function v8CoverageReportCreate({
10380
10639
  <style>
10381
10640
  /* jslint utility2:true */
10382
10641
  /*csslint ignore:start*/
10383
- * {
10384
- box-sizing: border-box;
10385
- font-family: consolas, menlo, monospace;
10642
+ .coverage,
10643
+ .coverage a,
10644
+ .coverage div,
10645
+ .coverage pre,
10646
+ .coverage span,
10647
+ .coverage table,
10648
+ .coverage tbody,
10649
+ .coverage td,
10650
+ .coverage th,
10651
+ .coverage thead,
10652
+ .coverage tr {
10653
+ box-sizing: border-box;
10654
+ font-family: monospace;
10386
10655
  }
10387
10656
  /*csslint ignore:end*/
10388
10657
 
@@ -10528,6 +10797,7 @@ body {
10528
10797
  }
10529
10798
  txtBorder = (
10530
10799
  "+" + "-".repeat(padPathname + 2) + "+"
10800
+ + "-".repeat(padLines + 2) + "+"
10531
10801
  + "-".repeat(padLines + 2) + "+\n"
10532
10802
  );
10533
10803
  txt = "";
@@ -10535,7 +10805,8 @@ body {
10535
10805
  txt += txtBorder;
10536
10806
  txt += (
10537
10807
  "| " + String("Files covered").padEnd(padPathname, " ") + " | "
10538
- + String("Lines").padStart(padLines, " ") + " |\n"
10808
+ + String("Lines").padStart(padLines, " ") + " | "
10809
+ + String("Remaining").padStart(padLines, " ") + " |\n"
10539
10810
  );
10540
10811
  txt += txtBorder;
10541
10812
  fileList.forEach(function ({
@@ -10615,7 +10886,8 @@ body {
10615
10886
  + String("./" + pathname).padEnd(padPathname, " ") + " | "
10616
10887
  + String(
10617
10888
  modeCoverageIgnoreFile + " " + coveragePct + " %"
10618
- ).padStart(padLines, " ") + " |\n"
10889
+ ).padStart(padLines, " ") + " | "
10890
+ + " ".repeat(padLines) + " |\n"
10619
10891
  );
10620
10892
  txt += (
10621
10893
  "| " + "*".repeat(
@@ -10623,6 +10895,9 @@ body {
10623
10895
  ).padEnd(padPathname, "_") + " | "
10624
10896
  + String(
10625
10897
  linesCovered + " / " + linesTotal
10898
+ ).padStart(padLines, " ") + " | "
10899
+ + String(
10900
+ (linesTotal - linesCovered) + " / " + linesTotal
10626
10901
  ).padStart(padLines, " ") + " |\n"
10627
10902
  );
10628
10903
  txt += txtBorder;
@@ -10786,21 +11061,6 @@ ${String(count || "-0").padStart(7, " ")}
10786
11061
  ), txt));
10787
11062
  }
10788
11063
 
10789
- function pathnameRelativeCwd(pathname) {
10790
-
10791
- // This function will if <pathname> is inside <cwd>,
10792
- // return it relative to <cwd>, else empty-string.
10793
-
10794
- pathname = modulePath.resolve(pathname).replace((
10795
- /\\/g
10796
- ), "/");
10797
- if (!pathname.startsWith(cwd)) {
10798
- return;
10799
- }
10800
- pathname = pathname.slice(cwd.length);
10801
- return pathname;
10802
- }
10803
-
10804
11064
  /*
10805
11065
  function sentinel() {}
10806
11066
  */
@@ -10832,28 +11092,28 @@ function sentinel() {}
10832
11092
  processArgElem[1] = processArgElem.slice(1).join("=");
10833
11093
  switch (processArgElem[0]) {
10834
11094
 
10835
- // PR-371 - add cli-option `--exclude=aa,bb`
11095
+ // PR-371
11096
+ // Add cli-option `--exclude=...`.
10836
11097
 
10837
11098
  case "--exclude":
10838
- fileExcludeList = fileExcludeList.concat(
10839
- processArgElem[1].split(",")
10840
- );
11099
+ excludeList.push(processArgElem[1]);
10841
11100
  break;
10842
11101
 
10843
- // PR-371 - add cli-option `--exclude-node-modules=false`
11102
+ // PR-371
11103
+ // Add cli-option `--include=...`
10844
11104
 
10845
- case "--exclude-node-modules":
10846
- fileIncludeNodeModules = (
10847
- /0|false|null|undefined/
10848
- ).test(processArgElem[1]);
11105
+ case "--include":
11106
+ includeList.push(processArgElem[1]);
10849
11107
  break;
10850
11108
 
10851
- // PR-371 - add cli-option `--include=aa,bb`
11109
+ // PR-400
11110
+ // Disable default-coverage of directory `node_modules`,
11111
+ // but allow override with cli-option `--include-node-modules=1`.
10852
11112
 
10853
- case "--include":
10854
- fileIncludeList = fileIncludeList.concat(
10855
- processArgElem[1].split(",")
10856
- );
11113
+ case "--include-node-modules":
11114
+ modeIncludeNodeModules = !(
11115
+ /0|false|null|undefined/
11116
+ ).test(processArgElem[1]);
10857
11117
  break;
10858
11118
  }
10859
11119
  }
@@ -10907,9 +11167,11 @@ function sentinel() {}
10907
11167
  ).test(file);
10908
11168
  });
10909
11169
  v8CoverageObj = await Promise.all(v8CoverageObj.map(async function (file) {
10910
- let data = await moduleFs.promises.readFile(coverageDir + file, "utf8");
11170
+ let data;
11171
+ let pathnameDict = Object.create(null);
11172
+ data = await moduleFs.promises.readFile(coverageDir + file, "utf8");
10911
11173
  data = JSON.parse(data);
10912
- data.result = data.result.filter(function (scriptCov) {
11174
+ data.result.forEach(function (scriptCov) {
10913
11175
  let pathname = scriptCov.url;
10914
11176
 
10915
11177
  // Filter out internal coverages.
@@ -10920,38 +11182,40 @@ function sentinel() {}
10920
11182
 
10921
11183
  // Normalize pathname.
10922
11184
 
10923
- pathname = pathnameRelativeCwd(moduleUrl.fileURLToPath(pathname));
10924
- if (
11185
+ pathname = moduleUrl.fileURLToPath(pathname);
11186
+ pathname = modulePath.resolve(pathname).replace((
11187
+ /\\/g
11188
+ ), "/");
10925
11189
 
10926
11190
  // Filter files outside of cwd.
10927
11191
 
10928
- !pathname
10929
- || pathname.startsWith("[")
11192
+ if (pathname.indexOf("[") >= 0 || !pathname.startsWith(cwd)) {
11193
+ return;
11194
+ }
10930
11195
 
10931
- // PR-371 - Filter directory node_modules.
11196
+ // Normalize pathname relative to cwd.
10932
11197
 
10933
- || (
10934
- !fileIncludeNodeModules
10935
- && (
10936
- /(?:^|\/)node_modules\//m
10937
- ).test(pathname)
10938
- )
11198
+ pathname = pathname.slice(cwd.length);
11199
+ scriptCov.url = pathname;
11200
+ pathnameDict[pathname] = scriptCov;
11201
+ });
10939
11202
 
10940
- // PR-371 - Filter fileExcludeList.
11203
+ // PR-400
11204
+ // Filter directory `node_modules`.
10941
11205
 
10942
- || fileExcludeList.indexOf(pathname) >= 0
11206
+ if (!modeIncludeNodeModules) {
11207
+ excludeList.push("node_modules/");
11208
+ }
10943
11209
 
10944
- // PR-371 - Filter fileIncludeList.
11210
+ // PR-400
11211
+ // Filter files by glob-patterns in excludeList, includeList.
10945
11212
 
10946
- || (
10947
- fileIncludeList.length > 0
10948
- && fileIncludeList.indexOf(pathname) === -1
10949
- )
10950
- ) {
10951
- return;
10952
- }
10953
- scriptCov.url = pathname;
10954
- return true;
11213
+ data.result = globExclude({
11214
+ excludeList,
11215
+ includeList,
11216
+ pathnameList: Object.keys(pathnameDict)
11217
+ }).pathnameList.map(function (pathname) {
11218
+ return pathnameDict[pathname];
10955
11219
  });
10956
11220
  return data;
10957
11221
  }));
@@ -10960,7 +11224,7 @@ function sentinel() {}
10960
11224
 
10961
11225
  v8CoverageObj = v8CoverageListMerge(v8CoverageObj);
10962
11226
 
10963
- // debug v8CoverageObj.
11227
+ // Debug v8CoverageObj.
10964
11228
 
10965
11229
  await fsWriteFileWithParents(
10966
11230
  coverageDir + "v8_coverage_merged.json",
@@ -11100,6 +11364,7 @@ jslint_export = Object.freeze(Object.assign(jslint, {
11100
11364
  assertOrThrow,
11101
11365
  debugInline,
11102
11366
  fsWriteFileWithParents,
11367
+ globExclude,
11103
11368
  htmlEscape,
11104
11369
  jslint,
11105
11370
  jslint_apidoc,