From b8b35efdf43975d9c9cd1eb01ff530ce7c3276c2 Mon Sep 17 00:00:00 2001 From: Charles Iliya Krempeaux Date: Fri, 3 Nov 2023 14:00:32 -0700 Subject: [PATCH] initial commits --- parsefalse.go | 121 ++++++++++++++++++++++ parsefalse_test.go | 250 +++++++++++++++++++++++++++++++++++++++++++++ parsetrue.go | 104 +++++++++++++++++++ parsetrue_test.go | 242 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 717 insertions(+) create mode 100644 parsefalse.go create mode 100644 parsefalse_test.go create mode 100644 parsetrue.go create mode 100644 parsetrue_test.go diff --git a/parsefalse.go b/parsefalse.go new file mode 100644 index 0000000..6ca490d --- /dev/null +++ b/parsefalse.go @@ -0,0 +1,121 @@ +package rfc8259 + +import ( + "io" + + "sourcecode.social/reiver/go-erorr" +) + +func errProblemParsingBooleanFalse(expected rune, actual rune) error { + return erorr.Errorf("rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a %q (%U) but actually got a %q (%U)", expected, expected, actual, actual) +} + +// ParseFalse tries to parse the JSON boolean literal 'false'. +// If it succeeds, then it return nil. +// If it failed, it returns an error. +// +// Example usage: +// +// var rr io.RuneReader +// +// // ... +// +// err := rfc8259.ParseFalse(rr) +// +// if nil != err { +// fmt.Printf("We did NOT have a 'false', but instead got the error: %s\n", err) +// } else { +// fmt.Print("We had a 'false'\n") +// } +func ParseFalse(rr io.RuneReader) error { + if nil == rr { + return errNilRuneReader + } + + { + const expected rune = 'f' + + r, _, err := rr.ReadRune() + if nil != err { + if io.EOF == err { + return errUnexpectedEndOfFile + } + + return errProblemReadingRune(err) + } + + if expected != r { + return errProblemParsingBooleanFalse(expected, r) + } + } + + { + const expected rune = 'a' + + r, _, err := rr.ReadRune() + if nil != err { + if io.EOF == err { + return errUnexpectedEndOfFile + } + + return errProblemReadingRune(err) + } + + if expected != r { + return errProblemParsingBooleanFalse(expected, r) + } + } + + { + const expected rune = 'l' + + r, _, err := rr.ReadRune() + if nil != err { + if io.EOF == err { + return errUnexpectedEndOfFile + } + + return errProblemReadingRune(err) + } + + if expected != r { + return errProblemParsingBooleanFalse(expected, r) + } + } + + { + const expected rune = 's' + + r, _, err := rr.ReadRune() + if nil != err { + if io.EOF == err { + return errUnexpectedEndOfFile + } + + return errProblemReadingRune(err) + } + + if expected != r { + return errProblemParsingBooleanFalse(expected, r) + } + } + + { + const expected rune = 'e' + + r, _, err := rr.ReadRune() + if nil != err { + if io.EOF == err { + return errUnexpectedEndOfFile + } + + return errProblemReadingRune(err) + } + + if expected != r { + return errProblemParsingBooleanFalse(expected, r) + } + } + + return nil +} diff --git a/parsefalse_test.go b/parsefalse_test.go new file mode 100644 index 0000000..d08f601 --- /dev/null +++ b/parsefalse_test.go @@ -0,0 +1,250 @@ +package rfc8259_test + +import ( + "testing" + + "bytes" + "io" + + "sourcecode.social/reiver/go-utf8" + + "sourcecode.social/reiver/go-rfc8259" +) + +func TestParseFalse_success(t *testing.T) { + + var p []byte = []byte("false") + + var reader io.Reader = bytes.NewReader(p) + var runereader io.RuneReader = utf8.NewRuneReader(reader) + + err := rfc8259.ParseFalse(runereader) + + if nil != err { + t.Errorf("Did not expect an error but actually got one.") + t.Logf("ERROR: (%T) %s", err, err) + return + } +} + +func TestParseFalse_failure(t *testing.T) { + + tests := []struct{ + Value []byte + Expected string + }{ + { + Value: []byte(nil), + Expected: "rfc8259: unexpected end-of-file", + }, + { + Value: []byte(""), + Expected: "rfc8259: unexpected end-of-file", + }, + { + Value: []byte("f"), + Expected: "rfc8259: unexpected end-of-file", + }, + { + Value: []byte("fa"), + Expected: "rfc8259: unexpected end-of-file", + }, + { + Value: []byte("fal"), + Expected: "rfc8259: unexpected end-of-file", + }, + { + Value: []byte("fals"), + Expected: "rfc8259: unexpected end-of-file", + }, + + + + { + Value: []byte("\t"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a '\\t' (U+0009)", + }, + { + Value: []byte("\n"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a '\\n' (U+000A)", + }, + { + Value: []byte("\r"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a '\\r' (U+000D)", + }, + { + Value: []byte(" "), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a ' ' (U+0020)", + }, + { + Value: []byte("\""), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a '\"' (U+0022)", + }, + { + Value: []byte("-"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a '-' (U+002D)", + }, + { + Value: []byte("0"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a '0' (U+0030)", + }, + { + Value: []byte("1"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a '1' (U+0031)", + }, + { + Value: []byte("2"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a '2' (U+0032)", + }, + { + Value: []byte("3"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a '3' (U+0033)", + }, + { + Value: []byte("4"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a '4' (U+0034)", + }, + { + Value: []byte("5"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a '5' (U+0035)", + }, + { + Value: []byte("6"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a '6' (U+0036)", + }, + { + Value: []byte("7"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a '7' (U+0037)", + }, + { + Value: []byte("8"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a '8' (U+0038)", + }, + { + Value: []byte("9"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a '9' (U+0039)", + }, + { + Value: []byte("n"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a 'n' (U+006E)", + }, + { + Value: []byte("t"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a 't' (U+0074)", + }, + + + + { + Value: []byte("\"name\""), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a '\"' (U+0022)", + }, + { + Value: []byte("-34"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a '-' (U+002D)", + }, + { + Value: []byte("0.123"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a '0' (U+0030)", + }, + { + Value: []byte("123"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a '1' (U+0031)", + }, + { + Value: []byte("22.22"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a '2' (U+0032)", + }, + { + Value: []byte("3.141592653589793238462643383279502884"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a '3' (U+0033)", + }, + { + Value: []byte("4E31"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a '4' (U+0034)", + }, + { + Value: []byte("5e23"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a '5' (U+0035)", + }, + { + Value: []byte("6789"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a '6' (U+0036)", + }, + { + Value: []byte("7978777675"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a '7' (U+0037)", + }, + { + Value: []byte("812"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a '8' (U+0038)", + }, + { + Value: []byte("901"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a '9' (U+0039)", + }, + { + Value: []byte("null"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a 'n' (U+006E)", + }, + { + Value: []byte("true"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a 't' (U+0074)", + }, + + + + { + Value: []byte("F"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'f' (U+0066) but actually got a 'F' (U+0046)", + }, + { + Value: []byte("fA"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'a' (U+0061) but actually got a 'A' (U+0041)", + }, + { + Value: []byte("faL"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'l' (U+006C) but actually got a 'L' (U+004C)", + }, + { + Value: []byte("falS"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 's' (U+0073) but actually got a 'S' (U+0053)", + }, + { + Value: []byte("falsE"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'e' (U+0065) but actually got a 'E' (U+0045)", + }, + { + Value: []byte("fals,"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'false' — expected a 'e' (U+0065) but actually got a ',' (U+002C)", + }, + } + + for testNumber, test := range tests { + + var reader io.Reader = bytes.NewReader(test.Value) + var runereader io.RuneReader = utf8.NewRuneReader(reader) + + err := rfc8259.ParseFalse(runereader) + + if nil == err { + t.Errorf("Expected an error but did not actually get one.") + t.Logf("VALUE: %#v", test.Value) + t.Logf("VALUE: %q", test.Value) + continue + } + + { + actual := err.Error() + expected := test.Expected + + if expected != actual { + t.Errorf("For test #%d, the actual value for the error is not what was expected." , testNumber) + t.Logf("EXPECTED: %q", expected) + t.Logf("ACTUAL: %q", actual) + continue + } + } + + } +} diff --git a/parsetrue.go b/parsetrue.go new file mode 100644 index 0000000..24d9176 --- /dev/null +++ b/parsetrue.go @@ -0,0 +1,104 @@ +package rfc8259 + +import ( + "io" + + "sourcecode.social/reiver/go-erorr" +) + +func errProblemParsingBooleanTrue(expected rune, actual rune) error { + return erorr.Errorf("rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a %q (%U) but actually got a %q (%U)", expected, expected, actual, actual) +} + +// ParseTrue tries to parse the JSON boolean literal 'true'. +// If it succeeds, then it return nil. +// If it failed, it returns an error. +// +// Example usage: +// +// var rr io.RuneReader +// +// // ... +// +// err := rfc8259.ParseTrue(rr) +// +// if nil != err { +// fmt.Printf("We did NOT have a 'true', but instead got the error: %s\n", err) +// } else { +// fmt.Print("We had a 'true'\n") +// } +func ParseTrue(rr io.RuneReader) error { + if nil == rr { + return errNilRuneReader + } + + { + const expected rune = 't' + + r, _, err := rr.ReadRune() + if nil != err { + if io.EOF == err { + return errUnexpectedEndOfFile + } + + return errProblemReadingRune(err) + } + + if expected != r { + return errProblemParsingBooleanTrue(expected, r) + } + } + + { + const expected rune = 'r' + + r, _, err := rr.ReadRune() + if nil != err { + if io.EOF == err { + return errUnexpectedEndOfFile + } + + return errProblemReadingRune(err) + } + + if expected != r { + return errProblemParsingBooleanTrue(expected, r) + } + } + + { + const expected rune = 'u' + + r, _, err := rr.ReadRune() + if nil != err { + if io.EOF == err { + return errUnexpectedEndOfFile + } + + return errProblemReadingRune(err) + } + + if expected != r { + return errProblemParsingBooleanTrue(expected, r) + } + } + + { + const expected rune = 'e' + + r, _, err := rr.ReadRune() + if nil != err { + if io.EOF == err { + return errUnexpectedEndOfFile + } + + return errProblemReadingRune(err) + } + + if expected != r { + return errProblemParsingBooleanTrue(expected, r) + } + } + + return nil +} diff --git a/parsetrue_test.go b/parsetrue_test.go new file mode 100644 index 0000000..448c2fd --- /dev/null +++ b/parsetrue_test.go @@ -0,0 +1,242 @@ +package rfc8259_test + +import ( + "testing" + + "bytes" + "io" + + "sourcecode.social/reiver/go-utf8" + + "sourcecode.social/reiver/go-rfc8259" +) + +func TestParseTrue_success(t *testing.T) { + + var p []byte = []byte("true") + + var reader io.Reader = bytes.NewReader(p) + var runereader io.RuneReader = utf8.NewRuneReader(reader) + + err := rfc8259.ParseTrue(runereader) + + if nil != err { + t.Errorf("Did not expect an error but actually got one.") + t.Logf("ERROR: (%T) %s", err, err) + return + } +} + +func TestParseTrue_failure(t *testing.T) { + + tests := []struct{ + Value []byte + Expected string + }{ + { + Value: []byte(nil), + Expected: "rfc8259: unexpected end-of-file", + }, + { + Value: []byte(""), + Expected: "rfc8259: unexpected end-of-file", + }, + { + Value: []byte("t"), + Expected: "rfc8259: unexpected end-of-file", + }, + { + Value: []byte("tr"), + Expected: "rfc8259: unexpected end-of-file", + }, + { + Value: []byte("tru"), + Expected: "rfc8259: unexpected end-of-file", + }, + + + + { + Value: []byte("\t"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a '\\t' (U+0009)", + }, + { + Value: []byte("\n"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a '\\n' (U+000A)", + }, + { + Value: []byte("\r"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a '\\r' (U+000D)", + }, + { + Value: []byte(" "), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a ' ' (U+0020)", + }, + { + Value: []byte("\""), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a '\"' (U+0022)", + }, + { + Value: []byte("-"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a '-' (U+002D)", + }, + { + Value: []byte("0"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a '0' (U+0030)", + }, + { + Value: []byte("1"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a '1' (U+0031)", + }, + { + Value: []byte("2"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a '2' (U+0032)", + }, + { + Value: []byte("3"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a '3' (U+0033)", + }, + { + Value: []byte("4"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a '4' (U+0034)", + }, + { + Value: []byte("5"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a '5' (U+0035)", + }, + { + Value: []byte("6"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a '6' (U+0036)", + }, + { + Value: []byte("7"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a '7' (U+0037)", + }, + { + Value: []byte("8"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a '8' (U+0038)", + }, + { + Value: []byte("9"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a '9' (U+0039)", + }, + { + Value: []byte("f"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a 'f' (U+0066)", + }, + { + Value: []byte("n"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a 'n' (U+006E)", + }, + + + + { + Value: []byte("\"name\""), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a '\"' (U+0022)", + }, + { + Value: []byte("-34"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a '-' (U+002D)", + }, + { + Value: []byte("0.123"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a '0' (U+0030)", + }, + { + Value: []byte("123"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a '1' (U+0031)", + }, + { + Value: []byte("22.22"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a '2' (U+0032)", + }, + { + Value: []byte("3.141592653589793238462643383279502884"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a '3' (U+0033)", + }, + { + Value: []byte("4E31"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a '4' (U+0034)", + }, + { + Value: []byte("5e23"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a '5' (U+0035)", + }, + { + Value: []byte("6789"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a '6' (U+0036)", + }, + { + Value: []byte("7978777675"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a '7' (U+0037)", + }, + { + Value: []byte("812"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a '8' (U+0038)", + }, + { + Value: []byte("901"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a '9' (U+0039)", + }, + { + Value: []byte("false"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a 'f' (U+0066)", + }, + { + Value: []byte("null"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a 'n' (U+006E)", + }, + + + + { + Value: []byte("T"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 't' (U+0074) but actually got a 'T' (U+0054)", + }, + { + Value: []byte("tR"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 'r' (U+0072) but actually got a 'R' (U+0052)", + }, + { + Value: []byte("trU"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 'u' (U+0075) but actually got a 'U' (U+0055)", + }, + { + Value: []byte("truE"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 'e' (U+0065) but actually got a 'E' (U+0045)", + }, + { + Value: []byte("tru,"), + Expected: "rfc8259: problem when trying to parse JSON boolean literal 'true' — expected a 'e' (U+0065) but actually got a ',' (U+002C)", + }, + } + + for testNumber, test := range tests { + + var reader io.Reader = bytes.NewReader(test.Value) + var runereader io.RuneReader = utf8.NewRuneReader(reader) + + err := rfc8259.ParseTrue(runereader) + + if nil == err { + t.Errorf("Expected an error but did not actually get one.") + t.Logf("VALUE: %#v", test.Value) + t.Logf("VALUE: %q", test.Value) + continue + } + + { + actual := err.Error() + expected := test.Expected + + if expected != actual { + t.Errorf("For test #%d, the actual value for the error is not what was expected." , testNumber) + t.Logf("EXPECTED: %q", expected) + t.Logf("ACTUAL: %q", actual) + continue + } + } + + } +}