github.com/MontFerret/ferret@v0.18.0/pkg/stdlib/objects/merge_recursive_test.go (about) 1 package objects_test 2 3 import ( 4 "context" 5 "testing" 6 7 "github.com/MontFerret/ferret/pkg/runtime/values" 8 "github.com/MontFerret/ferret/pkg/stdlib/objects" 9 10 . "github.com/smartystreets/goconvey/convey" 11 ) 12 13 func TestMergeRecursive(t *testing.T) { 14 Convey("Wrong arguments", t, func() { 15 Convey("It should error when 0 arguments", func() { 16 actual, err := objects.MergeRecursive(context.Background()) 17 18 So(err, ShouldBeError) 19 So(actual.Compare(values.None), ShouldEqual, 0) 20 }) 21 22 Convey("It should error when there is not object arguments", func() { 23 actual, err := objects.MergeRecursive(context.Background(), values.NewInt(0)) 24 25 So(err, ShouldBeError) 26 So(actual.Compare(values.None), ShouldEqual, 0) 27 28 actual, err = objects.MergeRecursive(context.Background(), 29 values.NewInt(0), values.NewObject(), 30 ) 31 32 So(err, ShouldBeError) 33 So(actual.Compare(values.None), ShouldEqual, 0) 34 }) 35 }) 36 37 Convey("Merge single object", t, func() { 38 obj := values.NewObjectWith( 39 values.NewObjectProperty("a", values.NewInt(0)), 40 ) 41 expected := values.NewObjectWith( 42 values.NewObjectProperty("a", values.NewInt(0)), 43 ) 44 45 actual, err := objects.MergeRecursive(context.Background(), obj) 46 47 So(err, ShouldBeNil) 48 So(actual.Compare(expected), ShouldEqual, 0) 49 }) 50 51 Convey("Merge two objects", t, func() { 52 Convey("When there are no common keys", func() { 53 obj1 := values.NewObjectWith( 54 values.NewObjectProperty("a", values.NewInt(0)), 55 ) 56 obj2 := values.NewObjectWith( 57 values.NewObjectProperty("b", values.NewInt(1)), 58 ) 59 expected := values.NewObjectWith( 60 values.NewObjectProperty("a", values.NewInt(0)), 61 values.NewObjectProperty("b", values.NewInt(1)), 62 ) 63 64 actual, err := objects.MergeRecursive(context.Background(), obj1, obj2) 65 66 So(err, ShouldBeNil) 67 So(actual.Compare(expected), ShouldEqual, 0) 68 }) 69 70 Convey("When objects with the same key", func() { 71 obj1 := values.NewObjectWith( 72 values.NewObjectProperty("a", values.NewInt(0)), 73 values.NewObjectProperty("b", values.NewInt(10)), 74 ) 75 obj2 := values.NewObjectWith( 76 values.NewObjectProperty("c", values.NewInt(1)), 77 values.NewObjectProperty("b", values.NewInt(20)), 78 ) 79 expected := values.NewObjectWith( 80 values.NewObjectProperty("a", values.NewInt(0)), 81 values.NewObjectProperty("b", values.NewInt(20)), 82 values.NewObjectProperty("c", values.NewInt(1)), 83 ) 84 85 actual, err := objects.MergeRecursive(context.Background(), obj1, obj2) 86 87 So(err, ShouldBeNil) 88 So(actual.Compare(expected), ShouldEqual, 0) 89 }) 90 91 Convey("Merge two objects with the same keys", func() { 92 obj1 := values.NewObjectWith( 93 values.NewObjectProperty("a", values.NewInt(0)), 94 values.NewObjectProperty("b", values.NewInt(10)), 95 ) 96 obj2 := values.NewObjectWith( 97 values.NewObjectProperty("a", values.NewInt(1)), 98 values.NewObjectProperty("b", values.NewInt(20)), 99 ) 100 expected := values.NewObjectWith( 101 values.NewObjectProperty("a", values.NewInt(1)), 102 values.NewObjectProperty("b", values.NewInt(20)), 103 ) 104 105 actual, err := objects.MergeRecursive(context.Background(), obj1, obj2) 106 107 So(err, ShouldBeNil) 108 So(actual.Compare(expected), ShouldEqual, 0) 109 }) 110 111 Convey("When there are nested arrays", func() { 112 obj1 := values.NewObjectWith( 113 values.NewObjectProperty("a", values.NewArrayWith( 114 values.NewInt(1), values.NewInt(2), 115 )), 116 ) 117 obj2 := values.NewObjectWith( 118 values.NewObjectProperty("b", values.NewArrayWith( 119 values.NewInt(1), values.NewInt(2), 120 )), 121 ) 122 expected := values.NewObjectWith( 123 values.NewObjectProperty("a", values.NewArrayWith( 124 values.NewInt(1), values.NewInt(2), 125 )), 126 values.NewObjectProperty("b", values.NewArrayWith( 127 values.NewInt(1), values.NewInt(2), 128 )), 129 ) 130 131 actual, err := objects.MergeRecursive(context.Background(), obj1, obj2) 132 133 So(err, ShouldBeNil) 134 So(actual.Compare(expected), ShouldEqual, 0) 135 }) 136 137 Convey("When there are nested objects (example from ArangoDB doc)", func() { 138 // { "user-1": { "name": "Jane", "livesIn": { "city": "LA" } } } 139 obj1 := values.NewObjectWith( 140 values.NewObjectProperty( 141 "user-1", values.NewObjectWith( 142 values.NewObjectProperty( 143 "name", values.NewString("Jane"), 144 ), 145 values.NewObjectProperty( 146 "livesIn", values.NewObjectWith( 147 values.NewObjectProperty( 148 "city", values.NewString("LA"), 149 ), 150 ), 151 ), 152 ), 153 ), 154 ) 155 // { "user-1": { "age": 42, "livesIn": { "state": "CA" } } } 156 obj2 := values.NewObjectWith( 157 values.NewObjectProperty( 158 "user-1", values.NewObjectWith( 159 values.NewObjectProperty( 160 "age", values.NewInt(42), 161 ), 162 values.NewObjectProperty( 163 "livesIn", values.NewObjectWith( 164 values.NewObjectProperty( 165 "state", values.NewString("CA"), 166 ), 167 ), 168 ), 169 ), 170 ), 171 ) 172 // { "user-1": { "age": 42, "livesIn": { "city": "LA", "state": "CA" }, "name": "Jane" } } 173 expected := values.NewObjectWith( 174 values.NewObjectProperty( 175 "user-1", values.NewObjectWith( 176 values.NewObjectProperty( 177 "age", values.NewInt(42), 178 ), 179 values.NewObjectProperty( 180 "name", values.NewString("Jane"), 181 ), 182 values.NewObjectProperty( 183 "livesIn", values.NewObjectWith( 184 values.NewObjectProperty( 185 "state", values.NewString("CA"), 186 ), 187 values.NewObjectProperty( 188 "city", values.NewString("LA"), 189 ), 190 ), 191 ), 192 ), 193 ), 194 ) 195 196 actual, err := objects.MergeRecursive(context.Background(), obj1, obj2) 197 198 So(err, ShouldBeNil) 199 So(actual.Compare(expected), ShouldEqual, 0) 200 }) 201 }) 202 203 Convey("Merged object should be independent of source objects", t, func() { 204 Convey("When array", func() { 205 arr := values.NewArrayWith(values.NewInt(1), values.NewInt(2)) 206 obj := values.NewObjectWith(values.NewObjectProperty("arr", arr)) 207 208 actual, err := objects.MergeRecursive(context.Background(), obj) 209 210 So(err, ShouldBeNil) 211 So(actual.Compare(obj), ShouldEqual, 0) 212 213 arr.Push(values.NewInt(0)) 214 215 So(actual.Compare(obj), ShouldNotEqual, 0) 216 }) 217 218 Convey("When object", func() { 219 nested := values.NewObjectWith( 220 values.NewObjectProperty("nested", values.NewInt(0)), 221 ) 222 obj := values.NewObjectWith(values.NewObjectProperty("obj", nested)) 223 224 actual, err := objects.MergeRecursive(context.Background(), obj) 225 226 So(err, ShouldBeNil) 227 So(actual.Compare(obj), ShouldEqual, 0) 228 229 nested.Set(values.NewString("str"), values.NewInt(0)) 230 231 So(actual.Compare(obj), ShouldNotEqual, 0) 232 }) 233 }) 234 }