blob: 8dd25404e17749c9a05bc863c91fbd9d1892603b [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
package utils
import (
"bytes"
"encoding/json"
"reflect"
"testing"
)
func compareJSON(a, b string) bool {
var objA, objB interface{}
json.Unmarshal([]byte(a), &objA)
json.Unmarshal([]byte(b), &objB)
return reflect.DeepEqual(objA, objB)
}
func formatJSON(j string) string {
buf := new(bytes.Buffer)
json.Indent(buf, []byte(j), "", " ")
return buf.String()
}
func TestMergeJson(t *testing.T) {
cases := []struct {
doc, patch, result, desc string
}{
{
desc: "simple merge",
doc: `{
"id": "1",
"status": 1,
"key": "fake key",
"cert": "fake cert",
"create_time": 1,
"update_time": 2
}`,
patch: `{
"id": "1",
"status": 0,
"key": "fake key1",
"cert": "fake cert1"
}`,
result: `{
"id": "1",
"status": 0,
"key": "fake key1",
"cert": "fake cert1",
"create_time": 1,
"update_time": 2
}`,
},
{
desc: `array merge`,
doc: `{
"uri": "/index.html",
"upstream": {
"type": "roundrobin",
"nodes": [{
"host": "39.97.63.215",
"port": 80,
"weight" : 1
}]
}
}`,
patch: `{
"upstream": {
"nodes": [{
"host": "39.97.63.216",
"port": 80,
"weight" : 1
},{
"host": "39.97.63.217",
"port": 80,
"weight" : 1
}]
}
}`,
result: `{
"uri": "/index.html",
"upstream": {
"type": "roundrobin",
"nodes": [{
"host": "39.97.63.216",
"port": 80,
"weight" : 1
},{
"host": "39.97.63.217",
"port": 80,
"weight" : 1
}]
}
}`,
},
}
for _, c := range cases {
out, err := MergeJson([]byte(c.doc), []byte(c.patch))
if err != nil {
t.Errorf("Unable to merge patch: %s", err)
}
if !compareJSON(string(out), c.result) {
t.Errorf("Merge failed. Expected:\n%s\n\nActual:\n%s",
formatJSON(c.result), formatJSON(string(out)))
}
}
}
func TestPatchJson(t *testing.T) {
cases := []struct {
doc, path, value, result, desc string
}{
{
desc: "patch array",
doc: `{
"uri": "/index.html",
"upstream": {
"type": "roundrobin",
"nodes": [{
"host": "39.97.63.215",
"port": 80,
"weight" : 1
}]
}
}`,
path: `/upstream/nodes`,
value: `[{
"host": "39.97.63.216",
"port": 80,
"weight" : 1
},{
"host": "39.97.63.217",
"port": 80,
"weight" : 1
}]`,
result: `{
"uri": "/index.html",
"upstream": {
"type": "roundrobin",
"nodes": [{
"host": "39.97.63.216",
"port": 80,
"weight" : 1
},{
"host": "39.97.63.217",
"port": 80,
"weight" : 1
}]
}
}`,
},
{
desc: "patch field that non existent",
doc: `{
"uri": "/index.html",
"upstream": {
"type": "roundrobin",
"nodes": [{
"host": "39.97.63.215",
"port": 80,
"weight" : 1
}]
}
}`,
path: `/upstream/labels`,
value: `{"app": "test"}`,
result: `{
"uri": "/index.html",
"upstream": {
"type": "roundrobin",
"nodes": [{
"host": "39.97.63.215",
"port": 80,
"weight" : 1
}],
"labels": {"app": "test"}
}
}`,
},
}
for _, c := range cases {
out, err := PatchJson([]byte(c.doc), c.path, c.value)
if err != nil {
t.Errorf("Unable to patch: %s", err)
}
if !compareJSON(string(out), c.result) {
t.Errorf("Patch failed. Expected:\n%s\n\nActual:\n%s",
formatJSON(c.result), formatJSON(string(out)))
}
}
}