1// Copyright Joyent, Inc. and other Node contributors. 2// 3// Permission is hereby granted, free of charge, to any person obtaining a 4// copy of this software and associated documentation files (the 5// "Software"), to deal in the Software without restriction, including 6// without limitation the rights to use, copy, modify, merge, publish, 7// distribute, sublicense, and/or sell copies of the Software, and to permit 8// persons to whom the Software is furnished to do so, subject to the 9// following conditions: 10// 11// The above copyright notice and this permission notice shall be included 12// in all copies or substantial portions of the Software. 13// 14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20// USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22'use strict'; 23const common = require('../common'); 24const tmpdir = require('../common/tmpdir'); 25 26const assert = require('assert'); 27const fs = require('fs'); 28const path = require('path'); 29 30const backslash = /\\/g; 31 32process.on('warning', common.mustCall()); 33 34console.error('load test-module-loading.js'); 35 36assert.strictEqual(require.main.id, '.'); 37assert.strictEqual(require.main, module); 38assert.strictEqual(process.mainModule, module); 39 40// Assert that it's *not* the main module in the required module. 41require('../fixtures/not-main-module.js'); 42 43{ 44 // Require a file with a request that includes the extension 45 const a_js = require('../fixtures/a.js'); 46 assert.strictEqual(a_js.number, 42); 47} 48 49{ 50 // Require a file without any extensions 51 const foo_no_ext = require('../fixtures/foo'); 52 assert.strictEqual(foo_no_ext.foo, 'ok'); 53} 54 55const a = require('../fixtures/a'); 56const d = require('../fixtures/b/d'); 57const d2 = require('../fixtures/b/d'); 58 59{ 60 const c = require('../fixtures/b/c'); 61 // Absolute 62 const d3 = require(path.join(__dirname, '../fixtures/b/d')); 63 // Relative 64 const d4 = require('../fixtures/b/d'); 65 66 assert.ok(a.A instanceof Function); 67 assert.strictEqual(a.A(), 'A'); 68 69 assert.ok(a.C instanceof Function); 70 assert.strictEqual(a.C(), 'C'); 71 72 assert.ok(a.D instanceof Function); 73 assert.strictEqual(a.D(), 'D'); 74 75 assert.ok(d.D instanceof Function); 76 assert.strictEqual(d.D(), 'D'); 77 78 assert.ok(d2.D instanceof Function); 79 assert.strictEqual(d2.D(), 'D'); 80 81 assert.ok(d3.D instanceof Function); 82 assert.strictEqual(d3.D(), 'D'); 83 84 assert.ok(d4.D instanceof Function); 85 assert.strictEqual(d4.D(), 'D'); 86 87 assert.ok((new a.SomeClass()) instanceof c.SomeClass); 88} 89 90{ 91 console.error('test index.js modules ids and relative loading'); 92 const one = require('../fixtures/nested-index/one'); 93 const two = require('../fixtures/nested-index/two'); 94 assert.notStrictEqual(one.hello, two.hello); 95} 96 97{ 98 console.error('test index.js in a folder with a trailing slash'); 99 const three = require('../fixtures/nested-index/three'); 100 const threeFolder = require('../fixtures/nested-index/three/'); 101 const threeIndex = require('../fixtures/nested-index/three/index.js'); 102 assert.strictEqual(threeFolder, threeIndex); 103 assert.notStrictEqual(threeFolder, three); 104} 105 106assert.strictEqual(require('../fixtures/packages/index').ok, 'ok'); 107assert.strictEqual(require('../fixtures/packages/main').ok, 'ok'); 108assert.strictEqual(require('../fixtures/packages/main-index').ok, 'ok'); 109 110common.expectWarning( 111 'DeprecationWarning', 112 "Invalid 'main' field in '" + 113 require.resolve('../fixtures/packages/missing-main/package.json') + 114 "' of 'doesnotexist.js'. Please either fix that or report it to the" + 115 ' module author', 116 'DEP0128'); 117assert.strictEqual(require('../fixtures/packages/missing-main').ok, 'ok'); 118 119assert.throws( 120 () => require('../fixtures/packages/missing-main-no-index'), 121 { 122 code: 'MODULE_NOT_FOUND', 123 message: /packages[/\\]missing-main-no-index[/\\]doesnotexist\.js'\. Please.+package\.json.+valid "main"/, 124 path: /fixtures[/\\]packages[/\\]missing-main-no-index[/\\]package\.json/, 125 requestPath: /^\.\.[/\\]fixtures[/\\]packages[/\\]missing-main-no-index$/ 126 } 127); 128 129assert.throws( 130 function() { require('../fixtures/packages/unparseable'); }, 131 /^SyntaxError: Error parsing/ 132); 133 134{ 135 console.error('test cycles containing a .. path'); 136 const root = require('../fixtures/cycles/root'); 137 const foo = require('../fixtures/cycles/folder/foo'); 138 assert.strictEqual(root.foo, foo); 139 assert.strictEqual(root.sayHello(), root.hello); 140} 141 142console.error('test node_modules folders'); 143// Asserts are in the fixtures files themselves, 144// since they depend on the folder structure. 145require('../fixtures/node_modules/foo'); 146 147{ 148 console.error('test name clashes'); 149 // This one exists and should import the local module 150 const my_path = require('../fixtures/path'); 151 assert.ok(my_path.path_func instanceof Function); 152 // This one does not exist and should throw 153 assert.throws(function() { require('./utils'); }, 154 /^Error: Cannot find module '\.\/utils'/); 155} 156 157let errorThrown = false; 158try { 159 require('../fixtures/throws_error'); 160} catch (e) { 161 errorThrown = true; 162 assert.strictEqual(e.message, 'blah'); 163} 164 165assert.strictEqual(path.dirname(__filename), __dirname); 166 167console.error('load custom file types with extensions'); 168require.extensions['.test'] = function(module, filename) { 169 let content = fs.readFileSync(filename).toString(); 170 assert.strictEqual(content, 'this is custom source\n'); 171 content = content.replace('this is custom source', 172 'exports.test = \'passed\''); 173 module._compile(content, filename); 174}; 175 176assert.strictEqual(require('../fixtures/registerExt').test, 'passed'); 177// Unknown extension, load as .js 178assert.strictEqual(require('../fixtures/registerExt.hello.world').test, 179 'passed'); 180 181console.error('load custom file types that return non-strings'); 182require.extensions['.test'] = function(module) { 183 module.exports = { 184 custom: 'passed' 185 }; 186}; 187 188assert.strictEqual(require('../fixtures/registerExt2').custom, 'passed'); 189 190assert.strictEqual(require('../fixtures/foo').foo, 'ok'); 191 192// Should not attempt to load a directory 193assert.throws( 194 () => { 195 tmpdir.refresh(); 196 require(tmpdir.path); 197 }, 198 (err) => err.message.startsWith(`Cannot find module '${tmpdir.path}`) 199); 200 201{ 202 // Check load order is as expected 203 console.error('load order'); 204 205 const loadOrder = '../fixtures/module-load-order/'; 206 207 require.extensions['.reg'] = require.extensions['.js']; 208 require.extensions['.reg2'] = require.extensions['.js']; 209 210 assert.strictEqual(require(`${loadOrder}file1`).file1, 'file1'); 211 assert.strictEqual(require(`${loadOrder}file2`).file2, 'file2.js'); 212 assert.throws( 213 () => require(`${loadOrder}file3`), 214 (e) => { 215 // Not a real .node module, but we know we require'd the right thing. 216 if (common.isOpenBSD) { // OpenBSD errors with non-ELF object error 217 assert.match(e.message, /File not an ELF object/); 218 } else { 219 assert.match(e.message, /file3\.node/); 220 } 221 return true; 222 } 223 ); 224 225 assert.strictEqual(require(`${loadOrder}file4`).file4, 'file4.reg'); 226 assert.strictEqual(require(`${loadOrder}file5`).file5, 'file5.reg2'); 227 assert.strictEqual(require(`${loadOrder}file6`).file6, 'file6/index.js'); 228 assert.throws( 229 () => require(`${loadOrder}file7`), 230 (e) => { 231 if (common.isOpenBSD) { 232 assert.match(e.message, /File not an ELF object/); 233 } else { 234 assert.match(e.message.replace(backslash, '/'), /file7\/index\.node/); 235 } 236 return true; 237 } 238 ); 239 240 assert.strictEqual(require(`${loadOrder}file8`).file8, 'file8/index.reg'); 241 assert.strictEqual(require(`${loadOrder}file9`).file9, 'file9/index.reg2'); 242} 243 244{ 245 // Make sure that module.require() is the same as 246 // doing require() inside of that module. 247 const parent = require('../fixtures/module-require/parent/'); 248 const child = require('../fixtures/module-require/child/'); 249 assert.strictEqual(child.loaded, parent.loaded); 250} 251 252{ 253 // Loading JSON files with require() 254 // See https://github.com/nodejs/node-v0.x-archive/issues/1357. 255 const json = require('../fixtures/packages/main/package.json'); 256 assert.deepStrictEqual(json, { 257 name: 'package-name', 258 version: '1.2.3', 259 main: 'package-main-module' 260 }); 261} 262 263 264{ 265 // Now verify that module.children contains all the different 266 // modules that we've required, and that all of them contain 267 // the appropriate children, and so on. 268 269 const visited = new Set(); 270 const children = module.children.reduce(function red(set, child) { 271 if (visited.has(child)) return set; 272 visited.add(child); 273 let id = path.relative(path.dirname(__dirname), child.id); 274 id = id.replace(backslash, '/'); 275 set[id] = child.children.reduce(red, {}); 276 return set; 277 }, {}); 278 279 assert.deepStrictEqual(children, { 280 'common/index.js': { 281 'common/tmpdir.js': {} 282 }, 283 'fixtures/not-main-module.js': {}, 284 'fixtures/a.js': { 285 'fixtures/b/c.js': { 286 'fixtures/b/d.js': {}, 287 'fixtures/b/package/index.js': {} 288 } 289 }, 290 'fixtures/foo': {}, 291 'fixtures/nested-index/one/index.js': { 292 'fixtures/nested-index/one/hello.js': {} 293 }, 294 'fixtures/nested-index/two/index.js': { 295 'fixtures/nested-index/two/hello.js': {} 296 }, 297 'fixtures/nested-index/three.js': {}, 298 'fixtures/nested-index/three/index.js': {}, 299 'fixtures/packages/index/index.js': {}, 300 'fixtures/packages/main/package-main-module.js': {}, 301 'fixtures/packages/main-index/package-main-module/index.js': {}, 302 'fixtures/packages/missing-main/index.js': {}, 303 'fixtures/cycles/root.js': { 304 'fixtures/cycles/folder/foo.js': {} 305 }, 306 'fixtures/node_modules/foo.js': { 307 'fixtures/node_modules/baz/index.js': { 308 'fixtures/node_modules/bar.js': {}, 309 'fixtures/node_modules/baz/node_modules/asdf.js': {} 310 } 311 }, 312 'fixtures/path.js': {}, 313 'fixtures/registerExt.test': {}, 314 'fixtures/registerExt.hello.world': {}, 315 'fixtures/registerExt2.test': {}, 316 'fixtures/module-load-order/file1': {}, 317 'fixtures/module-load-order/file2.js': {}, 318 'fixtures/module-load-order/file4.reg': {}, 319 'fixtures/module-load-order/file5.reg2': {}, 320 'fixtures/module-load-order/file6/index.js': {}, 321 'fixtures/module-load-order/file8/index.reg': {}, 322 'fixtures/module-load-order/file9/index.reg2': {}, 323 'fixtures/module-require/parent/index.js': { 324 'fixtures/module-require/child/index.js': { 325 'fixtures/module-require/child/node_modules/target.js': {} 326 } 327 }, 328 'fixtures/packages/main/package.json': {} 329 }); 330} 331 332 333process.on('exit', function() { 334 assert.ok(a.A instanceof Function); 335 assert.strictEqual(a.A(), 'A done'); 336 337 assert.ok(a.C instanceof Function); 338 assert.strictEqual(a.C(), 'C done'); 339 340 assert.ok(a.D instanceof Function); 341 assert.strictEqual(a.D(), 'D done'); 342 343 assert.ok(d.D instanceof Function); 344 assert.strictEqual(d.D(), 'D done'); 345 346 assert.ok(d2.D instanceof Function); 347 assert.strictEqual(d2.D(), 'D done'); 348 349 assert.strictEqual(errorThrown, true); 350 351 console.log('exit'); 352}); 353 354 355// Loading files with a byte order marker. 356// See https://github.com/nodejs/node-v0.x-archive/issues/1440. 357assert.strictEqual(require('../fixtures/utf8-bom.js'), 42); 358assert.strictEqual(require('../fixtures/utf8-bom.json'), 42); 359 360// Loading files with BOM + shebang. 361// See https://github.com/nodejs/node/issues/27767 362assert.throws(() => { 363 require('../fixtures/utf8-bom-shebang-shebang.js'); 364}, { name: 'SyntaxError' }); 365assert.strictEqual(require('../fixtures/utf8-shebang-bom.js'), 42); 366 367// Error on the first line of a module should 368// have the correct line number 369assert.throws(function() { 370 require('../fixtures/test-error-first-line-offset.js'); 371}, function(err) { 372 return /test-error-first-line-offset\.js:1:/.test(err.stack); 373}, 'Expected appearance of proper offset in Error stack'); 374