builtin_test: don't exit 1 for eval errors, add tests for big args

Return STATUS_INVALID_ARGS when failing due to evaluation errors,
so we can tell the difference between an error and falseness.

Add a test for the ERANGE error
This commit is contained in:
Aaron Gyes 2018-12-15 22:05:19 -08:00
parent cf2b40040a
commit 57d6124e6e
3 changed files with 26 additions and 14 deletions

View file

@ -648,7 +648,6 @@ static bool parse_number(const wcstring &arg, number_t *number, wcstring_list_t
const wchar_t *argcs = arg.c_str();
double floating = 0;
bool got_float = parse_double(argcs, &floating);
errno = 0;
long long integral = fish_wcstoll(argcs);
bool got_int = (errno == 0);
@ -656,6 +655,7 @@ static bool parse_number(const wcstring &arg, number_t *number, wcstring_list_t
// Here the value is just an integer; ignore the floating point parse because it may be
// invalid (e.g. not a representable integer).
*number = number_t{integral, 0.0};
return true;
} else if (got_float && errno != ERANGE) {
// Here we parsed an (in range) floating point value that could not be parsed as an integer.
@ -664,6 +664,7 @@ static bool parse_number(const wcstring &arg, number_t *number, wcstring_list_t
double intpart = std::floor(floating);
double delta = floating - intpart;
*number = number_t{static_cast<long long>(intpart), delta};
return true;
} else {
// We could not parse a float or an int.
@ -835,7 +836,7 @@ int builtin_test(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
const wcstring_list_t args(argv + 1, argv + 1 + argc);
if (argc == 0) {
return STATUS_CMD_ERROR; // Per 1003.1, exit false.
return STATUS_INVALID_ARGS; // Per 1003.1, exit false.
} else if (argc == 1) {
// Per 1003.1, exit true if the arg is non-empty.
return args.at(0).empty() ? STATUS_CMD_ERROR : STATUS_CMD_OK;
@ -858,11 +859,13 @@ int builtin_test(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
wcstring_list_t eval_errors;
bool result = expr->evaluate(eval_errors);
if (!eval_errors.empty() && !should_suppress_stderr_for_tests()) {
streams.err.append(L"test returned eval errors:\n");
for (size_t i = 0; i < eval_errors.size(); i++) {
streams.err.append_format(L"\t%ls\n", eval_errors.at(i).c_str());
if (!eval_errors.empty()) {
if (!should_suppress_stderr_for_tests()) {
for (size_t i = 0; i < eval_errors.size(); i++) {
streams.err.append_format(L"\t%ls\n", eval_errors.at(i).c_str());
}
}
return STATUS_INVALID_ARGS;
}
return result ? STATUS_CMD_OK : STATUS_CMD_ERROR;
}

View file

@ -2155,7 +2155,12 @@ static bool run_one_test_test(int expected, wcstring_list_t &lst, bool bracket)
argv[i + 1] = NULL;
io_streams_t streams(0);
int result = builtin_test(parser, streams, argv);
if (expected != result)
err(L"expected builtin_test() to return %d, got %d", expected, result);
delete[] argv;
return expected == result;
}
@ -2207,13 +2212,13 @@ static void test_test() {
do_test(run_test_test(0, L"' 2' -eq 2"));
do_test(run_test_test(0, L"'2 ' -eq 2"));
do_test(run_test_test(0, L"' 2 ' -eq 2"));
do_test(run_test_test(1, L"' 2x' -eq 2"));
do_test(run_test_test(1, L"'' -eq 0"));
do_test(run_test_test(1, L"'' -ne 0"));
do_test(run_test_test(1, L"' ' -eq 0"));
do_test(run_test_test(1, L"' ' -ne 0"));
do_test(run_test_test(1, L"'x' -eq 0"));
do_test(run_test_test(1, L"'x' -ne 0"));
do_test(run_test_test(2, L"' 2x' -eq 2"));
do_test(run_test_test(2, L"'' -eq 0"));
do_test(run_test_test(2, L"'' -ne 0"));
do_test(run_test_test(2, L"' ' -eq 0"));
do_test(run_test_test(2, L"' ' -ne 0"));
do_test(run_test_test(2, L"'x' -eq 0"));
do_test(run_test_test(2, L"'x' -ne 0"));
do_test(run_test_test(1, L"-1 -ne -1"));
do_test(run_test_test(0, L"abc != def"));
do_test(run_test_test(1, L"abc = def"));
@ -2284,6 +2289,10 @@ static void test_test() {
do_test(run_test_test(1, L"-4611686018427387904 -ge 4611686018427387904"));
do_test(run_test_test(1, L"4611686018427387904 -gt 4611686018427387904"));
do_test(run_test_test(0, L"4611686018427387904 -ge 4611686018427387904"));
// test out-of-range numbers
do_test(run_test_test(2, L"99999999999999999999999999 -ge 1"));
do_test(run_test_test(2, L"1 -eq -99999999999999999999999999.9"));
}
static void test_wcstod() {

View file

@ -38,7 +38,7 @@ Test 22 pass
6 0
7 4
8 0
9 121
9 2
10 0 A
11 1 B