package provider import ( "strings" "testing" ) // Spec v0.16, §47.1: the strict reading of drand's JSON, at the edges of the // grammar of RFC 8259 that release.json does not reach. func TestStrictJSON(t *testing.T) { for _, tc := range []struct { in string ok bool }{ {`{}`, true}, {` {"a":1} `, true}, {"\t{\"a\":1}\r\n", true}, {`{"a":[]}`, true}, {`{"a":[1,2,[3,{}]]}`, true}, {`{"a":true,"b":false,"c":null}`, true}, {`{"a":-0,"b":0.5,"c":1E+2,"d":1e-2,"e":-12.25e3}`, true}, {`{"a":"\"\\\/\b\f\n\r\té"}`, true}, {`{"é":1,"é":2}`, false}, // one name, escaped and not {`{"a":1,"a":2}`, false}, {`{"a":{"b":1},"c":{"b":2}}`, true}, // the same name in two objects {`{"a":[{"b":1,"b":1}]}`, false}, {`{"a":01}`, false}, {`{"a":1.}`, false}, {`{"a":.5}`, false}, {`{"a":1e}`, false}, {`{"a":+1}`, false}, {`{"a":-}`, false}, {`{"a":tru}`, false}, {`{"a":nul}`, false}, {`{"a":"\x"}`, false}, {`{"a":"\u12"}`, false}, {`{"a":"\u12g4"}`, false}, {`{"a":"\ud800"}`, false}, {`{"a":"\ud800A"}`, false}, {`{"a":"\ud800x"}`, false}, {`{"a":"\udfff\ud800"}`, false}, {`{"a":"😀"}`, true}, {`{"a":"` + "\x01" + `"}`, false}, {`{"a":"` + "\xff" + `"}`, false}, {"{\"a\":\"\xed\xa0\x80\"}", false}, // a surrogate in UTF-8 {`{"a":1,}`, false}, {`{,"a":1}`, false}, {`{"a" 1}`, false}, {`{"a":1 "b":2}`, false}, {`{a:1}`, false}, {`{"a":[1,]}`, false}, {`{"a":[1 2]}`, false}, {`{"a":"b"`, false}, {`{"a":1}x`, false}, {`[]`, false}, {`"a"`, false}, {``, false}, {"{\"a\":1}\v", false}, // not a space of JSON } { if _, ok := strictJSON([]byte(tc.in)); ok != tc.ok { t.Errorf("%q: %v, want %v", tc.in, ok, tc.ok) } } m, ok := strictJSON([]byte(`{"round":1000,"note":"a😀","n":-1.5}`)) if !ok || len(m) != 3 || m[0].name != "round" || string(m[0].raw) != "1000" || m[1].str != "a\U0001F600" || m[2].kind != '0' || string(m[2].raw) != "-1.5" { t.Errorf("members %+v", m) } } func TestJSONRound(t *testing.T) { for raw, want := range map[string]bool{ "1": true, "1000": true, "9007199254740991": true, "0": false, "9007199254740992": false, "99999999999999999": false, "-1": false, "1.0": false, "1e3": false, "01": false, } { if _, ok := jsonRound(jsonMember{kind: '0', raw: []byte(raw)}); ok != want { t.Errorf("%s: %v, want %v", raw, ok, want) } } if _, ok := jsonRound(jsonMember{kind: '"', raw: []byte(`"1"`)}); ok { t.Error("a string is not a round") } if _, err := ParseDrandJSON([]byte(`{"round":1000,"signature":"` + strings.Repeat("ab", 48) + `","note":"` + "\xff" + `"}`)); err == nil { t.Error("invalid UTF-8 is malformed") } }