index.js 3.98 KB
Newer Older
Rosanny Sihombing's avatar
Rosanny Sihombing committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
'use strict';

var test = require('tape');
var keys = require('object-keys');
var semver = require('semver');
var mockProperty = require('mock-property');

var isCore = require('../');
var data = require('../core.json');

var supportsNodePrefix = semver.satisfies(process.versions.node, '^14.18 || >= 16', { includePrerelease: true });

test('core modules', function (t) {
	t.test('isCore()', function (st) {
		st.ok(isCore('fs'));
		st.ok(isCore('net'));
		st.ok(isCore('http'));

		st.ok(!isCore('seq'));
		st.ok(!isCore('../'));

		st.ok(!isCore('toString'));

		st.end();
	});

	t.test('core list', function (st) {
		var cores = keys(data);
		st.plan(cores.length);

		for (var i = 0; i < cores.length; ++i) {
			var mod = cores[i];
			var requireFunc = function () { require(mod); }; // eslint-disable-line no-loop-func
			if (isCore(mod)) {
				st.doesNotThrow(requireFunc, mod + ' supported; requiring does not throw');
			} else {
				st['throws'](requireFunc, mod + ' not supported; requiring throws');
			}
		}

		st.end();
	});

	t.test('core via repl module', { skip: !data.repl }, function (st) {
		var libs = require('repl')._builtinLibs; // eslint-disable-line no-underscore-dangle
		if (!libs) {
			st.skip('module.builtinModules does not exist');
		} else {
			for (var i = 0; i < libs.length; ++i) {
				var mod = libs[i];
				st.ok(data[mod], mod + ' is a core module');
				st.doesNotThrow(
					function () { require(mod); }, // eslint-disable-line no-loop-func
					'requiring ' + mod + ' does not throw'
				);
				if (mod.slice(0, 5) !== 'node:') {
					if (supportsNodePrefix) {
						st.doesNotThrow(
							function () { require('node:' + mod); }, // eslint-disable-line no-loop-func
							'requiring node:' + mod + ' does not throw'
						);
					} else {
						st['throws'](
							function () { require('node:' + mod); }, // eslint-disable-line no-loop-func
							'requiring node:' + mod + ' throws'
						);
					}
				}
			}
		}
		st.end();
	});

	t.test('core via builtinModules list', { skip: !data.module }, function (st) {
		var libs = require('module').builtinModules;
		if (!libs) {
			st.skip('module.builtinModules does not exist');
		} else {
			var excludeList = [
				'_debug_agent',
				'v8/tools/tickprocessor-driver',
				'v8/tools/SourceMap',
				'v8/tools/tickprocessor',
				'v8/tools/profile'
			];
			// see https://github.com/nodejs/node/issues/42785
			if (semver.satisfies(process.version, '>= 18')) {
				libs = libs.concat('node:test');
			}
			for (var i = 0; i < libs.length; ++i) {
				var mod = libs[i];
				if (excludeList.indexOf(mod) === -1) {
					st.ok(data[mod], mod + ' is a core module');
					st.doesNotThrow(
						function () { require(mod); }, // eslint-disable-line no-loop-func
						'requiring ' + mod + ' does not throw'
					);
					if (mod.slice(0, 5) !== 'node:') {
						if (supportsNodePrefix) {
							st.doesNotThrow(
								function () { require('node:' + mod); }, // eslint-disable-line no-loop-func
								'requiring node:' + mod + ' does not throw'
							);
						} else {
							st['throws'](
								function () { require('node:' + mod); }, // eslint-disable-line no-loop-func
								'requiring node:' + mod + ' throws'
							);
						}
					}
				}
			}
		}
		st.end();
	});

	t.test('Object.prototype pollution', function (st) {
		var nonKey = 'not a core module';
		st.teardown(mockProperty(Object.prototype, 'fs', { value: false }));
		st.teardown(mockProperty(Object.prototype, 'path', { value: '>= 999999999' }));
		st.teardown(mockProperty(Object.prototype, 'http', { value: data.http }));
		st.teardown(mockProperty(Object.prototype, nonKey, { value: true }));

		st.equal(isCore('fs'), true, 'fs is a core module even if Object.prototype lies');
		st.equal(isCore('path'), true, 'path is a core module even if Object.prototype lies');
		st.equal(isCore('http'), true, 'path is a core module even if Object.prototype matches data');
		st.equal(isCore(nonKey), false, '"' + nonKey + '" is not a core module even if Object.prototype lies');

		st.end();
	});

	t.end();
});