@@ -315,6 +315,236 @@ public void ParseArgsLine_roundtrips_via_ToRunInputs_as_shipped_path()
315315 Assert . Equal ( [ "arg1" , "arg2" ] , appArgs ) ;
316316 }
317317
318+ [ Fact ]
319+ public void List_formats_gists_as_owner_filename_from_path_suffix ( )
320+ {
321+ var path = NewSettingsPath ( ) ;
322+ try
323+ {
324+ SettingsStore . Save ( new Settings
325+ {
326+ History =
327+ [
328+ new HistoryEntry
329+ {
330+ Input = "gist.github.com/kzu/0ac826dc7de666546aaedd38e5965381:run.cs" ,
331+ LastUsedUtc = DateTimeOffset . UtcNow ,
332+ UseCount = 1 ,
333+ } ,
334+ new HistoryEntry
335+ {
336+ Input = "kzu/sandbox" ,
337+ LastUsedUtc = DateTimeOffset . UtcNow ,
338+ UseCount = 1 ,
339+ } ,
340+ ] ,
341+ } , path ) ;
342+
343+ var listed = RunHistory . List ( path ) ;
344+ var gist = listed . Single ( e => e . Input . Contains ( "0ac826dc" , StringComparison . Ordinal ) ) ;
345+ Assert . Equal ( "kzu/run.cs" , gist . Display ) ;
346+
347+ var repo = listed . Single ( e => e . Input == "kzu/sandbox" ) ;
348+ Assert . Equal ( "kzu/sandbox" , repo . Display ) ;
349+ }
350+ finally
351+ {
352+ TryDelete ( path ) ;
353+ }
354+ }
355+
356+ [ Fact ]
357+ public void List_formats_gists_as_owner_filename_from_cached_entry ( )
358+ {
359+ var path = NewSettingsPath ( ) ;
360+ try
361+ {
362+ SettingsStore . Save ( new Settings
363+ {
364+ History =
365+ [
366+ new HistoryEntry
367+ {
368+ Input = "gist.github.com/kzu/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ,
369+ LastUsedUtc = DateTimeOffset . UtcNow ,
370+ UseCount = 1 ,
371+ Entry = "hello.cs" ,
372+ } ,
373+ ] ,
374+ } , path ) ;
375+
376+ var listed = RunHistory . List ( path ) ;
377+ Assert . Single ( listed ) ;
378+ Assert . Equal ( "kzu/hello.cs" , listed [ 0 ] . Display ) ;
379+ }
380+ finally
381+ {
382+ TryDelete ( path ) ;
383+ }
384+ }
385+
386+ [ Fact ]
387+ public void List_disambiguates_same_owner_file_with_short_gist_id ( )
388+ {
389+ var path = NewSettingsPath ( ) ;
390+ try
391+ {
392+ SettingsStore . Save ( new Settings
393+ {
394+ History =
395+ [
396+ new HistoryEntry
397+ {
398+ Input = "gist.github.com/kzu/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ,
399+ LastUsedUtc = DateTimeOffset . UtcNow ,
400+ UseCount = 2 ,
401+ Entry = "run.cs" ,
402+ } ,
403+ new HistoryEntry
404+ {
405+ Input = "gist.github.com/kzu/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" ,
406+ LastUsedUtc = DateTimeOffset . UtcNow ,
407+ UseCount = 1 ,
408+ Entry = "run.cs" ,
409+ } ,
410+ new HistoryEntry
411+ {
412+ Input = "gist.github.com/other/cccccccccccccccccccccccccccccccc" ,
413+ LastUsedUtc = DateTimeOffset . UtcNow ,
414+ UseCount = 1 ,
415+ Entry = "run.cs" ,
416+ } ,
417+ ] ,
418+ } , path ) ;
419+
420+ var listed = RunHistory . List ( path ) ;
421+ var kzuA = listed . Single ( e => e . Input . Contains ( "aaaaaaaa" , StringComparison . Ordinal ) ) ;
422+ var kzuB = listed . Single ( e => e . Input . Contains ( "bbbbbbbb" , StringComparison . Ordinal ) ) ;
423+ var other = listed . Single ( e => e . Input . Contains ( "cccccccc" , StringComparison . Ordinal ) ) ;
424+
425+ Assert . Equal ( "kzu/aaaaaaa:run.cs" , kzuA . Display ) ;
426+ Assert . Equal ( "kzu/bbbbbbb:run.cs" , kzuB . Display ) ;
427+ // Different owner — no disambiguation needed even though file name matches.
428+ Assert . Equal ( "other/run.cs" , other . Display ) ;
429+ }
430+ finally
431+ {
432+ TryDelete ( path ) ;
433+ }
434+ }
435+
436+ [ Fact ]
437+ public void List_gist_without_known_file_keeps_raw_input ( )
438+ {
439+ var path = NewSettingsPath ( ) ;
440+ try
441+ {
442+ var input = "gist.github.com/kzu/dddddddddddddddddddddddddddddddd" ;
443+ SettingsStore . Save ( new Settings
444+ {
445+ History =
446+ [
447+ new HistoryEntry
448+ {
449+ Input = input ,
450+ LastUsedUtc = DateTimeOffset . UtcNow ,
451+ UseCount = 1 ,
452+ } ,
453+ ] ,
454+ } , path ) ;
455+
456+ var listed = RunHistory . List ( path ) ;
457+ Assert . Single ( listed ) ;
458+ Assert . Equal ( input , listed [ 0 ] . Display ) ;
459+ }
460+ finally
461+ {
462+ TryDelete ( path ) ;
463+ }
464+ }
465+
466+ [ Fact ]
467+ public void FormatBaseDisplay_and_ShortId_helpers ( )
468+ {
469+ Assert . Equal ( "aaaaaaa" , RunHistory . ShortId ( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ) ) ;
470+ Assert . Equal ( "short" , RunHistory . ShortId ( "short" ) ) ;
471+
472+ var withPath = RunHistory . FormatBaseDisplay (
473+ "gist.github.com/kzu/0ac826dc7de666546aaedd38e5965381:app.cs" ,
474+ cachedEntry : null ,
475+ out var owner , out var gistId , out var file ) ;
476+ Assert . Equal ( "kzu/app.cs" , withPath ) ;
477+ Assert . Equal ( "kzu" , owner ) ;
478+ Assert . Equal ( "0ac826dc7de666546aaedd38e5965381" , gistId ) ;
479+ Assert . Equal ( "app.cs" , file ) ;
480+
481+ var withCache = RunHistory . FormatBaseDisplay (
482+ "gist.github.com/kzu/0ac826dc7de666546aaedd38e5965381" ,
483+ cachedEntry : "from-cache.cs" ,
484+ out owner , out gistId , out file ) ;
485+ Assert . Equal ( "kzu/from-cache.cs" , withCache ) ;
486+ Assert . Equal ( "kzu" , owner ) ;
487+ Assert . Equal ( "0ac826dc7de666546aaedd38e5965381" , gistId ) ;
488+ Assert . Equal ( "from-cache.cs" , file ) ;
489+
490+ var repo = RunHistory . FormatBaseDisplay ( "kzu/sandbox" , null , out owner , out gistId , out file ) ;
491+ Assert . Equal ( "kzu/sandbox" , repo ) ;
492+ Assert . Null ( owner ) ;
493+ Assert . Null ( gistId ) ;
494+ Assert . Null ( file ) ;
495+ }
496+
497+ [ Fact ]
498+ public void Record_captures_gist_entry_from_path_suffix ( )
499+ {
500+ var path = NewSettingsPath ( ) ;
501+ try
502+ {
503+ RunHistory . Record ( "gist.github.com/kzu/0ac826dc7de666546aaedd38e5965381:run.cs" , path ) ;
504+
505+ var settings = SettingsStore . Load ( path ) ;
506+ Assert . Single ( settings . History ! ) ;
507+ Assert . Equal ( "run.cs" , settings . History ! [ 0 ] . Entry ) ;
508+
509+ var listed = RunHistory . List ( path ) ;
510+ Assert . Equal ( "kzu/run.cs" , listed [ 0 ] . Display ) ;
511+ }
512+ finally
513+ {
514+ TryDelete ( path ) ;
515+ }
516+ }
517+
518+ [ Fact ]
519+ public void List_formats_https_gist_url_with_cached_entry ( )
520+ {
521+ var path = NewSettingsPath ( ) ;
522+ try
523+ {
524+ SettingsStore . Save ( new Settings
525+ {
526+ History =
527+ [
528+ new HistoryEntry
529+ {
530+ Input = "https://gist.github.com/kzu/0ac826dc7de666546aaedd38e5965381" ,
531+ LastUsedUtc = DateTimeOffset . UtcNow ,
532+ UseCount = 1 ,
533+ Entry = "run.cs" ,
534+ } ,
535+ ] ,
536+ } , path ) ;
537+
538+ var listed = RunHistory . List ( path ) ;
539+ Assert . Single ( listed ) ;
540+ Assert . Equal ( "kzu/run.cs" , listed [ 0 ] . Display ) ;
541+ }
542+ finally
543+ {
544+ TryDelete ( path ) ;
545+ }
546+ }
547+
318548 static string NewSettingsPath ( )
319549 => Path . Combine ( Path . GetTempPath ( ) , "go-hist-test-" + Guid . NewGuid ( ) . ToString ( "N" ) + ".toml" ) ;
320550
0 commit comments