@@ -12,7 +12,7 @@ t.test('modified file produces a unified diff', async t => {
1212 orig : { 'index.js' : 'hello\n' } ,
1313 edit : { 'index.js' : 'world\n' } ,
1414 } )
15- const diff = await diffDirs ( resolve ( dir , 'orig' ) , resolve ( dir , 'edit' ) )
15+ const { diff } = await diffDirs ( resolve ( dir , 'orig' ) , resolve ( dir , 'edit' ) )
1616 t . match ( diff , '--- a/index.js' , 'has old header' )
1717 t . match ( diff , '+++ b/index.js' , 'has new header' )
1818 t . match ( diff , '-hello' , 'removes old line' )
@@ -25,7 +25,7 @@ t.test('added file uses --- /dev/null', async t => {
2525 orig : { 'keep.js' : 'same\n' } ,
2626 edit : { 'keep.js' : 'same\n' , 'added.js' : 'brand new\n' } ,
2727 } )
28- const diff = await diffDirs ( resolve ( dir , 'orig' ) , resolve ( dir , 'edit' ) )
28+ const { diff } = await diffDirs ( resolve ( dir , 'orig' ) , resolve ( dir , 'edit' ) )
2929 t . match ( diff , '--- /dev/null' , 'old side is /dev/null' )
3030 t . match ( diff , '+++ b/added.js' , 'new side names the added file' )
3131 t . match ( diff , '+brand new' , 'includes added content' )
@@ -37,7 +37,7 @@ t.test('deleted file uses +++ /dev/null', async t => {
3737 orig : { 'gone.js' : 'remove me\n' } ,
3838 edit : { } ,
3939 } )
40- const diff = await diffDirs ( resolve ( dir , 'orig' ) , resolve ( dir , 'edit' ) )
40+ const { diff } = await diffDirs ( resolve ( dir , 'orig' ) , resolve ( dir , 'edit' ) )
4141 t . match ( diff , '--- a/gone.js' , 'old side names the deleted file' )
4242 t . match ( diff , '+++ /dev/null' , 'new side is /dev/null' )
4343 t . match ( diff , '-remove me' , 'includes removed content' )
@@ -48,7 +48,7 @@ t.test('nested file path is posix-separated in the diff', async t => {
4848 orig : { lib : { deep : { 'x.js' : 'a\n' } } } ,
4949 edit : { lib : { deep : { 'x.js' : 'b\n' } } } ,
5050 } )
51- const diff = await diffDirs ( resolve ( dir , 'orig' ) , resolve ( dir , 'edit' ) )
51+ const { diff } = await diffDirs ( resolve ( dir , 'orig' ) , resolve ( dir , 'edit' ) )
5252 t . match ( diff , '--- a/lib/deep/x.js' , 'old header uses posix separators' )
5353 t . match ( diff , '+++ b/lib/deep/x.js' , 'new header uses posix separators' )
5454} )
@@ -58,7 +58,7 @@ t.test('identical files produce no diff', async t => {
5858 orig : { 'a.js' : 'x\n' , sub : { 'b.js' : 'y\n' } } ,
5959 edit : { 'a.js' : 'x\n' , sub : { 'b.js' : 'y\n' } } ,
6060 } )
61- const diff = await diffDirs ( resolve ( dir , 'orig' ) , resolve ( dir , 'edit' ) )
61+ const { diff } = await diffDirs ( resolve ( dir , 'orig' ) , resolve ( dir , 'edit' ) )
6262 t . equal ( diff , '' , 'empty diff for identical trees' )
6363} )
6464
@@ -75,20 +75,50 @@ t.test('node_modules and .git are ignored', async t => {
7575 '.git' : { HEAD : 'ref: refs/heads/other\n' } ,
7676 } ,
7777 } )
78- const diff = await diffDirs ( resolve ( dir , 'orig' ) , resolve ( dir , 'edit' ) )
78+ const { diff } = await diffDirs ( resolve ( dir , 'orig' ) , resolve ( dir , 'edit' ) )
7979 t . match ( diff , 'index.js' , 'top-level change is captured' )
8080 t . notMatch ( diff , 'node_modules' , 'node_modules contents are excluded' )
8181 t . notMatch ( diff , 'HEAD' , '.git contents are excluded' )
8282} )
8383
84+ t . test ( 'root package.json is excluded and flagged, nested is kept' , async t => {
85+ const dir = t . testdir ( {
86+ orig : {
87+ 'package.json' : '{ "version": "1.0.0" }\n' ,
88+ 'index.js' : 'a\n' ,
89+ sub : { 'package.json' : '{ "private": true }\n' } ,
90+ } ,
91+ edit : {
92+ 'package.json' : '{ "version": "2.0.0" }\n' ,
93+ 'index.js' : 'b\n' ,
94+ sub : { 'package.json' : '{ "private": false }\n' } ,
95+ } ,
96+ } )
97+ const { diff, packageJsonChanged } = await diffDirs ( resolve ( dir , 'orig' ) , resolve ( dir , 'edit' ) )
98+ t . equal ( packageJsonChanged , true , 'root package.json change is flagged' )
99+ t . notMatch ( diff , 'a/package.json\t' , 'root package.json is not in the diff' )
100+ t . match ( diff , 'a/sub/package.json' , 'nested package.json is still diffed' )
101+ t . match ( diff , 'a/index.js' , 'other files are still diffed' )
102+ } )
103+
104+ t . test ( 'packageJsonChanged is false when only other files change' , async t => {
105+ const dir = t . testdir ( {
106+ orig : { 'package.json' : '{ "version": "1.0.0" }\n' , 'index.js' : 'a\n' } ,
107+ edit : { 'package.json' : '{ "version": "1.0.0" }\n' , 'index.js' : 'b\n' } ,
108+ } )
109+ const { diff, packageJsonChanged } = await diffDirs ( resolve ( dir , 'orig' ) , resolve ( dir , 'edit' ) )
110+ t . equal ( packageJsonChanged , false , 'unchanged package.json is not flagged' )
111+ t . match ( diff , 'a/index.js' , 'the real change is captured' )
112+ } )
113+
84114t . test ( 'non-file entries like symlinks are skipped' , async t => {
85115 const dir = t . testdir ( {
86116 orig : { 'real.js' : 'a\n' } ,
87117 edit : { 'real.js' : 'b\n' } ,
88118 } )
89119 // A symlink is neither a directory nor a regular file so it is ignored.
90120 symlinkSync ( resolve ( dir , 'orig' , 'real.js' ) , resolve ( dir , 'edit' , 'link.js' ) )
91- const diff = await diffDirs ( resolve ( dir , 'orig' ) , resolve ( dir , 'edit' ) )
121+ const { diff } = await diffDirs ( resolve ( dir , 'orig' ) , resolve ( dir , 'edit' ) )
92122 t . match ( diff , 'real.js' , 'regular file is diffed' )
93123 t . notMatch ( diff , 'link.js' , 'symlink entry is skipped' )
94124} )
@@ -107,7 +137,7 @@ t.test('round-trip: applying the diff reproduces the edited tree', async t => {
107137 } ,
108138 } )
109139 const orig = resolve ( dir , 'orig' )
110- const diff = await diffDirs ( orig , resolve ( dir , 'edit' ) )
140+ const { diff } = await diffDirs ( orig , resolve ( dir , 'edit' ) )
111141
112142 // Apply the diff back onto a copy of the original and check the result.
113143 await applyPatchToDir ( { patch : diff , cwd : orig } )
0 commit comments