1/* eslint-env jest */ 2import JsonFile from '@expo/json-file'; 3import fs from 'fs/promises'; 4import klawSync from 'klaw-sync'; 5import path from 'path'; 6import execa from 'execa'; 7 8import { 9 execute, 10 projectRoot, 11 getRoot, 12 getLoadedModulesAsync, 13 bin, 14 setupTestProjectAsync, 15} from './utils'; 16 17const originalForceColor = process.env.FORCE_COLOR; 18beforeAll(async () => { 19 await fs.mkdir(projectRoot, { recursive: true }); 20 process.env.FORCE_COLOR = '0'; 21}); 22afterAll(() => { 23 process.env.FORCE_COLOR = originalForceColor; 24}); 25 26it('loads expected modules by default', async () => { 27 const modules = await getLoadedModulesAsync(`require('../../build/src/install').expoInstall`); 28 expect(modules).toStrictEqual([ 29 '../node_modules/ansi-styles/index.js', 30 '../node_modules/arg/index.js', 31 '../node_modules/chalk/source/index.js', 32 '../node_modules/chalk/source/util.js', 33 '../node_modules/has-flag/index.js', 34 '../node_modules/supports-color/index.js', 35 '@expo/cli/build/src/install/index.js', 36 '@expo/cli/build/src/log.js', 37 '@expo/cli/build/src/utils/args.js', 38 ]); 39}); 40 41it('runs `npx install install --help`', async () => { 42 const results = await execute('install', '--help'); 43 expect(results.stdout).toMatchInlineSnapshot(` 44 " 45 Description 46 Install a module or other package to a project 47 48 Usage 49 $ npx expo install [packages...] [options] 50 51 Options 52 --npm Use npm to install dependencies. Default when package-lock.json exists 53 --yarn Use Yarn to install dependencies. Default when yarn.lock exists 54 -h, --help Output usage information 55 56 Additional options can be passed to the underlying install command by using -- 57 $ expo install react -- --verbose 58 > yarn add react --verbose 59 " 60 `); 61}); 62 63it( 64 'runs `npx expo install expo-sms`', 65 async () => { 66 const projectRoot = await setupTestProjectAsync('basic-install', 'with-blank'); 67 // `npx expo install expo-sms` 68 await execa('node', [bin, 'install', 'expo-sms'], { cwd: projectRoot }); 69 70 // List output files with sizes for snapshotting. 71 // This is to make sure that any changes to the output are intentional. 72 // Posix path formatting is used to make paths the same across OSes. 73 const files = klawSync(projectRoot) 74 .map((entry) => { 75 if (entry.path.includes('node_modules') || !entry.stats.isFile()) { 76 return null; 77 } 78 return path.posix.relative(projectRoot, entry.path); 79 }) 80 .filter(Boolean); 81 82 const pkg = await JsonFile.readAsync(path.resolve(projectRoot, 'package.json')); 83 84 // Added expected package 85 expect(pkg.dependencies['expo-sms']).toBe('~10.1.0'); 86 expect(pkg.devDependencies).toEqual({ 87 '@babel/core': '^7.12.9', 88 }); 89 90 // Added new packages 91 expect(Object.keys(pkg.dependencies).sort()).toStrictEqual([ 92 'expo', 93 'expo-sms', 94 'react', 95 'react-native', 96 ]); 97 98 expect(files).toStrictEqual(['App.js', 'app.json', 'package.json', 'yarn.lock']); 99 }, 100 // Could take 45s depending on how fast npm installs 101 60 * 1000 102); 103