package wand import ( "fmt" "strings" "testing" ) func TestConfig(t *testing.T) { type f struct{ One, SecondVar string } ff := func(f f) string { return f.One + f.SecondVar } type i struct{ One, SecondVar int } fi := func(i i) string { return fmt.Sprintf("%d;%d", i.One, i.SecondVar) } type m struct{ One, SecondVar []string } fm := func(m m) string { return strings.Join([]string{strings.Join(m.One, ","), strings.Join(m.SecondVar, ",")}, ";") } t.Run( "common config var casing", testExec(testCase{impl: ff, conf: "one=bar\nsecond_var=baz", command: "foo"}, "", "barbaz"), ) t.Run( "camel casing", testExec(testCase{impl: ff, conf: "one=bar\nsecondVar=baz", command: "foo"}, "", "barbaz"), ) t.Run( "empty var", testExec(testCase{impl: ff, conf: "one=bar\nsecondVar=", command: "foo"}, "", "bar"), ) t.Run( "discard env var", testExec(testCase{impl: ff, conf: "one=bar\nsecondVar=baz\none", command: "foo"}, "", "baz"), ) t.Run( "eq in value", // this one is a good example for fixing the error reporting in the parser. Try it by removing the // quotes: testExec(testCase{impl: ff, conf: "one=\"bar=baz\"", command: "foo"}, "", "bar=baz"), ) t.Run( "keeps original name", testExec(testCase{impl: fi, conf: "ONE=bar", command: "foo"}, "ONE", ""), ) t.Run( "keeps original name, last wins on conflict", testExec(testCase{impl: fi, conf: "ONE=bar\none=baz", command: "foo"}, "one", ""), ) t.Run( "2 entries", testExec(testCase{impl: fm, conf: "one=bar\none=baz", command: "foo"}, "", "bar,baz;"), ) t.Run( "3 entries", testExec(testCase{impl: fm, conf: "one=bar\none=baz\none=qux", command: "foo"}, "", "bar,baz,qux;"), ) t.Run( "with empty", testExec(testCase{impl: fm, conf: "one=bar\none=baz\none=\none=qux\none=", command: "foo"}, "", "bar,baz,,qux,;"), ) t.Run( "escape", testExec(testCase{impl: fm, conf: "one=bar\\\nbaz", command: "foo"}, "", "bar\nbaz;"), ) t.Run( "quote", testExec(testCase{impl: fm, conf: "one=\"bar\nbaz\"", command: "foo"}, "", "bar\nbaz;"), ) t.Run( "escape char", testExec(testCase{impl: fm, conf: "one=bar\\\\\none=baz", command: "foo"}, "", "bar\\,baz;"), ) t.Run( "escape char last", testExec(testCase{impl: fm, conf: "one=bar\\", command: "foo"}, "parse failed", ""), ) t.Run( "discard in same doc", testExec(testCase{impl: fm, conf: "one=bar\nsecond-var=baz\none", command: "foo"}, "", ";baz"), ) t.Run( "discard in previous doc", testExec( testCase{ impl: fm, mergeConf: []string{"one=bar\nsecond-var=baz", "one\nsecond-var=qux"}, command: "foo", }, "", ";qux", ), ) t.Run( "discard in previous and same doc", testExec( testCase{ impl: fm, mergeConf: []string{"one=bar\nsecond-var=baz", "one\nsecond-var=qux\nsecond-var"}, command: "foo", }, "", ";", ), ) t.Run( "discard multiple values", testExec( testCase{ impl: fm, mergeConf: []string{"one=bar\none=baz\nsecond-var=baz", "one\nsecond-var=qux\nsecond-var"}, command: "foo", }, "", ";", ), ) t.Run("white space ignored", testExec(testCase{impl: fm, conf: "one = bar ", command: "foo"}, "", "bar;")) t.Run( "comments", testExec( testCase{ impl: fm, conf: "# comment on a line\none=bar # comment after an entry", command: "foo", }, "", "bar;", ), ) t.Run("invald key", testExec(testCase{impl: fm, conf: "one two = bar", command: "foo"}, "parse failed", "")) t.Run( "config file", testExec( testCase{ impl: fm, mergeConfTyped: []Config{ConfigFile("./internal/tests/testconfig.ini")}, command: "foo", }, "", "42;", ), ) t.Run( "config file error", testExec( testCase{ impl: fm, mergeConfTyped: []Config{ConfigFile("./internal/tests/testconfig-noexist.ini")}, command: "foo", }, "file", ), ) t.Run( "config file error optional", testExec( testCase{ impl: fm, mergeConfTyped: []Config{OptionalConfig(ConfigFile("./internal/tests/testconfig-noexist.ini"))}, command: "foo", }, "", ";", ), ) t.Run( "config from option", testExec( testCase{ impl: fm, mergeConfTyped: []Config{ConfigFromOption()}, command: "foo --second-var bar --config ./internal/tests/testconfig.ini", }, "", "42;bar", ), ) t.Run( "config from option shadowed", testExec( testCase{ impl: func(struct{ Config int }) {}, mergeConfTyped: []Config{ConfigFromOption()}, command: "foo --config ./internal/tests/testconfig.ini", }, "option reserved", ), ) t.Run( "dangling backslash", testExec( testCase{ impl: fm, conf: "one = foo\\", }, "parse failed", ), ) }