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  }