...

Source file src/sigs.k8s.io/kustomize/kyaml/yaml/fns_test.go

Documentation: sigs.k8s.io/kustomize/kyaml/yaml

     1  // Copyright 2019 The Kubernetes Authors.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package yaml_test
     5  
     6  import (
     7  	"fmt"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  	"sigs.k8s.io/kustomize/kyaml/errors"
    13  	. "sigs.k8s.io/kustomize/kyaml/yaml"
    14  	yaml "sigs.k8s.io/yaml/goyaml.v3"
    15  )
    16  
    17  const (
    18  	NodeSampleData = `n: o
    19  a: b
    20  c: d
    21  `
    22  )
    23  
    24  func TestResourceNode_SetValue(t *testing.T) {
    25  	instance := *NewScalarRNode("foo")
    26  	instanceCopy := instance
    27  	instance.SetYNode(&yaml.Node{Kind: yaml.ScalarNode, Value: "bar"})
    28  	assert.Equal(t, `bar
    29  `, assertNoErrorString(t)(instanceCopy.String()))
    30  	assert.Equal(t, `bar
    31  `, assertNoErrorString(t)(instance.String()))
    32  
    33  	instance = *NewScalarRNode("foo")
    34  	instanceCopy = instance
    35  	instance.SetYNode(nil)
    36  	instance.SetYNode(&yaml.Node{Kind: yaml.ScalarNode, Value: "bar"})
    37  	assert.Equal(t, `foo
    38  `, assertNoErrorString(t)(instanceCopy.String()))
    39  	assert.Equal(t, `bar
    40  `, assertNoErrorString(t)(instance.String()))
    41  }
    42  
    43  func TestAppend(t *testing.T) {
    44  	node, err := Parse(NodeSampleData)
    45  	require.NoError(t, err)
    46  	rn, err := node.Pipe(Append(NewScalarRNode("").YNode()))
    47  	if assert.Error(t, err) {
    48  		assert.Contains(t, err.Error(), "wrong node kind")
    49  	}
    50  	assert.Nil(t, rn)
    51  
    52  	s := `- a
    53  - b
    54  `
    55  	node, err = Parse(s)
    56  	require.NoError(t, err)
    57  	rn, err = node.Pipe(Append())
    58  	require.NoError(t, err)
    59  	assert.Nil(t, rn)
    60  }
    61  
    62  func TestGetElementByIndex(t *testing.T) {
    63  	node, err := Parse(`
    64  - 0
    65  - 1
    66  - 2
    67  `)
    68  	require.NoError(t, err)
    69  
    70  	rn, err := node.Pipe(GetElementByIndex(0))
    71  	require.NoError(t, err)
    72  	assert.Equal(t, "0\n", assertNoErrorString(t)(rn.String()))
    73  
    74  	rn, err = node.Pipe(GetElementByIndex(2))
    75  	require.NoError(t, err)
    76  	assert.Equal(t, "2\n", assertNoErrorString(t)(rn.String()))
    77  
    78  	rn, err = node.Pipe(GetElementByIndex(-1))
    79  	require.NoError(t, err)
    80  	assert.Equal(t, "2\n", assertNoErrorString(t)(rn.String()))
    81  }
    82  
    83  func TestGetElementByKey(t *testing.T) {
    84  	node, err := Parse(`
    85  - b: c
    86  - i
    87  - d: e
    88  - f: g
    89  - f: h
    90  `)
    91  	require.NoError(t, err)
    92  
    93  	rn, err := node.Pipe(GetElementByKey("b"))
    94  	require.NoError(t, err)
    95  	assert.Equal(t, "b: c\n", assertNoErrorString(t)(rn.String()))
    96  
    97  	rn, err = node.Pipe(GetElementByKey("f"))
    98  	require.NoError(t, err)
    99  	assert.Equal(t, "f: g\n", assertNoErrorString(t)(rn.String()))
   100  }
   101  
   102  func TestElementSetter(t *testing.T) {
   103  	orig := MustParse(`
   104  - a: b
   105  - scalarValue
   106  - c: d
   107  # null will be removed
   108  - null
   109  `)
   110  
   111  	// ElementSetter will update node, so make a copy
   112  	node := orig.Copy()
   113  	// Remove an element, because ElementSetter.Element is left nil.
   114  	rn, err := node.Pipe(ElementSetter{Keys: []string{"a"}, Values: []string{"b"}})
   115  	require.NoError(t, err)
   116  	assert.Nil(t, rn)
   117  	assert.Equal(t, `- scalarValue
   118  - c: d
   119  `, assertNoErrorString(t)(node.String()))
   120  
   121  	node = orig.Copy()
   122  	// Nothing happens because no element is matched
   123  	rn, err = node.Pipe(ElementSetter{Keys: []string{"a"}, Values: []string{"zebra"}})
   124  	require.NoError(t, err)
   125  	assert.Nil(t, rn)
   126  	assert.Equal(t, `- a: b
   127  - scalarValue
   128  - c: d
   129  `, assertNoErrorString(t)(node.String()))
   130  
   131  	node = orig.Copy()
   132  	// When the element is not found, return an empty ist
   133  	_, err = node.Pipe(ElementSetter{Keys: []string{"a"}})
   134  	require.NoError(t, err)
   135  	assert.Equal(t, `[]
   136  `, assertNoErrorString(t)(node.String()))
   137  
   138  	_, err = node.Pipe(ElementSetter{Values: []string{"b"}})
   139  	require.NoError(t, err)
   140  	assert.Equal(t, `[]
   141  `, assertNoErrorString(t)(node.String()))
   142  
   143  	node = MustParse(`
   144  - a: b
   145  - c: d
   146  `)
   147  	// If given a key and no values, ElementSetter will
   148  	// change node to be an empty list
   149  	rn, err = node.Pipe(ElementSetter{Keys: []string{"a"}})
   150  	require.NoError(t, err)
   151  	assert.Nil(t, rn)
   152  	assert.Equal(t, `[]
   153  `, assertNoErrorString(t)(node.String()))
   154  
   155  	node = MustParse(`
   156  - a: b
   157  - c: d
   158  `)
   159  	// Return error because ElementSetter will assume all elements are scalar when
   160  	// there is only value provided.
   161  	_, err = node.Pipe(ElementSetter{Values: []string{"b"}})
   162  	assert.EqualError(t, err, `wrong node kind: expected ScalarNode but got MappingNode: node contents:
   163  a: b
   164  `)
   165  
   166  	node = MustParse(`
   167  - a
   168  - b
   169  `)
   170  	// b is removed since ElementSetter use the value "b" to match the
   171  	// scalar values.
   172  	rn, err = node.Pipe(ElementSetter{Values: []string{"b"}})
   173  	require.NoError(t, err)
   174  	assert.Nil(t, rn)
   175  	assert.Equal(t, `- a
   176  `, assertNoErrorString(t)(node.String()))
   177  
   178  	node = orig.Copy()
   179  	// Set an element, replacing 'a: b' with 'e: f'
   180  	newElement := NewMapRNode(&map[string]string{
   181  		"e": "f",
   182  	})
   183  	rn, err = node.Pipe(ElementSetter{
   184  		Keys:    []string{"a"},
   185  		Values:  []string{"b"},
   186  		Element: newElement.YNode(),
   187  	})
   188  	require.NoError(t, err)
   189  	assert.Equal(t, rn, newElement)
   190  	assert.Equal(t, `- e: f
   191  - scalarValue
   192  - c: d
   193  `, assertNoErrorString(t)(node.String()))
   194  
   195  	node = orig.Copy()
   196  	// Set an element with scalar, {"a": "b"} to "foo"
   197  	newElement = NewScalarRNode("foo")
   198  	rn, err = node.Pipe(ElementSetter{
   199  		Keys:    []string{"a"},
   200  		Values:  []string{"b"},
   201  		Element: newElement.YNode(),
   202  	})
   203  	require.NoError(t, err)
   204  	assert.Equal(t, rn, newElement)
   205  	assert.Equal(t, `- foo
   206  - scalarValue
   207  - c: d
   208  `, assertNoErrorString(t)(node.String()))
   209  
   210  	node = orig.Copy()
   211  	// Append an element, {"x": "y"} is not in the list
   212  	// so the element will be appended.
   213  	newElement = NewMapRNode(&map[string]string{
   214  		"e": "f",
   215  	})
   216  	rn, err = node.Pipe(ElementSetter{
   217  		Keys:    []string{"x"},
   218  		Values:  []string{"y"},
   219  		Element: newElement.YNode(),
   220  	})
   221  	require.NoError(t, err)
   222  	assert.Equal(t, rn, newElement)
   223  	assert.Equal(t, `- a: b
   224  - scalarValue
   225  - c: d
   226  - e: f
   227  `, assertNoErrorString(t)(node.String()))
   228  }
   229  
   230  func TestElementSetterMultipleKeys(t *testing.T) {
   231  	orig := MustParse(`
   232  - a: b
   233    c: d
   234  - scalarValue
   235  - e: f
   236  # null will be removed
   237  - null
   238  `)
   239  
   240  	// ElementSetter will update node, so make a copy
   241  	node := orig.Copy()
   242  	// Remove an element using one key-value pair,
   243  	// because ElementSetter.Element is left nil.
   244  	rn, err := node.Pipe(ElementSetter{
   245  		Keys:   []string{"a"},
   246  		Values: []string{"b"},
   247  	})
   248  	require.NoError(t, err)
   249  	assert.Nil(t, rn)
   250  	assert.Equal(t, `- scalarValue
   251  - e: f
   252  `, assertNoErrorString(t)(node.String()))
   253  
   254  	node = orig.Copy()
   255  	// Remove an element using multiple key-value pairs,
   256  	// because ElementSetter.Element is left nil.
   257  	rn, err = node.Pipe(ElementSetter{
   258  		Keys:   []string{"a", "c"},
   259  		Values: []string{"b", "d"},
   260  	})
   261  	require.NoError(t, err)
   262  	assert.Nil(t, rn)
   263  	assert.Equal(t, `- scalarValue
   264  - e: f
   265  `, assertNoErrorString(t)(node.String()))
   266  
   267  	node = orig.Copy()
   268  	// Should do nothing, because Element is nil
   269  	// and there is no element which matches all
   270  	// give key-value pairs
   271  	rn, err = node.Pipe(ElementSetter{
   272  		Keys:   []string{"a", "c"},
   273  		Values: []string{"b", "wrong value"},
   274  	})
   275  	require.NoError(t, err)
   276  	assert.Nil(t, rn)
   277  	assert.Equal(t, `- a: b
   278    c: d
   279  - scalarValue
   280  - e: f
   281  `, assertNoErrorString(t)(node.String()))
   282  
   283  	node = orig.Copy()
   284  	// Set an element, with a single key-value pair
   285  	// replacing 'a: b, c: d' with 'g: h'
   286  	newElement := NewMapRNode(&map[string]string{
   287  		"g": "h",
   288  	})
   289  	rn, err = node.Pipe(ElementSetter{
   290  		Keys:    []string{"a"},
   291  		Values:  []string{"b"},
   292  		Element: newElement.YNode(),
   293  	})
   294  	require.NoError(t, err)
   295  	assert.Equal(t, rn, newElement)
   296  	assert.Equal(t, `- g: h
   297  - scalarValue
   298  - e: f
   299  `, assertNoErrorString(t)(node.String()))
   300  
   301  	node = orig.Copy()
   302  	// Set an element, with multiple key-value pairs
   303  	// replacing 'a: b, c: d' with 'g: h'
   304  	newElement = NewMapRNode(&map[string]string{
   305  		"g": "h",
   306  	})
   307  	rn, err = node.Pipe(ElementSetter{
   308  		Keys:    []string{"a", "c"},
   309  		Values:  []string{"b", "d"},
   310  		Element: newElement.YNode(),
   311  	})
   312  	require.NoError(t, err)
   313  	assert.Equal(t, rn, newElement)
   314  	assert.Equal(t, `- g: h
   315  - scalarValue
   316  - e: f
   317  `, assertNoErrorString(t)(node.String()))
   318  
   319  	node = orig.Copy()
   320  	// Set an element scalar,
   321  	// {'a: b, c: d'} to "foo"
   322  	newElement = NewScalarRNode("foo")
   323  	rn, err = node.Pipe(ElementSetter{
   324  		Keys:    []string{"a", "c"},
   325  		Values:  []string{"b", "d"},
   326  		Element: newElement.YNode(),
   327  	})
   328  	require.NoError(t, err)
   329  	assert.Equal(t, rn, newElement)
   330  	assert.Equal(t, `- foo
   331  - scalarValue
   332  - e: f
   333  `, assertNoErrorString(t)(node.String()))
   334  
   335  	node = orig.Copy()
   336  	// Append an element
   337  	// There is no element which matches all given
   338  	// key-value pairs, so the element will be appended.
   339  	newElement = NewMapRNode(&map[string]string{
   340  		"g": "h",
   341  	})
   342  	rn, err = node.Pipe(ElementSetter{
   343  		Keys:    []string{"a", "c"},
   344  		Values:  []string{"b", "wrong value"},
   345  		Element: newElement.YNode(),
   346  	})
   347  	require.NoError(t, err)
   348  	assert.Equal(t, rn, newElement)
   349  	assert.Equal(t, `- a: b
   350    c: d
   351  - scalarValue
   352  - e: f
   353  - g: h
   354  `, assertNoErrorString(t)(node.String()))
   355  }
   356  
   357  func TestElementMatcherWithNoValue(t *testing.T) {
   358  	node, err := Parse(`
   359  - a: c
   360  - b: ""
   361  `)
   362  	require.NoError(t, err)
   363  
   364  	rn, err := node.Pipe(ElementMatcher{Keys: []string{"b"}})
   365  	require.NoError(t, err)
   366  	assert.Equal(t, "b: \"\"\n", assertNoErrorString(t)(rn.String()))
   367  
   368  	rn, err = node.Pipe(ElementMatcher{Keys: []string{"a"}})
   369  	require.NoError(t, err)
   370  	assert.Nil(t, rn)
   371  
   372  	rn, err = node.Pipe(ElementMatcher{Keys: []string{"a"}, MatchAnyValue: true})
   373  	require.NoError(t, err)
   374  	assert.Equal(t, "a: c\n", assertNoErrorString(t)(rn.String()))
   375  
   376  	_, err = node.Pipe(ElementMatcher{Keys: []string{"a"}, Values: []string{"c"}, MatchAnyValue: true})
   377  	require.Errorf(t, err, "Values must be empty when MatchAnyValue is set to true")
   378  }
   379  
   380  func TestElementMatcherMultipleKeys(t *testing.T) {
   381  	node, err := Parse(`
   382  - a: b
   383    c: d
   384  - e: f
   385  `)
   386  	require.NoError(t, err)
   387  
   388  	// matches all key-value pairs
   389  	rn, err := node.Pipe(MatchElementList(
   390  		[]string{"a", "c"}, // keys
   391  		[]string{"b", "d"}, // values
   392  	))
   393  	require.NoError(t, err)
   394  	assert.NotEmpty(t, rn)
   395  
   396  	// matches one key value pair but not the other
   397  	rn, err = node.Pipe(MatchElementList(
   398  		[]string{"a", "c"}, // keys
   399  		[]string{"b", "f"}, // values
   400  	))
   401  	require.NoError(t, err)
   402  	assert.Nil(t, rn)
   403  
   404  	// matches single given key value pair
   405  	rn, err = node.Pipe(MatchElementList(
   406  		[]string{"e"}, // keys
   407  		[]string{"f"}, // values
   408  	))
   409  	require.NoError(t, err)
   410  	assert.NotEmpty(t, rn)
   411  
   412  	// matching key, but value doesn't match
   413  	rn, err = node.Pipe(MatchElementList(
   414  		[]string{"e"}, // keys
   415  		[]string{"g"}, // values
   416  	))
   417  	require.NoError(t, err)
   418  	assert.Nil(t, rn)
   419  }
   420  
   421  func TestClearField_Fn(t *testing.T) {
   422  	node, err := Parse(NodeSampleData)
   423  	require.NoError(t, err)
   424  	rn, err := node.Pipe(FieldClearer{Name: "a"})
   425  	require.NoError(t, err)
   426  	assert.Equal(t, "n: o\nc: d\n", assertNoErrorString(t)(node.String()))
   427  	assert.Equal(t, "b\n", assertNoErrorString(t)(rn.String()))
   428  
   429  	node, err = Parse(NodeSampleData)
   430  	require.NoError(t, err)
   431  	rn, err = node.Pipe(FieldClearer{Name: "n"})
   432  	require.NoError(t, err)
   433  	assert.Equal(t, "a: b\nc: d\n", assertNoErrorString(t)(node.String()))
   434  	assert.Equal(t, "o\n", assertNoErrorString(t)(rn.String()))
   435  
   436  	node, err = Parse(NodeSampleData)
   437  	require.NoError(t, err)
   438  	rn, err = node.Pipe(FieldClearer{Name: "c"})
   439  	require.NoError(t, err)
   440  	assert.Equal(t, "n: o\na: b\n", assertNoErrorString(t)(node.String()))
   441  	assert.Equal(t, "d\n", assertNoErrorString(t)(rn.String()))
   442  
   443  	s := `n: o
   444  a: b
   445  `
   446  	node, err = Parse(s)
   447  	require.NoError(t, err)
   448  	rn, err = node.Pipe(FieldClearer{Name: "o"})
   449  	require.NoError(t, err)
   450  	assert.Nil(t, rn)
   451  	assert.Equal(t, "n: o\na: b\n", assertNoErrorString(t)(node.String()))
   452  
   453  	s = `- a
   454  - b
   455  `
   456  	node, err = Parse(s)
   457  	require.NoError(t, err)
   458  	rn, err = node.Pipe(FieldClearer{Name: "a"})
   459  	if assert.Error(t, err) {
   460  		assert.Contains(t, err.Error(), "wrong node kind")
   461  	}
   462  	assert.Nil(t, rn)
   463  	assert.Equal(t, s, assertNoErrorString(t)(node.String()))
   464  
   465  	// should not clear n because it is not empty
   466  	s = `n:
   467    k: v
   468  a: b
   469  c: d
   470  `
   471  	node, err = Parse(s)
   472  	require.NoError(t, err)
   473  	rn, err = node.Pipe(FieldClearer{Name: "n", IfEmpty: true})
   474  	require.NoError(t, err)
   475  	assert.Equal(t, "n:\n  k: v\na: b\nc: d\n", assertNoErrorString(t)(node.String()))
   476  	assert.Equal(t, "", assertNoErrorString(t)(rn.String()))
   477  
   478  	// should clear n because it is empty
   479  	s = `n: {}
   480  a: b
   481  c: d
   482  `
   483  	node, err = Parse(s)
   484  	require.NoError(t, err)
   485  	rn, err = node.Pipe(FieldClearer{Name: "n", IfEmpty: true})
   486  	require.NoError(t, err)
   487  	assert.Equal(t, "a: b\nc: d\n", assertNoErrorString(t)(node.String()))
   488  	assert.Equal(t, "{}\n", assertNoErrorString(t)(rn.String()))
   489  }
   490  
   491  var s = `n: o
   492  a:
   493    l: m
   494    b:
   495    - f: g
   496    - c: e
   497    - h: i
   498  r: s
   499  `
   500  
   501  func TestLookup_Fn_create(t *testing.T) {
   502  	// primitive
   503  	node, err := Parse(s)
   504  	require.NoError(t, err)
   505  	rn, err := node.Pipe(PathGetter{
   506  		Path:   []string{"a", "b", "[c=d]", "t", "f", "[=h]"},
   507  		Create: yaml.ScalarNode,
   508  	})
   509  	require.NoError(t, err)
   510  	assert.Equal(t, `n: o
   511  a:
   512    l: m
   513    b:
   514    - f: g
   515    - c: e
   516    - h: i
   517    - c: d
   518      t:
   519        f:
   520        - h
   521  r: s
   522  `, assertNoErrorString(t)(node.String()))
   523  	assert.Equal(t, `h
   524  `, assertNoErrorString(t)(rn.String()))
   525  }
   526  
   527  func TestLookup_Fn_create2(t *testing.T) {
   528  	node, err := Parse(s)
   529  	require.NoError(t, err)
   530  	rn, err := node.Pipe(PathGetter{
   531  		Path:   []string{"a", "b", "[c=d]", "t", "f"},
   532  		Create: yaml.SequenceNode,
   533  	})
   534  	require.NoError(t, err)
   535  	assert.Equal(t, `n: o
   536  a:
   537    l: m
   538    b:
   539    - f: g
   540    - c: e
   541    - h: i
   542    - c: d
   543      t:
   544        f: []
   545  r: s
   546  `, assertNoErrorString(t)(node.String()))
   547  	assert.Equal(t, `[]
   548  `, assertNoErrorString(t)(rn.String()))
   549  }
   550  
   551  func TestLookup_Fn_create3(t *testing.T) {
   552  	node, err := Parse(s)
   553  	require.NoError(t, err)
   554  	rn, err := node.Pipe(LookupCreate(yaml.MappingNode, "a", "b", "[c=d]", "t"))
   555  	require.NoError(t, err)
   556  	assert.Equal(t, `n: o
   557  a:
   558    l: m
   559    b:
   560    - f: g
   561    - c: e
   562    - h: i
   563    - c: d
   564      t: {}
   565  r: s
   566  `, assertNoErrorString(t)(node.String()))
   567  	assert.Equal(t, `{}
   568  `, assertNoErrorString(t)(rn.String()))
   569  }
   570  
   571  func TestLookupCreate_4(t *testing.T) {
   572  	node, err := Parse(`
   573  a: {}
   574  `)
   575  	require.NoError(t, err)
   576  	rn, err := node.Pipe(
   577  		LookupCreate(yaml.MappingNode, "a", "b", "[c=d]", "t", "f", "[=h]"))
   578  
   579  	node.YNode().Style = yaml.FlowStyle
   580  	require.NoError(t, err)
   581  	assert.Equal(t, "{a: {b: [{c: d, t: {f: [h]}}]}}\n", assertNoErrorString(t)(node.String()))
   582  	assert.Equal(t, "h\n", assertNoErrorString(t)(rn.String()))
   583  }
   584  
   585  func TestLookup_Fn_create_with_wildcard_error(t *testing.T) {
   586  	node, err := Parse(s)
   587  	require.NoError(t, err)
   588  	_, err = node.Pipe(LookupCreate(yaml.MappingNode, "a", "b", "*", "t"))
   589  	require.Error(t, err, "wildcard is not supported in PathGetter")
   590  }
   591  
   592  func TestLookup(t *testing.T) {
   593  	s := `n: o
   594  a:
   595    l: m
   596    b:
   597    - f: g
   598    - c: e
   599    - c: d
   600      t:
   601        u: v
   602        f:
   603        - g
   604        - h
   605        - i
   606      j: k
   607    - h: i
   608      p: q
   609  r: s
   610  `
   611  	node, err := Parse(s)
   612  	require.NoError(t, err)
   613  
   614  	// primitive
   615  	rn, err := node.Pipe(Lookup("a", "b", "[c=d]", "t", "f", "[=h]"))
   616  	require.NoError(t, err)
   617  	assert.Equal(t, s, assertNoErrorString(t)(node.String()))
   618  	assert.Equal(t, `h
   619  `, assertNoErrorString(t)(rn.String()))
   620  
   621  	// seq
   622  	rn, err = node.Pipe(Lookup("a", "b", "[c=d]", "t", "f"))
   623  	require.NoError(t, err)
   624  	assert.Equal(t, s, assertNoErrorString(t)(node.String()))
   625  	assert.Equal(t, `- g
   626  - h
   627  - i
   628  `, assertNoErrorString(t)(rn.String()))
   629  
   630  	rn, err = node.Pipe(Lookup("a", "b", "[c=d]", "t"))
   631  	require.NoError(t, err)
   632  	assert.Equal(t, s, assertNoErrorString(t)(node.String()))
   633  	assert.Equal(t, `u: v
   634  f:
   635  - g
   636  - h
   637  - i
   638  `, assertNoErrorString(t)(rn.String()))
   639  
   640  	rn, err = node.Pipe(Lookup("a", "b", "[c=d]"))
   641  	require.NoError(t, err)
   642  	assert.Equal(t, s, assertNoErrorString(t)(node.String()))
   643  	assert.Equal(t, `c: d
   644  t:
   645    u: v
   646    f:
   647    - g
   648    - h
   649    - i
   650  j: k
   651  `, assertNoErrorString(t)(rn.String()))
   652  
   653  	rn, err = node.Pipe(Lookup("a", "b"))
   654  	require.NoError(t, err)
   655  	assert.Equal(t, s, assertNoErrorString(t)(node.String()))
   656  	assert.Equal(t, `- f: g
   657  - c: e
   658  - c: d
   659    t:
   660      u: v
   661      f:
   662      - g
   663      - h
   664      - i
   665    j: k
   666  - h: i
   667    p: q
   668  `, assertNoErrorString(t)(rn.String()))
   669  
   670  	rn, err = node.Pipe(Lookup("a", "b", "0"))
   671  	require.NoError(t, err)
   672  	assert.Equal(t, s, assertNoErrorString(t)(node.String()))
   673  	assert.Equal(t, `f: g
   674  `, assertNoErrorString(t)(rn.String()))
   675  
   676  	rn, err = node.Pipe(Lookup("a", "b", "-", "h"))
   677  	require.NoError(t, err)
   678  	assert.Equal(t, s, assertNoErrorString(t)(node.String()))
   679  	assert.Equal(t, `i
   680  `, assertNoErrorString(t)(rn.String()))
   681  
   682  	rn, err = node.Pipe(Lookup("l"))
   683  	require.NoError(t, err)
   684  	assert.Equal(t, s, assertNoErrorString(t)(node.String()))
   685  	assert.Nil(t, rn)
   686  
   687  	rn, err = node.Pipe(Lookup("zzz"))
   688  	require.NoError(t, err)
   689  	assert.Equal(t, s, assertNoErrorString(t)(node.String()))
   690  	assert.Nil(t, rn)
   691  
   692  	rn, err = node.Pipe(Lookup("[a=b]"))
   693  	require.Error(t, err)
   694  	assert.Equal(t, s, assertNoErrorString(t)(node.String()))
   695  	assert.Nil(t, rn)
   696  
   697  	rn, err = node.Pipe(Lookup("a", "b", "f"))
   698  	require.Error(t, err)
   699  	assert.Equal(t, s, assertNoErrorString(t)(node.String()))
   700  	assert.Nil(t, rn)
   701  
   702  	rn, err = node.Pipe(Lookup("a", "b", "c=zzz"))
   703  	require.Error(t, err)
   704  	assert.Equal(t, s, assertNoErrorString(t)(node.String()))
   705  	assert.Nil(t, rn)
   706  
   707  	rn, err = node.Pipe(Lookup(" ", "a", "", "b", " ", "[c=d]", "\n", "t", "\t", "f", "  ", "[=h]", "  "))
   708  	require.NoError(t, err)
   709  	assert.Equal(t, s, assertNoErrorString(t)(node.String()))
   710  	assert.Equal(t, `h
   711  `, assertNoErrorString(t)(rn.String()))
   712  
   713  	rn, err = node.Pipe(Lookup(" ", "a", "", "b", " ", "[]"))
   714  	require.Error(t, err)
   715  	assert.Nil(t, rn)
   716  
   717  	rn, err = node.Pipe(Lookup("a", "b", "[c=d]", "t", "f", "[=c]"))
   718  	require.NoError(t, err)
   719  	assert.Equal(t, s, assertNoErrorString(t)(node.String()))
   720  	assert.Nil(t, rn)
   721  
   722  	rn, err = node.Pipe(Lookup("a", "b", "[z=z]"))
   723  	require.NoError(t, err)
   724  	assert.Equal(t, s, assertNoErrorString(t)(node.String()))
   725  	assert.Nil(t, rn)
   726  
   727  	rn, err = node.Pipe(Lookup("a", "b", "-1"))
   728  	require.Errorf(t, err, "array index -1 cannot be negative")
   729  	assert.Equal(t, s, assertNoErrorString(t)(node.String()))
   730  	assert.Nil(t, rn)
   731  
   732  	rn, err = node.Pipe(Lookup("a", "b", "99"))
   733  	require.NoError(t, err)
   734  	assert.Equal(t, s, assertNoErrorString(t)(node.String()))
   735  	assert.Nil(t, rn)
   736  }
   737  
   738  func TestLookupFirstMatch(t *testing.T) {
   739  	tests := []struct {
   740  		name     string
   741  		paths    [][]string
   742  		wantPath []string
   743  	}{
   744  		{
   745  			name:     "finds path that exists",
   746  			paths:    [][]string{{"spec", "jobTemplate", "spec", "template", "spec", "containers"}},
   747  			wantPath: []string{"spec", "jobTemplate", "spec", "template", "spec", "containers"},
   748  		},
   749  		{
   750  			name:     "chooses first path when multiple exist: containers example",
   751  			paths:    ConventionalContainerPaths,
   752  			wantPath: []string{"spec", "template", "spec", "containers"},
   753  		},
   754  		{
   755  			name: "chooses first path when multiple exist: annotations example",
   756  			paths: [][]string{
   757  				{"metadata", "annotations", "example.kustomize.io/new"},
   758  				{"metadata", "annotations", "example.kustomize.io/deprecated"},
   759  			},
   760  			wantPath: []string{"metadata", "annotations", "example.kustomize.io/new"},
   761  		},
   762  		{
   763  			name: "returns nil when path does not exist",
   764  			paths: [][]string{
   765  				{"metadata", "annotations", "example.kustomize.io/does-not-exist"},
   766  				{"metadata", "annotations", "example.kustomize.io/also-not-exist"},
   767  			},
   768  			wantPath: nil,
   769  		},
   770  	}
   771  	for _, tt := range tests {
   772  		s := `
   773  apiVersion: example.kustomize.io/v1
   774  kind: Custom
   775  metadata:
   776    annotations:
   777      example.kustomize.io/deprecated: foo
   778      example.kustomize.io/new: foo
   779  spec:
   780    template:
   781      spec:
   782        containers:
   783        - name: foo
   784    jobTemplate:
   785      spec:
   786        template:
   787          spec:
   788            containers:
   789            - name: foo
   790  `
   791  		resource := MustParse(s)
   792  		t.Run(tt.name, func(t *testing.T) {
   793  			result, err := LookupFirstMatch(tt.paths).Filter(resource)
   794  			require.NoError(t, err)
   795  			if tt.wantPath != nil {
   796  				assert.Equal(t, tt.wantPath, result.FieldPath())
   797  			} else {
   798  				assert.Nil(t, result)
   799  			}
   800  		})
   801  	}
   802  }
   803  
   804  func TestMapEntrySetter(t *testing.T) {
   805  	withStyle := func(rn *RNode, style yaml.Style) *RNode {
   806  		rn.YNode().Style = style
   807  		return rn
   808  	}
   809  	testCases := []struct {
   810  		desc        string
   811  		input       string
   812  		setter      MapEntrySetter
   813  		expected    string
   814  		expectedErr error
   815  	}{
   816  		{
   817  			desc:  "it should override Key's value map entry",
   818  			input: "foo: baz\n",
   819  			setter: MapEntrySetter{
   820  				Key:   NewScalarRNode("foo"),
   821  				Value: NewScalarRNode("bar"),
   822  			},
   823  			expected: "foo: bar\n",
   824  		},
   825  		{
   826  			desc:  "it should override Name's map entry",
   827  			input: "foo: baz\n",
   828  			setter: MapEntrySetter{
   829  				Name:  "foo",
   830  				Key:   NewScalarRNode("bar"),
   831  				Value: NewScalarRNode("baz"),
   832  			},
   833  			expected: "bar: baz\n",
   834  		},
   835  		{
   836  			desc:  "it should insert new map entry",
   837  			input: "foo: baz\n",
   838  			setter: MapEntrySetter{
   839  				Key:   NewScalarRNode("bar"),
   840  				Value: NewScalarRNode("42"),
   841  			},
   842  			expected: "foo: baz\nbar: 42\n",
   843  		},
   844  		{
   845  			desc:  "it should override the style",
   846  			input: "foo: baz\n",
   847  			setter: MapEntrySetter{
   848  				Key:   withStyle(NewScalarRNode("foo"), yaml.DoubleQuotedStyle),
   849  				Value: withStyle(NewScalarRNode("bar"), yaml.SingleQuotedStyle),
   850  			},
   851  			expected: `"foo": 'bar'` + "\n",
   852  		},
   853  		{
   854  			desc:  "it should return error on sequence nodes",
   855  			input: "- foo: baz\n",
   856  			setter: MapEntrySetter{
   857  				Key:   NewScalarRNode("foo"),
   858  				Value: NewScalarRNode("bar"),
   859  			},
   860  			expectedErr: errors.Errorf(`wrong node kind: expected MappingNode but got SequenceNode: node contents:
   861  - foo: baz
   862  `),
   863  		},
   864  	}
   865  	for _, tc := range testCases {
   866  		t.Run(tc.desc, func(t *testing.T) {
   867  			node, err := Parse(tc.input)
   868  			require.NoError(t, err)
   869  			k, err := tc.setter.Filter(node)
   870  			if tc.expectedErr == nil {
   871  				require.NoError(t, err)
   872  				assert.Equal(t, tc.expected, assertNoErrorString(t)(node.String()))
   873  				assert.Equal(t, tc.expected, assertNoErrorString(t)(k.String()))
   874  			} else {
   875  				assert.NotNil(t, err)
   876  				assert.Equal(t, tc.expectedErr.Error(), err.Error())
   877  			}
   878  		})
   879  	}
   880  }
   881  
   882  func TestFieldSetter(t *testing.T) {
   883  	// Change field
   884  	node, err := Parse(`
   885  foo: baz
   886  `)
   887  	require.NoError(t, err)
   888  	instance := FieldSetter{
   889  		Name:  "foo",
   890  		Value: NewScalarRNode("bar"),
   891  	}
   892  	k, err := instance.Filter(node)
   893  	require.NoError(t, err)
   894  	assert.Equal(t, `foo: bar
   895  `, assertNoErrorString(t)(node.String()))
   896  	assert.Equal(t, `bar
   897  `, assertNoErrorString(t)(k.String()))
   898  
   899  	// Add field
   900  	node, err = Parse(`
   901  foo: baz
   902  `)
   903  	require.NoError(t, err)
   904  	instance = FieldSetter{
   905  		Name:  "bar",
   906  		Value: NewScalarRNode("buz"),
   907  	}
   908  	k, err = instance.Filter(node)
   909  	require.NoError(t, err)
   910  	assert.Equal(t, `foo: baz
   911  bar: buz
   912  `, assertNoErrorString(t)(node.String()))
   913  	assert.Equal(t, `buz
   914  `, assertNoErrorString(t)(k.String()))
   915  
   916  	// Clear field
   917  	node, err = Parse(`
   918  foo: baz
   919  bar: buz
   920  `)
   921  	require.NoError(t, err)
   922  	instance = FieldSetter{
   923  		Name: "foo",
   924  	}
   925  	k, err = instance.Filter(node)
   926  	require.NoError(t, err)
   927  	assert.Equal(t, `bar: buz
   928  `, assertNoErrorString(t)(node.String()))
   929  	assert.Equal(t, `baz
   930  `, assertNoErrorString(t)(k.String()))
   931  
   932  	// Empty value
   933  	node, err = Parse(`
   934  foo
   935  `)
   936  	require.NoError(t, err)
   937  	instance = FieldSetter{}
   938  	k, err = instance.Filter(node)
   939  	require.NoError(t, err)
   940  	assert.Equal(t, `foo
   941  `, assertNoErrorString(t)(node.String()))
   942  	assert.Equal(t, `foo
   943  `, assertNoErrorString(t)(k.String()))
   944  
   945  	// Encounter error
   946  	node, err = Parse(`
   947  -a
   948  -b
   949  `)
   950  	require.NoError(t, err)
   951  	instance = FieldSetter{
   952  		Name:  "foo",
   953  		Value: NewScalarRNode("v"),
   954  	}
   955  	k, err = instance.Filter(node)
   956  	if assert.Error(t, err) {
   957  		assert.Contains(t, err.Error(), "wrong node kind")
   958  	}
   959  	assert.Nil(t, k)
   960  }
   961  
   962  func TestFieldSetterNumberInKeyRegression(t *testing.T) {
   963  	node := NewMapRNode(&map[string]string{"river": "mississippi"})
   964  
   965  	k, err := FieldSetter{
   966  		Name:  "forty 2",
   967  		Value: NewScalarRNode("number key one"),
   968  	}.Filter(node)
   969  	require.NoError(t, err)
   970  	assert.Equal(t, `number key one
   971  `, assertNoErrorString(t)(k.String()))
   972  
   973  	k, err = FieldSetter{
   974  		Name:  "fortytwo",
   975  		Value: NewScalarRNode("number key two"),
   976  	}.Filter(node)
   977  	require.NoError(t, err)
   978  	assert.Equal(t, `number key two
   979  `, assertNoErrorString(t)(k.String()))
   980  
   981  	k, err = FieldSetter{
   982  		Name:  "42",
   983  		Value: NewScalarRNode("number key three"),
   984  	}.Filter(node)
   985  	require.NoError(t, err)
   986  	assert.Equal(t, `number key three
   987  `, assertNoErrorString(t)(k.String()))
   988  
   989  	assert.Equal(t, `river: mississippi
   990  forty 2: number key one
   991  fortytwo: number key two
   992  42: number key three
   993  `, assertNoErrorString(t)(node.String()))
   994  }
   995  
   996  func TestSet_Fn(t *testing.T) {
   997  	node, err := Parse(`
   998  foo: baz
   999  `)
  1000  	require.NoError(t, err)
  1001  	k, err := node.Pipe(Get("foo"), Set(NewScalarRNode("bar")))
  1002  	require.NoError(t, err)
  1003  	assert.Equal(t, `foo: bar
  1004  `, assertNoErrorString(t)(node.String()))
  1005  	assert.Equal(t, `bar
  1006  `, assertNoErrorString(t)(k.String()))
  1007  
  1008  	node, err = Parse(`
  1009  foo: baz
  1010  `)
  1011  	require.NoError(t, err)
  1012  	_, err = node.Pipe(Set(NewScalarRNode("bar")))
  1013  	if !assert.Error(t, err) {
  1014  		return
  1015  	}
  1016  	assert.Contains(t, err.Error(), "wrong node kind")
  1017  	assert.Equal(t, `foo: baz
  1018  `, assertNoErrorString(t)(node.String()))
  1019  }
  1020  
  1021  func TestErrorIfInvalid(t *testing.T) {
  1022  	err := ErrorIfInvalid(
  1023  		NewRNode(&yaml.Node{Kind: yaml.SequenceNode}), yaml.SequenceNode)
  1024  	require.NoError(t, err)
  1025  
  1026  	// nil values should pass validation -- they were not specified
  1027  	err = ErrorIfInvalid(&RNode{}, yaml.SequenceNode)
  1028  	if !assert.NoError(t, err) {
  1029  		t.FailNow()
  1030  	}
  1031  
  1032  	err = ErrorIfInvalid(NewRNode(&Node{Content: []*yaml.Node{{Value: "hello"}}}), yaml.SequenceNode)
  1033  	if !assert.Error(t, err) {
  1034  		t.FailNow()
  1035  	}
  1036  	assert.Contains(t, err.Error(), "wrong node kind")
  1037  
  1038  	err = ErrorIfInvalid(NewRNode(&yaml.Node{}), yaml.SequenceNode)
  1039  	if assert.Error(t, err) {
  1040  		assert.Contains(t, err.Error(), "wrong node kind")
  1041  	}
  1042  	err = ErrorIfInvalid(NewRNode(&yaml.Node{}), yaml.MappingNode)
  1043  	if assert.Error(t, err) {
  1044  		assert.Contains(t, err.Error(), "wrong node kind")
  1045  	}
  1046  
  1047  	err = ErrorIfInvalid(NewRNode(&yaml.Node{
  1048  		Kind:    yaml.MappingNode,
  1049  		Content: []*yaml.Node{{}, {}},
  1050  	}), yaml.MappingNode)
  1051  	require.NoError(t, err)
  1052  
  1053  	err = ErrorIfInvalid(NewRNode(&yaml.Node{}), yaml.SequenceNode)
  1054  	if assert.Error(t, err) {
  1055  		assert.Contains(t, err.Error(), "wrong node kind")
  1056  	}
  1057  
  1058  	err = ErrorIfInvalid(NewRNode(&yaml.Node{
  1059  		Kind:    yaml.MappingNode,
  1060  		Content: []*yaml.Node{{}},
  1061  	}), yaml.MappingNode)
  1062  	if assert.Error(t, err) {
  1063  		assert.Contains(t, err.Error(), "even length")
  1064  	}
  1065  }
  1066  
  1067  func TestSplitIndexNameValue(t *testing.T) {
  1068  	k, v, err := SplitIndexNameValue("")
  1069  	if assert.Error(t, err) {
  1070  		assert.Contains(t, err.Error(), "fieldName=fieldValue")
  1071  	}
  1072  	assert.Equal(t, "", k)
  1073  	assert.Equal(t, "", v)
  1074  
  1075  	k, v, err = SplitIndexNameValue("a=b")
  1076  	require.NoError(t, err)
  1077  	assert.Equal(t, "a", k)
  1078  	assert.Equal(t, "b", v)
  1079  
  1080  	k, v, err = SplitIndexNameValue("=b")
  1081  	require.NoError(t, err)
  1082  	assert.Equal(t, "", k)
  1083  	assert.Equal(t, "b", v)
  1084  
  1085  	k, v, err = SplitIndexNameValue("a=b=c")
  1086  	require.NoError(t, err)
  1087  	assert.Equal(t, "a", k)
  1088  	assert.Equal(t, "b=c", v)
  1089  
  1090  	k, v, err = SplitIndexNameValue("=-jar")
  1091  	require.NoError(t, err)
  1092  	assert.Equal(t, "", k)
  1093  	assert.Equal(t, "-jar", v)
  1094  }
  1095  
  1096  type filter struct {
  1097  	fn func(object *RNode) (*RNode, error)
  1098  }
  1099  
  1100  func (c filter) Filter(object *RNode) (*RNode, error) {
  1101  	return c.fn(object)
  1102  }
  1103  
  1104  func TestResourceNode_Pipe(t *testing.T) {
  1105  	var r0, r1, r2, r3 *RNode
  1106  	var called []string
  1107  
  1108  	// check the nil value case
  1109  	_, err := r0.Pipe(FieldMatcher{Name: "foo"})
  1110  	require.NoError(t, err)
  1111  
  1112  	r0, r1, r2, r3 = &RNode{}, &RNode{}, &RNode{}, &RNode{}
  1113  	// all filters successful
  1114  	v, err := r0.Pipe(
  1115  		filter{fn: func(object *RNode) (*RNode, error) {
  1116  			assert.True(t, r0 == object)
  1117  			called = append(called, "a")
  1118  			return r1, nil
  1119  		}},
  1120  		filter{fn: func(object *RNode) (*RNode, error) {
  1121  			assert.True(t, object == r1, "function arg doesn't match last function output")
  1122  			called = append(called, "b")
  1123  			return r2, nil
  1124  		}},
  1125  		filter{fn: func(object *RNode) (*RNode, error) {
  1126  			assert.True(t, object == r2, "function arg doesn't match last function output")
  1127  			return r3, nil
  1128  		}},
  1129  	)
  1130  	assert.True(t, v == r3, "expected r3")
  1131  	assert.Nil(t, err)
  1132  	assert.Equal(t, called, []string{"a", "b"})
  1133  
  1134  	// filter returns nil
  1135  	called = []string{}
  1136  	v, err = r0.Pipe(
  1137  		filter{fn: func(object *RNode) (*RNode, error) {
  1138  			assert.True(t, r0 == object)
  1139  			called = append(called, "a")
  1140  			return r1, nil
  1141  		}},
  1142  		filter{fn: func(object *RNode) (*RNode, error) {
  1143  			assert.True(t, object == r1, "function arg doesn't match last function output")
  1144  			called = append(called, "b")
  1145  			return nil, nil
  1146  		}},
  1147  		filter{fn: func(object *RNode) (*RNode, error) {
  1148  			assert.Fail(t, "function should be run after error")
  1149  			return nil, nil
  1150  		}},
  1151  	)
  1152  	assert.Nil(t, v)
  1153  	assert.Nil(t, err)
  1154  	assert.Equal(t, called, []string{"a", "b"})
  1155  
  1156  	// filter returns an error
  1157  	called = []string{}
  1158  	v, err = r0.Pipe(
  1159  		filter{fn: func(object *RNode) (*RNode, error) {
  1160  			assert.True(t, r0 == object)
  1161  			called = append(called, "a")
  1162  			return r1, nil
  1163  		}},
  1164  		filter{fn: func(object *RNode) (*RNode, error) {
  1165  			assert.True(t, object == r1, "function arg doesn't match last function output")
  1166  			called = append(called, "b")
  1167  			return r1, fmt.Errorf("expected-error")
  1168  		}},
  1169  		filter{fn: func(object *RNode) (*RNode, error) {
  1170  			assert.Fail(t, "function should be run after error")
  1171  			return nil, nil
  1172  		}},
  1173  	)
  1174  	assert.True(t, v == r1, "expected r1 as value")
  1175  	assert.EqualError(t, err, "expected-error")
  1176  	assert.Equal(t, called, []string{"a", "b"})
  1177  }
  1178  
  1179  func TestClearAnnotation(t *testing.T) {
  1180  	// create metadata.annotations field
  1181  	r0 := assertNoError(t)(Parse(`apiVersion: apps/v1
  1182  kind: Deployment
  1183  metadata:
  1184   annotations:
  1185     z: y
  1186     a.b.c: d.e.f
  1187     s: t
  1188  `))
  1189  
  1190  	rn := assertNoError(t)(r0.Pipe(ClearAnnotation("a.b.c")))
  1191  	assert.Equal(t, "d.e.f\n", assertNoErrorString(t)(rn.String()))
  1192  	assert.Equal(t, `apiVersion: apps/v1
  1193  kind: Deployment
  1194  metadata:
  1195    annotations:
  1196      z: y
  1197      s: t
  1198  `, assertNoErrorString(t)(r0.String()))
  1199  }
  1200  
  1201  func TestGetAnnotation(t *testing.T) {
  1202  	r0 := assertNoError(t)(Parse(`apiVersion: apps/v1
  1203  kind: Deployment
  1204  metadata:
  1205   labels:
  1206     app: java
  1207   annotations:
  1208     a.b.c: d.e.f
  1209     g: h
  1210     i: j
  1211     k: l
  1212   name: app`))
  1213  
  1214  	rn := assertNoError(t)(
  1215  		r0.Pipe(GetAnnotation("a.b.c")))
  1216  	assert.Equal(t, "d.e.f\n", assertNoErrorString(t)(rn.String()))
  1217  }
  1218  
  1219  func TestSetAnnotation_Fn(t *testing.T) {
  1220  	// create metadata.annotations field
  1221  	r0 := assertNoError(t)(Parse(`apiVersion: apps/v1
  1222  kind: Deployment`))
  1223  
  1224  	rn := assertNoError(t)(r0.Pipe(SetAnnotation("a.b.c", "d.e.f")))
  1225  	assert.Equal(t, "'d.e.f'\n", assertNoErrorString(t)(rn.String()))
  1226  	assert.Equal(t, `apiVersion: apps/v1
  1227  kind: Deployment
  1228  metadata:
  1229    annotations:
  1230      a.b.c: 'd.e.f'
  1231  `, assertNoErrorString(t)(r0.String()))
  1232  }
  1233  
  1234  func TestUpdateAnnotation_Fn(t *testing.T) {
  1235  	// create metadata.annotations field
  1236  	r0 := assertNoError(t)(Parse(`apiVersion: apps/v1
  1237  kind: Deployment
  1238  metadata:
  1239    annotations:
  1240      a.b.c: "h.i.j"
  1241  `))
  1242  
  1243  	rn := assertNoError(t)(r0.Pipe(SetAnnotation("a.b.c", "d.e.f")))
  1244  	assert.Equal(t, "\"d.e.f\"\n", assertNoErrorString(t)(rn.String()))
  1245  	assert.Equal(t, `apiVersion: apps/v1
  1246  kind: Deployment
  1247  metadata:
  1248    annotations:
  1249      a.b.c: "d.e.f"
  1250  `, assertNoErrorString(t)(r0.String()))
  1251  }
  1252  
  1253  func TestRNode_GetMeta(t *testing.T) {
  1254  	s := `apiVersion: v1/apps
  1255  kind: Deployment
  1256  metadata:
  1257    name: foo
  1258    namespace: bar
  1259    labels:
  1260      kl: vl
  1261    annotations:
  1262      ka: va
  1263  `
  1264  	node, err := Parse(s)
  1265  	if !assert.NoError(t, err) {
  1266  		return
  1267  	}
  1268  	meta, err := node.GetMeta()
  1269  	if !assert.NoError(t, err) {
  1270  		return
  1271  	}
  1272  	assert.Equal(t, ResourceMeta{
  1273  		TypeMeta: TypeMeta{
  1274  			Kind:       "Deployment",
  1275  			APIVersion: "v1/apps",
  1276  		},
  1277  		ObjectMeta: ObjectMeta{
  1278  			NameMeta: NameMeta{
  1279  				Name:      "foo",
  1280  				Namespace: "bar",
  1281  			},
  1282  			Annotations: map[string]string{
  1283  				"ka": "va",
  1284  			},
  1285  			Labels: map[string]string{
  1286  				"kl": "vl",
  1287  			},
  1288  		},
  1289  	}, meta)
  1290  }
  1291  
  1292  func assertNoError(t *testing.T) func(o *RNode, err error) *RNode {
  1293  	t.Helper()
  1294  	return func(o *RNode, err error) *RNode {
  1295  		require.NoError(t, err)
  1296  		return o
  1297  	}
  1298  }
  1299  
  1300  func assertNoErrorString(t *testing.T) func(string, error) string {
  1301  	t.Helper()
  1302  	return func(s string, err error) string {
  1303  		require.NoError(t, err)
  1304  		return s
  1305  	}
  1306  }
  1307  

View as plain text