diff --git a/error.go b/error.go index ec0909b..eb1ddf5 100644 --- a/error.go +++ b/error.go @@ -18,16 +18,7 @@ func (err *Error) Error() string { if err == nil { callerPanic(1, "parsekit.Error.Error(): method called with nil error at {caller}") } - return err.Message -} - -// Full returns the current error message, including information about -// the position in the input where the error occurred. -func (err *Error) Full() string { - if err == nil { - callerPanic(1, "parsekit.Error.Full(): method called with nil error at {caller}") - } - return fmt.Sprintf("%s at %s", err, err.Cursor) + return fmt.Sprintf("%s at %s", err.Message, err.Cursor) } func callerFunc(depth int) string { diff --git a/error_test.go b/error_test.go index 06f92ef..697b6fd 100644 --- a/error_test.go +++ b/error_test.go @@ -14,33 +14,7 @@ func ExampleError() { fmt.Println(err.Error()) fmt.Printf("%s\n", err) - fmt.Println(err.Full()) - // Output: - // it broke down - // it broke down - // it broke down at line 10, column 42 -} - -func ExampleError_Error() { - err := &parsekit.Error{ - Message: "it broke down", - Cursor: parsekit.Cursor{Line: 9, Column: 41}, - } - - fmt.Println(err.Error()) - fmt.Printf("%s\n", err) - // Output: - // it broke down - // it broke down -} - -func ExampleError_Full() { - err := &parsekit.Error{ - Message: "it broke down", - Cursor: parsekit.Cursor{Line: 9, Column: 41}, - } - - fmt.Println(err.Full()) // Output: // it broke down at line 10, column 42 + // it broke down at line 10, column 42 } diff --git a/examples/example_basiccalculator1_test.go b/examples/example_basiccalculator1_test.go index 1809d22..91edab2 100644 --- a/examples/example_basiccalculator1_test.go +++ b/examples/example_basiccalculator1_test.go @@ -40,11 +40,11 @@ func Example_basicCalculator1() { // Input: "1", got outcome: 1, correct = true // Input: "1+2+3", got outcome: 6, correct = true // Input: " 10 + \t20 - 3 + 7 -10 ", got outcome: 24, correct = true - // Input: "", got error: unexpected end of file (expected integer number) - // Input: " \t ", got error: unexpected input (expected integer number) - // Input: "+", got error: unexpected input (expected integer number) - // Input: "10.8 + 12", got error: unexpected input (expected operator, '+' or '-') - // Input: "42+ ", got error: unexpected input (expected integer number) + // Input: "", got error: unexpected end of file (expected integer number) at start of file + // Input: " \t ", got error: unexpected input (expected integer number) at start of file + // Input: "+", got error: unexpected input (expected integer number) at start of file + // Input: "10.8 + 12", got error: unexpected input (expected operator, '+' or '-') at line 1, column 3 + // Input: "42+ ", got error: unexpected input (expected integer number) at line 1, column 4 } // --------------------------------------------------------------------------- @@ -92,7 +92,7 @@ func (c *simpleCalculator) operatorOrEndOfFile(p *parsekit.ParseAPI) { case p.Accept(A.Subtract): c.op = -1 p.Handle(c.number) - case !p.Accept(A.EndOfFile): + case !p.Peek(A.EndOfFile): p.Expected("operator, '+' or '-'") default: p.ExpectEndOfFile() diff --git a/examples/example_basiccalculator2_test.go b/examples/example_basiccalculator2_test.go index 78aa963..a768ddf 100644 --- a/examples/example_basiccalculator2_test.go +++ b/examples/example_basiccalculator2_test.go @@ -40,7 +40,7 @@ func Example_basicCalculator2() { output, err := Compute(c.input) output = math.Round(output*1000000) / 1000000 // to make the expectation comparisons usable if err != nil { - fmt.Printf("Input: %q, got error: %s\n", c.input, err.Full()) + fmt.Printf("Input: %q, got error: %s\n", c.input, err) } else { fmt.Printf("Input: %q, got outcome: %f, correct = %t\n", c.input, output, output == c.expected) } diff --git a/examples/example_dutchpostcode_test.go b/examples/example_dutchpostcode_test.go index be088a6..e93b690 100644 --- a/examples/example_dutchpostcode_test.go +++ b/examples/example_dutchpostcode_test.go @@ -26,7 +26,7 @@ func Example_dutchPostcodeUsingTokenizer() { } { result, err := parser.Execute(input) if err != nil { - fmt.Printf("[%d] Input: %q Error: %s\n", i, input, err.Full()) + fmt.Printf("[%d] Input: %q Error: %s\n", i, input, err) } else { fmt.Printf("[%d] Input: %q Output: %s Tokens:", i, input, result) for _, t := range result.Tokens() { diff --git a/examples/example_helloParserCombinator_test.go b/examples/example_helloParserCombinator_test.go index 51a29fc..2d96f8f 100644 --- a/examples/example_helloParserCombinator_test.go +++ b/examples/example_helloParserCombinator_test.go @@ -27,7 +27,7 @@ func Example_helloWorldUsingTokenizer() { } { output, err := parser.Execute(input) if err != nil { - fmt.Printf("[%d] Input: %q Error: %s\n", i, input, err.Full()) + fmt.Printf("[%d] Input: %q Error: %s\n", i, input, err) } else { fmt.Printf("[%d] Input: %q Output: %s\n", i, input, output) } diff --git a/examples/example_helloSingleStateParser_test.go b/examples/example_helloSingleStateParser_test.go index 40c5d4b..b889caa 100644 --- a/examples/example_helloSingleStateParser_test.go +++ b/examples/example_helloSingleStateParser_test.go @@ -50,18 +50,18 @@ func Example_helloWorldUsingParser2() { // [0] Input: "Hello, world!" Output: world // [1] Input: "HELLO ,Johnny!" Output: Johnny // [2] Input: "hello , Bob123!" Output: Bob123 - // [3] Input: "hello Pizza!" Error: the greeting is not properly separated - // [4] Input: "" Error: the greeting is not being friendly - // [5] Input: " " Error: the greeting is not being friendly - // [6] Input: "hello" Error: the greeting is not properly separated - // [7] Input: "hello," Error: the greeting is targeted at thin air - // [8] Input: "hello , " Error: the greeting is targeted at thin air - // [9] Input: "hello , Droopy" Error: the greeting is not loud enough + // [3] Input: "hello Pizza!" Error: the greeting is not properly separated at line 1, column 6 + // [4] Input: "" Error: the greeting is not being friendly at start of file + // [5] Input: " " Error: the greeting is not being friendly at start of file + // [6] Input: "hello" Error: the greeting is not properly separated at line 1, column 6 + // [7] Input: "hello," Error: the greeting is targeted at thin air at line 1, column 7 + // [8] Input: "hello , " Error: the greeting is targeted at thin air at line 1, column 9 + // [9] Input: "hello , Droopy" Error: the greeting is not loud enough at line 1, column 15 // [10] Input: "hello , Droopy!" Output: Droopy // [11] Input: "hello , \t \t Droopy \t !" Output: Droopy - // [12] Input: "Oh no!" Error: the greeting is not being friendly - // [13] Input: "hello,!" Error: the greeting is targeted at thin air - // [14] Input: "HELLO, Buster! Eat this!" Error: too much stuff going on after the closing '!' + // [12] Input: "Oh no!" Error: the greeting is not being friendly at start of file + // [13] Input: "hello,!" Error: the greeting is targeted at thin air at line 1, column 7 + // [14] Input: "HELLO, Buster! Eat this!" Error: too much stuff going on after the closing '!' at line 1, column 15 } // --------------------------------------------------------------------------- diff --git a/parser_test.go b/parser_test.go index f483f59..1f3acba 100644 --- a/parser_test.go +++ b/parser_test.go @@ -49,10 +49,10 @@ func ExampleParseAPI_Expected() { p.Expected("a thing") }) err := parser.Execute("Whatever, this parser will never be happy...") - fmt.Println(err.Full()) + fmt.Printf("Error: %s\n", err) // Output: - // unexpected input (expected a thing) at start of file + // Error: unexpected input (expected a thing) at start of file } func ExampleParseAPI_Accept_inIfStatement() { @@ -138,7 +138,7 @@ func ExampleParseAPI_Stop_notCalledButInputPending() { fmt.Printf("\n") }) err := parser.Execute("Input with spaces") - fmt.Printf("Error: %s\n", err.Full()) + fmt.Printf("Error: %s\n", err) // Output: // First word: Input @@ -267,7 +267,7 @@ func TestGivenParserWhichIsNotStopped_WithNoMoreInput_FallbackExpectEndOfFileKic func TestGivenParserWhichIsNotStopped_WithMoreInput_ProducesError(t *testing.T) { p := parsekit.NewParser(func(p *parsekit.ParseAPI) {}) err := p.Execute("x") - parsekit.AssertEqual(t, "unexpected input (expected end of file) at start of file", err.Full(), "err") + parsekit.AssertEqual(t, "unexpected input (expected end of file) at start of file", err.Error(), "err") } type parserWithLoop struct { diff --git a/reader/reader_test.go b/reader/reader_test.go index 902320a..e325520 100644 --- a/reader/reader_test.go +++ b/reader/reader_test.go @@ -158,3 +158,20 @@ func TestGivenNumberOfRunesTooHigh_Flush_Panics(t *testing.T) { "(12) exceeds size of the buffer (11)", func() { r.Flush(12) }) } + +func TestGivenEOFFollowedByFlush_EOFCanStillBeRead(t *testing.T) { + r := reader.New(strings.NewReader("Hello, world!")) + _, err := r.RuneAt(13) + assert.Equal(t, err.Error(), "EOF") + _, err = r.RuneAt(13) + assert.Equal(t, err.Error(), "EOF") + _, err = r.RuneAt(14) + assert.Equal(t, err.Error(), "EOF") + r.Flush(13) + _, err = r.RuneAt(0) + assert.Equal(t, err.Error(), "EOF") + _, err = r.RuneAt(1) + assert.Equal(t, err.Error(), "EOF") + _, err = r.RuneAt(2) + assert.Equal(t, err.Error(), "EOF") +} diff --git a/tokenapi_example_test.go b/tokenapi_example_test.go index 9a46fed..46caca5 100644 --- a/tokenapi_example_test.go +++ b/tokenapi_example_test.go @@ -40,8 +40,8 @@ func ExampleTokenAPI_Fork() { // Output: // abcd // abcd - // unexpected input - // unexpected input + // unexpected input at start of file + // unexpected input at start of file } func ExampleTokenAPI_Merge() { diff --git a/tokenizer_test.go b/tokenizer_test.go index 0c583a1..737cbc9 100644 --- a/tokenizer_test.go +++ b/tokenizer_test.go @@ -46,8 +46,8 @@ func ExampleTokenizer_Execute() { // Result: ip("0.0.0.0", value = (string)0.0.0.0) mask("0", value = (int8)0) // Result: ip("192.168.0.1", value = (string)192.168.0.1) mask("24", value = (int8)24) // Result: ip("255.255.255.255", value = (string)255.255.255.255) mask("32", value = (int8)32) - // Error: unexpected input - // Error: unexpected input + // Error: unexpected input at start of file + // Error: unexpected input at start of file } func TestCallingNextRune_ReturnsNextRune(t *testing.T) {