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:
Rohan Verma 2024-03-06 23:43:58 +05:30
parent 7765d9d198
commit be4c9c0e8c
2 changed files with 44 additions and 11 deletions

View File

@ -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)
}
})
}
}

View File

@ -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 {