1. GET_LONG_ANSWER error return
- Posted by slowmaker Jun 02, 2013
- 1712 views
The get()/value() documentation states this regarding the third element of the GET_LONG_ANSWER return sequence:
"an integer, the number of characters read. On an error, this is the point at which the error was detected." (emphasis added)
While tinkering with test cases, I found that the following fails:
test_equal("value() bad integer [LONG ANSWER]", {GET_FAIL, 0, 1, 0}, value("John",,GET_LONG_ANSWER))
causing this fail message:
failed: value() bad integer [LONG ANSWER], expected: {1,0,1,0} but got: {1,0,0,0}
The documentation seems to me to be saying that the value("John", ,GET_LONG_ANSWER) call should return a 1 in the third element, as that is the point at which the error was detected, i.e. the very first character.
So, is this:
- get() bug?
- documentation error?
- slowmaker's misunderstanding?
2. Re: GET_LONG_ANSWER error return
- Posted by DerekParnell (admin) Jun 02, 2013
- 1677 views
The documentation seems to me to be saying that the value("John", ,GET_LONG_ANSWER) call should return a 1 in the third element, as that is the point at which the error was detected, i.e. the very first character.
The documentation and the library are correct. The documentation is a bit ambiguous though. The key point is that the third item is the count of characters read so far in the processing. So therefore, if the first character is invalid, then the number processed so far is zero.
Your test case should read ...
test_equal("value() bad integer [LONG ANSWER]", {GET_FAIL, 0, 0, 0}, value("John",,GET_LONG_ANSWER))
We need to put in a LOT more test cases for this function.
3. Re: GET_LONG_ANSWER error return
- Posted by slowmaker Jun 03, 2013
- 1508 views
The documentation seems to me to be saying that the value("John", ,GET_LONG_ANSWER) call should return a 1 in the third element, as that is the point at which the error was detected, i.e. the very first character.
The documentation and the library are correct. The documentation is a bit ambiguous though. The key point is that the third item is the count of characters read so far in the processing. So therefore, if the first character is invalid, then the number processed so far is zero.
Your test case should read ...
test_equal("value() bad integer [LONG ANSWER]", {GET_FAIL, 0, 0, 0}, value("John",,GET_LONG_ANSWER))
We need to put in a LOT more test cases for this function.
Okay, so restating to check my understanding: where the docs for these two routines say 'read', I should be thinking 'read and validated as part of a legitimate Euphoria object', correct?
Regarding ambiguity: yes definitely. After all, it does read one character. Even the word 'processed' does not necessarily imply successful interpretation/translation; if a character has been read and deemed 'bad' for the current context, you could make a good case for the viewpoint that it has been processed.
Likewise with the other phrase:
On an error, this is the point at which the error was detected." (emphasis added)
To me, that phrasing would have meant I could use that number as an index to put me smack dab on the first bad/illegal/nonconforming character. As you have pointed out, that is not the case after all.
The only problem is, having said all this and claimed ambiguity for the existing phrasing, I don't really have any better phrasing to suggest; crap. The phrase I used above, 'read and validated as part of a legitimate Euphoria object', works for me, but it's extremely verbose and probably has its own vagueness I'm just not seeing because I thought of it.
Anyway, skipping the vague docs phrasing, thanks for the clarification. I'm definitely going to need to start over on my rewrite of get() & company; the approach I initially took, apart from other issues it has, is almost entirely based on the assumption that the docs meant the way I initially assumed (i.e. opposite what has been now stated as the right way).
Back to building test cases...
4. Re: GET_LONG_ANSWER error return
- Posted by DerekParnell (admin) Jun 03, 2013
- 1529 views
The only problem is, having said all this and claimed ambiguity for the existing phrasing, I don't really have any better phrasing to suggest.
How about ...
The number of successfully processed characters
5. Re: GET_LONG_ANSWER error return
- Posted by slowmaker Jun 04, 2013
- 1453 views
The only problem is, having said all this and claimed ambiguity for the existing phrasing, I don't really have any better phrasing to suggest.
How about ...
The number of successfully processed characters
Still possibilities for misunderstanding (e.g. a bad character has still been successfully processed; the routine wouldn't know the char was bad unless it had successfully read it and chewed it up). Depends on how the reader is thinking of 'processed'. I still have no better wording to suggest, just pointing out that all available ones seem to lend themselves to multiple interpretations.
However...
You might be better off keeping the original, more-concise-albeit-ambiguous wording, but adding more examples to the docs for GET_LONG_ANSWER usage. Less ambiguity there; the example code either works, and the coder can then say 'OH! That's what they meant!', or it doesn't, and they can go harass the maintainers.
A side benefit in that approach is that no-one ever fusses about too many examples, or too wide a variety of examples, in my experience. Almost always a can't hurt, probably will help, kind of thing.
6. Re: GET_LONG_ANSWER error return
- Posted by mattlewis (admin) Jun 04, 2013
- 1458 views
The only problem is, having said all this and claimed ambiguity for the existing phrasing, I don't really have any better phrasing to suggest.
How about ...
The number of successfully processed characters
Still possibilities for misunderstanding (e.g. a bad character has still been successfully processed; the routine wouldn't know the char was bad unless it had successfully read it and chewed it up). Depends on how the reader is thinking of 'processed'. I still have no better wording to suggest, just pointing out that all available ones seem to lend themselves to multiple interpretations.
We might say something like, "the last character before the error, or the last character processed."
Matt
7. Re: GET_LONG_ANSWER error return
- Posted by jimcbrown (admin) Jun 04, 2013
- 1483 views
We might say something like, "the last character before the error, or the last character processed."
Well.. that's ok, but a certain point it gets too wordly and reads like a complex legal document.
8. Re: GET_LONG_ANSWER error return
- Posted by DerekParnell (admin) Jun 04, 2013
- 1481 views
We might say something like, "the last character before the error, or the last character processed."
Well.. that's ok, but a certain point it gets too wordly and reads like a complex legal document.
Still that might be better than ambiguity.
9. Re: GET_LONG_ANSWER error return
- Posted by jimcbrown (admin) Jun 04, 2013
- 1478 views
We might say something like, "the last character before the error, or the last character processed."
Well.. that's ok, but a certain point it gets too wordly and reads like a complex legal document.
Still that might be better than ambiguity.
Either way, I like slowmaker's point of using examples to clarify...
10. Re: GET_LONG_ANSWER error return
- Posted by useless_ Jun 04, 2013
- 1465 views
A side benefit in that approach is that no-one ever fusses about too many examples, or too wide a variety of examples, in my experience. Almost always a can't hurt, probably will help, kind of thing.
LOL! Man, what a problem there is with multiple examples! Or eubot, but that's a different thread.
useless
11. Re: GET_LONG_ANSWER error return
- Posted by slowmaker Jul 27, 2013
- 1369 views
We need to put in a LOT more test cases for this function.
Here's what I managed so far, should anyone care to make use of it. I won't be able to continue on it myself; I've been forced to admit I've just got too many other irons in the fire to make any more progress on the get()/value() related stuff I had started.
--t_get.e include std/get.e include std/unittest.e include std/filesys.e procedure dual_test_value(sequence name, object expected, object input, integer offset=1) -- Reduce a little of the pain of extensive test case typing by running -- both GET_LONG_ANSWER and GET_SHORT_ANSWER versions from a single -- call. -- so...you have to always specify the long answer in 'expected'. -- -- Automatically appends ' [LONG ANSWER]' to test names when appropriate. -- Prepends "value() " string to test name. -- Also allows offset specification, defaulted to the 'no offset' case. -- -- ASSUMPTION: the expected return for the short answer case will -- always match the first two elements of the expected return -- for the long answer case. -- -- The name parameter is the same as for test_equal(), bearing in mind -- that it will be modified for the long answer run. -- test_equal("value() " & name, expected[1..2], value(input,offset,GET_SHORT_ANSWER)) test_equal("value() " & name & " [LONG ANSWER]", expected, value(input,offset,GET_LONG_ANSWER)) end procedure dual_test_value("no data supplied", {GET_EOF, 0, 0, 0}, "") dual_test_value("integer", {GET_SUCCESS, 10, 2, 0}, "10") dual_test_value("integer terminated by non-integer, whitespace", {GET_SUCCESS, 10, 3, 1}, " 10john") dual_test_value("bad integer", {GET_FAIL, 0, 0, 0}, "John") dual_test_value("integer, from offset", {GET_SUCCESS, 10, 2, 0}, "Data: 10", 7) dual_test_value("integer, underscores", {GET_SUCCESS, 44444, 8, 0}, "4__444_4") dual_test_value("integer, from offset, leading whitespace", {GET_SUCCESS, 10, 3, 1}, "Data: 10", 6) dual_test_value("hex integer, # notation", {GET_SUCCESS, 241, 3, 0}, "#F1") dual_test_value("hex integer, # notation, lower case", {GET_SUCCESS, 241, 3, 0}, "#f1") dual_test_value("hex integer, 0x notation", {GET_SUCCESS, 241, 4, 0}, "0xF1") dual_test_value("hex integer, 0x notation, mixed case", {GET_SUCCESS, 254, 4, 0}, "0xFe") dual_test_value("hex integer, 0X notation (capital X)", {GET_SUCCESS, 254, 4, 0}, "0Xfe") dual_test_value("binary integer, 0b notation", {GET_SUCCESS, 15, 6, 0}, "0b1111") dual_test_value("binary integer, 0B notation (capital B)", {GET_SUCCESS, 15, 6, 0}, "0B1111") dual_test_value("float", {GET_SUCCESS, 10.5, 4, 0}, "10.5") dual_test_value("float, whitespace", {GET_SUCCESS, 10.5, 5, 1}, " 10.5 ") dual_test_value("sequence", {GET_SUCCESS, {1,2}, 5, 0}, "{1,2}") dual_test_value("sequence terminator", {GET_SUCCESS, {4}, 6, 0}, "{4, $}") dual_test_value("float, underscores", {GET_SUCCESS, 6.6, 5, 0}, "6_._6") dual_test_value("scientific notation #1", {GET_SUCCESS, 3.14e2, 6, 0}, "3.14e2") dual_test_value("scientific notation #2", {GET_SUCCESS, 3.14e-12, 8, 0}, "3.14E-12") dual_test_value("scientific notation #3", {GET_SUCCESS, 3.14e+12, 9, 0}, "+3.14e+12") dual_test_value("scientific notation #4 no exponent", {GET_FAIL, 0, 6, 0}, "+3.14e") dual_test_value("no hex digits", {GET_FAIL, 0, 1, 0}, "#") dual_test_value("decimal point only", {GET_FAIL, 0, 1, 0}, ".") dual_test_value("mixed object", {GET_SUCCESS, { 1, 2, 3, "foo", {-9},{}}, 26, 0}, "{ 1, 2, 3, \"foo\", {-9},{}}") dual_test_value("quoted text", {GET_SUCCESS, "some text", 11, 0},"\"some text\"") dual_test_value("single-quoted character", {GET_SUCCESS, 'f', 3, 0}, "'f'") dual_test_value("escaped binary", {GET_SUCCESS, 170, 10, 0}, "\"\b10101010\"") dual_test_value("escaped binary, terminated by non-binary", {GET_SUCCESS, 240, 10, 0}, "\"\b11110000abcdefg\"") test_equal("defaulted_value() #1", 0, defaulted_value("abc", 0)) test_equal("defaulted_value() #2", 10, defaulted_value("10", 0)) test_equal("defaulted_value() #3", 10.5, defaulted_value("10.5", 0)) test_equal("defaulted_value() #4", 0, defaulted_value(10.5, 0)) test_equal("defaulted_value() #5", {1,2,3}, defaulted_value("123={1,2,3}", 0, 5)) test_equal("defaulted_value() #6", 0, defaulted_value("123={1,2,3}", 0, 4)) constant OBJECT = { 1, 2, 3, "foo", {-9},{}}, TEXT = "some text", CHAR = 'f' integer fn = open( "get.txt", "w" ) print(fn, OBJECT ) printf(fn, "\n\"%s\"\n'%s'\n", { TEXT, CHAR } ) close(fn) fn = open( "get.txt", "r" ) test_equal( "print / get", { GET_SUCCESS, OBJECT}, get( fn ) ) test_equal( "print / get", { GET_SUCCESS, TEXT}, get( fn ) ) test_equal( "print / get", { GET_SUCCESS, CHAR}, get( fn ) ) test_equal( "print / get", { GET_EOF, 0}, get( fn ) ) close(fn) delete_file( "get.txt" ) test_report()
12. Re: GET_LONG_ANSWER error return
- Posted by DerekParnell (admin) Jul 27, 2013
- 1318 views
Here's what I managed so far...
Thanks. We'll incorporate and expand on these. A good effort.