1e330c216SEvan Baconimport assert from 'assert'; 2dc51e206SEvan Baconimport { vol } from 'memfs'; 3dc51e206SEvan Baconimport path from 'path'; 4dc51e206SEvan Bacon 5dc51e206SEvan Baconimport { 6dc51e206SEvan Bacon writeAssetMapAsync, 7dc51e206SEvan Bacon writeBundlesAsync, 8dc51e206SEvan Bacon writeDebugHtmlAsync, 9dc51e206SEvan Bacon writeSourceMapsAsync, 10dc51e206SEvan Bacon} from '../writeContents'; 11dc51e206SEvan Bacon 12dc51e206SEvan Bacondescribe(writeDebugHtmlAsync, () => { 13dc51e206SEvan Bacon afterEach(() => { 14dc51e206SEvan Bacon vol.reset(); 15dc51e206SEvan Bacon }); 16dc51e206SEvan Bacon 17dc51e206SEvan Bacon it(`creates a debug html file`, async () => { 18dc51e206SEvan Bacon const projectRoot = '/'; 19dc51e206SEvan Bacon await writeDebugHtmlAsync({ 20dc51e206SEvan Bacon outputDir: projectRoot, 21dc51e206SEvan Bacon fileNames: { ios: 'index.ios.js', android: 'index.android.js', windows: 'index.windows.js' }, 22dc51e206SEvan Bacon }); 23dc51e206SEvan Bacon expect(vol.readFileSync(path.join(projectRoot, 'debug.html'), 'utf8')).toMatchSnapshot(); 24dc51e206SEvan Bacon }); 25dc51e206SEvan Bacon}); 26dc51e206SEvan Bacon 27dc51e206SEvan Bacondescribe(writeBundlesAsync, () => { 28dc51e206SEvan Bacon afterEach(() => { 29dc51e206SEvan Bacon vol.reset(); 30dc51e206SEvan Bacon }); 31dc51e206SEvan Bacon it(`writes JS bundles to disk`, async () => { 32dc51e206SEvan Bacon const projectRoot = '/'; 33dc51e206SEvan Bacon 34dc51e206SEvan Bacon const contents = `var foo = true;`; 35dc51e206SEvan Bacon const results = await writeBundlesAsync({ 36dc51e206SEvan Bacon outputDir: projectRoot, 37dc51e206SEvan Bacon bundles: { 38dc51e206SEvan Bacon ios: { 39dc51e206SEvan Bacon code: contents, 40dc51e206SEvan Bacon }, 41dc51e206SEvan Bacon android: { 42dc51e206SEvan Bacon code: contents, 43dc51e206SEvan Bacon }, 44dc51e206SEvan Bacon }, 45dc51e206SEvan Bacon }); 46dc51e206SEvan Bacon 47dc51e206SEvan Bacon expect(results.fileNames.android).toBeDefined(); 48dc51e206SEvan Bacon 49dc51e206SEvan Bacon expect(results.fileNames.ios).toBe('ios-4fe3891dcaca43901bd8797db78405e4.js'); 50dc51e206SEvan Bacon expect(results.hashes).toStrictEqual({ 51dc51e206SEvan Bacon ios: expect.any(String), 52dc51e206SEvan Bacon android: expect.any(String), 53dc51e206SEvan Bacon }); 54e330c216SEvan Bacon expect(vol.readFileSync(path.join(projectRoot, results.fileNames.ios!), 'utf8')).toBe(contents); 55dc51e206SEvan Bacon }); 56dc51e206SEvan Bacon it(`writes hbc bundles to disk`, async () => { 57dc51e206SEvan Bacon const projectRoot = '/'; 58dc51e206SEvan Bacon const contents = Uint8Array.from([1, 2, 3]); 59dc51e206SEvan Bacon const results = await writeBundlesAsync({ 60dc51e206SEvan Bacon outputDir: projectRoot, 61dc51e206SEvan Bacon bundles: { 62dc51e206SEvan Bacon ios: { 63dc51e206SEvan Bacon // this overwrites js code if present 64dc51e206SEvan Bacon hermesBytecodeBundle: contents, 65dc51e206SEvan Bacon code: 'var foo = true;', 66dc51e206SEvan Bacon }, 67dc51e206SEvan Bacon }, 68dc51e206SEvan Bacon }); 69dc51e206SEvan Bacon 70*864ec879SEvan Bacon expect(results.fileNames.ios).toBe('ios-5289df737df57326fcdd22597afb1fac.hbc'); 71dc51e206SEvan Bacon expect(results.hashes).toStrictEqual({ 72dc51e206SEvan Bacon ios: expect.any(String), 73dc51e206SEvan Bacon }); 74e330c216SEvan Bacon expect(vol.readFileSync(path.join(projectRoot, results.fileNames.ios!))).toBeDefined(); 75dc51e206SEvan Bacon }); 76dc51e206SEvan Bacon}); 77dc51e206SEvan Bacon 78dc51e206SEvan Bacondescribe(writeAssetMapAsync, () => { 79dc51e206SEvan Bacon afterEach(() => { 80dc51e206SEvan Bacon vol.reset(); 81dc51e206SEvan Bacon }); 82dc51e206SEvan Bacon it(`writes asset map to disk`, async () => { 83dc51e206SEvan Bacon const projectRoot = '/'; 84dc51e206SEvan Bacon 85dc51e206SEvan Bacon const results = await writeAssetMapAsync({ 86dc51e206SEvan Bacon outputDir: projectRoot, 87dc51e206SEvan Bacon assets: [{ hash: 'alpha' }, { hash: 'beta' }] as any, 88dc51e206SEvan Bacon }); 89dc51e206SEvan Bacon 90dc51e206SEvan Bacon expect(results).toStrictEqual({ 91dc51e206SEvan Bacon alpha: { hash: 'alpha' }, 92dc51e206SEvan Bacon beta: { hash: 'beta' }, 93dc51e206SEvan Bacon }); 94dc51e206SEvan Bacon 95dc51e206SEvan Bacon expect( 96dc51e206SEvan Bacon JSON.parse(vol.readFileSync(path.join(projectRoot, 'assetmap.json'), 'utf8') as string) 97dc51e206SEvan Bacon ).toBeDefined(); 98dc51e206SEvan Bacon }); 99dc51e206SEvan Bacon}); 100dc51e206SEvan Bacon 101dc51e206SEvan Bacondescribe(writeSourceMapsAsync, () => { 102dc51e206SEvan Bacon afterEach(() => { 103dc51e206SEvan Bacon vol.reset(); 104dc51e206SEvan Bacon }); 105dc51e206SEvan Bacon 106dc51e206SEvan Bacon it(`writes source maps to disk`, async () => { 107dc51e206SEvan Bacon const projectRoot = '/'; 108dc51e206SEvan Bacon 109dc51e206SEvan Bacon // User wrote this 110dc51e206SEvan Bacon const contents = `var foo = true;\ninvalid-source-map-comment`; 111dc51e206SEvan Bacon 112dc51e206SEvan Bacon // Metro made this 113dc51e206SEvan Bacon const bundles = { 114dc51e206SEvan Bacon ios: { 115dc51e206SEvan Bacon code: contents, 116dc51e206SEvan Bacon map: 'ios_map', 117dc51e206SEvan Bacon }, 118dc51e206SEvan Bacon android: { 119dc51e206SEvan Bacon code: contents, 120dc51e206SEvan Bacon map: 'android_map', 121dc51e206SEvan Bacon }, 122dc51e206SEvan Bacon }; 123dc51e206SEvan Bacon 124dc51e206SEvan Bacon // Expo persists the code and returns info 125dc51e206SEvan Bacon const jsResults = await writeBundlesAsync({ 126dc51e206SEvan Bacon outputDir: projectRoot, 127dc51e206SEvan Bacon bundles, 128dc51e206SEvan Bacon }); 129dc51e206SEvan Bacon 130dc51e206SEvan Bacon // Expo also modifies the source maps and persists 131dc51e206SEvan Bacon const results = await writeSourceMapsAsync({ 132dc51e206SEvan Bacon outputDir: projectRoot, 133dc51e206SEvan Bacon hashes: jsResults.hashes, 134dc51e206SEvan Bacon fileNames: jsResults.fileNames, 135dc51e206SEvan Bacon bundles, 136dc51e206SEvan Bacon }); 137dc51e206SEvan Bacon 138dc51e206SEvan Bacon for (const item of results) { 139e330c216SEvan Bacon assert(item); 140dc51e206SEvan Bacon expect(vol.readFileSync(path.join(projectRoot, item.fileName), 'utf8')).toBe(item.map); 141dc51e206SEvan Bacon expect( 142dc51e206SEvan Bacon vol.readFileSync(path.join(projectRoot, `${item.platform}-${item.hash}.js`), 'utf8') 143dc51e206SEvan Bacon ).toMatch(/\/\/# sourceMappingURL=/); 144dc51e206SEvan Bacon // // Removed by `removeOriginalSourceMappingUrl` 145dc51e206SEvan Bacon // expect( 146dc51e206SEvan Bacon // vol.readFileSync(path.join(projectRoot, `${item.platform}-${item.hash}.js`), 'utf8') 147dc51e206SEvan Bacon // ).not.toMatch(/invalid-source-map-comment/); 148dc51e206SEvan Bacon } 149dc51e206SEvan Bacon }); 150e330c216SEvan Bacon 151e330c216SEvan Bacon it(`skips writing when the map is not defined`, async () => { 152e330c216SEvan Bacon const projectRoot = '/'; 153e330c216SEvan Bacon 154e330c216SEvan Bacon // User wrote this 155e330c216SEvan Bacon const contents = `var foo = true;\ninvalid-source-map-comment`; 156e330c216SEvan Bacon 157e330c216SEvan Bacon // Metro made this 158e330c216SEvan Bacon const bundles = { 159e330c216SEvan Bacon ios: { 160e330c216SEvan Bacon code: contents, 161e330c216SEvan Bacon }, 162e330c216SEvan Bacon android: { 163e330c216SEvan Bacon code: contents, 164e330c216SEvan Bacon map: 'android_map', 165e330c216SEvan Bacon }, 166e330c216SEvan Bacon }; 167e330c216SEvan Bacon 168e330c216SEvan Bacon // Expo persists the code and returns info 169e330c216SEvan Bacon const jsResults = await writeBundlesAsync({ 170e330c216SEvan Bacon outputDir: projectRoot, 171e330c216SEvan Bacon bundles, 172e330c216SEvan Bacon }); 173e330c216SEvan Bacon 174e330c216SEvan Bacon // Expo also modifies the source maps and persists 175e330c216SEvan Bacon const results = await writeSourceMapsAsync({ 176e330c216SEvan Bacon outputDir: projectRoot, 177e330c216SEvan Bacon hashes: jsResults.hashes, 178e330c216SEvan Bacon fileNames: jsResults.fileNames, 179e330c216SEvan Bacon bundles, 180e330c216SEvan Bacon }); 181e330c216SEvan Bacon 182e330c216SEvan Bacon expect(results).toHaveLength(1); 183e330c216SEvan Bacon }); 184dc51e206SEvan Bacon}); 185