aboutsummaryrefslogtreecommitdiffstats
path: root/asspb_test.go
diff options
context:
space:
mode:
authorRose Hogenson <rosehogenson@posteo.net>2025-10-25 11:55:51 -0700
committerRose Hogenson <rosehogenson@posteo.net>2025-10-25 11:55:51 -0700
commit0d3f73864b689b80411adc2979660da6cf883959 (patch)
tree1f9a8cd6bbdb7bbce27d09204cda453b05ad572a /asspb_test.go
downloadccl-0d3f73864b689b80411adc2979660da6cf883959.tar.zst
Initial commit
Diffstat (limited to 'asspb_test.go')
-rw-r--r--asspb_test.go227
1 files changed, 227 insertions, 0 deletions
diff --git a/asspb_test.go b/asspb_test.go
new file mode 100644
index 0000000..36e8e5f
--- /dev/null
+++ b/asspb_test.go
@@ -0,0 +1,227 @@
+package asspb
+
+import (
+ "testing"
+
+ "github.com/google/go-cmp/cmp"
+)
+
+func TestUnmarshal(t *testing.T) {
+ t.Parallel()
+
+ for _, tc := range []struct {
+ desc string
+ msg string
+ want map[string]any
+ }{{
+ desc: "Complete",
+ msg: `# This is a comment
+field_string: 'asdf\n' # comment end of line
+field_doublestring: "asdf\n"
+field_int: 10
+field_float: 10.5e13
+field_true: true
+field_false: false
+field_nested { asdf: 10 }
+field_repeated [1, 2, 3]
+field_repeated: 4
+field_repeated [5, 6]
+`,
+ want: map[string]any{
+ "field_string": "asdf\n",
+ "field_doublestring": "asdf\n",
+ "field_int": 10.,
+ "field_float": 10.5e13,
+ "field_true": true,
+ "field_false": false,
+ "field_nested": map[string]any{"asdf": 10.},
+ "field_repeated": []any{1., 2., 3., 4., 5., 6.},
+ },
+ }, {
+ desc: "MultilineString",
+ msg: `field: "strings
+can just span multiple lines"`,
+ want: map[string]any{"field": "strings\ncan just span multiple lines"},
+ }, {
+ desc: "Hex",
+ msg: `field: 0xff`,
+ want: map[string]any{"field": 255.},
+ }, {
+ desc: "Float",
+ msg: `field: 1.5e10`,
+ want: map[string]any{"field": 1.5e10},
+ }, {
+ desc: "NegativeFloat",
+ msg: `field: -1.5e-10`,
+ want: map[string]any{"field": -1.5e-10},
+ }, {
+ desc: "Int",
+ msg: `field: 10`,
+ want: map[string]any{"field": 10.},
+ }, {
+ desc: "NegativeInt",
+ msg: `field: -10`,
+ want: map[string]any{"field": -10.},
+ }, {
+ desc: "String",
+ msg: `field: 'asdf'`,
+ want: map[string]any{"field": "asdf"},
+ }, {
+ desc: "DoubleString",
+ msg: `field: "asdf"`,
+ want: map[string]any{"field": "asdf"},
+ }, {
+ desc: "StringEscapeSingle",
+ msg: `you: 'ain\'t'`,
+ want: map[string]any{"you": "ain't"},
+ }, {
+ desc: "DoubleStringEscapeSingle",
+ msg: `I: "won\'t"`,
+ want: map[string]any{"I": "won't"},
+ }, {
+ desc: "StringEscapeDouble",
+ msg: `field: '\"'`,
+ want: map[string]any{"field": `"`},
+ }, {
+ desc: "DoubleStringEscapeDouble",
+ msg: `field: "\""`,
+ want: map[string]any{"field": `"`},
+ }, {
+ desc: "StringEscapeBackslash",
+ msg: `field: '\\'`,
+ want: map[string]any{"field": `\`},
+ }, {
+ desc: "StringEscapeA",
+ msg: `field: '\a'`,
+ want: map[string]any{"field": "\a"},
+ }, {
+ desc: "StringEscapeB",
+ msg: `field: '\b'`,
+ want: map[string]any{"field": "\b"},
+ }, {
+ desc: "StringEscapeF",
+ msg: `field: '\f'`,
+ want: map[string]any{"field": "\f"},
+ }, {
+ desc: "StringEscapeN",
+ msg: `field: '\n'`,
+ want: map[string]any{"field": "\n"},
+ }, {
+ desc: "StringEscapeR",
+ msg: `field: '\r'`,
+ want: map[string]any{"field": "\r"},
+ }, {
+ desc: "StringEscapeT",
+ msg: `field: '\t'`,
+ want: map[string]any{"field": "\t"},
+ }, {
+ desc: "StringEscapeV",
+ msg: `field: '\v'`,
+ want: map[string]any{"field": "\v"},
+ }, {
+ desc: "StringHex",
+ msg: `field: '\x0a'`,
+ want: map[string]any{"field": "\n"},
+ }, {
+ desc: "StringUnicode",
+ msg: `field: '\u2014'`,
+ want: map[string]any{"field": "—"},
+ }, {
+ desc: "StringOctal",
+ msg: `field: '\033'`,
+ want: map[string]any{"field": "\033"},
+ }, {
+ desc: "Message",
+ msg: `field { nested_field: 10 }`,
+ want: map[string]any{"field": map[string]any{"nested_field": 10.}},
+ }, {
+ desc: "EmptyMessage",
+ msg: `field {}`,
+ want: map[string]any{"field": map[string]any{}},
+ }, {
+ desc: "Repeated",
+ msg: `field: 1
+field: 2`,
+ want: map[string]any{"field": []any{1., 2.}},
+ }, {
+ desc: "RepeatedList",
+ msg: `field: [1, 2]`,
+ want: map[string]any{"field": []any{1., 2.}},
+ }, {
+ desc: "EmptyList",
+ msg: `field: []`,
+ want: map[string]any{"field": []any{}},
+ }, {
+ desc: "RepeatedListTrailingComma",
+ msg: `field: [
+ 1,
+ 2,
+ ]`,
+ want: map[string]any{"field": []any{1., 2.}},
+ }, {
+ desc: "ListOfMessage",
+ msg: `field: [{}]`,
+ want: map[string]any{"field": []any{map[string]any{}}},
+ }} {
+ t.Run(tc.desc, func(t *testing.T) {
+ t.Parallel()
+
+ got := make(map[string]any)
+ if err := Unmarshal([]byte(tc.msg), &got); err != nil {
+ t.Fatalf("Unmarshal(%q) failed: %s\n", tc.msg, err)
+ }
+ if diff := cmp.Diff(tc.want, got); diff != "" {
+ t.Errorf("Unmarshal(%q) returned unexpected diff (-want +got):\n%s", tc.msg, diff)
+ }
+ })
+ }
+}
+
+func TestUnmarshal_Invalid(t *testing.T) {
+ t.Parallel()
+
+ for _, tc := range []struct {
+ desc string
+ msg string
+ }{{
+ desc: "BadNum",
+ msg: `field: .`,
+ }, {
+ desc: "BadStringEscape",
+ msg: `field: '\g'`,
+ }, {
+ desc: "BadDoubleStringEscape",
+ msg: `field: "\g"`,
+ }, {
+ desc: "UnterminatedString",
+ msg: `field: '`,
+ }, {
+ desc: "UnterminatedDoubleString",
+ msg: `field: "`,
+ }, {
+ desc: "NoFieldName",
+ msg: `10`,
+ }, {
+ desc: "MsgNoFieldName",
+ msg: `field {10}`,
+ }, {
+ desc: "ListMissingComma",
+ msg: `field [1 2]`,
+ }, {
+ desc: "ListBadVal",
+ msg: `field [asdf]`,
+ }, {
+ desc: "ListBadMsgVal",
+ msg: `field [{asdf}]`,
+ }} {
+ t.Run(tc.desc, func(t *testing.T) {
+ t.Parallel()
+
+ got := make(map[string]any)
+ err := Unmarshal([]byte(tc.msg), &got)
+ if err == nil {
+ t.Errorf("Unmarshal(%q) returned success, want error", tc.msg)
+ }
+ })
+ }
+}