// Copyright 2015 xeipuuv ( https://github.com/xeipuuv ) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // author xeipuuv // author-github https://github.com/xeipuuv // author-mail xeipuuv@gmail.com // // repository-name gojsonpointer // repository-desc An implementation of JSON Pointer - Go language // // description Automated tests on package. // // created 03-03-2013 package gojsonpointer import ( "encoding/json" "testing" ) const ( TEST_DOCUMENT_NB_ELEMENTS = 13 TEST_NODE_OBJ_NB_ELEMENTS = 4 TEST_DOCUMENT_STRING = `{ "foo": ["bar", "baz"], "obj": { "a":1, "b":2, "c":[3,4], "d":[ {"e":9}, {"f":[50,51]} ] }, "": 0, "a/b": 1, "c%d": 2, "e^f": 3, "g|h": 4, "i\\j": 5, "k\"l": 6, " ": 7, "m~n": 8, "o~/p": 9, "q/~r": 10 }` ) var testDocumentJson interface{} func init() { json.Unmarshal([]byte(TEST_DOCUMENT_STRING), &testDocumentJson) } func TestEscaping(t *testing.T) { ins := []string{`/`, `/`, `/a~1b`, `/a~1b`, `/c%d`, `/e^f`, `/g|h`, `/i\j`, `/k"l`, `/ `, `/m~0n`, `/o~0~1p`, `/q~1~0r`} outs := []float64{0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10} for i := range ins { p, err := NewJsonPointer(ins[i]) if err != nil { t.Errorf("NewJsonPointer(%v) error %v", ins[i], err.Error()) } s := p.String() if s != ins[i] { t.Errorf("\"%v\" -> \"%v\"", ins[i], s) } result, _, err := p.Get(testDocumentJson) if err != nil { t.Errorf("Get(%v) error %v", ins[i], err.Error()) } if result != outs[i] { t.Errorf("Get(%v) = %v, expect %v", ins[i], result, outs[i]) } } } func BenchmarkParse(b *testing.B) { for i := 0; i < b.N; i++ { NewJsonPointer(`/definitions/simple/0/next`) } } func BenchmarkParseWithEscape(b *testing.B) { for i := 0; i < b.N; i++ { NewJsonPointer(`/definiti~0ons/simple/0/next`) } } func BenchmarkString(b *testing.B) { p, _ := NewJsonPointer(`/definitions/simple/0/next`) b.ResetTimer() for i := 0; i < b.N; i++ { p.String() } } func BenchmarkStringWithEscape(b *testing.B) { p, _ := NewJsonPointer(`/definiti~0ons/simple/0/next`) b.ResetTimer() for i := 0; i < b.N; i++ { p.String() } } func TestFullDocument(t *testing.T) { in := `` p, err := NewJsonPointer(in) if err != nil { t.Errorf("NewJsonPointer(%v) error %v", in, err.Error()) } result, _, err := p.Get(testDocumentJson) if err != nil { t.Errorf("Get(%v) error %v", in, err.Error()) } if len(result.(map[string]interface{})) != TEST_DOCUMENT_NB_ELEMENTS { t.Errorf("Get(%v) = %v, expect full document", in, result) } } func TestGetNode(t *testing.T) { in := `/obj` p, err := NewJsonPointer(in) if err != nil { t.Errorf("NewJsonPointer(%v) error %v", in, err.Error()) } result, _, err := p.Get(testDocumentJson) if err != nil { t.Errorf("Get(%v) error %v", in, err.Error()) } if len(result.(map[string]interface{})) != TEST_NODE_OBJ_NB_ELEMENTS { t.Errorf("Get(%v) = %v, expect full document", in, result) } } func BenchmarkGet(b *testing.B) { p, _ := NewJsonPointer(`/obj/d/1/f`) b.ResetTimer() for i := 0; i < b.N; i++ { p.Get(testDocumentJson) } } func TestArray(t *testing.T) { ins := []string{`/foo/0`, `/foo/0`, `/foo/1`} outs := []string{"bar", "bar", "baz"} for i := range ins { p, err := NewJsonPointer(ins[i]) if err != nil { t.Errorf("NewJsonPointer(%v) error %v", ins[i], err.Error()) } result, _, err := p.Get(testDocumentJson) if err != nil { t.Errorf("Get(%v) error %v", ins[i], err.Error()) } if result != outs[i] { t.Errorf("Get(%v) = %v, expect %v", ins[i], result, outs[i]) } } } func TestObject(t *testing.T) { ins := []string{`/obj/a`, `/obj/b`, `/obj/c/0`, `/obj/c/1`, `/obj/c/1`, `/obj/d/1/f/0`} outs := []float64{1, 2, 3, 4, 4, 50} for i := range ins { p, err := NewJsonPointer(ins[i]) if err != nil { t.Errorf("NewJsonPointer(%v) error %v", ins[i], err.Error()) } result, _, err := p.Get(testDocumentJson) if err != nil { t.Errorf("Get(%v) error %v", ins[i], err.Error()) } if result != outs[i] { t.Errorf("Get(%v) = %v, expect %v", ins[i], result, outs[i]) } } } func TestSetNode(t *testing.T) { jsonText := `{"a":[{"b": 1, "c": 2}], "d": 3}` var jsonDocument interface{} json.Unmarshal([]byte(jsonText), &jsonDocument) in := "/a/0/c" p, err := NewJsonPointer(in) if err != nil { t.Errorf("NewJsonPointer(%v) error %v", in, err.Error()) } _, err = p.Set(jsonDocument, 999) if err != nil { t.Errorf("Set(%v) error %v", in, err.Error()) } firstNode := jsonDocument.(map[string]interface{}) if len(firstNode) != 2 { t.Errorf("Set(%s) failed", in) } sliceNode := firstNode["a"].([]interface{}) if len(sliceNode) != 1 { t.Errorf("Set(%s) failed", in) } changedNode := sliceNode[0].(map[string]interface{}) changedNodeValue := changedNode["c"].(int) if changedNodeValue != 999 { if len(sliceNode) != 1 { t.Errorf("Set(%s) failed", in) } } } func TestSetEmptyNode(t *testing.T) { jsonText := `{}` var jsonDocument interface{} json.Unmarshal([]byte(jsonText), &jsonDocument) in := "/a" p, err := NewJsonPointer(in) if err != nil { t.Errorf("NewJsonPointer(%v) error %v", in, err.Error()) } _, err = p.Set(jsonDocument, 999) if err != nil { t.Errorf("Set(%v) error %v", in, err.Error()) } firstNode := jsonDocument.(map[string]interface{}) target := firstNode["a"].(int) if target != 999 { t.Errorf("Set(%s) failed", in) } } func TestDelObject(t *testing.T) { jsonText := `{ "a":["apple sauce", "ketchup", "soy sauce"], "d": { "z" : { "v" : { "name" : "donald mcbobble", "occupation" : "corporate overlord" } } } }` var jsonDocument map[string]interface{} json.Unmarshal([]byte(jsonText), &jsonDocument) //Deleting an object key in := "/d/z/v/occupation" p, err := NewJsonPointer(in) if err != nil { t.Errorf("NewJsonPointer(%v) error %v", in, err.Error()) } _, err = p.Delete(jsonDocument) if err != nil { t.Errorf("Delete(%v) error %v", in, err.Error()) } var d map[string]interface{} = jsonDocument["d"].(map[string]interface{}) var z map[string]interface{} = d["z"].(map[string]interface{}) var v map[string]interface{} = z["v"].(map[string]interface{}) if _, present := v["occupation"]; present { t.Errorf("Delete (%s) failed: key is still present in the map", in) } } func TestDelArray(t *testing.T) { jsonText := `{ "a":["applesauce", "ketchup", "soysauce", "oliveoil"], "d": { "z" : { "v" : { "name" : "donald mcbobble", "occupation" : "corporate overlord", "responsibilities" : ["managing", "hiring"] } } } }` var jsonDocument map[string]interface{} json.Unmarshal([]byte(jsonText), &jsonDocument) //Deleting an array member in := "/a/2" p, err := NewJsonPointer(in) if err != nil { t.Errorf("NewJsonPointer(%v) error %v", in, err.Error()) } _, err = p.Delete(jsonDocument) if err != nil { t.Errorf("Delete(%v) error %v", in, err.Error()) } a := jsonDocument["a"].([]interface{}) if len(a) != 3 || a[2] == "soysauce" { t.Errorf("Delete(%v) error (%s)", in, a) } }