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 32if (!process.env.NODE_PENDING_DEPRECATION) 33 process.on('warning', common.mustNotCall()); 34 35console.error('load test-module-loading.js'); 36 37assert.strictEqual(require.main.id, '.'); 38assert.strictEqual(require.main, module); 39assert.strictEqual(process.mainModule, module); 40 41// Assert that it's *not* the main module in the required module. 42require('../fixtures/not-main-module.js'); 43 44{ 45 // Require a file with a request that includes the extension 46 const a_js = require('../fixtures/a.js'); 47 assert.strictEqual(a_js.number, 42); 48} 49 50{ 51 // Require a file without any extensions 52 const foo_no_ext = require('../fixtures/foo'); 53 assert.strictEqual(foo_no_ext.foo, 'ok'); 54} 55 56const a = require('../fixtures/a'); 57const d = require('../fixtures/b/d'); 58const d2 = require('../fixtures/b/d'); 59 60{ 61 const c = require('../fixtures/b/c'); 62 // Absolute 63 const d3 = require(path.join(__dirname, '../fixtures/b/d')); 64 // Relative 65 const d4 = require('../fixtures/b/d'); 66 67 assert.ok(a.A instanceof Function); 68 assert.strictEqual(a.A(), 'A'); 69 70 assert.ok(a.C instanceof Function); 71 assert.strictEqual(a.C(), 'C'); 72 73 assert.ok(a.D instanceof Function); 74 assert.strictEqual(a.D(), 'D'); 75 76 assert.ok(d.D instanceof Function); 77 assert.strictEqual(d.D(), 'D'); 78 79 assert.ok(d2.D instanceof Function); 80 assert.strictEqual(d2.D(), 'D'); 81 82 assert.ok(d3.D instanceof Function); 83 assert.strictEqual(d3.D(), 'D'); 84 85 assert.ok(d4.D instanceof Function); 86 assert.strictEqual(d4.D(), 'D'); 87 88 assert.ok((new a.SomeClass()) instanceof c.SomeClass); 89} 90 91{ 92 console.error('test index.js modules ids and relative loading'); 93 const one = require('../fixtures/nested-index/one'); 94 const two = require('../fixtures/nested-index/two'); 95 assert.notStrictEqual(one.hello, two.hello); 96} 97 98{ 99 console.error('test index.js in a folder with a trailing slash'); 100 const three = require('../fixtures/nested-index/three'); 101 const threeFolder = require('../fixtures/nested-index/three/'); 102 const threeIndex = require('../fixtures/nested-index/three/index.js'); 103 assert.strictEqual(threeFolder, threeIndex); 104 assert.notStrictEqual(threeFolder, three); 105} 106 107assert.strictEqual(require('../fixtures/packages/index').ok, 'ok'); 108assert.strictEqual(require('../fixtures/packages/main').ok, 'ok'); 109assert.strictEqual(require('../fixtures/packages/main-index').ok, 'ok'); 110assert.strictEqual(require('../fixtures/packages/missing-main').ok, 'ok'); 111assert.throws( 112 () => require('../fixtures/packages/missing-main-no-index'), 113 { 114 code: 'MODULE_NOT_FOUND', 115 message: /packages[/\\]missing-main-no-index[/\\]doesnotexist\.js'\. Please.+package\.json.+valid "main"/, 116 path: /fixtures[/\\]packages[/\\]missing-main-no-index[/\\]package\.json/, 117 requestPath: /^\.\.[/\\]fixtures[/\\]packages[/\\]missing-main-no-index$/ 118 } 119); 120 121assert.throws( 122 function() { require('../fixtures/packages/unparseable'); }, 123 /^SyntaxError: Error parsing/ 124); 125 126{ 127 console.error('test cycles containing a .. path'); 128 const root = require('../fixtures/cycles/root'); 129 const foo = require('../fixtures/cycles/folder/foo'); 130 assert.strictEqual(root.foo, foo); 131 assert.strictEqual(root.sayHello(), root.hello); 132} 133 134console.error('test node_modules folders'); 135// Asserts are in the fixtures files themselves, 136// since they depend on the folder structure. 137require('../fixtures/node_modules/foo'); 138 139{ 140 console.error('test name clashes'); 141 // This one exists and should import the local module 142 const my_path = require('../fixtures/path'); 143 assert.ok(my_path.path_func instanceof Function); 144 // This one does not exist and should throw 145 assert.throws(function() { require('./utils'); }, 146 /^Error: Cannot find module '\.\/utils'/); 147} 148 149let errorThrown = false; 150try { 151 require('../fixtures/throws_error'); 152} catch (e) { 153 errorThrown = true; 154 assert.strictEqual(e.message, 'blah'); 155} 156 157assert.strictEqual(path.dirname(__filename), __dirname); 158 159console.error('load custom file types with extensions'); 160require.extensions['.test'] = function(module, filename) { 161 let content = fs.readFileSync(filename).toString(); 162 assert.strictEqual(content, 'this is custom source\n'); 163 content = content.replace('this is custom source', 164 'exports.test = \'passed\''); 165 module._compile(content, filename); 166}; 167 168assert.strictEqual(require('../fixtures/registerExt').test, 'passed'); 169// Unknown extension, load as .js 170assert.strictEqual(require('../fixtures/registerExt.hello.world').test, 171 'passed'); 172 173console.error('load custom file types that return non-strings'); 174require.extensions['.test'] = function(module) { 175 module.exports = { 176 custom: 'passed' 177 }; 178}; 179 180assert.strictEqual(require('../fixtures/registerExt2').custom, 'passed'); 181 182assert.strictEqual(require('../fixtures/foo').foo, 'ok'); 183 184// Should not attempt to load a directory 185assert.throws( 186 () => { 187 tmpdir.refresh(); 188 require(tmpdir.path); 189 }, 190 (err) => err.message.startsWith(`Cannot find module '${tmpdir.path}`) 191); 192 193{ 194 // Check load order is as expected 195 console.error('load order'); 196 197 const loadOrder = '../fixtures/module-load-order/'; 198 199 require.extensions['.reg'] = require.extensions['.js']; 200 require.extensions['.reg2'] = require.extensions['.js']; 201 202 assert.strictEqual(require(`${loadOrder}file1`).file1, 'file1'); 203 assert.strictEqual(require(`${loadOrder}file2`).file2, 'file2.js'); 204 assert.throws( 205 () => require(`${loadOrder}file3`), 206 (e) => { 207 // Not a real .node module, but we know we require'd the right thing. 208 if (common.isOpenBSD) { // OpenBSD errors with non-ELF object error 209 assert.ok(/File not an ELF object/.test(e.message.replace(backslash, '/'))); 210 } else { 211 assert.ok(/file3\.node/.test(e.message.replace(backslash, '/'))); 212 } 213 return true; 214 } 215 ); 216 217 assert.strictEqual(require(`${loadOrder}file4`).file4, 'file4.reg'); 218 assert.strictEqual(require(`${loadOrder}file5`).file5, 'file5.reg2'); 219 assert.strictEqual(require(`${loadOrder}file6`).file6, 'file6/index.js'); 220 assert.throws( 221 () => require(`${loadOrder}file7`), 222 (e) => { 223 if (common.isOpenBSD) { 224 assert.ok(/File not an ELF object/.test(e.message.replace(backslash, '/'))); 225 } else { 226 assert.ok(/file7\/index\.node/.test(e.message.replace(backslash, '/'))); 227 } 228 return true; 229 } 230 ); 231 232 assert.strictEqual(require(`${loadOrder}file8`).file8, 'file8/index.reg'); 233 assert.strictEqual(require(`${loadOrder}file9`).file9, 'file9/index.reg2'); 234} 235 236{ 237 // Make sure that module.require() is the same as 238 // doing require() inside of that module. 239 const parent = require('../fixtures/module-require/parent/'); 240 const child = require('../fixtures/module-require/child/'); 241 assert.strictEqual(child.loaded, parent.loaded); 242} 243 244{ 245 // Loading JSON files with require() 246 // See https://github.com/nodejs/node-v0.x-archive/issues/1357. 247 const json = require('../fixtures/packages/main/package.json'); 248 assert.deepStrictEqual(json, { 249 name: 'package-name', 250 version: '1.2.3', 251 main: 'package-main-module' 252 }); 253} 254 255 256{ 257 // Now verify that module.children contains all the different 258 // modules that we've required, and that all of them contain 259 // the appropriate children, and so on. 260 261 const visited = new Set(); 262 const children = module.children.reduce(function red(set, child) { 263 if (visited.has(child)) return set; 264 visited.add(child); 265 let id = path.relative(path.dirname(__dirname), child.id); 266 id = id.replace(backslash, '/'); 267 set[id] = child.children.reduce(red, {}); 268 return set; 269 }, {}); 270 271 assert.deepStrictEqual(children, { 272 'common/index.js': { 273 'common/tmpdir.js': {} 274 }, 275 'fixtures/not-main-module.js': {}, 276 'fixtures/a.js': { 277 'fixtures/b/c.js': { 278 'fixtures/b/d.js': {}, 279 'fixtures/b/package/index.js': {} 280 } 281 }, 282 'fixtures/foo': {}, 283 'fixtures/nested-index/one/index.js': { 284 'fixtures/nested-index/one/hello.js': {} 285 }, 286 'fixtures/nested-index/two/index.js': { 287 'fixtures/nested-index/two/hello.js': {} 288 }, 289 'fixtures/nested-index/three.js': {}, 290 'fixtures/nested-index/three/index.js': {}, 291 'fixtures/packages/index/index.js': {}, 292 'fixtures/packages/main/package-main-module.js': {}, 293 'fixtures/packages/main-index/package-main-module/index.js': {}, 294 'fixtures/packages/missing-main/index.js': {}, 295 'fixtures/cycles/root.js': { 296 'fixtures/cycles/folder/foo.js': {} 297 }, 298 'fixtures/node_modules/foo.js': { 299 'fixtures/node_modules/baz/index.js': { 300 'fixtures/node_modules/bar.js': {}, 301 'fixtures/node_modules/baz/node_modules/asdf.js': {} 302 } 303 }, 304 'fixtures/path.js': {}, 305 'fixtures/registerExt.test': {}, 306 'fixtures/registerExt.hello.world': {}, 307 'fixtures/registerExt2.test': {}, 308 'fixtures/module-load-order/file1': {}, 309 'fixtures/module-load-order/file2.js': {}, 310 'fixtures/module-load-order/file4.reg': {}, 311 'fixtures/module-load-order/file5.reg2': {}, 312 'fixtures/module-load-order/file6/index.js': {}, 313 'fixtures/module-load-order/file8/index.reg': {}, 314 'fixtures/module-load-order/file9/index.reg2': {}, 315 'fixtures/module-require/parent/index.js': { 316 'fixtures/module-require/child/index.js': { 317 'fixtures/module-require/child/node_modules/target.js': {} 318 } 319 }, 320 'fixtures/packages/main/package.json': {} 321 }); 322} 323 324 325process.on('exit', function() { 326 assert.ok(a.A instanceof Function); 327 assert.strictEqual(a.A(), 'A done'); 328 329 assert.ok(a.C instanceof Function); 330 assert.strictEqual(a.C(), 'C done'); 331 332 assert.ok(a.D instanceof Function); 333 assert.strictEqual(a.D(), 'D done'); 334 335 assert.ok(d.D instanceof Function); 336 assert.strictEqual(d.D(), 'D done'); 337 338 assert.ok(d2.D instanceof Function); 339 assert.strictEqual(d2.D(), 'D done'); 340 341 assert.strictEqual(errorThrown, true); 342 343 console.log('exit'); 344}); 345 346 347// Loading files with a byte order marker. 348// See https://github.com/nodejs/node-v0.x-archive/issues/1440. 349assert.strictEqual(require('../fixtures/utf8-bom.js'), 42); 350assert.strictEqual(require('../fixtures/utf8-bom.json'), 42); 351 352// Loading files with BOM + shebang. 353// See https://github.com/nodejs/node/issues/27767 354assert.throws(() => { 355 require('../fixtures/utf8-bom-shebang-shebang.js'); 356}, { name: 'SyntaxError' }); 357assert.strictEqual(require('../fixtures/utf8-shebang-bom.js'), 42); 358 359// Error on the first line of a module should 360// have the correct line number 361assert.throws(function() { 362 require('../fixtures/test-error-first-line-offset.js'); 363}, function(err) { 364 return /test-error-first-line-offset\.js:1:/.test(err.stack); 365}, 'Expected appearance of proper offset in Error stack'); 366