Compare commits

...

2 Commits

Author SHA1 Message Date
Sasha Koshka 73ea9d304b Add key value parsing tests 2024-04-27 20:17:00 -04:00
Sasha Koshka a5d4cd727b Minor key/value parsing fixes 2024-04-27 20:16:46 -04:00
2 changed files with 178 additions and 3 deletions

View File

@ -14,6 +14,7 @@ package keyValue
import "io"
import "fmt"
import "bufio"
import "errors"
import "strings"
import "strconv"
import "unicode"
@ -65,7 +66,9 @@ func Parse (reader io.Reader) (File, error) {
var specifiedValues map[string] struct { }
for {
line, err := buffer.ReadString('\n')
if err != nil { return nil, err }
if errors.Is(err, io.EOF) { return file, nil }
if err != nil { return nil, err }
line = strings.TrimSpace(line)
switch {
@ -167,8 +170,10 @@ func parseEntry (line string) (key, val string, loc locale.Locale, err error) {
}
if state != getVal { err = ErrInvalidEntry; return }
loc, err = locale.Parse(locb.String())
if err != nil { return}
if locb.Len() > 0 {
loc, err = locale.Parse(locb.String())
if err != nil { return}
}
key = strings.TrimSpace(keyb.String())
val = strings.TrimSpace(valb.String())

170
key-value/key-value_test.go Normal file
View File

@ -0,0 +1,170 @@
package keyValue
import "strings"
import "testing"
import "git.tebibyte.media/tomo/xdg/locale"
func testParseString (test *testing.T, input string, correct File) {
got, err := Parse(strings.NewReader(input))
if err != nil {
test.Fatal("Parse function returned error:", err)
}
fail := func (v ...any) {
test.Logf (
"\n---input file---\n%s\n---correct---\n%v\n---got---\n%v\n",
input, correct, got)
test.Log(v...)
test.FailNow()
}
if len(got) != len(correct) {
fail("number of groups is different")
}
for name, group := range correct {
gotGroup, ok := got[name]
if !ok { fail("did not get group", name) }
if len(gotGroup) != len(group) {
fail("number of entries in", name, "is different")
}
for key, entry := range group {
gotEntry, ok := gotGroup[key]
if !ok { fail("did not get key", name, ">", key) }
if gotEntry.Value != entry.Value {
fail("value of ", name, ">", key, "is different")
}
if len(gotEntry.Localized) != len(entry.Localized) {
fail("number of localized values in", name, ">", key, "is different")
}
for loc, localized := range entry.Localized {
gotLocalized, ok := gotEntry.Localized[loc]
if !ok { fail("did not get value", name, ">", key, ">", loc) }
if gotLocalized != localized {
fail("value of", name, ">", key, ">", loc, "is different")
}
}
}
}
}
func testEntry (value string) Entry {
entry := newEntry()
entry.Value = value
return entry
}
func TestParseEmpty (test *testing.T) {
testParseString(test,
``,
File { })}
func TestParseFooReader (test *testing.T) {
// Directly from the spec
testParseString(test, `
[Desktop Entry]
Version=1.0
Type=Application
Name=Foo Viewer
Comment=The best viewer for Foo objects available!
TryExec=fooview
Exec=fooview %F
Icon=fooview
MimeType=image/x-foo;
Actions=Gallery;Create;
[Desktop Action Gallery]
Exec=fooview --gallery
Name=Browse Gallery
[Desktop Action Create]
Exec=fooview --create-new
Name=Create a new Foo!
Icon=fooview-new
`,
File {
"Desktop Entry": Group {
"Version": testEntry("1.0"),
"Type": testEntry("Application"),
"Name": testEntry("Foo Viewer"),
"Comment": testEntry("The best viewer for Foo objects available!"),
"TryExec": testEntry("fooview"),
"Exec": testEntry("fooview %F"),
"Icon": testEntry("fooview"),
"MimeType": testEntry("image/x-foo;"),
"Actions": testEntry("Gallery;Create;"),
},
"Desktop Action Gallery": Group {
"Exec": testEntry("fooview --gallery"),
"Name": testEntry("Browse Gallery"),
},
"Desktop Action Create": Group {
"Exec": testEntry("fooview --create-new"),
"Name": testEntry("Create a new Foo!"),
"Icon": testEntry("fooview-new"),
},
})}
func TestParseFooReaderLocalized (test *testing.T) {
testParseString(test, `
[Desktop Entry]
Version=1.0
Type=Application
Name=Foo Viewer
Comment=The best viewer for Foo objects available!
TryExec=fooview
Exec=fooview %F
Icon=fooview
MimeType=image/x-foo;
Actions=Gallery;Create;
[Desktop Action Gallery]
Exec=fooview --gallery
Name=Browse Gallery
[Desktop Action Create]
Exec=fooview --create-new
Name=Create a new Foo!
Name[en_US]=Create a new Foo!
Name[xx_XX.UTF-8]=Zweep zoop flooble glorp
Icon=fooview-new
`,
File {
"Desktop Entry": Group {
"Version": testEntry("1.0"),
"Type": testEntry("Application"),
"Name": testEntry("Foo Viewer"),
"Comment": testEntry("The best viewer for Foo objects available!"),
"TryExec": testEntry("fooview"),
"Exec": testEntry("fooview %F"),
"Icon": testEntry("fooview"),
"MimeType": testEntry("image/x-foo;"),
"Actions": testEntry("Gallery;Create;"),
},
"Desktop Action Gallery": Group {
"Exec": testEntry("fooview --gallery"),
"Name": testEntry("Browse Gallery"),
},
"Desktop Action Create": Group {
"Exec": testEntry("fooview --create-new"),
"Name": Entry {
Value: "Create a new Foo!",
Localized: map[locale.Locale] string {
locale.Locale {
Lang: "en",
Country: "US",
}: "Create a new Foo!",
locale.Locale {
Lang: "xx",
Country: "XX",
Encoding: "UTF-8",
}: "Zweep zoop flooble glorp",
},
},
"Icon": testEntry("fooview-new"),
},
})}