github.com/tomwright/dasel@v1.27.3/internal/command/put_internal_test.go (about)

     1  package command
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"github.com/tomwright/dasel/storage"
     7  	"io"
     8  	"reflect"
     9  	"strings"
    10  	"testing"
    11  )
    12  
    13  func TestParseValue(t *testing.T) {
    14  	tests := []struct {
    15  		Value     string
    16  		ValueType string
    17  		Out       interface{}
    18  		Err       error
    19  	}{
    20  		{Value: "a", ValueType: "string", Out: "a"},
    21  		{Value: "1", ValueType: "string", Out: "1"},
    22  		{Value: "1", ValueType: "int", Out: int64(1)},
    23  		{Value: "a", ValueType: "int", Err: fmt.Errorf("could not parse int [%s]: strconv.ParseInt: parsing \"%s\": invalid syntax", "a", "a")},
    24  		{Value: "true", ValueType: "string", Out: "true"},
    25  		{Value: "false", ValueType: "string", Out: "false"},
    26  		{Value: "true", ValueType: "bool", Out: true},
    27  		{Value: "false", ValueType: "bool", Out: false},
    28  		{Value: "a", ValueType: "bool", Err: fmt.Errorf("could not parse bool [%s]: unhandled value", "a")},
    29  		{Value: "a", ValueType: "bad", Err: fmt.Errorf("unhandled type: %s", "bad")},
    30  	}
    31  
    32  	for _, testCase := range tests {
    33  		tc := testCase
    34  		t.Run(fmt.Sprintf("%s_%s", tc.Value, tc.ValueType), func(t *testing.T) {
    35  			got, err := parseValue(tc.Value, tc.ValueType)
    36  			if tc.Err == nil && err != nil {
    37  				t.Errorf("expected err %v, got %v", tc.Err, err)
    38  				return
    39  			}
    40  			if tc.Err != nil && err == nil {
    41  				t.Errorf("expected err %v, got %v", tc.Err, err)
    42  				return
    43  			}
    44  			if tc.Err != nil && err != nil && err.Error() != tc.Err.Error() {
    45  				t.Errorf("expected err %v, got %v", tc.Err, err)
    46  				return
    47  			}
    48  			if !reflect.DeepEqual(tc.Out, got) {
    49  				t.Errorf("expected result %v, got %v", tc.Out, got)
    50  			}
    51  		})
    52  	}
    53  }
    54  
    55  func TestShouldReadFromStdin(t *testing.T) {
    56  	if exp, got := false, shouldReadFromStdin("asd"); exp != got {
    57  		t.Errorf("expected %v, got %v", exp, got)
    58  	}
    59  	if exp, got := true, shouldReadFromStdin(""); exp != got {
    60  		t.Errorf("expected %v, got %v", exp, got)
    61  	}
    62  }
    63  
    64  func TestGetReadParser(t *testing.T) {
    65  	tests := []struct {
    66  		File   string
    67  		Parser string
    68  		Out    storage.Parser
    69  		Err    error
    70  	}{
    71  		{File: "a.json", Out: &storage.JSONParser{}},
    72  		{Parser: "json", Out: &storage.JSONParser{}},
    73  		{File: "a.yaml", Out: &storage.YAMLParser{}},
    74  		{File: "a.yml", Out: &storage.YAMLParser{}},
    75  		{Parser: "yaml", Out: &storage.YAMLParser{}},
    76  		{File: "a.txt", Err: fmt.Errorf("could not get read parser from filename: unknown parser: .txt")},
    77  		{Parser: "txt", Err: fmt.Errorf("could not get read parser: unknown parser: txt")},
    78  	}
    79  
    80  	for _, testCase := range tests {
    81  		tc := testCase
    82  		t.Run("Test", func(t *testing.T) {
    83  			got, err := getReadParser(tc.File, tc.Parser, "")
    84  			if tc.Err == nil && err != nil {
    85  				t.Errorf("expected err %v, got %v", tc.Err, err)
    86  				return
    87  			}
    88  			if tc.Err != nil && err == nil {
    89  				t.Errorf("expected err %v, got %v", tc.Err, err)
    90  				return
    91  			}
    92  			if tc.Err != nil && err != nil && err.Error() != tc.Err.Error() {
    93  				t.Errorf("expected err %v, got %v", tc.Err, err)
    94  				return
    95  			}
    96  			if tc.Out != got {
    97  				t.Errorf("expected result %v, got %v", tc.Out, got)
    98  			}
    99  		})
   100  	}
   101  }
   102  
   103  func putTest(in string, parser string, selector string, value string, valueType string, out string, expErr error, initOptions ...func(options *genericPutOptions)) func(t *testing.T) {
   104  	return func(t *testing.T) {
   105  		outputBuffer := bytes.NewBuffer([]byte{})
   106  
   107  		opts := genericPutOptions{
   108  			Parser:    parser,
   109  			Selector:  selector,
   110  			Value:     value,
   111  			ValueType: valueType,
   112  			Reader:    strings.NewReader(in),
   113  			Writer:    outputBuffer,
   114  		}
   115  
   116  		for _, initOption := range initOptions {
   117  			initOption(&opts)
   118  		}
   119  
   120  		err := runGenericPutCommand(opts, nil)
   121  
   122  		if expErr == nil && err != nil {
   123  			t.Errorf("expected err %v, got %v", expErr, err)
   124  			return
   125  		}
   126  		if expErr != nil && err == nil {
   127  			t.Errorf("expected err %v, got %v", expErr, err)
   128  			return
   129  		}
   130  		if expErr != nil && err != nil && err.Error() != expErr.Error() {
   131  			t.Errorf("expected err %v, got %v", expErr, err)
   132  			return
   133  		}
   134  
   135  		output, err := io.ReadAll(outputBuffer)
   136  		if err != nil {
   137  			t.Errorf("unexpected error reading output buffer: %s", err)
   138  			return
   139  		}
   140  
   141  		out = strings.TrimSpace(out)
   142  		got := strings.TrimSpace(string(output))
   143  
   144  		if out != got {
   145  			t.Errorf("expected result:\n%s\ngot:\n%s", out, got)
   146  		}
   147  	}
   148  }
   149  
   150  func putObjectTest(in string, parser string, selector string, values []string, valueTypes []string, out string, expErr error) func(t *testing.T) {
   151  	return func(t *testing.T) {
   152  		outputBuffer := bytes.NewBuffer([]byte{})
   153  
   154  		err := runPutObjectCommand(putObjectOpts{
   155  			Parser:      parser,
   156  			Selector:    selector,
   157  			InputValues: values,
   158  			InputTypes:  valueTypes,
   159  			Reader:      strings.NewReader(in),
   160  			Writer:      outputBuffer,
   161  		}, nil)
   162  
   163  		if expErr == nil && err != nil {
   164  			t.Errorf("expected err %v, got %v", expErr, err)
   165  			return
   166  		}
   167  		if expErr != nil && err == nil {
   168  			t.Errorf("expected err %v, got %v", expErr, err)
   169  			return
   170  		}
   171  		if expErr != nil && err != nil && err.Error() != expErr.Error() {
   172  			t.Errorf("expected err %v, got %v", expErr, err)
   173  			return
   174  		}
   175  
   176  		output, err := io.ReadAll(outputBuffer)
   177  		if err != nil {
   178  			t.Errorf("unexpected error reading output buffer: %s", err)
   179  			return
   180  		}
   181  
   182  		out = strings.TrimSpace(out)
   183  		got := strings.TrimSpace(string(output))
   184  
   185  		if out != got {
   186  			t.Errorf("expected result:\n%s\ngot:\n%s", out, got)
   187  		}
   188  	}
   189  }
   190  
   191  func TestPut_MissingParserFlag(t *testing.T) {
   192  	err := runGenericPutCommand(genericPutOptions{}, nil)
   193  	if err == nil || err.Error() != "read parser flag required when reading from stdin" {
   194  		t.Errorf("unexpected error: %v", err)
   195  	}
   196  }
   197  
   198  func TestPut_InvalidVarType(t *testing.T) {
   199  	err := runGenericPutCommand(genericPutOptions{Parser: "yaml", ValueType: "int", Value: "asd", Reader: bytes.NewBuffer([]byte{})}, nil)
   200  	if err == nil || err.Error() != "could not parse int [asd]: strconv.ParseInt: parsing \"asd\": invalid syntax" {
   201  		t.Errorf("unexpected error: %v", err)
   202  	}
   203  }
   204  
   205  func TestPut_FailedWrite(t *testing.T) {
   206  	err := runGenericPutCommand(genericPutOptions{Parser: "yaml", ValueType: "string", Selector: ".name", Value: "asd", Reader: bytes.NewBuffer([]byte{}), Writer: &failingWriter{}}, nil)
   207  	if err == nil || err.Error() != "could not write output: could not write to output file: could not write data: i am meant to fail at writing" {
   208  		t.Errorf("unexpected error: %v", err)
   209  	}
   210  }
   211  
   212  func TestPut_ObjectMissingReadParserFlag(t *testing.T) {
   213  	err := runPutObjectCommand(putObjectOpts{}, nil)
   214  	if err == nil || err.Error() != "read parser flag required when reading from stdin" {
   215  		t.Errorf("unexpected error: %v", err)
   216  	}
   217  }
   218  
   219  func TestPut_ObjectMissingWriteParserFlag(t *testing.T) {
   220  	err := runPutObjectCommand(putObjectOpts{
   221  		ReadParser:  "yaml",
   222  		WriteParser: "bad",
   223  		Reader:      bytes.NewReader([]byte(`name: Tom`)),
   224  		Writer:      new(bytes.Buffer),
   225  		Selector:    ".name",
   226  		InputTypes:  []string{"string"},
   227  		InputValues: []string{"name=Tom"},
   228  	}, nil)
   229  	if err == nil || err.Error() != "could not get write parser: unknown parser: bad" {
   230  		t.Errorf("unexpected error: %v", err)
   231  	}
   232  }
   233  
   234  func TestPut_DocumentMissingReadParserFlag(t *testing.T) {
   235  	err := runPutDocumentCommand(putDocumentOpts{}, nil)
   236  	if err == nil || err.Error() != "read parser flag required when reading from stdin" {
   237  		t.Errorf("unexpected error: %v", err)
   238  	}
   239  }
   240  
   241  func TestPut_DocumentMissingWriteParserFlag(t *testing.T) {
   242  	err := runPutDocumentCommand(putDocumentOpts{
   243  		ReadParser:     "yaml",
   244  		WriteParser:    "bad",
   245  		Reader:         bytes.NewReader([]byte(`name: Tom`)),
   246  		Writer:         new(bytes.Buffer),
   247  		Selector:       ".name",
   248  		DocumentString: "first: Tom",
   249  		DocumentParser: "yaml",
   250  	}, nil)
   251  	if err == nil || err.Error() != "could not get write parser: unknown parser: bad" {
   252  		t.Errorf("unexpected error: %v", err)
   253  	}
   254  }
   255  
   256  func TestPut_ObjectInvalidTypes(t *testing.T) {
   257  	err := runPutObjectCommand(putObjectOpts{
   258  		File:        "../../tests/assets/example.json",
   259  		InputTypes:  []string{"string"},
   260  		InputValues: []string{"x", "y"},
   261  	}, nil)
   262  	if err == nil || err.Error() != "exactly 2 types are required, got 1" {
   263  		t.Errorf("unexpected error: %v", err)
   264  	}
   265  }
   266  
   267  func TestPut_JSON(t *testing.T) {
   268  	t.Run("SingleProperty", putTest(`{
   269    "details": {
   270      "age": 27,
   271      "name": "Tom"
   272    },
   273    "id": "1111"
   274  }`, "json", ".id", "2222", "string", `{
   275    "details": {
   276      "age": 27,
   277      "name": "Tom"
   278    },
   279    "id": "2222"
   280  }`, nil))
   281  
   282  	t.Run("SinglePropertyCompact", putTest(`{
   283    "details": {
   284      "age": 27,
   285      "name": "Tom"
   286    },
   287    "id": "1111"
   288  }`, "json", ".id", "2222", "string", `{"details":{"age":27,"name":"Tom"},"id":"2222"}`, nil,
   289  		func(options *genericPutOptions) {
   290  			options.Compact = true
   291  		}))
   292  
   293  	t.Run("ObjectPropertyString", putTest(`{
   294    "details": {
   295      "age": 27,
   296      "name": "Tom"
   297    },
   298    "id": "1111"
   299  }`, "json", ".details.name", "Frank", "string", `{
   300    "details": {
   301      "age": 27,
   302      "name": "Frank"
   303    },
   304    "id": "1111"
   305  }`, nil))
   306  
   307  	t.Run("ObjectPropertyInt", putTest(`{
   308    "details": {
   309      "age": 20,
   310      "name": "Tom"
   311    },
   312    "id": "1111"
   313  }`, "json", ".details.age", "27", "int", `{
   314    "details": {
   315      "age": 27,
   316      "name": "Tom"
   317    },
   318    "id": "1111"
   319  }`, nil))
   320  
   321  	t.Run("IndexString", putTest(`{
   322    "numbers": [
   323      "one",
   324      "two",
   325      "three"
   326    ]
   327  }`, "json", ".numbers.[1]", "four", "string", `{
   328    "numbers": [
   329      "one",
   330      "four",
   331      "three"
   332    ]
   333  }`, nil))
   334  
   335  	t.Run("DynamicString", putTest(`{
   336    "numbers": [
   337  	"one",
   338  	"two",
   339  	"three"
   340    ]
   341  }`, "json", ".numbers.(value=three)", "four", "string", `{
   342    "numbers": [
   343      "one",
   344      "two",
   345      "four"
   346    ]
   347  }`, nil))
   348  
   349  	t.Run("DynamicInt", putTest(`{
   350    "numbers": [
   351  	1,
   352  	2,
   353  	3
   354    ]
   355  }`, "json", ".numbers.(value=3)", "4", "int", `{
   356    "numbers": [
   357      1,
   358      2,
   359      4
   360    ]
   361  }`, nil))
   362  
   363  	t.Run("IndexInt", putTest(`{
   364    "numbers": [
   365      1,
   366      2,
   367      3
   368    ]
   369  }`, "json", ".numbers.[1]", "4", "int", `{
   370    "numbers": [
   371      1,
   372      4,
   373      3
   374    ]
   375  }`, nil))
   376  
   377  	t.Run("DynamicString", putTest(`{
   378    "numbers": [
   379      {
   380        "number": "one",
   381        "rank": 1
   382      },
   383      {
   384        "number": "two",
   385        "rank": 2
   386      },
   387      {
   388        "number": "three",
   389        "rank": 3
   390      }
   391    ]
   392  }`, "json", ".numbers.(number=two).number", "four", "string", `{
   393    "numbers": [
   394      {
   395        "number": "one",
   396        "rank": 1
   397      },
   398      {
   399        "number": "four",
   400        "rank": 2
   401      },
   402      {
   403        "number": "three",
   404        "rank": 3
   405      }
   406    ]
   407  }`, nil))
   408  
   409  	t.Run("DynamicInt", putTest(`{
   410    "numbers": [
   411      {
   412        "rank": 1,
   413        "number": "one"
   414      },
   415      {
   416        "rank": 2,
   417        "number": "two"
   418      },
   419      {
   420        "rank": 3,
   421        "number": "three"
   422      }
   423    ]
   424  }`, "json", ".numbers.(rank=2).rank", "4", "int", `{
   425    "numbers": [
   426      {
   427        "number": "one",
   428        "rank": 1
   429      },
   430      {
   431        "number": "two",
   432        "rank": 4
   433      },
   434      {
   435        "number": "three",
   436        "rank": 3
   437      }
   438    ]
   439  }`, nil))
   440  
   441  	t.Run("DynamicMapInt", putTest(`{
   442    "numbers": {
   443      "high": 3,
   444  	"low": 1,
   445  	"mid": 2
   446    }
   447  }`, "json", ".numbers.(.=3)", "5", "int", `{
   448    "numbers": {
   449      "high": 5,
   450      "low": 1,
   451      "mid": 2
   452    }
   453  }`, nil))
   454  
   455  	t.Run("OverwriteObject", putObjectTest(`{
   456    "numbers": [
   457      {
   458        "rank": 1,
   459        "number": "one"
   460      },
   461      {
   462        "rank": 2,
   463        "number": "two"
   464      },
   465      {
   466        "rank": 3,
   467        "number": "three"
   468      }
   469    ]
   470  }`, "json", ".numbers.[0]", []string{"number=five", "rank=5"}, []string{"string", "int"}, `{
   471    "numbers": [
   472      {
   473        "number": "five",
   474        "rank": 5
   475      },
   476      {
   477        "number": "two",
   478        "rank": 2
   479      },
   480      {
   481        "number": "three",
   482        "rank": 3
   483      }
   484    ]
   485  }`, nil))
   486  
   487  	t.Run("AppendObject", putObjectTest(`{
   488    "numbers": [
   489      {
   490        "rank": 1,
   491        "number": "one"
   492      },
   493      {
   494        "rank": 2,
   495        "number": "two"
   496      },
   497      {
   498        "rank": 3,
   499        "number": "three"
   500      }
   501    ]
   502  }`, "json", ".numbers.[]", []string{"number=five", "rank=5"}, []string{"string", "int"}, `{
   503    "numbers": [
   504      {
   505        "number": "one",
   506        "rank": 1
   507      },
   508      {
   509        "number": "two",
   510        "rank": 2
   511      },
   512      {
   513        "number": "three",
   514        "rank": 3
   515      },
   516      {
   517        "number": "five",
   518        "rank": 5
   519      }
   520    ]
   521  }`, nil))
   522  }
   523  
   524  func TestPut_YAML(t *testing.T) {
   525  	t.Run("SingleProperty", putTest(`
   526  details:
   527    age: 27
   528    name: Tom
   529  id: 1111
   530  `, "yaml", ".id", "2222", "string", `
   531  details:
   532    age: 27
   533    name: Tom
   534  id: "2222"
   535  `, nil))
   536  
   537  	t.Run("ObjectPropertyString", putTest(`
   538  details:
   539    age: 27
   540    name: Tom
   541  id: 1111
   542  `, "yaml", ".details.name", "Frank", "string", `details:
   543    age: 27
   544    name: Frank
   545  id: 1111
   546  `, nil))
   547  
   548  	t.Run("ObjectPropertyInt", putTest(`
   549  details:
   550    age: 20
   551    name: Tom
   552  id: 1111
   553  `, "yaml", ".details.age", "27", "int", `
   554  details:
   555    age: 27
   556    name: Tom
   557  id: 1111
   558  `, nil))
   559  
   560  	t.Run("IndexString", putTest(`
   561  numbers:
   562  - one
   563  - two
   564  - three
   565  `, "yaml", ".numbers.[1]", "four", "string", `
   566  numbers:
   567  - one
   568  - four
   569  - three
   570  `, nil))
   571  
   572  	t.Run("DynamicString", putTest(`
   573  numbers:
   574  - one
   575  - two
   576  - three
   577  `, "yaml", ".numbers.(value=three)", "four", "string", `
   578  numbers:
   579  - one
   580  - two
   581  - four
   582  `, nil))
   583  
   584  	t.Run("DynamicInt", putTest(`
   585  numbers:
   586  - 1
   587  - 2
   588  - 3
   589  `, "yaml", ".numbers.(value=3)", "4", "int", `
   590  numbers:
   591  - 1
   592  - 2
   593  - 4
   594  `, nil))
   595  
   596  	t.Run("IndexInt", putTest(`
   597  numbers:
   598  - 1
   599  - 2
   600  - 3
   601  `, "yaml", ".numbers.[1]", "4", "int", `
   602  numbers:
   603  - 1
   604  - 4
   605  - 3
   606  `, nil))
   607  
   608  	t.Run("DynamicString", putTest(`
   609  numbers:
   610  - number: one
   611    rank: 1
   612  - number: two
   613    rank: 2
   614  - number: three
   615    rank: 3
   616  `, "yaml", ".numbers.(number=two).number", "four", "string", `
   617  numbers:
   618  - number: one
   619    rank: 1
   620  - number: four
   621    rank: 2
   622  - number: three
   623    rank: 3
   624  `, nil))
   625  
   626  	t.Run("DynamicInt", putTest(`
   627  numbers:
   628  - number: one
   629    rank: 1
   630  - number: two
   631    rank: 2
   632  - number: three
   633    rank: 3
   634  `, "yaml", ".numbers.(rank=2).rank", "4", "int", `
   635  numbers:
   636  - number: one
   637    rank: 1
   638  - number: two
   639    rank: 4
   640  - number: three
   641    rank: 3
   642  `, nil))
   643  
   644  	t.Run("OverwriteObject", putObjectTest(`
   645  numbers:
   646  - number: one
   647    rank: 1
   648  - number: two
   649    rank: 2
   650  - number: three
   651    rank: 3
   652  `, "yaml", ".numbers.[0]", []string{"number=five", "rank=5"}, []string{"string", "int"}, `
   653  numbers:
   654  - number: five
   655    rank: 5
   656  - number: two
   657    rank: 2
   658  - number: three
   659    rank: 3
   660  `, nil))
   661  
   662  	t.Run("AppendObject", putObjectTest(`
   663  numbers:
   664  - number: one
   665    rank: 1
   666  - number: two
   667    rank: 2
   668  - number: three
   669    rank: 3
   670  `, "yaml", ".numbers.[]", []string{"number=five", "rank=5"}, []string{"string", "int"}, `
   671  numbers:
   672  - number: one
   673    rank: 1
   674  - number: two
   675    rank: 2
   676  - number: three
   677    rank: 3
   678  - number: five
   679    rank: 5
   680  `, nil))
   681  
   682  }
   683  
   684  func TestPut_TOML(t *testing.T) {
   685  	t.Run("SingleProperty", putTest(`
   686  id = "1111"
   687  
   688  [details]
   689    age = 27
   690    name = "Tom"
   691  `, "toml", ".id", "2222", "string", `
   692  id = "2222"
   693  
   694  [details]
   695    age = 27
   696    name = "Tom"
   697  `, nil))
   698  
   699  	t.Run("ObjectPropertyString", putTest(`
   700  id = "1111"
   701  
   702  [details]
   703    age = 27
   704    name = "Tom"
   705  `, "toml", ".details.name", "Frank", "string", `
   706  id = "1111"
   707  
   708  [details]
   709    age = 27
   710    name = "Frank"
   711  `, nil))
   712  
   713  	t.Run("ObjectPropertyInt", putTest(`
   714  id = "1111"
   715  
   716  [details]
   717    age = 20
   718    name = "Tom"
   719  `, "toml", ".details.age", "27", "int", `
   720  id = "1111"
   721  
   722  [details]
   723    age = 27
   724    name = "Tom"
   725  `, nil))
   726  
   727  	t.Run("IndexString", putTest(`
   728  numbers = ["one", "two", "three"]
   729  `, "toml", ".numbers.[1]", "four", "string", `
   730  numbers = ["one", "four", "three"]
   731  `, nil))
   732  
   733  	t.Run("DynamicString", putTest(`
   734  numbers = ["one", "two", "three"]
   735  `, "toml", ".numbers.(value=three)", "four", "string", `
   736  numbers = ["one", "two", "four"]
   737  `, nil))
   738  
   739  	t.Run("DynamicInt", putTest(`
   740  numbers = [1, 2, 3]
   741  `, "toml", ".numbers.(value=3)", "4", "int", `
   742  numbers = [1, 2, 4]
   743  `, nil))
   744  
   745  	t.Run("IndexInt", putTest(`
   746  numbers = [1, 2, 3]
   747  `, "toml", ".numbers.[1]", "4", "int", `
   748  numbers = [1, 4, 3]
   749  `, nil))
   750  
   751  	t.Run("DynamicString", putTest(`
   752  [[numbers]]
   753    number = "one"
   754    rank = 1
   755  
   756  [[numbers]]
   757    number = "two"
   758    rank = 2
   759  
   760  [[numbers]]
   761    number = "three"
   762    rank = 3
   763  `, "toml", ".numbers.(number=two).number", "four", "string", `
   764  [[numbers]]
   765    number = "one"
   766    rank = 1
   767  
   768  [[numbers]]
   769    number = "four"
   770    rank = 2
   771  
   772  [[numbers]]
   773    number = "three"
   774    rank = 3
   775  `, nil))
   776  
   777  	t.Run("DynamicInt", putTest(`
   778  [[numbers]]
   779    number = "one"
   780    rank = 1
   781  
   782  [[numbers]]
   783    number = "two"
   784    rank = 2
   785  
   786  [[numbers]]
   787    number = "three"
   788    rank = 3
   789  `, "toml", ".numbers.(rank=2).rank", "4", "int", `
   790  [[numbers]]
   791    number = "one"
   792    rank = 1
   793  
   794  [[numbers]]
   795    number = "two"
   796    rank = 4
   797  
   798  [[numbers]]
   799    number = "three"
   800    rank = 3
   801  `, nil))
   802  
   803  	t.Run("OverwriteObject", putObjectTest(`
   804  [[numbers]]
   805    number = "one"
   806    rank = 1
   807  
   808  [[numbers]]
   809    number = "two"
   810    rank = 2
   811  
   812  [[numbers]]
   813    number = "three"
   814    rank = 3
   815  `, "toml", ".numbers.[0]", []string{"number=five", "rank=5"}, []string{"string", "int"}, `
   816  [[numbers]]
   817    number = "five"
   818    rank = 5
   819  
   820  [[numbers]]
   821    number = "two"
   822    rank = 2
   823  
   824  [[numbers]]
   825    number = "three"
   826    rank = 3
   827  `, nil))
   828  
   829  	t.Run("AppendObject", putObjectTest(`
   830  [[numbers]]
   831    number = "one"
   832    rank = 1
   833  
   834  [[numbers]]
   835    number = "two"
   836    rank = 2
   837  
   838  [[numbers]]
   839    number = "three"
   840    rank = 3
   841  `, "toml", ".numbers.[]", []string{"number=five", "rank=5"}, []string{"string", "int"}, `
   842  [[numbers]]
   843    number = "one"
   844    rank = 1
   845  
   846  [[numbers]]
   847    number = "two"
   848    rank = 2
   849  
   850  [[numbers]]
   851    number = "three"
   852    rank = 3
   853  
   854  [[numbers]]
   855    number = "five"
   856    rank = 5
   857  `, nil))
   858  }