summaryrefslogtreecommitdiff
path: root/config_test.go
diff options
context:
space:
mode:
authorDave Henderson <dhenderson@gmail.com>2024-06-09 19:25:17 -0400
committerGitHub <noreply@github.com>2024-06-09 19:25:17 -0400
commit47b74a5505d4c9979d24a8bcffde711a60c5f23a (patch)
tree479b4331848c549d69d0e2ba1f228dddb2069402 /config_test.go
parentdc41e375484759c09e0480b10a30f6f80318bb56 (diff)
chore(api)!: Overhauling config and rendering types (#2094)
Signed-off-by: Dave Henderson <dhenderson@gmail.com>
Diffstat (limited to 'config_test.go')
-rw-r--r--config_test.go891
1 files changed, 891 insertions, 0 deletions
diff --git a/config_test.go b/config_test.go
new file mode 100644
index 00000000..de196459
--- /dev/null
+++ b/config_test.go
@@ -0,0 +1,891 @@
+package gomplate
+
+import (
+ "net/http"
+ "net/url"
+ "runtime"
+ "strings"
+ "testing"
+ "time"
+
+ "github.com/hairyhenderson/gomplate/v4/internal/iohelpers"
+ "github.com/hairyhenderson/yaml"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestParseConfigFile(t *testing.T) {
+ t.Parallel()
+ in := "in: hello world\n"
+ expected := &Config{
+ Input: "hello world",
+ }
+ cf, err := Parse(strings.NewReader(in))
+ require.NoError(t, err)
+ assert.Equal(t, expected, cf)
+
+ // legacy array form for templates (will be removed in v4.1.0 or so)
+ in = `in: hello world
+templates:
+ - foo=bar
+ - baz=https://example.com/baz.yaml
+`
+
+ expected = &Config{
+ Input: "hello world",
+ Templates: map[string]DataSource{
+ "foo": {URL: mustURL("bar")},
+ "baz": {URL: mustURL("https://example.com/baz.yaml")},
+ },
+ }
+ cf, err = Parse(strings.NewReader(in))
+ require.NoError(t, err)
+ assert.Equal(t, expected, cf)
+
+ in = `in: hello world
+outputFiles: [out.txt]
+chmod: 644
+
+datasources:
+ data:
+ url: file:///data.json
+ moredata:
+ url: https://example.com/more.json
+ header:
+ Authorization: ["Bearer abcd1234"]
+
+context:
+ .:
+ url: file:///data.json
+
+plugins:
+ foo:
+ cmd: echo
+ pipe: true
+
+templates:
+ foo:
+ url: file:///tmp/foo.t
+
+pluginTimeout: 2s
+`
+ expected = &Config{
+ Input: "hello world",
+ OutputFiles: []string{"out.txt"},
+ DataSources: map[string]DataSource{
+ "data": {
+ URL: mustURL("file:///data.json"),
+ },
+ "moredata": {
+ URL: mustURL("https://example.com/more.json"),
+ Header: map[string][]string{
+ "Authorization": {"Bearer abcd1234"},
+ },
+ },
+ },
+ Context: map[string]DataSource{
+ ".": {
+ URL: mustURL("file:///data.json"),
+ },
+ },
+ OutMode: "644",
+ Plugins: map[string]PluginConfig{
+ "foo": {Cmd: "echo", Pipe: true},
+ },
+ Templates: map[string]DataSource{"foo": {URL: mustURL("file:///tmp/foo.t")}},
+ PluginTimeout: 2 * time.Second,
+ }
+
+ cf, err = Parse(strings.NewReader(in))
+ require.NoError(t, err)
+ assert.EqualValues(t, expected, cf)
+}
+
+func mustURL(s string) *url.URL {
+ u, err := url.Parse(s)
+ if err != nil {
+ panic(err)
+ }
+
+ return u
+}
+
+func TestValidate(t *testing.T) {
+ t.Parallel()
+ require.NoError(t, validateConfig(""))
+
+ require.Error(t, validateConfig(`in: foo
+inputFiles: [bar]
+`))
+ require.Error(t, validateConfig(`inputDir: foo
+inputFiles: [bar]
+`))
+ require.Error(t, validateConfig(`inputDir: foo
+in: bar
+`))
+
+ require.Error(t, validateConfig(`outputDir: foo
+outputFiles: [bar]
+`))
+
+ require.Error(t, validateConfig(`in: foo
+outputFiles: [bar, baz]
+`))
+
+ require.Error(t, validateConfig(`inputFiles: [foo]
+outputFiles: [bar, baz]
+`))
+
+ require.Error(t, validateConfig(`outputDir: foo
+outputFiles: [bar]
+`))
+
+ require.Error(t, validateConfig(`outputDir: foo
+`))
+
+ require.Error(t, validateConfig(`outputMap: foo
+`))
+
+ require.Error(t, validateConfig(`outputMap: foo
+outputFiles: [bar]
+`))
+
+ require.Error(t, validateConfig(`inputDir: foo
+outputDir: bar
+outputMap: bar
+`))
+
+ require.Error(t, validateConfig(`execPipe: true
+`))
+ require.Error(t, validateConfig(`execPipe: true
+postExec: ""
+`))
+
+ require.NoError(t, validateConfig(`execPipe: true
+postExec: [echo, foo]
+`))
+
+ require.Error(t, validateConfig(`execPipe: true
+outputFiles: [foo]
+postExec: [echo]
+`))
+
+ require.NoError(t, validateConfig(`execPipe: true
+inputFiles: ['-']
+postExec: [echo]
+`))
+
+ require.Error(t, validateConfig(`inputDir: foo
+execPipe: true
+outputDir: foo
+postExec: [echo]
+`))
+
+ require.Error(t, validateConfig(`inputDir: foo
+execPipe: true
+outputMap: foo
+postExec: [echo]
+`))
+}
+
+func validateConfig(c string) error {
+ in := strings.NewReader(c)
+ cfg, err := Parse(in)
+ if err != nil {
+ return err
+ }
+ err = cfg.Validate()
+ return err
+}
+
+func TestMergeFrom(t *testing.T) {
+ t.Parallel()
+ cfg := &Config{
+ Input: "hello world",
+ DataSources: map[string]DataSource{
+ "data": {
+ URL: mustURL("file:///data.json"),
+ },
+ "moredata": {
+ URL: mustURL("https://example.com/more.json"),
+ Header: http.Header{
+ "Authorization": {"Bearer abcd1234"},
+ },
+ },
+ },
+ Context: map[string]DataSource{
+ "foo": {
+ URL: mustURL("https://example.com/foo.yaml"),
+ Header: http.Header{
+ "Accept": {"application/yaml"},
+ },
+ },
+ },
+ OutMode: "644",
+ }
+ other := &Config{
+ OutputFiles: []string{"out.txt"},
+ DataSources: map[string]DataSource{
+ "data": {
+ Header: http.Header{
+ "Accept": {"foo/bar"},
+ },
+ },
+ },
+ Context: map[string]DataSource{
+ "foo": {
+ Header: http.Header{
+ "Accept": {"application/json"},
+ },
+ },
+ "bar": {URL: mustURL("stdin:///")},
+ },
+ }
+
+ expected := &Config{
+ Input: "hello world",
+ OutputFiles: []string{"out.txt"},
+ DataSources: map[string]DataSource{
+ "data": {
+ URL: mustURL("file:///data.json"),
+ Header: http.Header{
+ "Accept": {"foo/bar"},
+ },
+ },
+ "moredata": {
+ URL: mustURL("https://example.com/more.json"),
+ Header: http.Header{
+ "Authorization": {"Bearer abcd1234"},
+ },
+ },
+ },
+ Context: map[string]DataSource{
+ "foo": {
+ URL: mustURL("https://example.com/foo.yaml"),
+ Header: http.Header{
+ "Accept": {"application/json"},
+ },
+ },
+ "bar": {URL: mustURL("stdin:///")},
+ },
+ OutMode: "644",
+ }
+
+ assert.EqualValues(t, expected, cfg.MergeFrom(other))
+
+ cfg = &Config{
+ Input: "hello world",
+ }
+ other = &Config{
+ InputFiles: []string{"in.tmpl", "in2.tmpl"},
+ OutputFiles: []string{"out", "out2"},
+ }
+ expected = &Config{
+ InputFiles: []string{"in.tmpl", "in2.tmpl"},
+ OutputFiles: []string{"out", "out2"},
+ }
+
+ assert.EqualValues(t, expected, cfg.MergeFrom(other))
+
+ cfg = &Config{
+ Input: "hello world",
+ OutputFiles: []string{"out", "out2"},
+ }
+ other = &Config{
+ InputDir: "in/",
+ OutputDir: "out/",
+ }
+ expected = &Config{
+ InputDir: "in/",
+ OutputDir: "out/",
+ }
+
+ assert.EqualValues(t, expected, cfg.MergeFrom(other))
+
+ cfg = &Config{
+ Input: "hello world",
+ OutputFiles: []string{"out"},
+ }
+ other = &Config{
+ Input: "hi",
+ ExecPipe: true,
+ PostExec: []string{"cat"},
+ }
+ expected = &Config{
+ Input: "hi",
+ ExecPipe: true,
+ PostExec: []string{"cat"},
+ }
+
+ assert.EqualValues(t, expected, cfg.MergeFrom(other))
+
+ cfg = &Config{
+ Input: "hello world",
+ OutputFiles: []string{"-"},
+ Plugins: map[string]PluginConfig{
+ "sleep": {Cmd: "echo"},
+ },
+ PluginTimeout: 500 * time.Microsecond,
+ }
+ other = &Config{
+ InputFiles: []string{"-"},
+ OutputFiles: []string{"-"},
+ Plugins: map[string]PluginConfig{
+ "sleep": {Cmd: "sleep.sh"},
+ },
+ }
+ expected = &Config{
+ Input: "hello world",
+ OutputFiles: []string{"-"},
+ Plugins: map[string]PluginConfig{
+ "sleep": {Cmd: "sleep.sh"},
+ },
+ PluginTimeout: 500 * time.Microsecond,
+ }
+
+ assert.EqualValues(t, expected, cfg.MergeFrom(other))
+
+ cfg = &Config{
+ Input: "hello world",
+ OutMode: "644",
+ }
+ other = &Config{
+ OutputFiles: []string{"out.txt"},
+ Context: map[string]DataSource{
+ "foo": {
+ URL: mustURL("https://example.com/foo.yaml"),
+ Header: http.Header{
+ "Accept": {"application/json"},
+ },
+ },
+ "bar": {URL: mustURL("stdin:///")},
+ },
+ DataSources: map[string]DataSource{
+ "data": {
+ URL: mustURL("file:///data.json"),
+ },
+ "moredata": {
+ URL: mustURL("https://example.com/more.json"),
+ Header: http.Header{
+ "Authorization": {"Bearer abcd1234"},
+ },
+ },
+ },
+ }
+ expected = &Config{
+ Input: "hello world",
+ OutputFiles: []string{"out.txt"},
+ Context: map[string]DataSource{
+ "foo": {
+ URL: mustURL("https://example.com/foo.yaml"),
+ Header: http.Header{
+ "Accept": {"application/json"},
+ },
+ },
+ "bar": {URL: mustURL("stdin:///")},
+ },
+ DataSources: map[string]DataSource{
+ "data": {
+ URL: mustURL("file:///data.json"),
+ },
+ "moredata": {
+ URL: mustURL("https://example.com/more.json"),
+ Header: http.Header{
+ "Authorization": {"Bearer abcd1234"},
+ },
+ },
+ },
+ OutMode: "644",
+ }
+
+ assert.EqualValues(t, expected, cfg.MergeFrom(other))
+
+ // test template merging & a few other things
+ cfg = &Config{
+ InputDir: "indir/",
+ ExcludeGlob: []string{"*.txt"},
+ Templates: map[string]DataSource{
+ "foo": {
+ URL: mustURL("file:///foo.yaml"),
+ },
+ "bar": {
+ URL: mustURL("stdin:///"),
+ Header: http.Header{"Accept": {"application/json"}},
+ },
+ },
+ }
+ other = &Config{
+ ExcludeGlob: []string{"*.yaml"},
+ OutputMap: "${ .in }.out",
+ OutMode: "600",
+ LDelim: "${",
+ RDelim: "}",
+ Templates: map[string]DataSource{
+ "foo": {URL: mustURL("https://example.com/foo.yaml")},
+ "baz": {URL: mustURL("vault:///baz")},
+ },
+ }
+ expected = &Config{
+ InputDir: "indir/",
+ ExcludeGlob: []string{"*.yaml"},
+ OutputMap: "${ .in }.out",
+ OutMode: "600",
+ LDelim: "${",
+ RDelim: "}",
+ Templates: map[string]DataSource{
+ "foo": {URL: mustURL("https://example.com/foo.yaml")},
+ "bar": {
+ URL: mustURL("stdin:///"),
+ Header: http.Header{"Accept": {"application/json"}},
+ },
+ "baz": {URL: mustURL("vault:///baz")},
+ },
+ }
+
+ assert.EqualValues(t, expected, cfg.MergeFrom(other))
+}
+
+func TestParseDataSourceFlags(t *testing.T) {
+ t.Parallel()
+ cfg := &Config{}
+ err := cfg.ParseDataSourceFlags(nil, nil, nil, nil)
+ require.NoError(t, err)
+ assert.EqualValues(t, &Config{}, cfg)
+
+ cfg = &Config{}
+ err = cfg.ParseDataSourceFlags([]string{"foo/bar/baz.json"}, nil, nil, nil)
+ require.Error(t, err)
+
+ cfg = &Config{}
+ err = cfg.ParseDataSourceFlags([]string{"baz=foo/bar/baz.json"}, nil, nil, nil)
+ require.NoError(t, err)
+ expected := &Config{
+ DataSources: map[string]DataSource{
+ "baz": {URL: mustURL("foo/bar/baz.json")},
+ },
+ }
+ assert.EqualValues(t, expected, cfg, "expected: %+v\nactual: %+v\n", expected, cfg)
+
+ cfg = &Config{}
+ err = cfg.ParseDataSourceFlags(
+ []string{"baz=foo/bar/baz.json"},
+ nil,
+ nil,
+ []string{"baz=Accept: application/json"})
+ require.NoError(t, err)
+ assert.EqualValues(t, &Config{
+ DataSources: map[string]DataSource{
+ "baz": {
+ URL: mustURL("foo/bar/baz.json"),
+ Header: http.Header{
+ "Accept": {"application/json"},
+ },
+ },
+ },
+ }, cfg)
+
+ cfg = &Config{}
+ err = cfg.ParseDataSourceFlags(
+ []string{"baz=foo/bar/baz.json"},
+ []string{"foo=http://example.com"},
+ nil,
+ []string{
+ "foo=Accept: application/json",
+ "bar=Authorization: Basic xxxxx",
+ },
+ )
+ require.NoError(t, err)
+ assert.EqualValues(t, &Config{
+ DataSources: map[string]DataSource{
+ "baz": {URL: mustURL("foo/bar/baz.json")},
+ },
+ Context: map[string]DataSource{
+ "foo": {
+ URL: mustURL("http://example.com"),
+ Header: http.Header{
+ "Accept": {"application/json"},
+ },
+ },
+ },
+ ExtraHeaders: map[string]http.Header{
+ "bar": {"Authorization": {"Basic xxxxx"}},
+ },
+ }, cfg)
+
+ cfg = &Config{}
+ err = cfg.ParseDataSourceFlags(
+ nil,
+ nil,
+ []string{"foo=http://example.com", "file.tmpl", "tmpldir/"},
+ []string{"foo=Accept: application/json", "bar=Authorization: Basic xxxxx"},
+ )
+ require.NoError(t, err)
+ assert.EqualValues(t, &Config{
+ Templates: map[string]DataSource{
+ "foo": {
+ URL: mustURL("http://example.com"),
+ Header: http.Header{"Accept": {"application/json"}},
+ },
+ "file.tmpl": {URL: mustURL("file.tmpl")},
+ "tmpldir/": {URL: mustURL("tmpldir/")},
+ },
+ ExtraHeaders: map[string]http.Header{
+ "bar": {"Authorization": {"Basic xxxxx"}},
+ },
+ }, cfg)
+}
+
+func TestParsePluginFlags(t *testing.T) {
+ t.Parallel()
+ cfg := &Config{}
+ err := cfg.ParsePluginFlags(nil)
+ require.NoError(t, err)
+
+ cfg = &Config{}
+ err = cfg.ParsePluginFlags([]string{"foo=bar"})
+ require.NoError(t, err)
+ assert.EqualValues(t, &Config{Plugins: map[string]PluginConfig{"foo": {Cmd: "bar"}}}, cfg)
+}
+
+func TestConfig_String(t *testing.T) {
+ t.Run("defaults", func(t *testing.T) {
+ c := &Config{}
+ c.ApplyDefaults()
+
+ expected := `---
+inputFiles: ['-']
+outputFiles: ['-']
+leftDelim: '{{'
+rightDelim: '}}'
+missingKey: error
+pluginTimeout: 5s
+`
+ assert.Equal(t, expected, c.String())
+ })
+
+ t.Run("overridden values", func(t *testing.T) {
+ c := &Config{
+ LDelim: "L",
+ RDelim: "R",
+ Input: "foo",
+ OutputFiles: []string{"-"},
+ Templates: map[string]DataSource{
+ "foo": {URL: mustURL("https://www.example.com/foo.tmpl")},
+ "bar": {URL: mustURL("file:///tmp/bar.t")},
+ },
+ }
+ expected := `---
+in: foo
+outputFiles: ['-']
+leftDelim: L
+rightDelim: R
+templates:
+ foo:
+ url: https://www.example.com/foo.tmpl
+ bar:
+ url: file:///tmp/bar.t
+`
+ assert.YAMLEq(t, expected, c.String())
+ })
+
+ t.Run("long input", func(t *testing.T) {
+ c := &Config{
+ LDelim: "L",
+ RDelim: "R",
+ Input: "long input that should be truncated",
+ OutputFiles: []string{"-"},
+ Templates: map[string]DataSource{
+ "foo": {URL: mustURL("https://www.example.com/foo.tmpl")},
+ "bar": {URL: mustURL("file:///tmp/bar.t")},
+ },
+ }
+ expected := `---
+in: long inp...
+outputFiles: ['-']
+leftDelim: L
+rightDelim: R
+templates:
+ foo:
+ url: https://www.example.com/foo.tmpl
+ bar:
+ url: file:///tmp/bar.t
+`
+ assert.YAMLEq(t, expected, c.String())
+ })
+
+ t.Run("relative dirs", func(t *testing.T) {
+ c := &Config{
+ InputDir: "in/",
+ OutputDir: "out/",
+ }
+ expected := `---
+inputDir: in/
+outputDir: out/
+`
+ assert.YAMLEq(t, expected, c.String())
+ })
+
+ t.Run("outputmap", func(t *testing.T) {
+ c := &Config{
+ InputDir: "in/",
+ OutputMap: "{{ .in }}",
+ }
+ expected := `---
+inputDir: in/
+outputMap: '{{ .in }}'
+`
+
+ assert.YAMLEq(t, expected, c.String())
+ })
+
+ t.Run("pluginTimeout", func(t *testing.T) {
+ c := &Config{
+ PluginTimeout: 500 * time.Millisecond,
+ }
+ expected := `---
+pluginTimeout: 500ms
+`
+
+ assert.YAMLEq(t, expected, c.String())
+ })
+
+ t.Run("plugins", func(t *testing.T) {
+ c := &Config{
+ Plugins: map[string]PluginConfig{
+ "foo": {
+ Cmd: "bar",
+ Timeout: 1 * time.Second,
+ Pipe: true,
+ },
+ },
+ }
+ expected := `---
+plugins:
+ foo:
+ cmd: bar
+ timeout: 1s
+ pipe: true
+`
+
+ assert.YAMLEq(t, expected, c.String())
+ })
+}
+
+func TestApplyDefaults(t *testing.T) {
+ t.Parallel()
+ cfg := &Config{}
+
+ cfg.ApplyDefaults()
+ assert.EqualValues(t, []string{"-"}, cfg.InputFiles)
+ assert.EqualValues(t, []string{"-"}, cfg.OutputFiles)
+ assert.Empty(t, cfg.OutputDir)
+ assert.Equal(t, "{{", cfg.LDelim)
+ assert.Equal(t, "}}", cfg.RDelim)
+
+ cfg = &Config{
+ InputDir: "in",
+ }
+
+ cfg.ApplyDefaults()
+ assert.Empty(t, cfg.InputFiles)
+ assert.Empty(t, cfg.OutputFiles)
+ assert.Equal(t, ".", cfg.OutputDir)
+ assert.Equal(t, "{{", cfg.LDelim)
+ assert.Equal(t, "}}", cfg.RDelim)
+
+ cfg = &Config{
+ Input: "foo",
+ LDelim: "<",
+ RDelim: ">",
+ }
+
+ cfg.ApplyDefaults()
+ assert.Empty(t, cfg.InputFiles)
+ assert.EqualValues(t, []string{"-"}, cfg.OutputFiles)
+ assert.Empty(t, cfg.OutputDir)
+ assert.Equal(t, "<", cfg.LDelim)
+ assert.Equal(t, ">", cfg.RDelim)
+
+ cfg = &Config{
+ Input: "foo",
+ ExecPipe: true,
+ }
+
+ cfg.ApplyDefaults()
+ assert.Empty(t, cfg.InputFiles)
+ assert.EqualValues(t, []string{"-"}, cfg.OutputFiles)
+ assert.Empty(t, cfg.OutputDir)
+ assert.True(t, cfg.ExecPipe)
+
+ cfg = &Config{
+ InputDir: "foo",
+ OutputMap: "bar",
+ }
+
+ cfg.ApplyDefaults()
+ assert.Empty(t, cfg.InputFiles)
+ assert.Empty(t, cfg.Input)
+ assert.Empty(t, cfg.OutputFiles)
+ assert.Empty(t, cfg.OutputDir)
+ assert.False(t, cfg.ExecPipe)
+ assert.Equal(t, "bar", cfg.OutputMap)
+}
+
+func TestGetMode(t *testing.T) {
+ c := &Config{}
+ m, o, err := c.GetMode()
+ require.NoError(t, err)
+ assert.Equal(t, iohelpers.NormalizeFileMode(0), m)
+ assert.False(t, o)
+
+ c = &Config{OutMode: "755"}
+ m, o, err = c.GetMode()
+ require.NoError(t, err)
+ assert.Equal(t, iohelpers.NormalizeFileMode(0o755), m)
+ assert.True(t, o)
+
+ c = &Config{OutMode: "0755"}
+ m, o, err = c.GetMode()
+ require.NoError(t, err)
+ assert.Equal(t, iohelpers.NormalizeFileMode(0o755), m)
+ assert.True(t, o)
+
+ c = &Config{OutMode: "foo"}
+ _, _, err = c.GetMode()
+ require.Error(t, err)
+}
+
+func TestParseHeaderArgs(t *testing.T) {
+ args := []string{
+ "foo=Accept: application/json",
+ "bar=Authorization: Bearer supersecret",
+ }
+ expected := map[string]http.Header{
+ "foo": {
+ "Accept": {"application/json"},
+ },
+ "bar": {
+ "Authorization": {"Bearer supersecret"},
+ },
+ }
+ parsed, err := parseHeaderArgs(args)
+ require.NoError(t, err)
+ assert.Equal(t, expected, parsed)
+
+ _, err = parseHeaderArgs([]string{"foo"})
+ require.Error(t, err)
+
+ _, err = parseHeaderArgs([]string{"foo=bar"})
+ require.Error(t, err)
+
+ args = []string{
+ "foo=Accept: application/json",
+ "foo=Foo: bar",
+ "foo=foo: baz",
+ "foo=fOO: qux",
+ "bar=Authorization: Bearer supersecret",
+ }
+ expected = map[string]http.Header{
+ "foo": {
+ "Accept": {"application/json"},
+ "Foo": {"bar", "baz", "qux"},
+ },
+ "bar": {
+ "Authorization": {"Bearer supersecret"},
+ },
+ }
+ parsed, err = parseHeaderArgs(args)
+ require.NoError(t, err)
+ assert.Equal(t, expected, parsed)
+}
+
+func TestParseDatasourceArgNoAlias(t *testing.T) {
+ alias, ds, err := parseDatasourceArg("foo.json")
+ require.NoError(t, err)
+ assert.Equal(t, "foo", alias)
+ assert.Empty(t, ds.URL.Scheme)
+
+ _, _, err = parseDatasourceArg("../foo.json")
+ require.Error(t, err)
+
+ _, _, err = parseDatasourceArg("ftp://example.com/foo.yml")
+ require.Error(t, err)
+}
+
+func TestParseDatasourceArgWithAlias(t *testing.T) {
+ alias, ds, err := parseDatasourceArg("data=foo.json")
+ require.NoError(t, err)
+ assert.Equal(t, "data", alias)
+ assert.EqualValues(t, &url.URL{Path: "foo.json"}, ds.URL)
+
+ alias, ds, err = parseDatasourceArg("data=/otherdir/foo.json")
+ require.NoError(t, err)
+ assert.Equal(t, "data", alias)
+ assert.Equal(t, "file", ds.URL.Scheme)
+ assert.True(t, ds.URL.IsAbs())
+ assert.Equal(t, "/otherdir/foo.json", ds.URL.Path)
+
+ if runtime.GOOS == "windows" {
+ alias, ds, err = parseDatasourceArg("data=foo.json")
+ require.NoError(t, err)
+ assert.Equal(t, "data", alias)
+ assert.EqualValues(t, &url.URL{Path: "foo.json"}, ds.URL)
+
+ alias, ds, err = parseDatasourceArg(`data=\otherdir\foo.json`)
+ require.NoError(t, err)
+ assert.Equal(t, "data", alias)
+ assert.EqualValues(t, &url.URL{Scheme: "file", Path: "/otherdir/foo.json"}, ds.URL)
+
+ alias, ds, err = parseDatasourceArg("data=C:\\windowsdir\\foo.json")
+ require.NoError(t, err)
+ assert.Equal(t, "data", alias)
+ assert.EqualValues(t, &url.URL{Scheme: "file", Path: "C:/windowsdir/foo.json"}, ds.URL)
+
+ alias, ds, err = parseDatasourceArg("data=\\\\somehost\\share\\foo.json")
+ require.NoError(t, err)
+ assert.Equal(t, "data", alias)
+ assert.EqualValues(t, &url.URL{Scheme: "file", Host: "somehost", Path: "/share/foo.json"}, ds.URL)
+ }
+
+ alias, ds, err = parseDatasourceArg("data=sftp://example.com/blahblah/foo.json")
+ require.NoError(t, err)
+ assert.Equal(t, "data", alias)
+ assert.EqualValues(t, &url.URL{Scheme: "sftp", Host: "example.com", Path: "/blahblah/foo.json"}, ds.URL)
+
+ alias, ds, err = parseDatasourceArg("merged=merge:./foo.yaml|http://example.com/bar.json%3Ffoo=bar")
+ require.NoError(t, err)
+ assert.Equal(t, "merged", alias)
+ assert.EqualValues(t, &url.URL{Scheme: "merge", Opaque: "./foo.yaml|http://example.com/bar.json%3Ffoo=bar"}, ds.URL)
+}
+
+func TestPluginConfig_UnmarshalYAML(t *testing.T) {
+ in := `foo`
+ out := PluginConfig{}
+ err := yaml.Unmarshal([]byte(in), &out)
+ require.NoError(t, err)
+ assert.EqualValues(t, PluginConfig{Cmd: "foo"}, out)
+
+ in = `[foo, bar]`
+ out = PluginConfig{}
+ err = yaml.Unmarshal([]byte(in), &out)
+ require.Error(t, err)
+
+ in = `cmd: foo`
+ out = PluginConfig{}
+ err = yaml.Unmarshal([]byte(in), &out)
+ require.NoError(t, err)
+ assert.EqualValues(t, PluginConfig{Cmd: "foo"}, out)
+
+ in = `cmd: foo
+timeout: 10ms
+pipe: true
+`
+ out = PluginConfig{}
+ err = yaml.Unmarshal([]byte(in), &out)
+ require.NoError(t, err)
+ assert.EqualValues(t, PluginConfig{
+ Cmd: "foo",
+ Timeout: time.Duration(10) * time.Millisecond,
+ Pipe: true,
+ }, out)
+}