1import { vol } from 'memfs'; 2 3import rnFixture from '../../plugins/__tests__/fixtures/react-native-project'; 4import { readAndroidManifestAsync } from '../Manifest'; 5import { 6 getApplicationIdAsync, 7 getPackage, 8 renameJniOnDiskForType, 9 renamePackageOnDiskForType, 10 setPackageInAndroidManifest, 11 setPackageInBuildGradle, 12} from '../Package'; 13import { getAndroidManifestAsync } from '../Paths'; 14 15jest.mock('fs'); 16 17const EXAMPLE_BUILD_GRADLE = ` 18 android { 19 compileSdkVersion rootProject.ext.compileSdkVersion 20 buildToolsVersion rootProject.ext.buildToolsVersion 21 22 namespace "com.helloworld" 23 defaultConfig { 24 applicationId "com.helloworld" 25 minSdkVersion rootProject.ext.minSdkVersion 26 targetSdkVersion rootProject.ext.targetSdkVersion 27 versionCode 1 28 versionName "1.0" 29 } 30 } 31 `; 32 33describe('package', () => { 34 afterAll(async () => { 35 vol.reset(); 36 }); 37 it(`returns null if no package is provided`, () => { 38 expect(getPackage({})).toBe(null); 39 }); 40 41 it(`returns the package if provided`, () => { 42 expect(getPackage({ android: { package: 'com.example.xyz' } })).toBe('com.example.xyz'); 43 }); 44 45 it(`returns the applicationId defined in build.gradle`, () => { 46 const projectRoot = '/'; 47 vol.fromJSON(rnFixture, projectRoot); 48 49 expect(getApplicationIdAsync(projectRoot)).resolves.toBe('com.helloworld'); 50 }); 51 52 it(`sets the applicationId in build.gradle if package is given`, () => { 53 expect( 54 setPackageInBuildGradle({ android: { package: 'my.new.app' } }, EXAMPLE_BUILD_GRADLE) 55 ).toMatch("applicationId 'my.new.app'"); 56 }); 57 58 it(`sets the namespace in build.gradle if package is given`, () => { 59 expect( 60 setPackageInBuildGradle({ android: { package: 'my.new.app' } }, EXAMPLE_BUILD_GRADLE) 61 ).toMatch("namespace 'my.new.app'"); 62 }); 63 64 it('adds package to android manifest', async () => { 65 const projectRoot = '/'; 66 vol.fromJSON(rnFixture, projectRoot); 67 68 let androidManifestJson = await readAndroidManifestAsync( 69 await getAndroidManifestAsync(projectRoot) 70 ); 71 androidManifestJson = await setPackageInAndroidManifest( 72 { android: { package: 'com.test.package' } }, 73 androidManifestJson 74 ); 75 76 expect(androidManifestJson.manifest.$.package).toMatch('com.test.package'); 77 }); 78}); 79 80describe(renamePackageOnDiskForType, () => { 81 afterAll(async () => { 82 vol.reset(); 83 }); 84 it(`refactors a main project`, async () => { 85 const projectRoot = '/'; 86 vol.fromJSON(rnFixture, projectRoot); 87 88 // Ensure the path that will be deleted exists before we 89 // delete it, this helps prevent the test from accidentally breaking. 90 const originalPath = '/android/app/src/main/java/com/helloworld/MainActivity.java'; 91 92 expect(vol.toJSON()[originalPath]).toBeDefined(); 93 await renamePackageOnDiskForType({ 94 projectRoot, 95 type: 'main', 96 packageName: 'com.bacon.foobar', 97 }); 98 99 const results = vol.toJSON(); 100 // Ensure the file exists in the new location with the new package name 101 expect(results['/android/app/src/main/java/com/bacon/foobar/MainActivity.java']).toMatch( 102 /^package com.bacon.foobar;/ 103 ); 104 expect(results[originalPath]).toBeUndefined(); 105 // Ensure the BUCK file is rewritten 106 // expect(results['/android/app/BUCK']).toMatch(/package = "com.bacon.foobar"/); 107 }); 108 it(`refactors a debug project`, async () => { 109 const projectRoot = '/'; 110 vol.fromJSON(rnFixture, projectRoot); 111 await renamePackageOnDiskForType({ 112 projectRoot, 113 type: 'debug', 114 packageName: 'com.bacon.foobar', 115 }); 116 117 const results = vol.toJSON(); 118 expect(results['/android/app/src/debug/java/com/bacon/foobar/ReactNativeFlipper.java']).toMatch( 119 /package com.bacon.foobar;/ 120 ); 121 }); 122}); 123 124describe(renameJniOnDiskForType, () => { 125 afterAll(async () => { 126 vol.reset(); 127 }); 128 it(`refactors a main project`, async () => { 129 const projectRoot = '/'; 130 vol.fromJSON(rnFixture, projectRoot); 131 await renameJniOnDiskForType({ 132 projectRoot, 133 type: 'main', 134 packageName: 'com.bacon.foobar', 135 }); 136 137 const results = vol.toJSON(); 138 expect( 139 results['/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h'] 140 ).toMatch( 141 /"Lcom\/bacon\/foobar\/newarchitecture\/modules\/MainApplicationTurboModuleManagerDelegate;";/ 142 ); 143 }); 144}); 145