diff options
-rw-r--r-- | build2/test/script/builtin.cxx | 89 | ||||
-rw-r--r-- | build2/test/script/runner.cxx | 2 | ||||
-rw-r--r-- | tests/test/script/builtin/buildfile | 2 | ||||
-rw-r--r-- | tests/test/script/builtin/test.test | 79 |
4 files changed, 171 insertions, 1 deletions
diff --git a/build2/test/script/builtin.cxx b/build2/test/script/builtin.cxx index 6a8ae16..008ac32 100644 --- a/build2/test/script/builtin.cxx +++ b/build2/test/script/builtin.cxx @@ -628,6 +628,94 @@ namespace build2 return 1; } + // test -f|-d <path> + // + // Test the specified path according to one of the following options. + // Succeed (0 exit code) if the test passes and fail (1 exit code) + // otherwise. In case of an error exit with code 2. Providing no + // arguments is an error (unlike POSIX). + // + // -f + // Path exists and is to a regular file. + // + // -d + // Path exists and is to a directory. + // + // Note that tests dereference symbolic links. + // + // Note: can be executed synchronously. + // + static uint8_t + test (scope& sp, + const strings& args, + auto_fd in, auto_fd out, auto_fd err) noexcept + try + { + uint8_t r (2); + ofdstream cerr (move (err)); + + try + { + in.close (); + out.close (); + + if (args.size () < 2) + { + cerr << "test: missing path" << endl; + throw failed (); + } + + bool file (args[0] == "-f"); + + if (!file && args[0] != "-d") + { + cerr << "test: invalid option" << endl; + throw failed (); + } + + if (args.size () > 2) + { + cerr << "test: unexpected argument" << endl; + throw failed (); + } + + path p (parse_path (args[1], sp.wd_path)); + + try + { + r = (file ? file_exists (p) : dir_exists (p)) ? 0 : 1; + } + catch (const system_error& e) + { + cerr << "test: cannot test '" << p << "': " << e << endl; + throw failed (); + } + } + catch (const invalid_path& e) + { + cerr << "test: invalid path '" << e.path << "'" << endl; + } + // Can be thrown while closing in, out or writing to cerr (that's why + // need to check its state before writing). + // + catch (const io_error& e) + { + if (cerr.good ()) + cerr << "test: " << e << endl; + } + catch (const failed&) + { + // Diagnostics has already been issued. + } + + cerr.close (); + return r; + } + catch (const std::exception&) + { + return 2; + } + // touch <file>... // // Change file access and modification times to the current time. Create @@ -808,6 +896,7 @@ namespace build2 {"mkdir", &sync_impl<&mkdir>}, {"rm", &sync_impl<&rm>}, {"rmdir", &sync_impl<&rmdir>}, + {"test", &sync_impl<&test>}, {"touch", &sync_impl<&touch>}, {"true", &true_} }; diff --git a/build2/test/script/runner.cxx b/build2/test/script/runner.cxx index 4a0c8e7..6f8446f 100644 --- a/build2/test/script/runner.cxx +++ b/build2/test/script/runner.cxx @@ -510,6 +510,8 @@ namespace build2 d << "invalid char-regex in " << what << " regex redirect" << e << info << "regex line: '" << line (l) << "'"; + + d << endf; } } diff --git a/tests/test/script/builtin/buildfile b/tests/test/script/builtin/buildfile index fe25065..e5bac10 100644 --- a/tests/test/script/builtin/buildfile +++ b/tests/test/script/builtin/buildfile @@ -2,4 +2,4 @@ # copyright : Copyright (c) 2014-2017 Code Synthesis Ltd # license : MIT; see accompanying LICENSE file -./: test{cat echo mkdir rm rmdir touch} $b +./: test{cat echo mkdir rm rmdir test touch} $b diff --git a/tests/test/script/builtin/test.test b/tests/test/script/builtin/test.test new file mode 100644 index 0000000..7e9ace4 --- /dev/null +++ b/tests/test/script/builtin/test.test @@ -0,0 +1,79 @@ +# file : tests/test/script/builtin/test.test +# copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +# license : MIT; see accompanying LICENSE file + +.include ../common.test + +: file +: +{ + : exists + : + $c <<EOI; + touch a; + test -f a + EOI + $b + + : not-exists + : + $c <'test -f a == 1'; + $b + + : not-file + : + $c <'test -f . == 1'; + $b +} + +: dir +: +{ + : exists + : + $c <'test -d .'; + $b + + : not-exists + : + $c <'test -d a == 1'; + $b + + : not-dir + : + $c <<EOI; + touch a; + test -d a == 1 + EOI + $b +} + +: no-args +: +: Test passing no arguments. +: +$c <'test 2>"test: missing path" == 2'; +$b + +: invalid-option +: +: Test passing invalid option. +: +$c <'test -c a 2>"test: invalid option" == 2'; +$b + +: unexpected-arg +: +: Test passing extra argument. +: +$c <'test -f a b 2>"test: unexpected argument" == 2'; +$b + +: empty-path +: +: Test testing an empty path. +: +$c <<EOI; +test -d '' 2>"test: invalid path ''" == 2 +EOI +$b |