@@ -308,6 +308,126 @@ func TestKeysEarlyTermination(t *testing.T) {
308308 }
309309}
310310
311+ func TestKeysSorted (t * testing.T ) {
312+ m := New [string , int ]()
313+ m .Set ("c" , 3 )
314+ m .Set ("a" , 1 )
315+ m .Set ("b" , 2 )
316+
317+ expected := []string {"a" , "b" , "c" }
318+ idx := 0
319+ for k := range m .KeysSorted (func (a , b string ) bool { return a < b }) {
320+ if idx >= len (expected ) {
321+ t .Fatalf ("received more keys than expected; extra key %q" , k )
322+ }
323+ if k != expected [idx ] {
324+ t .Fatalf ("expected key %q at position %d, got %q" , expected [idx ], idx , k )
325+ }
326+ idx ++
327+ }
328+ if idx != len (expected ) {
329+ t .Fatalf ("expected %d keys, got %d" , len (expected ), idx )
330+ }
331+
332+ t .Run ("earlyTermination" , func (t * testing.T ) {
333+ seqMap := New [string , int ]()
334+ seqMap .Set ("y" , 2 )
335+ seqMap .Set ("x" , 1 )
336+ seq := seqMap .KeysSorted (func (a , b string ) bool { return a < b })
337+ calls := 0
338+ seq (func (string ) bool {
339+ calls ++
340+ return false
341+ })
342+ if calls != 1 {
343+ t .Fatalf ("expected to stop after 1 iteration, got %d" , calls )
344+ }
345+ })
346+
347+ t .Run ("structKeyCustomSort" , func (t * testing.T ) {
348+ type compoundKey struct {
349+ label string
350+ priority int
351+ }
352+
353+ s := New [compoundKey , int ]()
354+ s .Set (compoundKey {label : "gamma" , priority : 2 }, 20 )
355+ s .Set (compoundKey {label : "alpha" , priority : 3 }, 30 )
356+ s .Set (compoundKey {label : "omega" , priority : 1 }, 10 )
357+
358+ less := func (a , b compoundKey ) bool {
359+ return a .priority < b .priority
360+ }
361+
362+ order := make ([]compoundKey , 0 , 3 )
363+ for k := range s .KeysSorted (less ) {
364+ order = append (order , k )
365+ }
366+
367+ expectedOrder := []compoundKey {
368+ {label : "omega" , priority : 1 },
369+ {label : "gamma" , priority : 2 },
370+ {label : "alpha" , priority : 3 },
371+ }
372+
373+ if len (order ) != len (expectedOrder ) {
374+ t .Fatalf ("expected %d keys, got %d" , len (expectedOrder ), len (order ))
375+ }
376+
377+ for i , got := range order {
378+ want := expectedOrder [i ]
379+ if got != want {
380+ t .Fatalf ("at position %d expected %v, got %v" , i , want , got )
381+ }
382+ }
383+ })
384+ }
385+
386+ func TestAllSorted (t * testing.T ) {
387+ m := New [int , string ]()
388+ m .Set (3 , "three" )
389+ m .Set (1 , "one" )
390+ m .Set (2 , "two" )
391+
392+ visited := make ([]KV [int , string ], 0 , 3 )
393+ for k , v := range m .AllSorted (func (a , b int ) bool { return a < b }) {
394+ visited = append (visited , KV [int , string ]{Key : k , Value : v })
395+ if k == 1 {
396+ m .Delete (2 )
397+ }
398+ }
399+
400+ expected := []KV [int , string ]{
401+ {Key : 1 , Value : "one" },
402+ {Key : 3 , Value : "three" },
403+ }
404+
405+ if len (visited ) != len (expected ) {
406+ t .Fatalf ("expected %d key/value pairs, got %d" , len (expected ), len (visited ))
407+ }
408+
409+ for i , kv := range expected {
410+ if visited [i ] != kv {
411+ t .Fatalf ("expected pair %v at position %d, got %v" , kv , i , visited [i ])
412+ }
413+ }
414+
415+ t .Run ("earlyTermination" , func (t * testing.T ) {
416+ seqMap := New [int , string ]()
417+ seqMap .Set (2 , "two" )
418+ seqMap .Set (1 , "one" )
419+ seq := seqMap .AllSorted (func (a , b int ) bool { return a < b })
420+ calls := 0
421+ seq (func (int , string ) bool {
422+ calls ++
423+ return false
424+ })
425+ if calls != 1 {
426+ t .Fatalf ("expected to stop after 1 iteration, got %d" , calls )
427+ }
428+ })
429+ }
430+
311431func TestIteratorWithDifferentTypes (t * testing.T ) {
312432 // Test with different types
313433 m := New [int , string ]()
@@ -629,3 +749,121 @@ func DeleteDuringIterationDeadlock(t *testing.T) {
629749 wg .Wait ()
630750 t .Errorf ("Unexpected no hang" )
631751}
752+
753+ func TestAllNaturalSort (t * testing.T ) { //nolint:gocognit // it's a test!
754+ t .Run ("int" , func (t * testing.T ) {
755+ m := New [int , string ]()
756+ m .Set (3 , "three" )
757+ m .Set (1 , "one" )
758+ m .Set (2 , "two" )
759+
760+ expected := []int {1 , 2 , 3 }
761+ i := 0
762+ for k , v := range NaturalSort (m ) {
763+ if k != expected [i ] {
764+ t .Errorf ("Expected key %d, got %d" , expected [i ], k )
765+ }
766+ if i == 0 && v != "one" {
767+ t .Errorf ("Expected value 'one', got '%s'" , v )
768+ }
769+ i ++
770+ }
771+ if i != 3 {
772+ t .Errorf ("Expected 3 iterations, got %d" , i )
773+ }
774+ })
775+
776+ t .Run ("string" , func (t * testing.T ) {
777+ m := New [string , int ]()
778+ m .Set ("charlie" , 3 )
779+ m .Set ("alice" , 1 )
780+ m .Set ("bob" , 2 )
781+
782+ expected := []string {"alice" , "bob" , "charlie" }
783+ i := 0
784+ for k , v := range NaturalSort (m ) {
785+ if k != expected [i ] {
786+ t .Errorf ("Expected key %s, got %s" , expected [i ], k )
787+ }
788+ if i == 0 && v != 1 {
789+ t .Errorf ("Expected value 1, got %d" , v )
790+ }
791+ i ++
792+ }
793+ if i != 3 {
794+ t .Errorf ("Expected 3 iterations, got %d" , i )
795+ }
796+ })
797+
798+ t .Run ("keyDeletedDuringIteration" , func (t * testing.T ) {
799+ m := New [int , string ]()
800+ m .Set (3 , "three" )
801+ m .Set (1 , "one" )
802+ m .Set (2 , "two" )
803+ m .Set (4 , "four" )
804+
805+ visited := make ([]KV [int , string ], 0 , 4 )
806+ for k , v := range NaturalSort (m ) {
807+ visited = append (visited , KV [int , string ]{Key : k , Value : v })
808+ // Delete key 2 after visiting key 1
809+ if k == 1 {
810+ m .Delete (2 )
811+ }
812+ }
813+
814+ // Expected: 1, 3, 4 (key 2 should be skipped because it was deleted)
815+ expected := []KV [int , string ]{
816+ {Key : 1 , Value : "one" },
817+ {Key : 3 , Value : "three" },
818+ {Key : 4 , Value : "four" },
819+ }
820+
821+ if len (visited ) != len (expected ) {
822+ t .Fatalf ("expected %d key/value pairs, got %d" , len (expected ), len (visited ))
823+ }
824+
825+ for i , kv := range expected {
826+ if visited [i ] != kv {
827+ t .Fatalf ("expected pair %v at position %d, got %v" , kv , i , visited [i ])
828+ }
829+ }
830+ })
831+
832+ t .Run ("earlyTermination" , func (t * testing.T ) {
833+ m := New [int , string ]()
834+ m .Set (3 , "three" )
835+ m .Set (1 , "one" )
836+ m .Set (2 , "two" )
837+ m .Set (4 , "four" )
838+
839+ calls := 0
840+ for range NaturalSort (m ) {
841+ calls ++
842+ if calls == 2 {
843+ break
844+ }
845+ }
846+
847+ if calls != 2 {
848+ t .Fatalf ("expected to stop after 2 iterations, got %d" , calls )
849+ }
850+ })
851+
852+ t .Run ("earlyTerminationViaYield" , func (t * testing.T ) {
853+ m := New [int , string ]()
854+ m .Set (5 , "five" )
855+ m .Set (1 , "one" )
856+ m .Set (3 , "three" )
857+
858+ seq := NaturalSort (m )
859+ calls := 0
860+ seq (func (int , string ) bool {
861+ calls ++
862+ return false // Stop immediately
863+ })
864+
865+ if calls != 1 {
866+ t .Fatalf ("expected to stop after 1 iteration when yield returns false, got %d" , calls )
867+ }
868+ })
869+ }
0 commit comments