@@ -3,25 +3,15 @@ import execa from 'execa';
33import path from 'path' ;
44import fs from 'fs' ;
55import snapshotDiff from 'snapshot-diff' ;
6+ import stripAnsi from 'strip-ansi' ;
67import upgrade from '../upgrade' ;
78import { fetch } from '../helpers' ;
89import logger from '../../../tools/logger' ;
910
1011jest . mock ( 'https' ) ;
1112jest . mock ( 'fs' ) ;
1213jest . mock ( 'path' ) ;
13- jest . mock ( 'execa' , ( ) => {
14- const module = jest . fn ( ( command , args ) => {
15- mockPushLog ( '$' , 'execa' , command , args ) ;
16- if ( command === 'npm' && args [ 3 ] === '--json' ) {
17- return Promise . resolve ( {
18- stdout : '{"react": "16.6.3"}' ,
19- } ) ;
20- }
21- return Promise . resolve ( { stdout : '' } ) ;
22- } ) ;
23- return module ;
24- } ) ;
14+ jest . mock ( 'execa' ) ;
2515jest . mock (
2616 '/project/root/node_modules/react-native/package.json' ,
2717 ( ) => ( { name : 'react-native' , version : '0.57.8' } ) ,
@@ -32,6 +22,19 @@ jest.mock(
3222 ( ) => ( { name : 'TestApp' , dependencies : { 'react-native' : '^0.57.8' } } ) ,
3323 { virtual : true } ,
3424) ;
25+ jest . mock (
26+ '/project/root/NestedApp/node_modules/react-native/package.json' ,
27+ ( ) => ( { name : 'react-native' , version : '0.57.8' } ) ,
28+ { virtual : true } ,
29+ ) ;
30+ jest . mock (
31+ '/project/root/NestedApp/package.json' ,
32+ ( ) => ( {
33+ name : 'TestAppNested' ,
34+ dependencies : { 'react-native' : '^0.57.8' } ,
35+ } ) ,
36+ { virtual : true } ,
37+ ) ;
3538jest . mock ( '../../../tools/PackageManager' , ( ) => ( {
3639 install : args => {
3740 mockPushLog ( '$ yarn add' , ...args ) ;
@@ -49,6 +52,28 @@ jest.mock('../../../tools/logger', () => ({
4952 log : jest . fn ( ( ...args ) => mockPushLog ( args ) ) ,
5053} ) ) ;
5154
55+ const mockExecaDefault = ( command , args ) => {
56+ mockPushLog ( '$' , 'execa' , command , args ) ;
57+ if ( command === 'npm' && args [ 3 ] === '--json' ) {
58+ return Promise . resolve ( { stdout : '{"react": "16.6.3"}' } ) ;
59+ }
60+ if ( command === 'git' && args [ 0 ] === 'rev-parse' ) {
61+ return Promise . resolve ( { stdout : '' } ) ;
62+ }
63+ return Promise . resolve ( { stdout : '' } ) ;
64+ } ;
65+
66+ const mockExecaNested = ( command , args ) => {
67+ mockPushLog ( '$' , 'execa' , command , args ) ;
68+ if ( command === 'npm' && args [ 3 ] === '--json' ) {
69+ return Promise . resolve ( { stdout : '{"react": "16.6.3"}' } ) ;
70+ }
71+ if ( command === 'git' && args [ 0 ] === 'rev-parse' ) {
72+ return Promise . resolve ( { stdout : 'NestedApp/' } ) ;
73+ }
74+ return Promise . resolve ( { stdout : '' } ) ;
75+ } ;
76+
5277const currentVersion = '0.57.8' ;
5378const newVersion = '0.58.4' ;
5479const olderVersion = '0.56.0' ;
@@ -67,22 +92,47 @@ const samplePatch = jest
6792let logs = [ ] ;
6893const mockPushLog = ( ...args ) =>
6994 logs . push ( args . map ( x => ( Array . isArray ( x ) ? x . join ( ' ' ) : x ) ) . join ( ' ' ) ) ;
70- const flushOutput = ( ) => logs . join ( '\n' ) ;
95+ const flushOutput = ( ) => stripAnsi ( logs . join ( '\n' ) ) ;
7196
7297beforeEach ( ( ) => {
7398 jest . clearAllMocks ( ) ;
99+ jest . restoreAllMocks ( ) ;
74100 // $FlowFixMe
75101 fs . writeFileSync = jest . fn ( filename => mockPushLog ( '[fs] write' , filename ) ) ;
76102 // $FlowFixMe
77103 fs . unlinkSync = jest . fn ( ( ...args ) => mockPushLog ( '[fs] unlink' , args ) ) ;
78104 logs = [ ] ;
105+ ( execa : any ) . mockImplementation ( mockExecaDefault ) ;
106+ } ) ;
107+
108+ afterEach ( ( ) => {
109+ // $FlowFixMe
110+ fs . writeFileSync = jest . requireMock ( 'fs' ) . writeFileSync ;
111+ // $FlowFixMe
112+ fs . unlinkSync = jest . requireMock ( 'fs' ) . unlinkSync ;
79113} ) ;
80114
81115test ( 'uses latest version of react-native when none passed' , async ( ) => {
82116 await upgrade . func ( [ ] , ctx , opts ) ;
83117 expect ( execa ) . toBeCalledWith ( 'npm' , [ 'info' , 'react-native' , 'version' ] ) ;
84118} ) ;
85119
120+ test ( 'applies patch in current working directory when nested' , async ( ) => {
121+ ( fetch : any ) . mockImplementation ( ( ) => Promise . resolve ( samplePatch ) ) ;
122+ ( execa : any ) . mockImplementation ( mockExecaNested ) ;
123+ const config = { ...ctx , root : '/project/root/NestedApp' } ;
124+ await upgrade . func ( [ newVersion ] , config , opts ) ;
125+
126+ expect ( execa ) . toBeCalledWith ( 'git' , [
127+ 'apply' ,
128+ 'tmp-upgrade-rn.patch' ,
129+ '--exclude=NestedApp/package.json' ,
130+ '-p2' ,
131+ '--3way' ,
132+ '--directory=NestedApp/' ,
133+ ] ) ;
134+ } ) ;
135+
86136test ( 'errors when invalid version passed' , async ( ) => {
87137 await upgrade . func ( [ 'next' ] , ctx , opts ) ;
88138 expect ( logger . error ) . toBeCalledWith (
@@ -126,9 +176,10 @@ test('fetches regular patch, adds remote, applies patch, installs deps, removes
126176 expect ( flushOutput ( ) ) . toMatchInlineSnapshot ( `
127177"info Fetching diff between v0.57.8 and v0.58.4...
128178[fs] write tmp-upgrade-rn.patch
129- $ execa git apply --check tmp-upgrade-rn.patch --exclude=package.json -p2 --3way
179+ $ execa git rev-parse --show-prefix
180+ $ execa git apply --check tmp-upgrade-rn.patch --exclude=package.json -p2 --3way --directory=
130181info Applying diff...
131- $ execa git apply tmp-upgrade-rn.patch --exclude=package.json -p2 --3way
182+ $ execa git apply tmp-upgrade-rn.patch --exclude=package.json -p2 --3way --directory=
132183[fs] unlink tmp-upgrade-rn.patch
133184$ execa git status -s
134185info Installing \\"[email protected] \\" and its peer dependencies... @@ -146,7 +197,32 @@ success Upgraded React Native to v0.58.4 🎉. Now you can review and commit the
146197 contextLines : 1 ,
147198 } ) ,
148199 ) . toMatchSnapshot ( 'RnDiffApp is replaced with app name (TestApp)' ) ;
149- } ) ;
200+ } , 60000 ) ;
201+ test ( 'fetches regular patch, adds remote, applies patch, installs deps, removes remote when updated from nested directory' , async ( ) => {
202+ ( fetch : any ) . mockImplementation ( ( ) => Promise . resolve ( samplePatch ) ) ;
203+ ( execa : any ) . mockImplementation ( mockExecaNested ) ;
204+ const config = { ...ctx , root : '/project/root/NestedApp' } ;
205+ await upgrade . func ( [ newVersion ] , config , opts ) ;
206+ expect ( flushOutput ( ) ) . toMatchInlineSnapshot ( `
207+ "info Fetching diff between v0.57.8 and v0.58.4...
208+ [fs] write tmp-upgrade-rn.patch
209+ $ execa git rev-parse --show-prefix
210+ $ execa git apply --check tmp-upgrade-rn.patch --exclude=NestedApp/package.json -p2 --3way --directory=NestedApp/
211+ info Applying diff...
212+ $ execa git apply tmp-upgrade-rn.patch --exclude=NestedApp/package.json -p2 --3way --directory=NestedApp/
213+ [fs] unlink tmp-upgrade-rn.patch
214+ $ execa git status -s
215+ info Installing \\"[email protected] \\" and its peer dependencies... 216+ $ execa npm info [email protected] peerDependencies --json 217+ 218+ $ execa git add package.json
219+ $ execa git add yarn.lock
220+ $ execa git add package-lock.json
221+ info Running \\"git status\\" to check what changed...
222+ $ execa git status
223+ success Upgraded React Native to v0.58.4 🎉. Now you can review and commit the changes"
224+ ` ) ;
225+ } , 60000 ) ;
150226test ( 'cleans up if patching fails,' , async ( ) => {
151227 ( fetch : any ) . mockImplementation ( ( ) => Promise . resolve ( samplePatch ) ) ;
152228 ( execa : any ) . mockImplementation ( ( command , args ) => {
@@ -162,6 +238,9 @@ test('cleans up if patching fails,', async () => {
162238 stderr : 'error: .flowconfig: does not exist in index\n' ,
163239 } ) ;
164240 }
241+ if ( command === 'git' && args [ 0 ] === 'rev-parse' ) {
242+ return Promise . resolve ( { stdout : '' } ) ;
243+ }
165244 return Promise . resolve ( { stdout : '' } ) ;
166245 } ) ;
167246 try {
@@ -174,17 +253,18 @@ test('cleans up if patching fails,', async () => {
174253 expect ( flushOutput ( ) ) . toMatchInlineSnapshot ( `
175254"info Fetching diff between v0.57.8 and v0.58.4...
176255[fs] write tmp-upgrade-rn.patch
177- $ execa git apply --check tmp-upgrade-rn.patch --exclude=package.json -p2 --3way
256+ $ execa git rev-parse --show-prefix
257+ $ execa git apply --check tmp-upgrade-rn.patch --exclude=package.json -p2 --3way --directory=
178258info Applying diff (excluding: package.json, .flowconfig)...
179- $ execa git apply tmp-upgrade-rn.patch --exclude=package.json --exclude=.flowconfig -p2 --3way
180- [2merror : .flowconfig: does not exist in index[22m
259+ $ execa git apply tmp-upgrade-rn.patch --exclude=package.json --exclude=.flowconfig -p2 --3way --directory=
260+ error : .flowconfig: does not exist in index
181261error Automatically applying diff failed
182262[fs] unlink tmp-upgrade-rn.patch
183263$ execa git status -s
184264error Patch failed to apply for unknown reason. Please fall back to manual way of upgrading
185265info You may find these resources helpful:
186- • Release notes: [4m[2mhttps ://github.com/facebook/react-native/releases/tag/v0.58.4[22m[24m
187- • Comparison between versions: [4m[2mhttps ://github.com/react-native-community/rn-diff-purge/compare/version/0.57.8..version/0.58.4[22m[24m
188- • Git diff: [4m[2mhttps ://github.com/react-native-community/rn-diff-purge/compare/version/0.57.8..version/0.58.4.diff[22m[24m "
266+ • Release notes: https ://github.com/facebook/react-native/releases/tag/v0.58.4
267+ • Comparison between versions: https ://github.com/react-native-community/rn-diff-purge/compare/version/0.57.8..version/0.58.4
268+ • Git diff: https ://github.com/react-native-community/rn-diff-purge/compare/version/0.57.8..version/0.58.4.diff"
189269` ) ;
190270} ) ;
0 commit comments