@@ -183,6 +183,188 @@ describe('JSON WorkspaceDefinition Tracks Workspace Changes', () => {
183183 }
184184 } ) ;
185185
186+ it ( 'tracks complex extension additions with Object.assign target' , async ( ) => {
187+ const host = createTestHost ( basicFile ) ;
188+
189+ const workspace = await readJsonWorkspace ( '' , host ) ;
190+
191+ const value = { a : 1 , b : 2 , c : { d : 'abc' } } ;
192+ workspace . extensions [ 'x-baz' ] = value ;
193+ expect ( workspace . extensions [ 'x-baz' ] ) . toEqual ( { a : 1 , b : 2 , c : { d : 'abc' } } ) ;
194+
195+ Object . assign ( value , { x : 9 , y : 8 , z : 7 } ) ;
196+ expect ( workspace . extensions [ 'x-baz' ] )
197+ . toEqual ( { a : 1 , b : 2 , c : { d : 'abc' } , x : 9 , y : 8 , z : 7 } ) ;
198+
199+ const metadata = getMetadata ( workspace ) ;
200+
201+ expect ( metadata . hasChanges ) . toBeTruthy ( ) ;
202+ expect ( metadata . changeCount ) . toBe ( 1 ) ;
203+
204+ const change = metadata . findChangesForPath ( '/x-baz' ) [ 0 ] ;
205+ expect ( change ) . not . toBeUndefined ( ) ;
206+ if ( change ) {
207+ expect ( change . op ) . toBe ( 'add' ) ;
208+ expect ( change . value ) . toEqual ( { a : 1 , b : 2 , c : { d : 'abc' } , x : 9 , y : 8 , z : 7 } ) ;
209+ }
210+ } ) ;
211+
212+ it ( 'tracks complex extension additions with Object.assign return' , async ( ) => {
213+ const host = createTestHost ( basicFile ) ;
214+
215+ const workspace = await readJsonWorkspace ( '' , host ) ;
216+
217+ const value = { a : 1 , b : 2 , c : { d : 'abc' } } ;
218+ workspace . extensions [ 'x-baz' ] = value ;
219+ expect ( workspace . extensions [ 'x-baz' ] ) . toEqual ( { a : 1 , b : 2 , c : { d : 'abc' } } ) ;
220+
221+ workspace . extensions [ 'x-baz' ] = Object . assign ( value , { x : 9 , y : 8 , z : 7 } ) ;
222+ expect ( workspace . extensions [ 'x-baz' ] )
223+ . toEqual ( { a : 1 , b : 2 , c : { d : 'abc' } , x : 9 , y : 8 , z : 7 } ) ;
224+
225+ const metadata = getMetadata ( workspace ) ;
226+
227+ expect ( metadata . hasChanges ) . toBeTruthy ( ) ;
228+ expect ( metadata . changeCount ) . toBe ( 1 ) ;
229+
230+ const change = metadata . findChangesForPath ( '/x-baz' ) [ 0 ] ;
231+ expect ( change ) . not . toBeUndefined ( ) ;
232+ if ( change ) {
233+ expect ( change . op ) . toBe ( 'add' ) ;
234+ expect ( change . value ) . toEqual ( { a : 1 , b : 2 , c : { d : 'abc' } , x : 9 , y : 8 , z : 7 } ) ;
235+ }
236+ } ) ;
237+
238+ it ( 'tracks complex extension additions with spread operator' , async ( ) => {
239+ const host = createTestHost ( basicFile ) ;
240+
241+ const workspace = await readJsonWorkspace ( '' , host ) ;
242+
243+ const value = { a : 1 , b : 2 , c : { d : 'abc' } } ;
244+ workspace . extensions [ 'x-baz' ] = value ;
245+ expect ( workspace . extensions [ 'x-baz' ] ) . toEqual ( { a : 1 , b : 2 , c : { d : 'abc' } } ) ;
246+
247+ workspace . extensions [ 'x-baz' ] = { ...value , ...{ x : 9 , y : 8 } , z : 7 } ;
248+ expect ( workspace . extensions [ 'x-baz' ] )
249+ . toEqual ( { a : 1 , b : 2 , c : { d : 'abc' } , x : 9 , y : 8 , z : 7 } ) ;
250+
251+ const metadata = getMetadata ( workspace ) ;
252+
253+ expect ( metadata . hasChanges ) . toBeTruthy ( ) ;
254+ expect ( metadata . changeCount ) . toBe ( 1 ) ;
255+
256+ const change = metadata . findChangesForPath ( '/x-baz' ) [ 0 ] ;
257+ expect ( change ) . not . toBeUndefined ( ) ;
258+ if ( change ) {
259+ expect ( change . op ) . toBe ( 'add' ) ;
260+ expect ( change . value ) . toEqual ( { a : 1 , b : 2 , c : { d : 'abc' } , x : 9 , y : 8 , z : 7 } ) ;
261+ }
262+ } ) ;
263+
264+ it ( 'tracks modifying an existing extension object with spread operator' , async ( ) => {
265+ const host = createTestHost ( basicFile ) ;
266+
267+ const workspace = await readJsonWorkspace ( '' , host ) ;
268+
269+ workspace . extensions [ 'x-foo' ] = {
270+ ...workspace . extensions [ 'x-foo' ] as JsonObject ,
271+ ...{ x : 9 , y : 8 } , z : 7 } ;
272+ expect ( workspace . extensions [ 'x-foo' ] )
273+ . toEqual ( { is : [ 'good' , 'great' , 'awesome' ] , x : 9 , y : 8 , z : 7 } ) ;
274+
275+ const metadata = getMetadata ( workspace ) ;
276+
277+ expect ( metadata . hasChanges ) . toBeTruthy ( ) ;
278+ expect ( metadata . changeCount ) . toBe ( 1 ) ;
279+
280+ const change = metadata . findChangesForPath ( '/x-foo' ) [ 0 ] ;
281+ expect ( change ) . not . toBeUndefined ( ) ;
282+ if ( change ) {
283+ expect ( change . op ) . toBe ( 'replace' ) ;
284+ expect ( change . value ) . toEqual ( { is : [ 'good' , 'great' , 'awesome' ] , x : 9 , y : 8 , z : 7 } ) ;
285+ }
286+ } ) ;
287+
288+ it ( 'tracks modifying an existing extension object with Object.assign target' , async ( ) => {
289+ const host = createTestHost ( basicFile ) ;
290+
291+ const workspace = await readJsonWorkspace ( '' , host ) ;
292+
293+ Object . assign (
294+ workspace . extensions [ 'x-foo' ] ,
295+ { x : 9 , y : 8 } ,
296+ { z : 7 } ,
297+ ) ;
298+ expect ( workspace . extensions [ 'x-foo' ] )
299+ . toEqual ( { is : [ 'good' , 'great' , 'awesome' ] , x : 9 , y : 8 , z : 7 } ) ;
300+
301+ const metadata = getMetadata ( workspace ) ;
302+
303+ expect ( metadata . hasChanges ) . toBeTruthy ( ) ;
304+ expect ( metadata . changeCount ) . toBe ( 3 ) ;
305+
306+ let change = metadata . findChangesForPath ( '/x-foo/x' ) [ 0 ] ;
307+ expect ( change ) . not . toBeUndefined ( ) ;
308+ if ( change ) {
309+ expect ( change . op ) . toBe ( 'add' ) ;
310+ expect ( change . value ) . toEqual ( 9 ) ;
311+ }
312+
313+ change = metadata . findChangesForPath ( '/x-foo/y' ) [ 0 ] ;
314+ expect ( change ) . not . toBeUndefined ( ) ;
315+ if ( change ) {
316+ expect ( change . op ) . toBe ( 'add' ) ;
317+ expect ( change . value ) . toEqual ( 8 ) ;
318+ }
319+
320+ change = metadata . findChangesForPath ( '/x-foo/z' ) [ 0 ] ;
321+ expect ( change ) . not . toBeUndefined ( ) ;
322+ if ( change ) {
323+ expect ( change . op ) . toBe ( 'add' ) ;
324+ expect ( change . value ) . toEqual ( 7 ) ;
325+ }
326+ } ) ;
327+
328+ it ( 'tracks modifying an existing extension object with Object.assign return' , async ( ) => {
329+ const host = createTestHost ( basicFile ) ;
330+
331+ const workspace = await readJsonWorkspace ( '' , host ) ;
332+
333+ workspace . extensions [ 'x-foo' ] = Object . assign (
334+ workspace . extensions [ 'x-foo' ] ,
335+ { x : 9 , y : 8 } ,
336+ { z : 7 } ,
337+ ) ;
338+ expect ( workspace . extensions [ 'x-foo' ] )
339+ . toEqual ( { is : [ 'good' , 'great' , 'awesome' ] , x : 9 , y : 8 , z : 7 } ) ;
340+
341+ const metadata = getMetadata ( workspace ) ;
342+
343+ expect ( metadata . hasChanges ) . toBeTruthy ( ) ;
344+ expect ( metadata . changeCount ) . toBe ( 3 ) ;
345+
346+ let change = metadata . findChangesForPath ( '/x-foo/x' ) [ 0 ] ;
347+ expect ( change ) . not . toBeUndefined ( ) ;
348+ if ( change ) {
349+ expect ( change . op ) . toBe ( 'add' ) ;
350+ expect ( change . value ) . toEqual ( 9 ) ;
351+ }
352+
353+ change = metadata . findChangesForPath ( '/x-foo/y' ) [ 0 ] ;
354+ expect ( change ) . not . toBeUndefined ( ) ;
355+ if ( change ) {
356+ expect ( change . op ) . toBe ( 'add' ) ;
357+ expect ( change . value ) . toEqual ( 8 ) ;
358+ }
359+
360+ change = metadata . findChangesForPath ( '/x-foo/z' ) [ 0 ] ;
361+ expect ( change ) . not . toBeUndefined ( ) ;
362+ if ( change ) {
363+ expect ( change . op ) . toBe ( 'add' ) ;
364+ expect ( change . value ) . toEqual ( 7 ) ;
365+ }
366+ } ) ;
367+
186368 it ( 'tracks add and remove of an existing extension object' , async ( ) => {
187369 const host = createTestHost ( basicFile ) ;
188370
0 commit comments