mirror of
https://github.com/joho/godotenv.git
synced 2024-11-10 12:10:50 +00:00
tests: add unit tests for parser errors
- Declares errors and wraps them for error checking by clients - Adds two unit tests for - terminated quote error - unexpected char
This commit is contained in:
parent
7765d9d198
commit
be4c9c0e8c
@ -2,6 +2,7 @@ package godotenv
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
@ -582,42 +583,42 @@ func TestWhitespace(t *testing.T) {
|
||||
}{
|
||||
"Leading whitespace": {
|
||||
input: " A=a\n",
|
||||
key: "A",
|
||||
key: "A",
|
||||
value: "a",
|
||||
},
|
||||
"Leading tab": {
|
||||
input: "\tA=a\n",
|
||||
key: "A",
|
||||
key: "A",
|
||||
value: "a",
|
||||
},
|
||||
"Leading mixed whitespace": {
|
||||
input: " \t \t\n\t \t A=a\n",
|
||||
key: "A",
|
||||
key: "A",
|
||||
value: "a",
|
||||
},
|
||||
"Leading whitespace before export": {
|
||||
input: " \t\t export A=a\n",
|
||||
key: "A",
|
||||
key: "A",
|
||||
value: "a",
|
||||
},
|
||||
"Trailing whitespace": {
|
||||
input: "A=a \t \t\n",
|
||||
key: "A",
|
||||
key: "A",
|
||||
value: "a",
|
||||
},
|
||||
"Trailing whitespace with export": {
|
||||
input: "export A=a\t \t \n",
|
||||
key: "A",
|
||||
key: "A",
|
||||
value: "a",
|
||||
},
|
||||
"No EOL": {
|
||||
input: "A=a",
|
||||
key: "A",
|
||||
key: "A",
|
||||
value: "a",
|
||||
},
|
||||
"Trailing whitespace with no EOL": {
|
||||
input: "A=a ",
|
||||
key: "A",
|
||||
key: "A",
|
||||
value: "a",
|
||||
},
|
||||
}
|
||||
@ -634,3 +635,28 @@ func TestWhitespace(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParserErrors(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
input string
|
||||
err error
|
||||
}{
|
||||
"Invalid char": {
|
||||
input: "foo-1=bar",
|
||||
err: ErrUnexpectedChar,
|
||||
},
|
||||
"UnterminatedQuote": {
|
||||
input: "foo=\"bar",
|
||||
err: ErrUnterminatedQuote,
|
||||
},
|
||||
}
|
||||
|
||||
for n, c := range cases {
|
||||
t.Run(n, func(t *testing.T) {
|
||||
v, err := Unmarshal(c.input)
|
||||
if !errors.Is(err, c.err) {
|
||||
t.Errorf("Input: %q Expected:\t %q\nGot:\t %q Val: %v", c.input, c.err, err, v)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
13
parser.go
13
parser.go
@ -17,6 +17,12 @@ const (
|
||||
exportPrefix = "export"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrZeroLengthString = errors.New("zero length string")
|
||||
ErrUnexpectedChar = errors.New("unexpected character")
|
||||
ErrUnterminatedQuote = errors.New("unterminated quoted value")
|
||||
)
|
||||
|
||||
func parseBytes(src []byte, out map[string]string) error {
|
||||
src = bytes.Replace(src, []byte("\r\n"), []byte("\n"), -1)
|
||||
cutset := src
|
||||
@ -101,13 +107,14 @@ loop:
|
||||
}
|
||||
|
||||
return "", nil, fmt.Errorf(
|
||||
`unexpected character %q in variable name near %q`,
|
||||
`%w %q in variable name near %q`,
|
||||
ErrUnexpectedChar,
|
||||
string(char), string(src))
|
||||
}
|
||||
}
|
||||
|
||||
if len(src) == 0 {
|
||||
return "", nil, errors.New("zero length string")
|
||||
return "", nil, ErrZeroLengthString
|
||||
}
|
||||
|
||||
// trim whitespace
|
||||
@ -186,7 +193,7 @@ func extractVarValue(src []byte, vars map[string]string) (value string, rest []b
|
||||
valEndIndex = len(src)
|
||||
}
|
||||
|
||||
return "", nil, fmt.Errorf("unterminated quoted value %s", src[:valEndIndex])
|
||||
return "", nil, fmt.Errorf("%w %s", ErrUnterminatedQuote, src[:valEndIndex])
|
||||
}
|
||||
|
||||
func expandEscapes(str string) string {
|
||||
|
Loading…
Reference in New Issue
Block a user