@@ -251,6 +251,80 @@ public async Task InlineDiscardLeavesTheSourceAlone()
251251 Console . WriteLine ( "Source unchanged, as it should be after a discard." ) ;
252252 }
253253
254+ /// <summary>
255+ /// Everything the queue column gained in one window: solution headers, a test sub-group, a
256+ /// conflicted entry with its variant button, and a per-kind accept label is out of reach here
257+ /// because moves and deletes need a tray owner.
258+ /// <para>
259+ /// On its own port, deliberately: a machine running the real DiffEngineTray would otherwise
260+ /// receive these patches into its live queue and open its installed viewer, which is not the
261+ /// code in this working tree.
262+ /// </para>
263+ /// </summary>
264+ [ Test ]
265+ [ Explicit ]
266+ public async Task GroupedQueue ( )
267+ {
268+ Environment . SetEnvironmentVariable ( "DiffEngine_ViewerPort" , "3499" ) ;
269+ try
270+ {
271+ var root = ManualViewer . TempDirectory ( ) ;
272+ var solutionA = root . CreateSubdirectory ( "SolutionA" ) ;
273+ await File . WriteAllTextAsync ( Path . Combine ( solutionA . FullName , "SolutionA.slnx" ) , "" ) ;
274+ var solutionB = root . CreateSubdirectory ( "SolutionB" ) ;
275+ await File . WriteAllTextAsync ( Path . Combine ( solutionB . FullName , "SolutionB.slnx" ) , "" ) ;
276+
277+ var grouped = WriteSource ( solutionA , "ATests.cs" , "\" old value\" " ) ;
278+ var single = WriteSource ( solutionA , "OtherTests.cs" , "\" other value\" " ) ;
279+ var conflicted = WriteSource ( solutionB , "BTests.cs" , "\" framework value\" " ) ;
280+
281+ ManualViewer . Expect (
282+ "Grouped queue with a conflict" ,
283+ "SolutionA (3) and SolutionB (1) headers, dimmed, with the entries indented" ,
284+ "Compare handles nulls (2) sub-header over the two ATests.cs call sites" ,
285+ "Order is stable labels the OtherTests.cs entry by test name" ,
286+ "The BTests.cs entry is marked *, its pane header says received (net8.0)" ,
287+ "The Variant 1/2: net8.0 button (or v) flips to net9.0 and back" ,
288+ "Accepting the conflicted entry writes the variant on screen" ,
289+ "Accept all skips the conflict and says 1 conflict needs review" ) ;
290+
291+ foreach ( var patch in new engine ::DiffEngine . InlinePatch [ ]
292+ {
293+ new ( grouped , 6 , "\" old value\" " , "first new" )
294+ {
295+ TestName = "Compare handles nulls"
296+ } ,
297+ new ( grouped , 7 , "\" old value\" " , "second new" )
298+ {
299+ TestName = "Compare handles nulls"
300+ } ,
301+ new ( single , 6 , "\" other value\" " , "other new" )
302+ {
303+ TestName = "Order is stable"
304+ } ,
305+ new ( conflicted , 6 , "\" framework value\" " , "eight" )
306+ {
307+ Framework = "net8.0"
308+ } ,
309+ new ( conflicted , 6 , "\" framework value\" " , "nine" )
310+ {
311+ Framework = "net9.0"
312+ }
313+ } )
314+ {
315+ var result = await EngineRunner . AddInlineAsync ( patch ) ;
316+ await Assert . That ( result ) . IsEqualTo ( EngineResult . Queued ) ;
317+ }
318+
319+ await ManualViewer . WaitForClose ( ) ;
320+ Report ( grouped , single , conflicted ) ;
321+ }
322+ finally
323+ {
324+ Environment . SetEnvironmentVariable ( "DiffEngine_ViewerPort" , null ) ;
325+ }
326+ }
327+
254328 /// <summary>
255329 /// Line 6 is the verify call in both shapes, which is what every patch above points at.
256330 /// </summary>
0 commit comments