mocha 6.0.0-1 → 6.0.0
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/CHANGELOG.md +38 -0
- package/bin/mocha +79 -45
- package/lib/browser/growl.js +3 -2
- package/lib/cli/node-flags.js +21 -0
- package/lib/cli/options.js +44 -13
- package/lib/cli/run-helpers.js +19 -10
- package/lib/cli/run-option-metadata.js +4 -0
- package/lib/cli/run.js +12 -8
- package/lib/errors.js +16 -14
- package/lib/growl.js +3 -2
- package/lib/interfaces/bdd.js +3 -1
- package/lib/interfaces/common.js +7 -6
- package/lib/interfaces/exports.js +1 -1
- package/lib/interfaces/qunit.js +3 -1
- package/lib/interfaces/tdd.js +3 -1
- package/lib/mocha.js +61 -27
- package/lib/reporters/base.js +5 -2
- package/lib/reporters/doc.js +9 -4
- package/lib/reporters/dot.js +11 -5
- package/lib/reporters/html.js +11 -5
- package/lib/reporters/json-stream.js +9 -4
- package/lib/reporters/json.js +11 -5
- package/lib/reporters/landing.js +10 -4
- package/lib/reporters/list.js +13 -6
- package/lib/reporters/markdown.js +9 -4
- package/lib/reporters/min.js +5 -2
- package/lib/reporters/nyan.js +11 -5
- package/lib/reporters/progress.js +7 -3
- package/lib/reporters/spec.js +15 -7
- package/lib/reporters/tap.js +13 -6
- package/lib/reporters/xunit.js +16 -9
- package/lib/runnable.js +50 -6
- package/lib/runner.js +187 -188
- package/lib/stats-collector.js +17 -15
- package/lib/suite.js +239 -26
- package/lib/test.js +3 -2
- package/lib/utils.js +256 -72
- package/mocha.js +1029 -458
- package/package.json +19 -4
package/lib/utils.js
CHANGED
|
@@ -1,31 +1,35 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Various utility functions used throughout Mocha's codebase.
|
|
5
|
+
* @module utils
|
|
5
6
|
*/
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Module dependencies.
|
|
9
10
|
*/
|
|
10
11
|
|
|
11
|
-
var debug = require('debug')('mocha:watch');
|
|
12
12
|
var fs = require('fs');
|
|
13
|
-
var glob = require('glob');
|
|
14
13
|
var path = require('path');
|
|
15
|
-
var
|
|
14
|
+
var util = require('util');
|
|
15
|
+
var glob = require('glob');
|
|
16
16
|
var he = require('he');
|
|
17
17
|
var errors = require('./errors');
|
|
18
18
|
var createNoFilesMatchPatternError = errors.createNoFilesMatchPatternError;
|
|
19
19
|
var createMissingArgumentError = errors.createMissingArgumentError;
|
|
20
|
-
|
|
20
|
+
|
|
21
|
+
var assign = (exports.assign = require('object.assign').getPolyfill());
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
|
-
*
|
|
24
|
+
* Inherit the prototype methods from one constructor into another.
|
|
25
|
+
*
|
|
26
|
+
* @param {function} ctor - Constructor function which needs to inherit the
|
|
27
|
+
* prototype.
|
|
28
|
+
* @param {function} superCtor - Constructor function to inherit prototype from.
|
|
29
|
+
* @throws {TypeError} if either constructor is null, or if super constructor
|
|
30
|
+
* lacks a prototype.
|
|
24
31
|
*/
|
|
25
|
-
|
|
26
|
-
var ignore = ['node_modules', '.git'];
|
|
27
|
-
|
|
28
|
-
exports.inherits = require('util').inherits;
|
|
32
|
+
exports.inherits = util.inherits;
|
|
29
33
|
|
|
30
34
|
/**
|
|
31
35
|
* Escape special characters in the given string of html.
|
|
@@ -59,6 +63,7 @@ exports.isString = function(obj) {
|
|
|
59
63
|
*/
|
|
60
64
|
exports.watch = function(files, fn) {
|
|
61
65
|
var options = {interval: 100};
|
|
66
|
+
var debug = require('debug')('mocha:watch');
|
|
62
67
|
files.forEach(function(file) {
|
|
63
68
|
debug('file %s', file);
|
|
64
69
|
fs.watchFile(file, options, function(curr, prev) {
|
|
@@ -70,39 +75,52 @@ exports.watch = function(files, fn) {
|
|
|
70
75
|
};
|
|
71
76
|
|
|
72
77
|
/**
|
|
73
|
-
*
|
|
78
|
+
* Predicate to screen `pathname` for further consideration.
|
|
79
|
+
*
|
|
80
|
+
* @description
|
|
81
|
+
* Returns <code>false</code> for pathname referencing:
|
|
82
|
+
* <ul>
|
|
83
|
+
* <li>'npm' package installation directory
|
|
84
|
+
* <li>'git' version control directory
|
|
85
|
+
* </ul>
|
|
74
86
|
*
|
|
75
87
|
* @private
|
|
76
|
-
* @param {string}
|
|
77
|
-
* @return {boolean}
|
|
88
|
+
* @param {string} pathname - File or directory name to screen
|
|
89
|
+
* @return {boolean} whether pathname should be further considered
|
|
90
|
+
* @example
|
|
91
|
+
* ['node_modules', 'test.js'].filter(considerFurther); // => ['test.js']
|
|
78
92
|
*/
|
|
79
|
-
function
|
|
80
|
-
|
|
93
|
+
function considerFurther(pathname) {
|
|
94
|
+
var ignore = ['node_modules', '.git'];
|
|
95
|
+
|
|
96
|
+
return !~ignore.indexOf(pathname);
|
|
81
97
|
}
|
|
82
98
|
|
|
83
99
|
/**
|
|
84
100
|
* Lookup files in the given `dir`.
|
|
85
101
|
*
|
|
102
|
+
* @description
|
|
103
|
+
* Filenames are returned in _traversal_ order by the OS/filesystem.
|
|
104
|
+
* **Make no assumption that the names will be sorted in any fashion.**
|
|
105
|
+
*
|
|
86
106
|
* @private
|
|
87
107
|
* @param {string} dir
|
|
88
|
-
* @param {string[]} [
|
|
108
|
+
* @param {string[]} [exts=['js']]
|
|
89
109
|
* @param {Array} [ret=[]]
|
|
90
110
|
* @return {Array}
|
|
91
111
|
*/
|
|
92
|
-
exports.files = function(dir,
|
|
112
|
+
exports.files = function(dir, exts, ret) {
|
|
93
113
|
ret = ret || [];
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
var re = new RegExp('\\.(' + ext.join('|') + ')$');
|
|
114
|
+
exts = exts || ['js'];
|
|
97
115
|
|
|
98
116
|
fs.readdirSync(dir)
|
|
99
|
-
.filter(
|
|
100
|
-
.forEach(function(
|
|
101
|
-
|
|
102
|
-
if (fs.lstatSync(
|
|
103
|
-
exports.files(
|
|
104
|
-
} else if (
|
|
105
|
-
ret.push(
|
|
117
|
+
.filter(considerFurther)
|
|
118
|
+
.forEach(function(dirent) {
|
|
119
|
+
var pathname = path.join(dir, dirent);
|
|
120
|
+
if (fs.lstatSync(pathname).isDirectory()) {
|
|
121
|
+
exports.files(pathname, exts, ret);
|
|
122
|
+
} else if (hasMatchingExtname(pathname, exts)) {
|
|
123
|
+
ret.push(pathname);
|
|
106
124
|
}
|
|
107
125
|
});
|
|
108
126
|
|
|
@@ -499,28 +517,72 @@ exports.canonicalize = function canonicalize(value, stack, typeHint) {
|
|
|
499
517
|
return canonicalizedObj;
|
|
500
518
|
};
|
|
501
519
|
|
|
520
|
+
/**
|
|
521
|
+
* Determines if pathname has a matching file extension.
|
|
522
|
+
*
|
|
523
|
+
* @private
|
|
524
|
+
* @param {string} pathname - Pathname to check for match.
|
|
525
|
+
* @param {string[]} exts - List of file extensions (sans period).
|
|
526
|
+
* @return {boolean} whether file extension matches.
|
|
527
|
+
* @example
|
|
528
|
+
* hasMatchingExtname('foo.html', ['js', 'css']); // => false
|
|
529
|
+
*/
|
|
530
|
+
function hasMatchingExtname(pathname, exts) {
|
|
531
|
+
var suffix = path.extname(pathname).slice(1);
|
|
532
|
+
return exts.some(function(element) {
|
|
533
|
+
return suffix === element;
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
/**
|
|
538
|
+
* Determines if pathname would be a "hidden" file (or directory) on UN*X.
|
|
539
|
+
*
|
|
540
|
+
* @description
|
|
541
|
+
* On UN*X, pathnames beginning with a full stop (aka dot) are hidden during
|
|
542
|
+
* typical usage. Dotfiles, plain-text configuration files, are prime examples.
|
|
543
|
+
*
|
|
544
|
+
* @see {@link http://xahlee.info/UnixResource_dir/writ/unix_origin_of_dot_filename.html|Origin of Dot File Names}
|
|
545
|
+
*
|
|
546
|
+
* @private
|
|
547
|
+
* @param {string} pathname - Pathname to check for match.
|
|
548
|
+
* @return {boolean} whether pathname would be considered a hidden file.
|
|
549
|
+
* @example
|
|
550
|
+
* isHiddenOnUnix('.profile'); // => true
|
|
551
|
+
*/
|
|
552
|
+
function isHiddenOnUnix(pathname) {
|
|
553
|
+
return path.basename(pathname)[0] === '.';
|
|
554
|
+
}
|
|
555
|
+
|
|
502
556
|
/**
|
|
503
557
|
* Lookup file names at the given `path`.
|
|
504
558
|
*
|
|
505
|
-
* @
|
|
559
|
+
* @description
|
|
560
|
+
* Filenames are returned in _traversal_ order by the OS/filesystem.
|
|
561
|
+
* **Make no assumption that the names will be sorted in any fashion.**
|
|
562
|
+
*
|
|
506
563
|
* @public
|
|
507
|
-
* @
|
|
508
|
-
* @param {string[]} extensions File extensions to look for.
|
|
509
|
-
* @param {boolean} recursive Whether or not to recurse into subdirectories.
|
|
564
|
+
* @memberof Mocha.utils
|
|
510
565
|
* @todo Fix extension handling
|
|
566
|
+
* @param {string} filepath - Base path to start searching from.
|
|
567
|
+
* @param {string[]} extensions - File extensions to look for.
|
|
568
|
+
* @param {boolean} recursive - Whether to recurse into subdirectories.
|
|
511
569
|
* @return {string[]} An array of paths.
|
|
570
|
+
* @throws {Error} if no files match pattern.
|
|
571
|
+
* @throws {TypeError} if `filepath` is directory and `extensions` not provided.
|
|
512
572
|
*/
|
|
513
573
|
exports.lookupFiles = function lookupFiles(filepath, extensions, recursive) {
|
|
514
574
|
var files = [];
|
|
575
|
+
var stat;
|
|
515
576
|
|
|
516
577
|
if (!fs.existsSync(filepath)) {
|
|
517
578
|
if (fs.existsSync(filepath + '.js')) {
|
|
518
579
|
filepath += '.js';
|
|
519
580
|
} else {
|
|
581
|
+
// Handle glob
|
|
520
582
|
files = glob.sync(filepath);
|
|
521
583
|
if (!files.length) {
|
|
522
584
|
throw createNoFilesMatchPatternError(
|
|
523
|
-
'
|
|
585
|
+
'Cannot find any files matching pattern ' + exports.dQuote(filepath),
|
|
524
586
|
filepath
|
|
525
587
|
);
|
|
526
588
|
}
|
|
@@ -528,8 +590,9 @@ exports.lookupFiles = function lookupFiles(filepath, extensions, recursive) {
|
|
|
528
590
|
}
|
|
529
591
|
}
|
|
530
592
|
|
|
593
|
+
// Handle file
|
|
531
594
|
try {
|
|
532
|
-
|
|
595
|
+
stat = fs.statSync(filepath);
|
|
533
596
|
if (stat.isFile()) {
|
|
534
597
|
return filepath;
|
|
535
598
|
}
|
|
@@ -538,13 +601,16 @@ exports.lookupFiles = function lookupFiles(filepath, extensions, recursive) {
|
|
|
538
601
|
return;
|
|
539
602
|
}
|
|
540
603
|
|
|
541
|
-
|
|
542
|
-
|
|
604
|
+
// Handle directory
|
|
605
|
+
fs.readdirSync(filepath).forEach(function(dirent) {
|
|
606
|
+
var pathname = path.join(filepath, dirent);
|
|
607
|
+
var stat;
|
|
608
|
+
|
|
543
609
|
try {
|
|
544
|
-
|
|
610
|
+
stat = fs.statSync(pathname);
|
|
545
611
|
if (stat.isDirectory()) {
|
|
546
612
|
if (recursive) {
|
|
547
|
-
files = files.concat(lookupFiles(
|
|
613
|
+
files = files.concat(lookupFiles(pathname, extensions, recursive));
|
|
548
614
|
}
|
|
549
615
|
return;
|
|
550
616
|
}
|
|
@@ -554,64 +620,73 @@ exports.lookupFiles = function lookupFiles(filepath, extensions, recursive) {
|
|
|
554
620
|
}
|
|
555
621
|
if (!extensions) {
|
|
556
622
|
throw createMissingArgumentError(
|
|
557
|
-
|
|
623
|
+
util.format(
|
|
624
|
+
'Argument %s required when argument %s is a directory',
|
|
625
|
+
exports.sQuote('extensions'),
|
|
626
|
+
exports.sQuote('filepath')
|
|
627
|
+
),
|
|
558
628
|
'extensions',
|
|
559
629
|
'array'
|
|
560
630
|
);
|
|
561
631
|
}
|
|
562
|
-
|
|
563
|
-
if (
|
|
632
|
+
|
|
633
|
+
if (
|
|
634
|
+
!stat.isFile() ||
|
|
635
|
+
!hasMatchingExtname(pathname, extensions) ||
|
|
636
|
+
isHiddenOnUnix(pathname)
|
|
637
|
+
) {
|
|
564
638
|
return;
|
|
565
639
|
}
|
|
566
|
-
files.push(
|
|
640
|
+
files.push(pathname);
|
|
567
641
|
});
|
|
568
642
|
|
|
569
643
|
return files;
|
|
570
644
|
};
|
|
571
645
|
|
|
572
646
|
/**
|
|
573
|
-
*
|
|
574
|
-
*
|
|
575
|
-
* @
|
|
647
|
+
* process.emitWarning or a polyfill
|
|
648
|
+
* @see https://nodejs.org/api/process.html#process_process_emitwarning_warning_options
|
|
649
|
+
* @ignore
|
|
576
650
|
*/
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
*
|
|
587
|
-
* @param {Error} err
|
|
588
|
-
* @return {Error}
|
|
589
|
-
*/
|
|
590
|
-
|
|
591
|
-
exports.getError = function(err) {
|
|
592
|
-
return err || exports.undefinedError();
|
|
593
|
-
};
|
|
651
|
+
function emitWarning(msg, type) {
|
|
652
|
+
if (process.emitWarning) {
|
|
653
|
+
process.emitWarning(msg, type);
|
|
654
|
+
} else {
|
|
655
|
+
process.nextTick(function() {
|
|
656
|
+
console.warn(type + ': ' + msg);
|
|
657
|
+
});
|
|
658
|
+
}
|
|
659
|
+
}
|
|
594
660
|
|
|
595
661
|
/**
|
|
596
662
|
* Show a deprecation warning. Each distinct message is only displayed once.
|
|
663
|
+
* Ignores empty messages.
|
|
597
664
|
*
|
|
598
|
-
* @param {string} msg
|
|
665
|
+
* @param {string} [msg] - Warning to print
|
|
666
|
+
* @private
|
|
599
667
|
*/
|
|
600
668
|
exports.deprecate = function deprecate(msg) {
|
|
601
669
|
msg = String(msg);
|
|
602
670
|
if (msg && !deprecate.cache[msg]) {
|
|
603
671
|
deprecate.cache[msg] = true;
|
|
604
|
-
|
|
605
|
-
process.emitWarning(msg, 'DeprecationWarning');
|
|
606
|
-
} else {
|
|
607
|
-
process.nextTick(function() {
|
|
608
|
-
console.warn(msg);
|
|
609
|
-
});
|
|
610
|
-
}
|
|
672
|
+
emitWarning(msg, 'DeprecationWarning');
|
|
611
673
|
}
|
|
612
674
|
};
|
|
613
675
|
exports.deprecate.cache = {};
|
|
614
676
|
|
|
677
|
+
/**
|
|
678
|
+
* Show a generic warning.
|
|
679
|
+
* Ignores empty messages.
|
|
680
|
+
*
|
|
681
|
+
* @param {string} [msg] - Warning to print
|
|
682
|
+
* @private
|
|
683
|
+
*/
|
|
684
|
+
exports.warn = function warn(msg) {
|
|
685
|
+
if (msg) {
|
|
686
|
+
emitWarning(msg);
|
|
687
|
+
}
|
|
688
|
+
};
|
|
689
|
+
|
|
615
690
|
/**
|
|
616
691
|
* @summary
|
|
617
692
|
* This Filter based on `mocha-clean` module.(see: `github.com/rstacruz/mocha-clean`)
|
|
@@ -639,8 +714,6 @@ exports.stackTraceFilter = function() {
|
|
|
639
714
|
function isMochaInternal(line) {
|
|
640
715
|
return (
|
|
641
716
|
~line.indexOf('node_modules' + slash + 'mocha' + slash) ||
|
|
642
|
-
~line.indexOf('node_modules' + slash + 'mocha.js') ||
|
|
643
|
-
~line.indexOf('bower_components' + slash + 'mocha.js') ||
|
|
644
717
|
~line.indexOf(slash + 'mocha.js')
|
|
645
718
|
);
|
|
646
719
|
}
|
|
@@ -669,7 +742,7 @@ exports.stackTraceFilter = function() {
|
|
|
669
742
|
}
|
|
670
743
|
|
|
671
744
|
// Clean up cwd(absolute)
|
|
672
|
-
if (
|
|
745
|
+
if (/:\d+:\d+\)?$/.test(line)) {
|
|
673
746
|
line = line.replace('(' + cwd, '(');
|
|
674
747
|
}
|
|
675
748
|
|
|
@@ -706,8 +779,119 @@ exports.clamp = function clamp(value, range) {
|
|
|
706
779
|
return Math.min(Math.max(value, range[0]), range[1]);
|
|
707
780
|
};
|
|
708
781
|
|
|
782
|
+
/**
|
|
783
|
+
* Single quote text by combining with undirectional ASCII quotation marks.
|
|
784
|
+
*
|
|
785
|
+
* @description
|
|
786
|
+
* Provides a simple means of markup for quoting text to be used in output.
|
|
787
|
+
* Use this to quote names of variables, methods, and packages.
|
|
788
|
+
*
|
|
789
|
+
* <samp>package 'foo' cannot be found</samp>
|
|
790
|
+
*
|
|
791
|
+
* @private
|
|
792
|
+
* @param {string} str - Value to be quoted.
|
|
793
|
+
* @returns {string} quoted value
|
|
794
|
+
* @example
|
|
795
|
+
* sQuote('n') // => 'n'
|
|
796
|
+
*/
|
|
797
|
+
exports.sQuote = function(str) {
|
|
798
|
+
return "'" + str + "'";
|
|
799
|
+
};
|
|
800
|
+
|
|
801
|
+
/**
|
|
802
|
+
* Double quote text by combining with undirectional ASCII quotation marks.
|
|
803
|
+
*
|
|
804
|
+
* @description
|
|
805
|
+
* Provides a simple means of markup for quoting text to be used in output.
|
|
806
|
+
* Use this to quote names of datatypes, classes, pathnames, and strings.
|
|
807
|
+
*
|
|
808
|
+
* <samp>argument 'value' must be "string" or "number"</samp>
|
|
809
|
+
*
|
|
810
|
+
* @private
|
|
811
|
+
* @param {string} str - Value to be quoted.
|
|
812
|
+
* @returns {string} quoted value
|
|
813
|
+
* @example
|
|
814
|
+
* dQuote('number') // => "number"
|
|
815
|
+
*/
|
|
816
|
+
exports.dQuote = function(str) {
|
|
817
|
+
return '"' + str + '"';
|
|
818
|
+
};
|
|
819
|
+
|
|
820
|
+
/**
|
|
821
|
+
* Provides simplistic message translation for dealing with plurality.
|
|
822
|
+
*
|
|
823
|
+
* @description
|
|
824
|
+
* Use this to create messages which need to be singular or plural.
|
|
825
|
+
* Some languages have several plural forms, so _complete_ message clauses
|
|
826
|
+
* are preferable to generating the message on the fly.
|
|
827
|
+
*
|
|
828
|
+
* @private
|
|
829
|
+
* @param {number} n - Non-negative integer
|
|
830
|
+
* @param {string} msg1 - Message to be used in English for `n = 1`
|
|
831
|
+
* @param {string} msg2 - Message to be used in English for `n = 0, 2, 3, ...`
|
|
832
|
+
* @returns {string} message corresponding to value of `n`
|
|
833
|
+
* @example
|
|
834
|
+
* var sprintf = require('util').format;
|
|
835
|
+
* var pkgs = ['one', 'two'];
|
|
836
|
+
* var msg = sprintf(
|
|
837
|
+
* ngettext(
|
|
838
|
+
* pkgs.length,
|
|
839
|
+
* 'cannot load package: %s',
|
|
840
|
+
* 'cannot load packages: %s'
|
|
841
|
+
* ),
|
|
842
|
+
* pkgs.map(sQuote).join(', ')
|
|
843
|
+
* );
|
|
844
|
+
* console.log(msg); // => cannot load packages: 'one', 'two'
|
|
845
|
+
*/
|
|
846
|
+
exports.ngettext = function(n, msg1, msg2) {
|
|
847
|
+
if (typeof n === 'number' && n >= 0) {
|
|
848
|
+
return n === 1 ? msg1 : msg2;
|
|
849
|
+
}
|
|
850
|
+
};
|
|
851
|
+
|
|
709
852
|
/**
|
|
710
853
|
* It's a noop.
|
|
711
854
|
* @public
|
|
712
855
|
*/
|
|
713
856
|
exports.noop = function() {};
|
|
857
|
+
|
|
858
|
+
/**
|
|
859
|
+
* Creates a map-like object.
|
|
860
|
+
*
|
|
861
|
+
* @description
|
|
862
|
+
* A "map" is an object with no prototype, for our purposes. In some cases
|
|
863
|
+
* this would be more appropriate than a `Map`, especially if your environment
|
|
864
|
+
* doesn't support it. Recommended for use in Mocha's public APIs.
|
|
865
|
+
*
|
|
866
|
+
* @public
|
|
867
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map|MDN:Map}
|
|
868
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create#Custom_and_Null_objects|MDN:Object.create - Custom objects}
|
|
869
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign|MDN:Object.assign}
|
|
870
|
+
* @param {...*} [obj] - Arguments to `Object.assign()`.
|
|
871
|
+
* @returns {Object} An object with no prototype, having `...obj` properties
|
|
872
|
+
*/
|
|
873
|
+
exports.createMap = function(obj) {
|
|
874
|
+
return assign.apply(
|
|
875
|
+
null,
|
|
876
|
+
[Object.create(null)].concat(Array.prototype.slice.call(arguments))
|
|
877
|
+
);
|
|
878
|
+
};
|
|
879
|
+
|
|
880
|
+
/**
|
|
881
|
+
* Creates a read-only map-like object.
|
|
882
|
+
*
|
|
883
|
+
* @description
|
|
884
|
+
* This differs from {@link module:utils.createMap createMap} only in that
|
|
885
|
+
* the argument must be non-empty, because the result is frozen.
|
|
886
|
+
*
|
|
887
|
+
* @see {@link module:utils.createMap createMap}
|
|
888
|
+
* @param {...*} [obj] - Arguments to `Object.assign()`.
|
|
889
|
+
* @returns {Object} A frozen object with no prototype, having `...obj` properties
|
|
890
|
+
* @throws {TypeError} if argument is not a non-empty object.
|
|
891
|
+
*/
|
|
892
|
+
exports.defineConstants = function(obj) {
|
|
893
|
+
if (type(obj) !== 'object' || !Object.keys(obj).length) {
|
|
894
|
+
throw new TypeError('Invalid argument; expected a non-empty object');
|
|
895
|
+
}
|
|
896
|
+
return Object.freeze(exports.createMap(obj));
|
|
897
|
+
};
|