package settings import ( "bufio" "bytes" "errors" "fmt" "io" "maps" "math/rand" "testing" ) var ( KeyValuePairs = map[string]string{ "A": "a", "B": "b", "C": "c", } ) func RandomKeyValueDelimiter() byte { return KeyValueDelimiterChars[rand.Intn(len(KeyValueDelimiterChars))] } func WriteMapToWriter(w io.Writer, m map[string]string) error { writer := bufio.NewWriter(w) comments := []string{"// this is a random comment", "# this is another random comment"} randomComment := func() string { return comments[rand.Intn(len(comments))] } var position int for k, v := range m { switch rand.Float64() >= .5 { case true: fmt.Fprintf(writer, "%s\n", randomComment()) } fmt.Fprintf(writer, "%s%c%s", k, RandomKeyValueDelimiter(), v) if position < len(m)-1 { writer.WriteByte('\n') } position++ } return writer.Flush() } func TestScannerParsesFilesProperly(t *testing.T) { var buffer bytes.Buffer err := WriteMapToWriter(&buffer, KeyValuePairs) if err != nil { t.Fatalf("error writing map to buffer: %v\n", err) } scanner := NewScanner(&buffer) got := make(map[string]string) loop: for { key, value, err := scanner.ReadNextLine() if err != nil { if errors.Is(err, io.EOF) { break loop } t.Fatalf("error reading next line from scanner: %v\n", err) } got[key] = value } if want := KeyValuePairs; !maps.Equal(want, got) { t.Fatalf("error: wanted '%+v'; got '%+v'\n", want, got) } } func TestScannerHandlesInvalidLinesProperly(t *testing.T) { buffer := bytes.NewBufferString("validKey-validValue") scanner := NewScanner(buffer) key, value, err := scanner.ReadNextLine() if !errors.Is(err, ErrNoValidDelimiter) { t.Fatalf("error: wanted %v; got %v\n", ErrNoValidDelimiter, err) } else if want, got := "", key; want != got { t.Fatalf("error: wanted key '%s'; got '%s'\n", want, got) } else if want, got := "", value; want != got { t.Fatalf("error: wanted value '%s'; got '%s'\n", want, got) } }