@@ -3,8 +3,10 @@ package analyzer
33import (
44 "bytes"
55 "encoding/json"
6+ "fmt"
67 "path/filepath"
78 "reflect"
9+ "sort"
810 "strconv"
911
1012 "github.com/pkg/errors"
@@ -97,7 +99,8 @@ func (a *AnalyzeJsonCompare) analyzeJsonCompare(analyzer *troubleshootv1beta2.Js
9799 IconURI : "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg" ,
98100 }
99101
100- equal := reflect .DeepEqual (actual , expected )
102+ // due to jsp.Execute may return a slice of results unsorted, we need to sort the slice before comparing
103+ equal := deepEqualWithSlicesSorted (actual , expected )
101104
102105 for _ , outcome := range analyzer .Outcomes {
103106 if outcome .Fail != nil {
@@ -159,3 +162,67 @@ func (a *AnalyzeJsonCompare) analyzeJsonCompare(analyzer *troubleshootv1beta2.Js
159162 Message : "Invalid analyzer" ,
160163 }, nil
161164}
165+
166+ // deepEqualWithSlicesSorted compares two interfaces and returns true if they contain the same values
167+ // If the interfaces are slices, they are sorted before comparison to ensure order does not matter
168+ // If the interfaces are not slices, reflect.DeepEqual is used
169+ func deepEqualWithSlicesSorted (actual , expected interface {}) bool {
170+ ra , re := reflect .ValueOf (actual ), reflect .ValueOf (expected )
171+
172+ // If types are different, they're not equal
173+ if ra .Kind () != re .Kind () {
174+ return false
175+ }
176+
177+ // If types are slices, compare sorted slices
178+ if ra .Kind () == reflect .Slice {
179+ return compareSortedSlices (ra .Interface ().([]interface {}), re .Interface ().([]interface {}))
180+ }
181+
182+ // Otherwise, compare values (reflect.DeepEqual)
183+ return reflect .DeepEqual (actual , expected )
184+ }
185+
186+ // compareSortedSlices compares two sorted slices of interfaces and returns true if they contain the same values
187+ func compareSortedSlices (actual , expected []interface {}) bool {
188+ if len (actual ) != len (expected ) {
189+ return false
190+ }
191+
192+ // Sort slices
193+ sortSliceOfInterfaces (actual )
194+ sortSliceOfInterfaces (expected )
195+
196+ // Compare slices (reflect.DeepEqual)
197+ return reflect .DeepEqual (actual , expected )
198+ }
199+
200+ func sortSliceOfInterfaces (slice []interface {}) {
201+ sort .Slice (slice , func (i , j int ) bool {
202+ return order (slice [i ], slice [j ])
203+ })
204+ }
205+
206+ // order function determines the order of two interface{} values
207+ func order (a , b interface {}) bool {
208+ switch va := a .(type ) {
209+ case int :
210+ if vb , ok := b .(int ); ok {
211+ return va < vb
212+ }
213+ case float64 :
214+ if vb , ok := b .(float64 ); ok {
215+ return va < vb
216+ }
217+ case string :
218+ if vb , ok := b .(string ); ok {
219+ return va < vb
220+ }
221+ case bool :
222+ if vb , ok := b .(bool ); ok {
223+ return ! va && vb // false < true
224+ }
225+ }
226+ // use string representation for comparison
227+ return fmt .Sprintf ("%v" , a ) < fmt .Sprintf ("%v" , b )
228+ }
0 commit comments