github.com/IBM-Blockchain/fabric-operator@v1.0.4/pkg/util/merge/merge_test.go (about)

     1  /*
     2   * Copyright contributors to the Hyperledger Fabric Operator project
     3   *
     4   * SPDX-License-Identifier: Apache-2.0
     5   *
     6   * Licensed under the Apache License, Version 2.0 (the "License");
     7   * you may not use this file except in compliance with the License.
     8   * You may obtain a copy of the License at:
     9   *
    10   * 	  http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing, software
    13   * distributed under the License is distributed on an "AS IS" BASIS,
    14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15   * See the License for the specific language governing permissions and
    16   * limitations under the License.
    17   */
    18  
    19  package merge_test
    20  
    21  import (
    22  	"github.com/IBM-Blockchain/fabric-operator/pkg/util/merge"
    23  	. "github.com/onsi/ginkgo/v2"
    24  	. "github.com/onsi/gomega"
    25  )
    26  
    27  var _ = Describe("Merge", func() {
    28  
    29  	var (
    30  		dst *Test
    31  		src *Test
    32  
    33  		trueVal  = true
    34  		falseVal = false
    35  	)
    36  
    37  	BeforeEach(func() {
    38  		dst = &Test{
    39  			String:  "string",
    40  			Int:     1,
    41  			Bool:    false,
    42  			BoolPtr: &falseVal,
    43  		}
    44  
    45  		src = &Test{}
    46  	})
    47  
    48  	Context("WithOverride", func() {
    49  		Context("string", func() {
    50  			When("src is not an empty string", func() {
    51  				It("merges string field by overwriting dst with src", func() {
    52  					src.String = "test"
    53  
    54  					err := merge.WithOverwrite(dst, src)
    55  					Expect(err).NotTo(HaveOccurred())
    56  					Expect(dst.String).To(Equal("test"))
    57  				})
    58  			})
    59  
    60  			When("src is an empty string", func() {
    61  				// NOTE: This is the expected behavior as defined by mergo.MergeWithOverwrite.
    62  				// If we allow empty values to be merged, then all instances of empty src attributes
    63  				// would overwrite both non-empty and empty dst attributes, which would possible
    64  				// overwrite dst fields we didn't want set back to an empty value.
    65  				It("does not merge string field", func() {
    66  					src.String = ""
    67  
    68  					err := merge.WithOverwrite(dst, src)
    69  					Expect(err).NotTo(HaveOccurred())
    70  					Expect(dst.String).To(Equal("string"))
    71  				})
    72  			})
    73  		})
    74  
    75  		Context("int", func() {
    76  			When("src is not an empty value (0)", func() {
    77  				It("merges int field by overwriting dst with src", func() {
    78  					src.Int = 2
    79  
    80  					err := merge.WithOverwrite(dst, src)
    81  					Expect(err).NotTo(HaveOccurred())
    82  					Expect(dst.Int).To(Equal(2))
    83  				})
    84  			})
    85  
    86  			When("src is an empty value (0)", func() {
    87  				// NOTE: This is the expected behavior as defined by mergo.MergeWithOverwrite.
    88  				// If we allow empty values to be merged, then all instances of empty src attributes
    89  				// would overwrite both non-empty and empty dst attributes, which would possible
    90  				// overwrite dst fields we didn't want set back to an empty value.
    91  				It("does not merge int field", func() {
    92  					src.Int = 0
    93  
    94  					err := merge.WithOverwrite(dst, src)
    95  					Expect(err).NotTo(HaveOccurred())
    96  					Expect(dst.Int).To(Equal(1))
    97  				})
    98  			})
    99  		})
   100  
   101  		Context("bool", func() {
   102  			When("src is not an empty value (i.e. true)", func() {
   103  				It("merges bool field by overwriting dst with src", func() {
   104  					src.Bool = true
   105  
   106  					err := merge.WithOverwrite(dst, src)
   107  					Expect(err).NotTo(HaveOccurred())
   108  					Expect(dst.Bool).To(Equal(true))
   109  				})
   110  			})
   111  
   112  			When("src is an empty value (i.e. false)", func() {
   113  				// NOTE: This is the expected behavior as defined by mergo.MergeWithOverwrite.
   114  				// If we allow empty values to be merged, then all instances of empty src attributes
   115  				// would overwrite both non-empty and empty dst attributes, which would possible
   116  				// overwrite dst fields we didn't want set back to an empty value.
   117  				It("does not merge bool field", func() {
   118  					dst.Bool = true
   119  					src.Bool = false
   120  
   121  					err := merge.WithOverwrite(dst, src)
   122  					Expect(err).NotTo(HaveOccurred())
   123  					Expect(dst.Bool).To(Equal(true))
   124  				})
   125  			})
   126  		})
   127  
   128  		Context("bool pointer", func() {
   129  			When("src is a pointer to 'true'", func() {
   130  				BeforeEach(func() {
   131  					// Reset dst and src to avoid issues with bool pointers
   132  					// unintentially persisting through test suite
   133  					dst = &Test{}
   134  					src = &Test{}
   135  				})
   136  
   137  				It("merges bool pointer field by overwriting non-nil dst with src", func() {
   138  					src.BoolPtr = &trueVal
   139  
   140  					err := merge.WithOverwrite(dst, src)
   141  					Expect(err).NotTo(HaveOccurred())
   142  					Expect(*dst.BoolPtr).To(Equal(true))
   143  				})
   144  				It("merges bool pointer field by overwriting nil dst with src", func() {
   145  					dst.BoolPtr = nil
   146  					src.BoolPtr = &trueVal
   147  
   148  					err := merge.WithOverwrite(dst, src)
   149  					Expect(err).NotTo(HaveOccurred())
   150  					Expect(*dst.BoolPtr).To(Equal(true))
   151  				})
   152  			})
   153  
   154  			When("src is a pointer to 'false'", func() {
   155  				BeforeEach(func() {
   156  					// Reset dst and src to avoid issues with bool pointers
   157  					// unintentially persisting through test suite
   158  					dst = &Test{}
   159  					src = &Test{}
   160  				})
   161  
   162  				It("merges bool pointer to field by overwriting non-nil dst with src", func() {
   163  					dst.BoolPtr = &trueVal
   164  					src.BoolPtr = &falseVal
   165  
   166  					err := merge.WithOverwrite(dst, src)
   167  					Expect(err).NotTo(HaveOccurred())
   168  					Expect(*dst.BoolPtr).To(Equal(false))
   169  				})
   170  
   171  				It("merges bool pointer field by ovewriting nil dst with src", func() {
   172  					dst.BoolPtr = nil
   173  					src.BoolPtr = &falseVal
   174  
   175  					err := merge.WithOverwrite(dst, src)
   176  					Expect(err).NotTo(HaveOccurred())
   177  					Expect(*dst.BoolPtr).To(Equal(false))
   178  				})
   179  
   180  				It("merges bool pointer field only if pointer is not nil in src", func() {
   181  					dst = &Test{
   182  						BoolPtr: &trueVal,
   183  						BoolTest: BoolTest{
   184  							BoolPtrA: &trueVal,
   185  						},
   186  					}
   187  					src = &Test{
   188  						BoolTest: BoolTest{
   189  							BoolPtrA: &falseVal,
   190  						},
   191  					}
   192  
   193  					err := merge.WithOverwrite(dst, src)
   194  					Expect(err).NotTo(HaveOccurred())
   195  					Expect(*dst.BoolTest.BoolPtrA).To(Equal(false))
   196  					Expect(*dst.BoolPtr).To(Equal(true))
   197  					Expect(dst.BoolTest.BoolPtrB).To(BeNil())
   198  				})
   199  			})
   200  		})
   201  
   202  	})
   203  })
   204  
   205  type Test struct {
   206  	String   string
   207  	Int      int
   208  	Bool     bool
   209  	BoolPtr  *bool
   210  	BoolTest BoolTest
   211  }
   212  
   213  type BoolTest struct {
   214  	BoolPtrA *bool
   215  	BoolPtrB *bool
   216  }