aboutsummaryrefslogtreecommitdiff
path: root/unit-tests
diff options
context:
space:
mode:
Diffstat (limited to 'unit-tests')
-rw-r--r--unit-tests/buildfile2
-rw-r--r--unit-tests/function/buildfile14
-rw-r--r--unit-tests/function/call.test131
-rw-r--r--unit-tests/function/driver.cxx110
-rw-r--r--unit-tests/function/syntax.test29
-rw-r--r--unit-tests/test/script/parser/buildfile4
6 files changed, 287 insertions, 3 deletions
diff --git a/unit-tests/buildfile b/unit-tests/buildfile
index 6e8b5c2..5d06ec7 100644
--- a/unit-tests/buildfile
+++ b/unit-tests/buildfile
@@ -2,6 +2,6 @@
# copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
# license : MIT; see accompanying LICENSE file
-d = test/script/
+d = function/ test/script/
./: $d
include $d
diff --git a/unit-tests/function/buildfile b/unit-tests/function/buildfile
new file mode 100644
index 0000000..6c1d346
--- /dev/null
+++ b/unit-tests/function/buildfile
@@ -0,0 +1,14 @@
+# file : unit-tests/function/buildfile
+# copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
+# license : MIT; see accompanying LICENSE file
+
+#@@ Temporary until we get utility library support.
+#
+import libs = libbutl%lib{butl}
+src = token lexer diagnostics utility variable name b-options types-parsers \
+context scope parser target operation rule prerequisite file module function \
+functions-path algorithm search dump filesystem config/{utility init operation}
+
+exe{driver}: cxx{driver} ../../build2/cxx{$src} $libs test{call syntax}
+
+include ../../build2/
diff --git a/unit-tests/function/call.test b/unit-tests/function/call.test
new file mode 100644
index 0000000..d459300
--- /dev/null
+++ b/unit-tests/function/call.test
@@ -0,0 +1,131 @@
+# file : unit-tests/function/call.test
+# copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
+# license : MIT; see accompanying LICENSE file
+
+: qual-implicit
+:
+$* <'print $dummy.dummy0()' >'abc'
+
+: qual-explicit
+:
+$* <'print $dummy.qual()' >'abc'
+
+: qual-fail
+:
+$* <'print $qual()' 2>>EOE != 0
+buildfile:1:8: error: unmatched call to qual\()
+EOE
+
+: variadic
+:
+# @@ TMP: add some args
+$* <'print $variadic([bool] true)' >'1'
+
+: fail
+:
+$* <'$fail()' 2>>EOE != 0
+error: failed
+buildfile:1:2: info: while calling fail\()
+EOE
+
+: fail-invalid-arg
+:
+$* <'$fail_arg(abc)' 2>>EOE != 0
+error: invalid argument: invalid uint64 value: 'abc'
+buildfile:1:2: info: while calling fail_arg\(<untyped>)
+EOE
+
+: no-match-name
+:
+$* <'$bogus()' 2>>EOE != 0
+buildfile:1:2: error: unmatched call to bogus\()
+EOE
+
+: no-match-count
+:
+$* <'$dummy0(abc)' 2>>EOE != 0
+buildfile:1:2: error: unmatched call to dummy0\(<untyped>)
+ info: candidate: dummy0\(), qualified name dummy.dummy0
+EOE
+
+: no-match-type
+:
+$* <'$dummy1([uint64] 123)' 2>>EOE != 0
+buildfile:1:2: error: unmatched call to dummy1\(uint64)
+ info: candidate: dummy1\(string), qualified name dummy.dummy1
+EOE
+
+: ambig
+:
+$* <'$ambig(abc)' 2>>EOE != 0
+buildfile:1:2: error: ambiguous call to ambig\(<untyped>)
+ info: candidate: ambig\(<untyped> [, uint64]), qualified name dummy.ambig
+ info: candidate: ambig\(<untyped> [, string]), qualified name dummy.ambig
+EOE
+
+: optional-absent
+:
+$* <'print $optional()' >'true'
+
+: optional-present
+:
+$* <'print $optional(abc)' >'false'
+
+: null-true
+:
+$* <'print $null([null])' >'true'
+
+: null-false
+:
+$* <'print $null(nonull)' >'false'
+
+: null-fail
+:
+$* <'$dummy1([string null])' 2>>EOE != 0
+error: invalid argument: null value
+buildfile:1:2: info: while calling dummy1\(string)
+EOE
+
+: print-call-1-untyped
+:
+$* <'$bogus(abc)' 2>>EOE != 0
+buildfile:1:2: error: unmatched call to bogus\(<untyped>)
+EOE
+
+: print-call-1-typed
+:
+$* <'$bogus([uint64] 123)' 2>>EOE != 0
+buildfile:1:2: error: unmatched call to bogus\(uint64)
+EOE
+
+#\
+@@ TMP
+: print-call-2
+:
+$* <'$bogus(abc, [uint64] 123)' 2>>EOE != 0
+buildfile:1:2: error: unmatched call to bogus\(<untyped>, uint64)
+EOE
+#\
+
+: print-fovl
+:
+$* <'$ambig([bool] true)' 2>>EOE != 0
+buildfile:1:2: error: unmatched call to ambig\(bool)
+ info: candidate: ambig\(<untyped> [, uint64]), qualified name dummy.ambig
+ info: candidate: ambig\(<untyped> [, string]), qualified name dummy.ambig
+EOE
+
+: print-fovl-variadic
+:
+$* <'$variadic(abc)' 2>>EOE != 0
+buildfile:1:2: error: unmatched call to variadic\(<untyped>)
+ info: candidate: variadic\(bool [, ...])
+EOE
+
+: member-function
+:
+$* <'print $dummy.length([string] abc)' >'3'
+
+: data-member
+:
+$* <'print $dummy.type([name] cxx{foo})' >'cxx'
diff --git a/unit-tests/function/driver.cxx b/unit-tests/function/driver.cxx
new file mode 100644
index 0000000..ba51662
--- /dev/null
+++ b/unit-tests/function/driver.cxx
@@ -0,0 +1,110 @@
+// file : unit-tests/function/driver.cxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#include <iostream>
+
+#include <build2/types>
+#include <build2/utility>
+
+#include <build2/parser>
+#include <build2/context>
+#include <build2/function>
+#include <build2/variable>
+#include <build2/diagnostics>
+
+using namespace std;
+
+namespace build2
+{
+ static const optional<const value_type*> arg_bool[1] =
+ {
+ &value_traits<bool>::value_type
+ };
+
+ int
+ main ()
+ {
+ init ("false", 1); // No build system driver, default verbosity.
+ reset (strings ()); // No command line variables.
+
+ function_family f ("dummy");
+
+ f["fail"] = []() {error << "failed"; throw failed ();};
+ f["fail_arg"] = [](names a) {return convert<uint64_t> (move (a[0]));};
+
+ f["null"] = [](names* a) {return a == nullptr;};
+ f["optional"] = [](optional<names> a) {return !a;};
+
+ f["dummy0"] = []() {return "abc";};
+ f["dummy1"] = [](string s) {return s;};
+
+ f["ambig"] = [](names a, optional<string>) {return a;};
+ f["ambig"] = [](names a, optional<uint64_t>) {return a;};
+
+ f[".qual"] = []() {return "abc";};
+
+ f[".length"] = &string::size; // Member function.
+ f[".type"] = &name::type; // Data member.
+
+ // Variadic function with first required argument of type bool. Returns
+ // number of arguments passed.
+ //
+ functions.insert (
+ "variadic",
+ function_overload (
+ nullptr,
+ 1,
+ function_overload::arg_variadic,
+ function_overload::types (arg_bool, 1),
+ [] (vector_view<value> args, const function_overload&)
+ {
+ return value (static_cast<uint64_t> (args.size ()));
+ }));
+
+ // Dump arguments.
+ //
+ functions.insert (
+ "dump",
+ function_overload (
+ nullptr,
+ 0,
+ function_overload::arg_variadic,
+ function_overload::types (),
+ [] (vector_view<value> args, const function_overload&)
+ {
+ for (value& a: args)
+ {
+ if (a.null)
+ cout << "[null]";
+ else if (!a.empty ())
+ {
+ names storage;
+ cout << reverse (a, storage);
+ }
+ cout << endl;
+ }
+ return value (nullptr);
+ }));
+
+ try
+ {
+ scope& s (*global_scope);
+
+ parser p;
+ p.parse_buildfile (cin, path ("buildfile"), s, s);
+ }
+ catch (const failed&)
+ {
+ return 1;
+ }
+
+ return 0;
+ }
+}
+
+int
+main ()
+{
+ return build2::main ();
+}
diff --git a/unit-tests/function/syntax.test b/unit-tests/function/syntax.test
new file mode 100644
index 0000000..9e653c8
--- /dev/null
+++ b/unit-tests/function/syntax.test
@@ -0,0 +1,29 @@
+# file : unit-tests/function/syntax.test
+# copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
+# license : MIT; see accompanying LICENSE file
+
+$* <'$dump()' >:'' : none
+$* <'$dump( )' >:'' : none-in-spaces
+$* <'$dump ()' >:'' : none-out-spaces
+$* <'$dump("")' >'{}' : one-empty
+$* <'$dump(a)' >'a' : one-single
+$* <'$dump(a b c)' >'a b c' : one-list
+$* <'$dump(d/t{x y z})' >'d/t{x} d/t{y} d/t{z}' : one-names
+
+$* <'print a$dummy1 ([string] b)c' >'abc' : concat
+
+: quoting
+: Verify we can inhibit function call with quoting
+:
+$* <<EOI >>EOO
+foo = FOO
+bar = BAR
+
+print \$foo"\(\$bar)"
+print "\$foo"\(\$bar)
+print "\$foo""\(\$bar)"
+EOI
+FOOBAR
+FOOBAR
+FOOBAR
+EOO
diff --git a/unit-tests/test/script/parser/buildfile b/unit-tests/test/script/parser/buildfile
index 2ed60ec..af3f2d3 100644
--- a/unit-tests/test/script/parser/buildfile
+++ b/unit-tests/test/script/parser/buildfile
@@ -7,8 +7,8 @@
import libs = libbutl%lib{butl}
src = token lexer parser diagnostics utility variable name context target \
scope prerequisite file module operation rule b-options algorithm search \
-filesystem config/{utility init operation} dump types-parsers \
-test/{target script/{token lexer parser script}}
+filesystem function functions-path config/{utility init operation} dump \
+types-parsers test/{target script/{token lexer parser script}}
exe{driver}: cxx{driver} ../../../../build2/cxx{$src} $libs \
test{cleanup command-if command-re-parse description exit expansion \