mirror of https://github.com/docker/cli.git
146 lines
3.9 KiB
Go
146 lines
3.9 KiB
Go
|
package kvfile
|
||
|
|
||
|
import (
|
||
|
"bufio"
|
||
|
"os"
|
||
|
"path/filepath"
|
||
|
"strings"
|
||
|
"testing"
|
||
|
|
||
|
"gotest.tools/v3/assert"
|
||
|
is "gotest.tools/v3/assert/cmp"
|
||
|
)
|
||
|
|
||
|
// Test Parse for a non existent file.
|
||
|
func TestParseNonExistentFile(t *testing.T) {
|
||
|
_, err := Parse("no_such_file", nil)
|
||
|
assert.Check(t, is.ErrorType(err, os.IsNotExist))
|
||
|
}
|
||
|
|
||
|
// Test Parse from a file with a lookup function.
|
||
|
func TestParseWithLookup(t *testing.T) {
|
||
|
content := `# comment=
|
||
|
VAR=VAR_VALUE
|
||
|
EMPTY_VAR=
|
||
|
UNDEFINED_VAR
|
||
|
DEFINED_VAR
|
||
|
`
|
||
|
vars := map[string]string{
|
||
|
"DEFINED_VAR": "defined-value",
|
||
|
}
|
||
|
lookupFn := func(name string) (string, bool) {
|
||
|
v, ok := vars[name]
|
||
|
return v, ok
|
||
|
}
|
||
|
|
||
|
fileName := filepath.Join(t.TempDir(), "envfile")
|
||
|
err := os.WriteFile(fileName, []byte(content), 0o644)
|
||
|
assert.NilError(t, err)
|
||
|
|
||
|
variables, err := Parse(fileName, lookupFn)
|
||
|
assert.NilError(t, err)
|
||
|
|
||
|
expectedLines := []string{"VAR=VAR_VALUE", "EMPTY_VAR=", "DEFINED_VAR=defined-value"}
|
||
|
assert.Check(t, is.DeepEqual(variables, expectedLines))
|
||
|
}
|
||
|
|
||
|
// Test ParseEnvFile for a file with a few well formatted lines
|
||
|
func TestParseFromReaderGoodFile(t *testing.T) {
|
||
|
content := `foo=bar
|
||
|
baz=quux
|
||
|
# comment
|
||
|
|
||
|
_foobar=foobaz
|
||
|
with.dots=working
|
||
|
and_underscore=working too
|
||
|
`
|
||
|
// Adding a newline + a line with pure whitespace.
|
||
|
// This is being done like this instead of the block above
|
||
|
// because it's common for editors to trim trailing whitespace
|
||
|
// from lines, which becomes annoying since that's the
|
||
|
// exact thing we need to test.
|
||
|
content += "\n \t "
|
||
|
|
||
|
lines, err := ParseFromReader(strings.NewReader(content), nil)
|
||
|
assert.NilError(t, err)
|
||
|
|
||
|
expectedLines := []string{
|
||
|
"foo=bar",
|
||
|
"baz=quux",
|
||
|
"_foobar=foobaz",
|
||
|
"with.dots=working",
|
||
|
"and_underscore=working too",
|
||
|
}
|
||
|
|
||
|
assert.Check(t, is.DeepEqual(lines, expectedLines))
|
||
|
}
|
||
|
|
||
|
// Test ParseFromReader for an empty file
|
||
|
func TestParseFromReaderEmptyFile(t *testing.T) {
|
||
|
lines, err := ParseFromReader(strings.NewReader(""), nil)
|
||
|
assert.NilError(t, err)
|
||
|
assert.Check(t, is.Len(lines, 0))
|
||
|
}
|
||
|
|
||
|
// Test ParseFromReader for a badly formatted file
|
||
|
func TestParseFromReaderBadlyFormattedFile(t *testing.T) {
|
||
|
content := `foo=bar
|
||
|
f =quux
|
||
|
`
|
||
|
_, err := ParseFromReader(strings.NewReader(content), nil)
|
||
|
const expectedMessage = "variable 'f ' contains whitespaces"
|
||
|
assert.Check(t, is.ErrorContains(err, expectedMessage))
|
||
|
}
|
||
|
|
||
|
// Test ParseFromReader for a file with a line exceeding bufio.MaxScanTokenSize
|
||
|
func TestParseFromReaderLineTooLongFile(t *testing.T) {
|
||
|
content := "foo=" + strings.Repeat("a", bufio.MaxScanTokenSize+42)
|
||
|
|
||
|
_, err := ParseFromReader(strings.NewReader(content), nil)
|
||
|
const expectedMessage = "bufio.Scanner: token too long"
|
||
|
assert.Check(t, is.ErrorContains(err, expectedMessage))
|
||
|
}
|
||
|
|
||
|
// ParseEnvFile with a random file, pass through
|
||
|
func TestParseFromReaderRandomFile(t *testing.T) {
|
||
|
content := `first line
|
||
|
another invalid line`
|
||
|
|
||
|
_, err := ParseFromReader(strings.NewReader(content), nil)
|
||
|
const expectedMessage = "variable 'first line' contains whitespaces"
|
||
|
assert.Check(t, is.ErrorContains(err, expectedMessage))
|
||
|
}
|
||
|
|
||
|
// Test ParseFromReader with a lookup function.
|
||
|
func TestParseFromReaderWithLookup(t *testing.T) {
|
||
|
content := `# comment=
|
||
|
VAR=VAR_VALUE
|
||
|
EMPTY_VAR=
|
||
|
UNDEFINED_VAR
|
||
|
DEFINED_VAR
|
||
|
`
|
||
|
vars := map[string]string{
|
||
|
"DEFINED_VAR": "defined-value",
|
||
|
}
|
||
|
lookupFn := func(name string) (string, bool) {
|
||
|
v, ok := vars[name]
|
||
|
return v, ok
|
||
|
}
|
||
|
|
||
|
variables, err := ParseFromReader(strings.NewReader(content), lookupFn)
|
||
|
assert.NilError(t, err)
|
||
|
|
||
|
expectedLines := []string{"VAR=VAR_VALUE", "EMPTY_VAR=", "DEFINED_VAR=defined-value"}
|
||
|
assert.Check(t, is.DeepEqual(variables, expectedLines))
|
||
|
}
|
||
|
|
||
|
// Test ParseFromReader with empty variable name
|
||
|
func TestParseFromReaderWithNoName(t *testing.T) {
|
||
|
content := `# comment=
|
||
|
=blank variable names are an error case
|
||
|
`
|
||
|
_, err := ParseFromReader(strings.NewReader(content), nil)
|
||
|
const expectedMessage = "no variable name on line '=blank variable names are an error case'"
|
||
|
assert.Check(t, is.ErrorContains(err, expectedMessage))
|
||
|
}
|