@@ -10,7 +10,7 @@ func testIteration(t *testing.T) {
1010 cv ("Range Array" , func () { testRangeArray (t ) })
1111 cv ("Range Object" , func () { testRangeObject (t ) })
1212 cv ("Range Object by seq" , func () { testRangeObjectsBySetSequence (t ) })
13- cv ("Walk() " , func () { testWalk (t ) })
13+ cv ("Walk" , func () { testWalk (t ) })
1414}
1515
1616func testRangeArray (t * testing.T ) {
@@ -266,7 +266,7 @@ func testWalkBasicTypes(t *testing.T) {
266266 cv ("string value" , func () {
267267 v := NewString ("hello" )
268268 walkCount := 0
269- v .Walk (func (path [] PathItem , val * V ) bool {
269+ v .Walk (func (path Path , val * V ) bool {
270270 walkCount ++
271271 so (len (path ), eq , 0 ) // Root level, no path
272272 so (val .ValueType (), eq , String )
@@ -280,9 +280,12 @@ func testWalkBasicTypes(t *testing.T) {
280280 cv ("number value" , func () {
281281 v := NewInt64 (42 )
282282 walkCount := 0
283- v .Walk (func (path [] PathItem , val * V ) bool {
283+ v .Walk (func (path Path , val * V ) bool {
284284 walkCount ++
285+ lastItem := path .Last ()
285286 so (len (path ), eq , 0 )
287+ so (lastItem .Idx , eq , - 1 )
288+ so (lastItem .Key , eq , "" )
286289 so (val .ValueType (), eq , Number )
287290 so (val .Int64 (), eq , 42 )
288291 return true
@@ -294,7 +297,7 @@ func testWalkBasicTypes(t *testing.T) {
294297 cv ("boolean value" , func () {
295298 v := NewBool (true )
296299 walkCount := 0
297- v .Walk (func (path [] PathItem , val * V ) bool {
300+ v .Walk (func (path Path , val * V ) bool {
298301 walkCount ++
299302 so (len (path ), eq , 0 )
300303 so (val .ValueType (), eq , Boolean )
@@ -308,7 +311,7 @@ func testWalkBasicTypes(t *testing.T) {
308311 cv ("null value" , func () {
309312 v := NewNull ()
310313 walkCount := 0
311- v .Walk (func (path [] PathItem , val * V ) bool {
314+ v .Walk (func (path Path , val * V ) bool {
312315 walkCount ++
313316 so (len (path ), eq , 0 )
314317 so (val .ValueType (), eq , Null )
@@ -324,7 +327,7 @@ func testWalkEmptyContainers(t *testing.T) {
324327 cv ("empty object" , func () {
325328 v := NewObject ()
326329 walkCount := 0
327- v .Walk (func (path [] PathItem , val * V ) bool {
330+ v .Walk (func (path Path , val * V ) bool {
328331 walkCount ++
329332 t .Errorf ("Should not walk through empty object" )
330333 return true
@@ -336,7 +339,7 @@ func testWalkEmptyContainers(t *testing.T) {
336339 cv ("empty array" , func () {
337340 v := NewArray ()
338341 walkCount := 0
339- v .Walk (func (path [] PathItem , val * V ) bool {
342+ v .Walk (func (path Path , val * V ) bool {
340343 walkCount ++
341344 t .Errorf ("Should not walk through empty array" )
342345 return true
@@ -354,7 +357,7 @@ func testWalkSimpleObject(t *testing.T) {
354357
355358 expected := map [string ]struct {
356359 valueType ValueType
357- value interface {}
360+ value any
358361 }{
359362 "greeting" : {String , "hello" },
360363 "number" : {Number , int64 (123 )},
@@ -363,7 +366,7 @@ func testWalkSimpleObject(t *testing.T) {
363366 }
364367
365368 walkCount := 0
366- v .Walk (func (path [] PathItem , val * V ) bool {
369+ v .Walk (func (path Path , val * V ) bool {
367370 walkCount ++
368371 so (len (path ), eq , 1 )
369372
@@ -403,7 +406,7 @@ func testWalkSimpleArray(t *testing.T) {
403406
404407 expectedValues := []struct {
405408 valueType ValueType
406- value interface {}
409+ value any
407410 }{
408411 {String , "first" },
409412 {Number , int64 (456 )},
@@ -412,7 +415,7 @@ func testWalkSimpleArray(t *testing.T) {
412415 }
413416
414417 walkCount := 0
415- v .Walk (func (path [] PathItem , val * V ) bool {
418+ v .Walk (func (path Path , val * V ) bool {
416419 so (len (path ), eq , 1 )
417420
418421 idx := path [0 ].Idx
@@ -459,7 +462,7 @@ func testWalkNestedObjects(t *testing.T) {
459462 v .MustSet (level1 ).At ("level1" )
460463
461464 walkCount := 0
462- v .Walk (func (path [] PathItem , val * V ) bool {
465+ v .Walk (func (path Path , val * V ) bool {
463466 walkCount ++
464467
465468 if len (path ) == 3 {
@@ -490,7 +493,7 @@ func testWalkNestedArrays(t *testing.T) {
490493 v .MustAppend (level1 ).InTheEnd ()
491494
492495 walkCount := 0
493- v .Walk (func (path [] PathItem , val * V ) bool {
496+ v .Walk (func (path Path , val * V ) bool {
494497 walkCount ++
495498
496499 if len (path ) == 3 {
@@ -531,24 +534,14 @@ func testWalkMixedNesting(t *testing.T) {
531534 v .MustSet (arr ).At ("array" )
532535 v .MustSetString ("value" ).At ("simple" )
533536
534- walkResults := make (map [string ]interface {} )
537+ walkResults := make (map [string ]any )
535538 walkCount := 0
536539
537- v .Walk (func (path [] PathItem , val * V ) bool {
540+ v .Walk (func (path Path , val * V ) bool {
538541 walkCount ++
539542
540- // Create a path string for identification
541- pathStr := ""
542- for i , p := range path {
543- if i > 0 {
544- pathStr += "."
545- }
546- if p .Key != "" {
547- pathStr += p .Key
548- } else {
549- pathStr += fmt .Sprintf ("[%d]" , p .Idx )
550- }
551- }
543+ // Create a path string for identification using Path.String()
544+ pathStr := path .String ()
552545
553546 if val .ValueType () == String {
554547 walkResults [pathStr ] = val .String ()
@@ -576,7 +569,7 @@ func testWalkPathValidation(t *testing.T) {
576569
577570 pathValidations := make (map [string ]bool )
578571
579- v .Walk (func (path [] PathItem , val * V ) bool {
572+ v .Walk (func (path Path , val * V ) bool {
580573 pathStr := ""
581574 for _ , p := range path {
582575 if p .Key != "" {
@@ -632,35 +625,22 @@ func testWalkComplexStructure(t *testing.T) {
632625 v , err := UnmarshalString (raw )
633626 so (err , isNil )
634627
635- leafValues := make (map [string ]interface {} )
628+ leafValues := make (map [string ]any )
636629 walkCount := 0
637630
638- v .Walk (func (path [] PathItem , val * V ) bool {
631+ v .Walk (func (path Path , val * V ) bool {
639632 walkCount ++
640633
641- // Build path string
642- pathStr := ""
643- for i , p := range path {
644- if i > 0 {
645- pathStr += "."
646- }
647- if p .Key != "" {
648- pathStr += p .Key
649- } else {
650- pathStr += fmt .Sprintf ("[%d]" , p .Idx )
651- }
652- }
653-
654634 // Store leaf values
655635 switch val .ValueType () {
656636 case String :
657- leafValues [pathStr ] = val .String ()
637+ leafValues [path . String () ] = val .String ()
658638 case Number :
659- leafValues [pathStr ] = val .Int64 ()
639+ leafValues [path . String () ] = val .Int64 ()
660640 case Boolean :
661- leafValues [pathStr ] = val .Bool ()
641+ leafValues [path . String () ] = val .Bool ()
662642 case Null :
663- leafValues [pathStr ] = nil
643+ leafValues [path . String () ] = nil
664644 }
665645
666646 return true
@@ -692,7 +672,7 @@ func testWalkEarlyTermination(t *testing.T) {
692672 v .MustAppendString ("fourth" ).InTheEnd ()
693673
694674 walkCount := 0
695- v .Walk (func (path [] PathItem , val * V ) bool {
675+ v .Walk (func (path Path , val * V ) bool {
696676 walkCount ++
697677 // Stop at the second element
698678 return walkCount < 2
@@ -711,7 +691,7 @@ func testWalkEarlyTermination(t *testing.T) {
711691
712692 walkCount := 0
713693 var lastKey string
714- v .Walk (func (path [] PathItem , val * V ) bool {
694+ v .Walk (func (path Path , val * V ) bool {
715695 walkCount ++
716696 lastKey = path [0 ].Key
717697 // Stop after first element
@@ -724,42 +704,29 @@ func testWalkEarlyTermination(t *testing.T) {
724704
725705 // Test early termination in nested structure
726706 cv ("early termination in nested structure" , func () {
727- v := NewObject ()
728-
729- // Create a nested structure with multiple elements
730- arr := NewArray ()
731- arr .MustAppendString ("item1" ).InTheEnd ()
732- arr .MustAppendString ("item2" ).InTheEnd ()
733- arr .MustAppendString ("item3" ).InTheEnd ()
734- v .MustSet (arr ).At ("array" )
735-
736- v .MustSetString ("simple_value" ).At ("simple" )
737- v .MustSetInt64 (42 ).At ("number" )
738-
739- walkCount := 0
740- terminatedAt := ""
741- v .Walk (func (path []PathItem , val * V ) bool {
742- walkCount ++
707+ // Use array structure to ensure deterministic iteration order
708+ v := NewArray ()
709+ v .MustAppendString ("item1" ).InTheEnd ()
710+ v .MustAppendString ("item2" ).InTheEnd ()
711+ v .MustAppendString ("item3" ).InTheEnd ()
712+ v .MustAppendString ("item4" ).InTheEnd ()
713+ v .MustAppendString ("item5" ).InTheEnd ()
714+
715+ // This structure has 5 leaf nodes with deterministic iteration order
716+ totalWalkCount := 0
717+ lastValue := ""
718+
719+ v .Walk (func (path Path , v * V ) bool {
720+ totalWalkCount ++
743721 // Build path string for debugging
744- pathStr := ""
745- for i , p := range path {
746- if i > 0 {
747- pathStr += "."
748- }
749- if p .Key != "" {
750- pathStr += p .Key
751- } else {
752- pathStr += fmt .Sprintf ("[%d]" , p .Idx )
753- }
754- }
755- terminatedAt = pathStr
722+ lastValue = v .String ()
756723
757- // Stop after third element to allow some iteration
758- return walkCount < 4
724+ // Stop after fourth element to allow some iteration
725+ return path . Last (). Idx < 3
759726 })
760727
761- so (walkCount , eq , 4 ) // Should have stopped after 4 elements
762- so (terminatedAt , ne , "" ) // Should have captured termination point
728+ so (totalWalkCount , eq , 4 )
729+ so (lastValue , eq , "item4" )
763730 })
764731
765732 // Test that returning true continues iteration normally
@@ -770,7 +737,7 @@ func testWalkEarlyTermination(t *testing.T) {
770737 v .MustAppendString ("c" ).InTheEnd ()
771738
772739 walkCount := 0
773- v .Walk (func (path [] PathItem , val * V ) bool {
740+ v .Walk (func (path Path , val * V ) bool {
774741 walkCount ++
775742 return true // Always continue
776743 })
@@ -788,7 +755,7 @@ func testWalkEarlyTermination(t *testing.T) {
788755
789756 walkCount := 0
790757 foundBanana := false
791- v .Walk (func (path [] PathItem , val * V ) bool {
758+ v .Walk (func (path Path , val * V ) bool {
792759 walkCount ++
793760 if val .String () == "banana" {
794761 foundBanana = true
0 commit comments