From 43c71741fcc225e3587a34e4bdedf50629f39503 Mon Sep 17 00:00:00 2001 From: Chris James Date: Sat, 23 Jan 2016 09:40:39 +0000 Subject: [PATCH] Update to jsonequaliser --- Godeps/Godeps.json | 2 +- .../quii/jsonequaliser/compatability.go | 56 +++++++------------ .../quii/jsonequaliser/fieldInspectors.go | 21 +++++++ .../src/github.com/quii/jsonequaliser/json.go | 17 ++++++ 4 files changed, 59 insertions(+), 37 deletions(-) create mode 100644 Godeps/_workspace/src/github.com/quii/jsonequaliser/fieldInspectors.go create mode 100644 Godeps/_workspace/src/github.com/quii/jsonequaliser/json.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 7775f084..3b119c73 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -16,7 +16,7 @@ }, { "ImportPath": "github.com/quii/jsonequaliser", - "Rev": "cbee96c2bf13f2d11fcbb941d12ef63b216c5aef" + "Rev": "39a5c13e9afa3efada63aa71bcfc78f9b7872d75" }, { "ImportPath": "gopkg.in/yaml.v2", diff --git a/Godeps/_workspace/src/github.com/quii/jsonequaliser/compatability.go b/Godeps/_workspace/src/github.com/quii/jsonequaliser/compatability.go index 2efdd4a5..cfbc4dec 100644 --- a/Godeps/_workspace/src/github.com/quii/jsonequaliser/compatability.go +++ b/Godeps/_workspace/src/github.com/quii/jsonequaliser/compatability.go @@ -1,71 +1,55 @@ package jsonequaliser import ( - "encoding/json" "fmt" "reflect" ) +type jsonNode map[string]interface{} + // IsCompatible checks that two json strings are structurally the same so that they are compatible. The first string should be your "correct" json, if there are extra fields in B then they will still be seen as compatible func IsCompatible(a, b string) (compatible bool, err error) { - aMap := make(map[string]interface{}) - if err = json.Unmarshal([]byte(a), &aMap); err != nil { - - //todo: Fix repetition here - - // Could be a top level array, in which case lets take the first item from it - var anArr []map[string]interface{} - if err = json.Unmarshal([]byte(a), &anArr); err != nil { - return - } - aMap = anArr[0] - } - - bMap := make(map[string]interface{}) - if err = json.Unmarshal([]byte(b), &bMap); err != nil { + aMap, err := getJSONNodeFromString(a) + bMap, err := getJSONNodeFromString(b) - // Could be a top level array, in which case lets take the first item from it - var anArr []map[string]interface{} - if err = json.Unmarshal([]byte(a), &anArr); err != nil { - return - } - bMap = anArr[0] + if err != nil { + return } return isStructurallyTheSame(aMap, bMap) } -func isStructurallyTheSame(a, b map[string]interface{}) (compatible bool, err error) { - for keyInA, v := range a { +func isStructurallyTheSame(a, b jsonNode) (compatible bool, err error) { + for jsonFieldName, v := range a { - if a[keyInA] == nil && b[keyInA] == nil { - return true, nil + if fieldMissingIn(b, jsonFieldName) { + return false, nil } - if b[keyInA] == nil { - return + if a[jsonFieldName] == nil { + return true, nil } switch v.(type) { case string: - if _, isString := b[keyInA].(string); !isString { + if !isString(b, jsonFieldName) { return } case bool: - if _, isBool := b[keyInA].(bool); !isBool { + if !isBool(b, jsonFieldName) { return } case float64: - if _, isFloat := b[keyInA].(float64); !isFloat { + if !isFloat(b, jsonFieldName) { return } case interface{}: - aArr, aIsArray := a[keyInA].([]interface{}) + aArr, aIsArray := a[jsonFieldName].([]interface{}) - bArr, bIsArray := b[keyInA].([]interface{}) + bArr, bIsArray := b[jsonFieldName].([]interface{}) if aIsArray && len(aArr) == 0 { return true, nil @@ -75,15 +59,15 @@ func isStructurallyTheSame(a, b map[string]interface{}) (compatible bool, err er return } - var aLeaf, bLeaf map[string]interface{} + var aLeaf, bLeaf jsonNode var aIsMap, bIsMap bool if aIsArray && bIsArray { aLeaf, aIsMap = aArr[0].(map[string]interface{}) bLeaf, bIsMap = bArr[0].(map[string]interface{}) } else { - aLeaf, aIsMap = a[keyInA].(map[string]interface{}) - bLeaf, bIsMap = b[keyInA].(map[string]interface{}) + aLeaf, aIsMap = a[jsonFieldName].(map[string]interface{}) + bLeaf, bIsMap = b[jsonFieldName].(map[string]interface{}) } if aIsMap && bIsMap { diff --git a/Godeps/_workspace/src/github.com/quii/jsonequaliser/fieldInspectors.go b/Godeps/_workspace/src/github.com/quii/jsonequaliser/fieldInspectors.go new file mode 100644 index 00000000..cf0a81e8 --- /dev/null +++ b/Godeps/_workspace/src/github.com/quii/jsonequaliser/fieldInspectors.go @@ -0,0 +1,21 @@ +package jsonequaliser + +func fieldMissingIn(node jsonNode, field string) bool { + _, exists := node[field] + return !exists +} + +func isString(node jsonNode, key string) bool { + _, isString := node[key].(string) + return isString +} + +func isBool(node jsonNode, key string) bool { + _, isString := node[key].(bool) + return isString +} + +func isFloat(node jsonNode, key string) bool { + _, isString := node[key].(float64) + return isString +} diff --git a/Godeps/_workspace/src/github.com/quii/jsonequaliser/json.go b/Godeps/_workspace/src/github.com/quii/jsonequaliser/json.go new file mode 100644 index 00000000..293c3d29 --- /dev/null +++ b/Godeps/_workspace/src/github.com/quii/jsonequaliser/json.go @@ -0,0 +1,17 @@ +package jsonequaliser + +import "encoding/json" + +func getJSONNodeFromString(data string) (node jsonNode, err error) { + node = make(map[string]interface{}) + if err = json.Unmarshal([]byte(data), &node); err != nil { + + // Could be a top level array, in which case lets take the first item from it + var anArr []jsonNode + if err = json.Unmarshal([]byte(data), &anArr); err != nil { + return + } + node = anArr[0] + } + return +}