From 0d3f73864b689b80411adc2979660da6cf883959 Mon Sep 17 00:00:00 2001 From: Rose Hogenson Date: Sat, 25 Oct 2025 11:55:51 -0700 Subject: Initial commit --- asspb_test.go | 227 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 227 insertions(+) create mode 100644 asspb_test.go (limited to 'asspb_test.go') 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) + } + }) + } +} -- cgit v1.3.1