1'use strict'; 2// Flags: --expose-internals 3 4require('../common'); 5 6const { strictEqual, throws } = require('assert'); 7const { createModuleLoader } = require('internal/modules/esm/loader'); 8const { LoadCache, ResolveCache } = require('internal/modules/esm/module_map'); 9const ModuleJob = require('internal/modules/esm/module_job'); 10const createDynamicModule = require( 11 'internal/modules/esm/create_dynamic_module'); 12 13const jsModuleDataUrl = 'data:text/javascript,export{}'; 14const jsonModuleDataUrl = 'data:application/json,""'; 15 16const stubJsModule = createDynamicModule([], ['default'], jsModuleDataUrl); 17const stubJsonModule = createDynamicModule([], ['default'], jsonModuleDataUrl); 18 19const loader = createModuleLoader(false); 20const jsModuleJob = new ModuleJob(loader, stubJsModule.module, undefined, 21 () => new Promise(() => {})); 22const jsonModuleJob = new ModuleJob(loader, stubJsonModule.module, 23 { type: 'json' }, 24 () => new Promise(() => {})); 25 26 27// LoadCache.set and LoadCache.get store and retrieve module jobs for a 28// specified url/type tuple; LoadCache.has correctly reports whether such jobs 29// are stored in the map. 30{ 31 const moduleMap = new LoadCache(); 32 33 moduleMap.set(jsModuleDataUrl, undefined, jsModuleJob); 34 moduleMap.set(jsonModuleDataUrl, 'json', jsonModuleJob); 35 36 strictEqual(moduleMap.get(jsModuleDataUrl), jsModuleJob); 37 strictEqual(moduleMap.get(jsonModuleDataUrl, 'json'), jsonModuleJob); 38 39 strictEqual(moduleMap.has(jsModuleDataUrl), true); 40 strictEqual(moduleMap.has(jsModuleDataUrl, 'javascript'), true); 41 strictEqual(moduleMap.has(jsonModuleDataUrl, 'json'), true); 42 43 strictEqual(moduleMap.has('unknown'), false); 44 45 // The types must match 46 strictEqual(moduleMap.has(jsModuleDataUrl, 'json'), false); 47 strictEqual(moduleMap.has(jsonModuleDataUrl, 'javascript'), false); 48 strictEqual(moduleMap.has(jsonModuleDataUrl), false); 49 strictEqual(moduleMap.has(jsModuleDataUrl, 'unknown'), false); 50 strictEqual(moduleMap.has(jsonModuleDataUrl, 'unknown'), false); 51} 52 53// LoadCache.get, LoadCache.has and LoadCache.set should only accept string 54// values as url argument. 55{ 56 const moduleMap = new LoadCache(); 57 58 const errorObj = { 59 code: 'ERR_INVALID_ARG_TYPE', 60 name: 'TypeError', 61 message: /^The "url" argument must be of type string/ 62 }; 63 64 [{}, [], true, 1].forEach((value) => { 65 throws(() => moduleMap.get(value), errorObj); 66 throws(() => moduleMap.has(value), errorObj); 67 throws(() => moduleMap.set(value, undefined, jsModuleJob), errorObj); 68 }); 69} 70 71// LoadCache.get, LoadCache.has and LoadCache.set should only accept string 72// values (or the kAssertType symbol) as type argument. 73{ 74 const moduleMap = new LoadCache(); 75 76 const errorObj = { 77 code: 'ERR_INVALID_ARG_TYPE', 78 name: 'TypeError', 79 message: /^The "type" argument must be of type string/ 80 }; 81 82 [{}, [], true, 1].forEach((value) => { 83 throws(() => moduleMap.get(jsModuleDataUrl, value), errorObj); 84 throws(() => moduleMap.has(jsModuleDataUrl, value), errorObj); 85 throws(() => moduleMap.set(jsModuleDataUrl, value, jsModuleJob), errorObj); 86 }); 87} 88 89// LoadCache.set should only accept ModuleJob values as job argument. 90{ 91 const moduleMap = new LoadCache(); 92 93 [{}, [], true, 1].forEach((value) => { 94 throws(() => moduleMap.set('', undefined, value), { 95 code: 'ERR_INVALID_ARG_TYPE', 96 name: 'TypeError', 97 message: /^The "job" argument must be an instance of ModuleJob/ 98 }); 99 }); 100} 101 102{ 103 const resolveMap = new ResolveCache(); 104 105 strictEqual(resolveMap.serializeKey('./file', { __proto__: null }), './file::'); 106 strictEqual(resolveMap.serializeKey('./file', { __proto__: null, type: 'json' }), './file::"type""json"'); 107 strictEqual(resolveMap.serializeKey('./file::"type""json"', { __proto__: null }), './file::"type""json"::'); 108 strictEqual(resolveMap.serializeKey('./file', { __proto__: null, c: 'd', a: 'b' }), './file::"a""b","c""d"'); 109 strictEqual(resolveMap.serializeKey('./s', { __proto__: null, c: 'd', a: 'b', b: 'c' }), './s::"a""b","b""c","c""d"'); 110 111 resolveMap.set('key1', 'parent1', 1); 112 resolveMap.set('key2', 'parent1', 2); 113 resolveMap.set('key2', 'parent2', 3); 114 115 strictEqual(resolveMap.get('key1', 'parent1'), 1); 116 strictEqual(resolveMap.get('key2', 'parent1'), 2); 117 strictEqual(resolveMap.get('key2', 'parent2'), 3); 118} 119