github.com/onsi/gomega@v1.32.0/matchers/semi_structured_data_support.go (about) 1 // untested sections: 5 2 3 package matchers 4 5 import ( 6 "fmt" 7 "reflect" 8 "strings" 9 ) 10 11 func formattedMessage(comparisonMessage string, failurePath []interface{}) string { 12 var diffMessage string 13 if len(failurePath) == 0 { 14 diffMessage = "" 15 } else { 16 diffMessage = fmt.Sprintf("\n\nfirst mismatched key: %s", formattedFailurePath(failurePath)) 17 } 18 return fmt.Sprintf("%s%s", comparisonMessage, diffMessage) 19 } 20 21 func formattedFailurePath(failurePath []interface{}) string { 22 formattedPaths := []string{} 23 for i := len(failurePath) - 1; i >= 0; i-- { 24 switch p := failurePath[i].(type) { 25 case int: 26 formattedPaths = append(formattedPaths, fmt.Sprintf(`[%d]`, p)) 27 default: 28 if i != len(failurePath)-1 { 29 formattedPaths = append(formattedPaths, ".") 30 } 31 formattedPaths = append(formattedPaths, fmt.Sprintf(`"%s"`, p)) 32 } 33 } 34 return strings.Join(formattedPaths, "") 35 } 36 37 func deepEqual(a interface{}, b interface{}) (bool, []interface{}) { 38 var errorPath []interface{} 39 if reflect.TypeOf(a) != reflect.TypeOf(b) { 40 return false, errorPath 41 } 42 43 switch a.(type) { 44 case []interface{}: 45 if len(a.([]interface{})) != len(b.([]interface{})) { 46 return false, errorPath 47 } 48 49 for i, v := range a.([]interface{}) { 50 elementEqual, keyPath := deepEqual(v, b.([]interface{})[i]) 51 if !elementEqual { 52 return false, append(keyPath, i) 53 } 54 } 55 return true, errorPath 56 57 case map[interface{}]interface{}: 58 if len(a.(map[interface{}]interface{})) != len(b.(map[interface{}]interface{})) { 59 return false, errorPath 60 } 61 62 for k, v1 := range a.(map[interface{}]interface{}) { 63 v2, ok := b.(map[interface{}]interface{})[k] 64 if !ok { 65 return false, errorPath 66 } 67 elementEqual, keyPath := deepEqual(v1, v2) 68 if !elementEqual { 69 return false, append(keyPath, k) 70 } 71 } 72 return true, errorPath 73 74 case map[string]interface{}: 75 if len(a.(map[string]interface{})) != len(b.(map[string]interface{})) { 76 return false, errorPath 77 } 78 79 for k, v1 := range a.(map[string]interface{}) { 80 v2, ok := b.(map[string]interface{})[k] 81 if !ok { 82 return false, errorPath 83 } 84 elementEqual, keyPath := deepEqual(v1, v2) 85 if !elementEqual { 86 return false, append(keyPath, k) 87 } 88 } 89 return true, errorPath 90 91 default: 92 return a == b, errorPath 93 } 94 }