1/* eslint-env jest */ 2import JsonFile from '@expo/json-file'; 3import execa from 'execa'; 4import fs from 'fs/promises'; 5import klawSync from 'klaw-sync'; 6import path from 'path'; 7 8import { 9 bin, 10 execute, 11 projectRoot, 12 getRoot, 13 setupTestProjectAsync, 14 getLoadedModulesAsync, 15} from './utils'; 16 17const originalForceColor = process.env.FORCE_COLOR; 18const originalCI = process.env.CI; 19 20beforeAll(async () => { 21 await fs.mkdir(projectRoot, { recursive: true }); 22 process.env.FORCE_COLOR = '0'; 23 process.env.CI = '1'; 24}); 25 26afterAll(() => { 27 process.env.FORCE_COLOR = originalForceColor; 28 process.env.CI = originalCI; 29}); 30 31it('loads expected modules by default', async () => { 32 const modules = await getLoadedModulesAsync(`require('../../build/src/prebuild').expoPrebuild`); 33 expect(modules).toStrictEqual([ 34 '../node_modules/ansi-styles/index.js', 35 '../node_modules/arg/index.js', 36 '../node_modules/chalk/source/index.js', 37 '../node_modules/chalk/source/util.js', 38 '../node_modules/has-flag/index.js', 39 '../node_modules/supports-color/index.js', 40 '@expo/cli/build/src/log.js', 41 '@expo/cli/build/src/prebuild/index.js', 42 '@expo/cli/build/src/utils/args.js', 43 ]); 44}); 45 46it('runs `npx expo prebuild --help`', async () => { 47 const results = await execute('prebuild', '--help'); 48 expect(results.stdout).toMatchInlineSnapshot(` 49 " 50 Info 51 Create native iOS and Android project files for building natively 52 53 Usage 54 $ npx expo prebuild <dir> 55 56 Options 57 <dir> Directory of the Expo project. Default: Current working directory 58 --no-install Skip installing npm packages and CocoaPods 59 --clean Delete the native folders and regenerate them before applying changes 60 --npm Use npm to install dependencies. Default when package-lock.json exists 61 --yarn Use Yarn to install dependencies. Default when yarn.lock exists 62 --pnpm Use pnpm to install dependencies. Default when pnpm-lock.yaml exists 63 --template <template> Project template to clone from. File path pointing to a local tar file or a github repo 64 -p, --platform <all|android|ios> Platforms to sync: ios, android, all. Default: all 65 --skip-dependency-update <dependencies> Preserves versions of listed packages in package.json (comma separated list) 66 -h, --help Usage info 67 " 68 `); 69}); 70 71it('runs `npx expo prebuild` asserts when expo is not installed', async () => { 72 const projectName = 'basic-prebuild-assert-no-expo'; 73 const projectRoot = getRoot(projectName); 74 // Create the project root aot 75 await fs.mkdir(projectRoot, { recursive: true }); 76 // Create a fake package.json -- this is a terminal file that cannot be overwritten. 77 await fs.writeFile(path.join(projectRoot, 'package.json'), '{ "version": "1.0.0" }'); 78 await fs.writeFile(path.join(projectRoot, 'app.json'), '{ "expo": { "name": "foobar" } }'); 79 80 await expect(execute('prebuild', projectName, '--no-install')).rejects.toThrowError( 81 /Cannot determine which native SDK version your project uses because the module `expo` is not installed\. Please install it with `yarn add expo` and try again./ 82 ); 83}); 84 85it( 86 'runs `npx expo prebuild`', 87 async () => { 88 const projectRoot = await setupTestProjectAsync('basic-prebuild', 'with-blank'); 89 // `npx expo prebuild --no-install` 90 await execa('node', [bin, 'prebuild', '--no-install'], { cwd: projectRoot }); 91 92 // List output files with sizes for snapshotting. 93 // This is to make sure that any changes to the output are intentional. 94 // Posix path formatting is used to make paths the same across OSes. 95 const files = klawSync(projectRoot) 96 .map((entry) => { 97 if (entry.path.includes('node_modules') || !entry.stats.isFile()) { 98 return null; 99 } 100 return path.posix.relative(projectRoot, entry.path); 101 }) 102 .filter(Boolean); 103 104 const pkg = await JsonFile.readAsync(path.resolve(projectRoot, 'package.json')); 105 106 // Deleted 107 expect(pkg.main).not.toBeDefined(); 108 109 // Added new packages 110 expect(Object.keys(pkg.dependencies).sort()).toStrictEqual([ 111 'expo', 112 'expo-splash-screen', 113 'expo-status-bar', 114 'react', 115 'react-dom', 116 'react-native', 117 'react-native-web', 118 ]); 119 120 // Updated scripts 121 expect(pkg.scripts).toStrictEqual({ 122 android: 'expo run:android', 123 ios: 'expo run:ios', 124 start: 'expo start --dev-client', 125 }); 126 127 // If this changes then everything else probably changed as well. 128 expect(files).toMatchInlineSnapshot(` 129 Array [ 130 "App.js", 131 "android/.gitignore", 132 "android/app/BUCK", 133 "android/app/build.gradle", 134 "android/app/build_defs.bzl", 135 "android/app/debug.keystore", 136 "android/app/proguard-rules.pro", 137 "android/app/src/debug/AndroidManifest.xml", 138 "android/app/src/debug/java/com/example/minimal/ReactNativeFlipper.java", 139 "android/app/src/main/AndroidManifest.xml", 140 "android/app/src/main/java/com/example/minimal/MainActivity.java", 141 "android/app/src/main/java/com/example/minimal/MainApplication.java", 142 "android/app/src/main/java/com/example/minimal/newarchitecture/MainApplicationReactNativeHost.java", 143 "android/app/src/main/java/com/example/minimal/newarchitecture/components/MainComponentsRegistry.java", 144 "android/app/src/main/java/com/example/minimal/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java", 145 "android/app/src/main/jni/Android.mk", 146 "android/app/src/main/jni/MainApplicationModuleProvider.cpp", 147 "android/app/src/main/jni/MainApplicationModuleProvider.h", 148 "android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp", 149 "android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h", 150 "android/app/src/main/jni/MainComponentsRegistry.cpp", 151 "android/app/src/main/jni/MainComponentsRegistry.h", 152 "android/app/src/main/jni/OnLoad.cpp", 153 "android/app/src/main/res/drawable/rn_edit_text_material.xml", 154 "android/app/src/main/res/drawable/splashscreen.xml", 155 "android/app/src/main/res/mipmap-hdpi/ic_launcher.png", 156 "android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png", 157 "android/app/src/main/res/mipmap-mdpi/ic_launcher.png", 158 "android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png", 159 "android/app/src/main/res/mipmap-xhdpi/ic_launcher.png", 160 "android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png", 161 "android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png", 162 "android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png", 163 "android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png", 164 "android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png", 165 "android/app/src/main/res/values/colors.xml", 166 "android/app/src/main/res/values/strings.xml", 167 "android/app/src/main/res/values/styles.xml", 168 "android/app/src/main/res/values-night/colors.xml", 169 "android/build.gradle", 170 "android/gradle/wrapper/gradle-wrapper.jar", 171 "android/gradle/wrapper/gradle-wrapper.properties", 172 "android/gradle.properties", 173 "android/gradlew", 174 "android/gradlew.bat", 175 "android/settings.gradle", 176 "app.json", 177 "index.js", 178 "ios/.gitignore", 179 "ios/Podfile", 180 "ios/Podfile.properties.json", 181 "ios/basicprebuild/AppDelegate.h", 182 "ios/basicprebuild/AppDelegate.mm", 183 "ios/basicprebuild/Images.xcassets/AppIcon.appiconset/Contents.json", 184 "ios/basicprebuild/Images.xcassets/Contents.json", 185 "ios/basicprebuild/Images.xcassets/SplashScreenBackground.imageset/Contents.json", 186 "ios/basicprebuild/Images.xcassets/SplashScreenBackground.imageset/image.png", 187 "ios/basicprebuild/Info.plist", 188 "ios/basicprebuild/SplashScreen.storyboard", 189 "ios/basicprebuild/Supporting/Expo.plist", 190 "ios/basicprebuild/basicprebuild.entitlements", 191 "ios/basicprebuild/main.m", 192 "ios/basicprebuild/noop-file.swift", 193 "ios/basicprebuild.xcodeproj/project.pbxproj", 194 "ios/basicprebuild.xcodeproj/project.xcworkspace/contents.xcworkspacedata", 195 "ios/basicprebuild.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist", 196 "ios/basicprebuild.xcodeproj/xcshareddata/xcschemes/basicprebuild.xcscheme", 197 "metro.config.js", 198 "package.json", 199 "yarn.lock", 200 ] 201 `); 202 }, 203 // Could take 45s depending on how fast npm installs 204 60 * 1000 205); 206