aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build2/test/script/builtin.cxx89
-rw-r--r--build2/test/script/runner.cxx2
-rw-r--r--tests/test/script/builtin/buildfile2
-rw-r--r--tests/test/script/builtin/test.test79
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