github.com/vishnusomank/figtree@v0.1.0/overwrite_test.go (about)

     1  package figtree
     2  
     3  import (
     4  	"os"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  	"github.com/stretchr/testify/require"
     9  	"gopkg.in/yaml.v3"
    10  )
    11  
    12  func init() {
    13  	StringifyValue = false
    14  }
    15  
    16  func TestOptionsOverwriteConfigD3(t *testing.T) {
    17  	opts := TestOptions{}
    18  	require.NoError(t, os.Chdir("d1/d2/d3"))
    19  	t.Cleanup(func() {
    20  		_ = os.Chdir("../../..")
    21  	})
    22  
    23  	arr1 := []StringOption{}
    24  	arr1 = append(arr1, StringOption{tSrc("../overwrite.yml", 8, 5), true, "d2arr1val1"})
    25  	arr1 = append(arr1, StringOption{tSrc("../overwrite.yml", 9, 5), true, "d2arr1val2"})
    26  
    27  	expected := TestOptions{
    28  		String1:    StringOption{tSrc("../overwrite.yml", 6, 7), true, "d2str1val1"},
    29  		LeaveEmpty: StringOption{},
    30  		Array1:     arr1,
    31  		Map1: map[string]StringOption{
    32  			"key0": {tSrc("../../overwrite.yml", 11, 9), true, "d1map1val0"},
    33  			"key1": {tSrc("../../overwrite.yml", 12, 9), true, "d1map1val1"},
    34  		},
    35  		Int1:   IntOption{tSrc("../../overwrite.yml", 13, 7), true, 111},
    36  		Float1: Float32Option{tSrc("../../overwrite.yml", 14, 9), true, 1.11},
    37  		Bool1:  BoolOption{tSrc("../overwrite.yml", 15, 8), true, false},
    38  	}
    39  
    40  	fig := newFigTreeFromEnv()
    41  	err := fig.LoadAllConfigs("overwrite.yml", &opts)
    42  	require.NoError(t, err)
    43  	require.Exactly(t, expected, opts)
    44  }
    45  
    46  func TestOptionsOverwriteConfigD2(t *testing.T) {
    47  	opts := TestOptions{}
    48  	require.NoError(t, os.Chdir("d1/d2"))
    49  	t.Cleanup(func() {
    50  		_ = os.Chdir("../..")
    51  	})
    52  
    53  	arr1 := []StringOption{}
    54  	arr1 = append(arr1, StringOption{tSrc("overwrite.yml", 8, 5), true, "d2arr1val1"})
    55  	arr1 = append(arr1, StringOption{tSrc("overwrite.yml", 9, 5), true, "d2arr1val2"})
    56  
    57  	expected := TestOptions{
    58  		String1:    StringOption{tSrc("overwrite.yml", 6, 7), true, "d2str1val1"},
    59  		LeaveEmpty: StringOption{},
    60  		Array1:     arr1,
    61  		Map1: map[string]StringOption{
    62  			"key0": {tSrc("../overwrite.yml", 11, 9), true, "d1map1val0"},
    63  			"key1": {tSrc("../overwrite.yml", 12, 9), true, "d1map1val1"},
    64  		},
    65  		Int1:   IntOption{tSrc("../overwrite.yml", 13, 7), true, 111},
    66  		Float1: Float32Option{tSrc("../overwrite.yml", 14, 9), true, 1.11},
    67  		Bool1:  BoolOption{tSrc("overwrite.yml", 15, 8), true, false},
    68  	}
    69  
    70  	fig := newFigTreeFromEnv()
    71  	err := fig.LoadAllConfigs("overwrite.yml", &opts)
    72  	assert.NoError(t, err)
    73  	assert.Exactly(t, expected, opts)
    74  }
    75  
    76  func TestBuiltinOverwriteConfigD3(t *testing.T) {
    77  	opts := TestBuiltin{}
    78  	require.NoError(t, os.Chdir("d1/d2/d3"))
    79  	t.Cleanup(func() {
    80  		_ = os.Chdir("../../..")
    81  	})
    82  
    83  	arr1 := []string{}
    84  	arr1 = append(arr1, "d2arr1val1")
    85  	arr1 = append(arr1, "d2arr1val2")
    86  
    87  	expected := TestBuiltin{
    88  		String1:    "d2str1val1",
    89  		LeaveEmpty: "",
    90  		Array1:     arr1,
    91  		Map1: map[string]string{
    92  			"key0": "d1map1val0",
    93  			"key1": "d1map1val1",
    94  		},
    95  		Int1:   111,
    96  		Float1: 1.11,
    97  		Bool1:  false,
    98  	}
    99  
   100  	fig := newFigTreeFromEnv()
   101  	err := fig.LoadAllConfigs("overwrite.yml", &opts)
   102  	assert.NoError(t, err)
   103  	assert.Exactly(t, expected, opts)
   104  }
   105  
   106  func TestBuiltinOverwriteConfigD2(t *testing.T) {
   107  	opts := TestBuiltin{}
   108  	require.NoError(t, os.Chdir("d1/d2"))
   109  	t.Cleanup(func() {
   110  		_ = os.Chdir("../..")
   111  	})
   112  
   113  	arr1 := []string{}
   114  	arr1 = append(arr1, "d2arr1val1")
   115  	arr1 = append(arr1, "d2arr1val2")
   116  
   117  	expected := TestBuiltin{
   118  		String1:    "d2str1val1",
   119  		LeaveEmpty: "",
   120  		Array1:     arr1,
   121  		Map1: map[string]string{
   122  			"key0": "d1map1val0",
   123  			"key1": "d1map1val1",
   124  		},
   125  		Int1:   111,
   126  		Float1: 1.11,
   127  		Bool1:  false,
   128  	}
   129  
   130  	fig := newFigTreeFromEnv()
   131  	err := fig.LoadAllConfigs("overwrite.yml", &opts)
   132  	assert.NoError(t, err)
   133  	assert.Exactly(t, expected, opts)
   134  }
   135  
   136  type TestArray struct {
   137  	IntArr      [2]int    `yaml:"intArr"`
   138  	PartialInt  [2]int    `yaml:"partialInt"`
   139  	TooManyInt  [2]int    `yaml:"tooManyInt"`
   140  	StrArr      [2]string `yaml:"strArr"`
   141  	ToOverwrite [2]string `yaml:"toOverwrite"`
   142  }
   143  
   144  func TestBuiltinOverwriteArrayD2(t *testing.T) {
   145  	opts := TestArray{}
   146  	require.NoError(t, os.Chdir("d1/d2"))
   147  	t.Cleanup(func() {
   148  		_ = os.Chdir("../..")
   149  	})
   150  
   151  	expected := TestArray{
   152  		IntArr:      [2]int{1, 2},
   153  		PartialInt:  [2]int{1, 0},
   154  		TooManyInt:  [2]int{1, 2},
   155  		StrArr:      [2]string{"abc", "def"},
   156  		ToOverwrite: [2]string{"c", "d"},
   157  	}
   158  
   159  	fig := newFigTreeFromEnv()
   160  	err := fig.LoadAllConfigs("array.yml", &opts)
   161  	assert.NoError(t, err)
   162  	assert.Exactly(t, expected, opts)
   163  }
   164  
   165  type TestOptionsArray struct {
   166  	IntArr      [2]IntOption    `yaml:"intArr"`
   167  	PartialInt  [2]IntOption    `yaml:"partialInt"`
   168  	TooManyInt  [2]IntOption    `yaml:"tooManyInt"`
   169  	StrArr      [2]StringOption `yaml:"strArr"`
   170  	ToOverwrite [2]StringOption `yaml:"toOverwrite"`
   171  }
   172  
   173  func TestOptionsOverwriteArrayD2(t *testing.T) {
   174  	opts := TestOptionsArray{}
   175  	require.NoError(t, os.Chdir("d1/d2"))
   176  	t.Cleanup(func() {
   177  		_ = os.Chdir("../..")
   178  	})
   179  
   180  	expected := TestOptionsArray{
   181  		IntArr: [2]IntOption{
   182  			{tSrc("array.yml", 1, 10), true, 1},
   183  			{tSrc("array.yml", 1, 12), true, 2},
   184  		},
   185  		PartialInt: [2]IntOption{
   186  			{tSrc("array.yml", 2, 14), true, 1},
   187  			{NewSource(""), false, 0},
   188  		},
   189  		TooManyInt: [2]IntOption{
   190  			{tSrc("array.yml", 3, 14), true, 1},
   191  			{tSrc("array.yml", 3, 16), true, 2},
   192  		},
   193  		StrArr: [2]StringOption{
   194  			{tSrc("array.yml", 4, 10), true, "abc"},
   195  			{tSrc("array.yml", 4, 15), true, "def"},
   196  		},
   197  		ToOverwrite: [2]StringOption{
   198  			{tSrc("../array.yml", 5, 15), true, "c"},
   199  			{tSrc("../array.yml", 5, 17), true, "d"},
   200  		},
   201  	}
   202  
   203  	fig := newFigTreeFromEnv()
   204  	err := fig.LoadAllConfigs("array.yml", &opts)
   205  	assert.NoError(t, err)
   206  	assert.Exactly(t, expected, opts)
   207  }
   208  
   209  // auto-upgrade:
   210  //   enabled: true
   211  
   212  func TestOverwritePartialStruct(t *testing.T) {
   213  	type MyStruct struct {
   214  		A StringOption `yaml:"a"`
   215  		B BoolOption   `yaml:"b"`
   216  	}
   217  	type data struct {
   218  		MyStruct MyStruct `yaml:"my-struct"`
   219  	}
   220  	configs := []struct {
   221  		Name string
   222  		Body string
   223  	}{{
   224  		Name: "test",
   225  		Body: `
   226  my-struct:
   227    b: true
   228  `,
   229  	}, {
   230  		Name: "../test",
   231  		Body: `
   232  config: {overwrite: [my-struct]}
   233  my-struct:
   234    b: false
   235    a: foo
   236  `,
   237  	}}
   238  	expected := data{
   239  		MyStruct: MyStruct{
   240  			A: StringOption{tSrc("../test", 5, 6), true, "foo"},
   241  			B: BoolOption{tSrc("../test", 4, 6), true, false},
   242  		},
   243  	}
   244  	sources := []ConfigSource{}
   245  	for _, c := range configs {
   246  		var node yaml.Node
   247  		err := yaml.Unmarshal([]byte(c.Body), &node)
   248  		require.NoError(t, err)
   249  		sources = append(sources, ConfigSource{
   250  			Config:   &node,
   251  			Filename: c.Name,
   252  		})
   253  	}
   254  	fig := newFigTreeFromEnv()
   255  	got := data{}
   256  	err := fig.LoadAllConfigSources(sources, &got)
   257  	require.NoError(t, err)
   258  	require.Equal(t, expected, got)
   259  }
   260  
   261  func TestOverwriteNil(t *testing.T) {
   262  	type MyStruct struct {
   263  		A StringOption `yaml:"a"`
   264  		B BoolOption   `yaml:"b"`
   265  	}
   266  	type data struct {
   267  		MyStruct MyStruct `yaml:"my-struct"`
   268  	}
   269  	config := `
   270  config: {overwrite: [my-struct]}
   271  my-struct:
   272  `
   273  	expected := data{
   274  		MyStruct: MyStruct{
   275  			A: StringOption{},
   276  			B: BoolOption{},
   277  		},
   278  	}
   279  	var node yaml.Node
   280  	err := yaml.Unmarshal([]byte(config), &node)
   281  	require.NoError(t, err)
   282  	fig := newFigTreeFromEnv()
   283  	got := data{}
   284  	err = fig.LoadConfigSource(&node, "test", &got)
   285  	require.NoError(t, err)
   286  	require.Equal(t, expected, got)
   287  }