1/* eslint-env jest */ 2import execa from 'execa'; 3import { constants as fsConstants } from 'fs'; 4import fs from 'fs-extra'; 5import klawSync from 'klaw-sync'; 6import path from 'path'; 7 8import { execute, projectRoot, getLoadedModulesAsync, setupTestProjectAsync, bin } from './utils'; 9 10const originalForceColor = process.env.FORCE_COLOR; 11const originalCI = process.env.CI; 12const originalUseTypedRoutes = process.env._EXPO_E2E_USE_TYPED_ROUTES; 13 14const generatedFiles = ['tsconfig.json', 'expo-env.d.ts', '.expo/types/router.d.ts', '.gitignore']; 15 16beforeAll(async () => { 17 await fs.mkdir(projectRoot, { recursive: true }); 18 process.env.FORCE_COLOR = '0'; 19 process.env.CI = '1'; 20 process.env._EXPO_E2E_USE_TYPED_ROUTES = '1'; 21}); 22 23afterAll(async () => { 24 process.env.FORCE_COLOR = originalForceColor; 25 process.env.CI = originalCI; 26 process.env._EXPO_E2E_USE_TYPED_ROUTES = originalUseTypedRoutes; 27 28 // Remove the generated files 29 await Promise.all( 30 generatedFiles.map((file) => 31 fs.promises.rm(path.join(projectRoot, file), { recursive: true, force: true }) 32 ) 33 ); 34}); 35 36it('loads expected modules by default', async () => { 37 const modules = await getLoadedModulesAsync(`require('../../build/src/customize').expoCustomize`); 38 expect(modules).toStrictEqual([ 39 '../node_modules/ansi-styles/index.js', 40 '../node_modules/arg/index.js', 41 '../node_modules/chalk/source/index.js', 42 '../node_modules/chalk/source/util.js', 43 '../node_modules/has-flag/index.js', 44 '../node_modules/supports-color/index.js', 45 '@expo/cli/build/src/customize/index.js', 46 '@expo/cli/build/src/log.js', 47 '@expo/cli/build/src/utils/args.js', 48 ]); 49}); 50 51it('runs `npx expo customize --help`', async () => { 52 const results = await execute('customize', '--help'); 53 expect(results.stdout).toMatchInlineSnapshot(` 54 " 55 Info 56 Generate static project files 57 58 Usage 59 $ npx expo customize [files...] -- [options] 60 61 Options 62 [files...] List of files to generate 63 [options] Options to pass to the install command 64 -h, --help Usage info 65 " 66 `); 67}); 68 69it( 70 'runs `npx expo customize`', 71 async () => { 72 const projectRoot = await setupTestProjectAsync('basic-customize', 'with-blank'); 73 // `npx expo customize index.html serve.json babel.config.js` 74 await execa('node', [bin, 'customize', 'web/index.html', 'web/serve.json', 'babel.config.js'], { 75 cwd: projectRoot, 76 }); 77 78 const files = klawSync(projectRoot) 79 .map((entry) => { 80 if (entry.path.includes('node_modules') || !entry.stats.isFile()) { 81 return null; 82 } 83 return path.posix.relative(projectRoot, entry.path); 84 }) 85 .filter(Boolean); 86 87 expect(files).toEqual([ 88 'App.js', 89 'app.json', 90 'babel.config.js', 91 'package.json', 92 'web/index.html', 93 'web/serve.json', 94 'yarn.lock', 95 ]); 96 }, 97 // Could take 45s depending on how fast npm installs 98 120 * 1000 99); 100 101it( 102 'runs `npx expo customize tsconfig.json`', 103 async () => { 104 const projectRoot = await setupTestProjectAsync('expo-typescript', 'with-router', '48.0.0'); 105 106 // `npx expo typescript 107 await execa('node', [bin, 'customize', 'tsconfig.json'], { 108 cwd: projectRoot, 109 // env: { NODE_OPTIONS: '--inspect-brk' }, 110 }); 111 112 // Expect them to exist with correct access controls 113 for (const file of generatedFiles) { 114 await expect( 115 fs.promises.access(path.join(projectRoot, file), fsConstants.F_OK) 116 ).resolves.toBeUndefined(); 117 } 118 }, 119 // Could take 45s depending on how fast npm installs 120 120 * 1000 121); 122 123it( 124 'runs `npx expo customize tsconfig.json` on a partially setup project', 125 async () => { 126 const projectRoot = await setupTestProjectAsync('expo-typescript', 'with-router', '48.0.0'); 127 128 const existingTsConfig = { 129 extends: 'custom-package', 130 compilerOptions: { 131 strict: true, 132 }, 133 customOption: true, 134 include: ['custom'], 135 }; 136 137 // Write a tsconfig with partial data 138 await fs.promises.writeFile( 139 path.join(projectRoot, 'tsconfig.json'), 140 JSON.stringify(existingTsConfig) 141 ); 142 143 // `npx expo typescript 144 const a = await execa('node', [bin, 'customize', 'tsconfig.json'], { 145 cwd: projectRoot, 146 }); 147 148 const newTsconfig = await fs.promises.readFile( 149 path.join(projectRoot, 'tsconfig.json'), 150 'utf-8' 151 ); 152 153 expect(JSON.parse(newTsconfig)).toEqual({ 154 ...existingTsConfig, 155 include: ['custom', '.expo/types/**/*.ts', 'expo-env.d.ts'], 156 }); 157 }, 158 // Could take 45s depending on how fast npm installs 159 120 * 1000 160); 161