1'use strict'; 2 3var test = require('tape'); 4var keys = require('object-keys'); 5var semver = require('semver'); 6var mockProperty = require('mock-property'); 7 8var isCore = require('../'); 9var data = require('../core.json'); 10 11var supportsNodePrefix = semver.satisfies(process.versions.node, '^14.18 || >= 16', { includePrerelease: true }); 12 13test('core modules', function (t) { 14 t.test('isCore()', function (st) { 15 st.ok(isCore('fs')); 16 st.ok(isCore('net')); 17 st.ok(isCore('http')); 18 19 st.ok(!isCore('seq')); 20 st.ok(!isCore('../')); 21 22 st.ok(!isCore('toString')); 23 24 st.end(); 25 }); 26 27 t.test('core list', function (st) { 28 var cores = keys(data); 29 st.plan(cores.length); 30 31 for (var i = 0; i < cores.length; ++i) { 32 var mod = cores[i]; 33 var requireFunc = function () { require(mod); }; // eslint-disable-line no-loop-func 34 if (isCore(mod)) { 35 st.doesNotThrow(requireFunc, mod + ' supported; requiring does not throw'); 36 } else { 37 st['throws'](requireFunc, mod + ' not supported; requiring throws'); 38 } 39 } 40 41 st.end(); 42 }); 43 44 t.test('core via repl module', { skip: !data.repl }, function (st) { 45 var libs = require('repl')._builtinLibs; // eslint-disable-line no-underscore-dangle 46 if (!libs) { 47 st.skip('repl._builtinLibs does not exist'); 48 } else { 49 for (var i = 0; i < libs.length; ++i) { 50 var mod = libs[i]; 51 st.ok(data[mod], mod + ' is a core module'); 52 st.doesNotThrow( 53 function () { require(mod); }, // eslint-disable-line no-loop-func 54 'requiring ' + mod + ' does not throw' 55 ); 56 if (mod.slice(0, 5) !== 'node:') { 57 if (supportsNodePrefix) { 58 st.doesNotThrow( 59 function () { require('node:' + mod); }, // eslint-disable-line no-loop-func 60 'requiring node:' + mod + ' does not throw' 61 ); 62 } else { 63 st['throws']( 64 function () { require('node:' + mod); }, // eslint-disable-line no-loop-func 65 'requiring node:' + mod + ' throws' 66 ); 67 } 68 } 69 } 70 } 71 st.end(); 72 }); 73 74 t.test('core via builtinModules list', { skip: !data.module }, function (st) { 75 var libs = require('module').builtinModules; 76 if (!libs) { 77 st.skip('module.builtinModules does not exist'); 78 } else { 79 var excludeList = [ 80 '_debug_agent', 81 'v8/tools/tickprocessor-driver', 82 'v8/tools/SourceMap', 83 'v8/tools/tickprocessor', 84 'v8/tools/profile' 85 ]; 86 // see https://github.com/nodejs/node/issues/42785 87 if (semver.satisfies(process.version, '>= 18')) { 88 libs = libs.concat('node:test'); 89 } 90 for (var i = 0; i < libs.length; ++i) { 91 var mod = libs[i]; 92 if (excludeList.indexOf(mod) === -1) { 93 st.ok(data[mod], mod + ' is a core module'); 94 st.doesNotThrow( 95 function () { require(mod); }, // eslint-disable-line no-loop-func 96 'requiring ' + mod + ' does not throw' 97 ); 98 if (mod.slice(0, 5) !== 'node:') { 99 if (supportsNodePrefix) { 100 st.doesNotThrow( 101 function () { require('node:' + mod); }, // eslint-disable-line no-loop-func 102 'requiring node:' + mod + ' does not throw' 103 ); 104 } else { 105 st['throws']( 106 function () { require('node:' + mod); }, // eslint-disable-line no-loop-func 107 'requiring node:' + mod + ' throws' 108 ); 109 } 110 } 111 } 112 } 113 } 114 st.end(); 115 }); 116 117 t.test('Object.prototype pollution', function (st) { 118 var nonKey = 'not a core module'; 119 st.teardown(mockProperty(Object.prototype, 'fs', { value: false })); 120 st.teardown(mockProperty(Object.prototype, 'path', { value: '>= 999999999' })); 121 st.teardown(mockProperty(Object.prototype, 'http', { value: data.http })); 122 st.teardown(mockProperty(Object.prototype, nonKey, { value: true })); 123 124 st.equal(isCore('fs'), true, 'fs is a core module even if Object.prototype lies'); 125 st.equal(isCore('path'), true, 'path is a core module even if Object.prototype lies'); 126 st.equal(isCore('http'), true, 'path is a core module even if Object.prototype matches data'); 127 st.equal(isCore(nonKey), false, '"' + nonKey + '" is not a core module even if Object.prototype lies'); 128 129 st.end(); 130 }); 131 132 t.end(); 133}); 134