aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/cc/modules/common.testscript16
-rw-r--r--tests/cc/modules/modules.testscript19
-rw-r--r--tests/cc/preprocessed/testscript1
-rw-r--r--tests/dependency/recipe/testscript2
-rw-r--r--tests/directive/config.testscript4
-rw-r--r--tests/function/builtin/testscript28
-rw-r--r--tests/function/filesystem/testscript48
-rw-r--r--tests/function/json/buildfile4
-rw-r--r--tests/function/json/testscript257
-rw-r--r--tests/function/path/testscript82
-rw-r--r--tests/function/string/testscript118
-rw-r--r--tests/type/json/buildfile4
-rw-r--r--tests/type/json/testscript504
-rw-r--r--tests/type/map/buildfile4
-rw-r--r--tests/type/map/testscript70
-rw-r--r--tests/type/set/buildfile4
-rw-r--r--tests/type/set/testscript55
-rw-r--r--tests/type/vector/buildfile4
-rw-r--r--tests/type/vector/testscript57
19 files changed, 1249 insertions, 32 deletions
diff --git a/tests/cc/modules/common.testscript b/tests/cc/modules/common.testscript
index 50dc865..9883e42 100644
--- a/tests/cc/modules/common.testscript
+++ b/tests/cc/modules/common.testscript
@@ -21,7 +21,15 @@ cxx.std = experimental
cxx.features.symexport = true
# @@ TMP revise
-if ($cxx.id == 'gcc')
+#
+# Note: there are some issues with enabling modules in Apple Clang 15 so
+# for now we only test vanilla Clang.
+#
+if (($cxx.id == 'gcc' && $cxx.version.major >= 11) || \
+ ($cxx.id == 'clang' && $cxx.version.major >= 16) || \
+ ($cxx.id == 'msvc' && ($cxx.version.major > 19 || \
+ ($cxx.version.major == 19 && \
+ $cxx.version.minor >= 36))))
cxx.features.modules = true
using cxx
@@ -38,7 +46,7 @@ if ($cxx.target.class == 'windows')
exe{*}: test = true
EOI
-# Determine if we have modules and header units support.
+# Determine if we have named modules and header units support.
#
+$* noop <<EOI | set modules
print $cxx.features.modules
@@ -49,8 +57,10 @@ print ($cxx.features.modules && $cxx.id == 'gcc')
EOI
# @@ TMP: modules support is broken in MinGW GCC (not just symexport).
+# @@ TMP: try modules with Clang on Windows (symexport seems to work).
#
-if ($cxx.target.class == 'windows' && $cxx.id == 'gcc')
+if ($cxx.target.class == 'windows' && \
+ ($cxx.id == 'gcc' || $cxx.id.type == 'clang'))
modules = false
headers = false
end
diff --git a/tests/cc/modules/modules.testscript b/tests/cc/modules/modules.testscript
index 8762885..c286c1f 100644
--- a/tests/cc/modules/modules.testscript
+++ b/tests/cc/modules/modules.testscript
@@ -205,15 +205,11 @@ $* test clean <<EOI
:
: Test global module fragment/leading module marker (module;).
:
-if ($cxx.id != 'msvc') # Disabled for MSVC due to issue 845845.
-{
cat <<EOI >=g.hxx;
void g ();
EOI
cat <<EOI >=core.mxx;
-#if __cpp_modules >= 201810
module;
-#endif
#include "g.hxx"
EOI
@@ -222,7 +218,6 @@ ln -s ../core.cxx ../driver.cxx ./;
$* test clean <<EOI
exe{test}: cxx{driver} {mxx cxx}{core}
EOI
-}
: re-export
:
@@ -373,20 +368,28 @@ cat <<EOI >=core.mxx;
export __symexport int f (int);
- __symexport int g_impl (int i) {return i - 1;}
+ __symexport int g_impl (int i);
export __symexport inline int g (int i) {return g_impl (i);}
+
+ export __symexport int v1 = 1;
+ export __symexport extern int v2;
EOI
ln -s ../core.cxx core-f.cxx;
cat <<EOI >=core-g.cxx;
module foo.core;
int g_impl (int i) {return i - 1;}
+ int v = 1;
+ EOI
+cat <<EOI >=core-v.cxx;
+ module foo.core;
+ int v2 = -1;
EOI
cat <<EOI >=driver.cxx;
import foo.core;
- int main (int argc, char*[]) {return f (argc) + g (argc);}
+ int main (int argc, char*[]) {return f (argc) + g (argc) + v1 + v2;}
EOI
$* test clean <<EOI
./: lib{foo} exe{test} # Full build.
exe{test}: cxx{driver} lib{foo}
- lib{foo}: mxx{core} cxx{core-f} # @@ VC: core-g
+ lib{foo}: mxx{core} cxx{core-g core-f core-v}
EOI
diff --git a/tests/cc/preprocessed/testscript b/tests/cc/preprocessed/testscript
index 507a92d..53e7755 100644
--- a/tests/cc/preprocessed/testscript
+++ b/tests/cc/preprocessed/testscript
@@ -98,6 +98,7 @@ $* &test* <<EOI 2>>EOE != 0
exe{test}: cxx{test}
EOI
error: modules support required by cxx{test}
+ info: consider enabling modules with cxx.features.modules=true in root.build
EOE
: all
diff --git a/tests/dependency/recipe/testscript b/tests/dependency/recipe/testscript
index f43111e..a581724 100644
--- a/tests/dependency/recipe/testscript
+++ b/tests/dependency/recipe/testscript
@@ -406,7 +406,7 @@ alias{x}:
echo
}
EOI
-<stdin>:3:1: error: expected recipe block instead of '{'
+<stdin>:3:1: error: expected recipe block or 'recipe' instead of '{'
EOE
: duplicate-action-single
diff --git a/tests/directive/config.testscript b/tests/directive/config.testscript
index fba858f..ebdd6ac 100644
--- a/tests/directive/config.testscript
+++ b/tests/directive/config.testscript
@@ -212,12 +212,14 @@ test.arguments =
config [strings, config.report=multiline] config.test.d ?= 1 2 3
config [string, config.report.variable=e] config.test.e ?= abc
config [ config.report] f
+ config [ config.report.variable=g] gg
config [bool] config.test.n ?= [null]
config [bool] config.test.p
config [bool] config.test.p ?= true
e = "'$config.test.e'"
f = ($config.test.b || $config.test.c)
+ g = abc
EOI
@@ -240,6 +242,7 @@ test.arguments =
3
e 'abc'
f true
+ gg abc
n [null]
p true
EOO
@@ -262,6 +265,7 @@ test.arguments =
3
e 'xyz'
f true
+ gg abc
n true
p false
EOO
diff --git a/tests/function/builtin/testscript b/tests/function/builtin/testscript
index 714a38d..04e8bd8 100644
--- a/tests/function/builtin/testscript
+++ b/tests/function/builtin/testscript
@@ -53,6 +53,34 @@
$* <'print $empty(abc)' >'false' : name
$* <'print $empty(abc cxx{foo})' >'false' : names
$* <'print $empty([bool] false)' >'false' : bool
+ $* <'print $empty([json] null)' >'true' : json-null
+ $* <'print $empty([json] "[]")' >'true' : json-array
+ $* <'print $empty([json] "{}")' >'true' : json-object
+}
+
+: first-second
+:
+{
+ $* <'print $first(a@1)' >'a' : first
+ $* <'print $second(a@1)' >'1' : second
+
+ $* <'print $first(@1)' >'{}' : first-empty
+ $* <'print $second(a@)' >'{}' : second-empty
+
+ $* <'print $first(1)' >'[null]' : first-null
+ $* <'print $second(a)' >'[null]' : second-null
+
+ $* <'print $first(1, true)' >'1' : first-all
+ $* <'print $second(a, true)' >'a' : second-all
+
+ $* <'print $first(0 a@1 b@2 c@ 4)' >'a b c' : firsts
+ $* <'print $second(z a@1 b@2 @3 d)' >'1 2 3' : seconds
+
+ $* <'print $first(0 a@1 b@2 c@ 4, true)' >'0 a b c 4' : firsts-all
+ $* <'print $second(z a@1 b@2 @3 d, true)' >'z 1 2 3 d' : seconds-all
+
+ $* <'print $first([name_pair] a@1)' >'a' : first-typed
+ $* <'print $second([name_pair] a@1)' >'1' : second-typed
}
: identity
diff --git a/tests/function/filesystem/testscript b/tests/function/filesystem/testscript
index cf93b8b..c7c08f1 100644
--- a/tests/function/filesystem/testscript
+++ b/tests/function/filesystem/testscript
@@ -73,3 +73,51 @@
EOE
}
}
+
+: file_exists
+:
+{
+ : file
+ :
+ touch f;
+ $* <'print $file_exists(f)' >'true'
+
+ : symlink
+ :
+ touch f && ln -s f s;
+ $* <'print $file_exists([path] s)' >'true'
+
+ : directory
+ :
+ mkdir d;
+ $* <'print $file_exists([dir_path] d)' >'false'
+
+ : testscript
+ :
+ touch f;
+ echo $file_exists(f) >'true'
+}
+
+: directory_exists
+:
+{
+ : directory
+ :
+ mkdir d;
+ $* <'print $directory_exists(d)' >'true'
+
+ : symlink
+ :
+ mkdir d && ln -s d s;
+ $* <'print $directory_exists([dir_path] d)' >'true'
+
+ : file
+ :
+ touch f;
+ $* <'print $directory_exists([path] f)' >'false'
+
+ : testscript
+ :
+ mkdir d;
+ echo $directory_exists(d) >'true'
+}
diff --git a/tests/function/json/buildfile b/tests/function/json/buildfile
new file mode 100644
index 0000000..45c60d2
--- /dev/null
+++ b/tests/function/json/buildfile
@@ -0,0 +1,4 @@
+# file : tests/function/json/buildfile
+# license : MIT; see accompanying LICENSE file
+
+./: testscript $b
diff --git a/tests/function/json/testscript b/tests/function/json/testscript
new file mode 100644
index 0000000..54e524f
--- /dev/null
+++ b/tests/function/json/testscript
@@ -0,0 +1,257 @@
+# file : tests/function/json/testscript
+# license : MIT; see accompanying LICENSE file
+
+# See also tests in type/json/.
+
+.include ../../common.testscript
+
+: type
+:
+$* <<EOI >>EOO
+print $value_type([json] )
+print $value_type([json] null)
+print $value_type([json] true)
+print $value_type([json] 123)
+print $value_type([json] -123)
+print $value_type([json] 123, true)
+print $value_type([json] -123, true)
+print $value_type([json] 1 2 3)
+print $value_type([json] one@1 two@2 three@3)
+
+j = [json] one@1 two@2 three@3
+i = [uint64] 1
+m = ($j[$i])
+print $value_type($j[$i])
+print $value_type($m)
+EOI
+null
+null
+boolean
+number
+number
+unsigned number
+signed number
+array
+object
+object
+object
+EOO
+
+: value-size
+:
+$* <<EOI >>EOO
+print $value_size([json] null)
+print $value_size([json] true)
+print $value_size([json] 123)
+print $value_size([json] abc)
+print $size([string] ([json] abc)) # @@ Should be 3 (quoted, type hint).
+print $value_size([json] 1 2 3)
+print $value_size([json] one@1 two@2 three@3)
+
+print $array_size([json] 1 2 3)
+print $array_size([json] null)
+EOI
+0
+1
+1
+1
+5
+3
+3
+3
+0
+EOO
+
+: member
+:
+$* <<EOI >>EOO
+j = [json] one@1 two@2 three@3
+i = [uint64] 1
+m = ($j[$i])
+print $member_name($j[$i]) $member_value($j[$i])
+print $member_name($m) $member_value($m)
+for m: $j
+ print $member_name($m) $member_value($m)
+EOI
+two 2
+two 2
+one 1
+two 2
+three 3
+EOO
+
+: names
+:
+$* <<EOI >>EOO
+j = [json] one@1 two@2 three@3
+for n: $object_names($j)
+ print $n ($j[$n])
+
+print $object_names([json] null)
+EOI
+one 1
+two 2
+three 3
+
+EOO
+
+: find
+:
+$* <<EOI >>EOO
+j = [json] 1 ([json] one@1 two@2) 2 true 3 null 4 abc -5 null ([json] 1 2 3)
+print $array_find_index($j, null)
+print $array_find_index($j, true)
+print $array_find_index($j, 3)
+print $array_find_index($j, 0x4)
+print $array_find_index($j, -5)
+print $array_find_index($j, abc)
+print $array_find_index($j, [json] 1 2 3)
+print $array_find_index($j, [json] two@2 one@1)
+print $array_find_index($j, [json] 1 2)
+print $array_find_index($j, [json] one@1)
+print $array_find_index($j, [json] one@1 two@2 three@3)
+print $array_find_index($j, [json] one@1 TWO@3)
+print $array_find_index($j, [json] one@1 two@3)
+print $array_find_index([json] null, 1)
+EOI
+5
+3
+4
+6
+8
+7
+10
+1
+11
+11
+11
+11
+11
+0
+EOO
+
+: parse
+:
+{
+ : basics
+ :
+ $* <<EOI >>EOO
+ print $json.parse('[123, "abc", {"one":1, "two":2}]')
+ EOI
+ [123,"abc",{"one":1,"two":2}]
+ EOO
+
+ : diagnostics-invalid-input
+ :
+ $* <<EOI 2>>EOE != 0
+ print $json.parse('{"one":, "two":2}]')
+ EOI
+ error: invalid json input: unexpected byte ',' in value
+ info: line 1, column 8, byte offset 8
+ <stdin>:1:8: info: while calling json.parse(<untyped>)
+ EOE
+
+ : diagnostics-duplicate-input
+ :
+ $* <<EOI 2>>EOE != 0
+ print $json.parse('{"one":1, "one":2}]')
+ EOI
+ error: invalid json input: duplicate object member 'one'
+ info: line 1, column 11, byte offset 15
+ <stdin>:1:8: info: while calling json.parse(<untyped>)
+ EOE
+}
+
+: serialize
+:
+{
+ : basics
+ :
+ $* <<EOI >>EOO
+ j = [json] 123 abc ([json] one@1 two@2)
+ print $json.serialize($j)
+ print $json.serialize($j, 0)
+ EOI
+ [
+ 123,
+ "abc",
+ {
+ "one": 1,
+ "two": 2
+ }
+ ]
+ [123,"abc",{"one":1,"two":2}]
+ EOO
+
+ : diagnostics
+ :
+ if false
+ {
+ # This is not easy to trigger normally so we have a normally-disabled
+ # special hack in the $json.serialize() implementation to trigger this.
+ #
+ $* <<EOI 2>>EOE != 0
+ print $json.serialize([json] deadbeef)
+ EOI
+ error: invalid json value: invalid UTF-8 text
+ info: while serializing string value
+ info: offending byte offset 4
+ <stdin>:1:8: info: while calling json.serialize(json)
+ EOE
+ }
+
+}
+
+: load
+:
+{
+ : basics
+ :
+ cat <<EOI >=input.json;
+ {
+ "str":"abc",
+ "num":123,
+ "arr":[1, 2, 3],
+ "obj":{"one":1, "two":2, "three":3}
+ }
+ EOI
+ $* <<EOI >>EOO
+ j = $json.load(input.json)
+ for m: $j
+ print $member_name($m) $member_value($m)
+ EOI
+ str abc
+ num 123
+ arr [1,2,3]
+ obj {"one":1,"two":2,"three":3}
+ EOO
+
+ : diagnostics
+ :
+ cat <<EOI >=input.json;
+ {
+ "str":"abc",
+ "num":,
+ "arr":[1, 2, 3],
+ "obj":{"one":1, "two":2, "three":3}
+ }
+ EOI
+ $* <<EOI 2>>EOE != 0
+ j = $json.load(input.json)
+ EOI
+ input.json:3:9: error: invalid json input: unexpected byte ',' in value
+ info: byte offset 26
+ <stdin>:1:6: info: while calling json.load(<untyped>)
+ EOE
+}
+
+: size
+:
+{
+ $* <'print $size([json_set] a b b)' >'2' : json-set
+ $* <'print $size([json_map] a@1 b@2 b@3)' >'2' : json-map
+}
+
+: keys
+:
+$* <'print $keys([json_map] 2@([json] a@1 b@2 c@3) 1@([json] 1 2 3))' >'[1,2]'
diff --git a/tests/function/path/testscript b/tests/function/path/testscript
index 1ed89ca..6321b3d 100644
--- a/tests/function/path/testscript
+++ b/tests/function/path/testscript
@@ -80,36 +80,35 @@ s = ($posix ? '/' : '\')
}
}
-: canonicalize
+: absolute
:
{
- $* <'print $canonicalize([path] a/b)' >"a$(s)b" : path
- $* <'print $canonicalize([paths] a/b a/c)' >"a$(s)b a$(s)c" : paths
- $* <'print $canonicalize([dir_path] a/b)' >"a$(s)b$s" : dir-path
- $* <'print $canonicalize([dir_paths] a/b a/c/)' >"a$(s)b$s a$(s)c$s" : dir-paths
- $* <'print $path.canonicalize(a/b)' >"a$(s)b" : untyped
- $* <'print $path.canonicalize(a/b/ a/c)' >"a$(s)b$s a$(s)c" : mixed
+ $* <'print $absolute($src_root)' >"true" : true
+ $* <'print $path.absolute(a/b)' >"false" : false
}
-: normalize
+: simple
:
{
- $* <'print $normalize([path] a/../b)' >"b" : path
- $* <'print $normalize([paths] a/../b a/../c)' >"b c" : paths
- $* <'print $normalize([dir_path] a/../b)' >"b$s" : dir-path
- $* <'print $normalize([dir_paths] a/../b a/../c/)' >"b$s c$s" : dir-paths
- $* <'print $path.normalize(a/../b)' >"b" : untyped
- $* <'print $path.normalize(a/../b/ a/../c)' >"b$s c" : mixed
+ $* <'print $simple([path] a)' >"true" : true
+ $* <'print $path.simple(a/b)' >"false" : false
}
-: actualize
+: sub_path
:
-if! $posix
{
- mkdir Foo;
- $* <'print $path.actualize($out_base/foo)' >~'/.+\\Foo/'
+ $* <'print $sub_path($src_base, $src_root)' >"true" : true-absolute
+ $* <'print $path.sub_path(a/b/c, a/b)' >"true" : true-relative
+ $* <'print $path.sub_path(a/b/c, a/d)' >"false" : false
}
+: super_path
+:
+{
+ $* <'print $super_path($src_base, true-absolute)' >"true" : true-absolute
+ $* <'print $path.super_path(a/b/c, b/c)' >"true" : true-relative
+ $* <'print $path.super_path(a/b/c, c/a)' >"false" : false
+}
: directory
:
@@ -205,6 +204,53 @@ if! $posix
EOO
}
+: complete
+:
+{
+ $* <'print $complete([path] a)' >"$~$(s)a" : path
+ $* <'print $complete([dir_path] a)' >"$~$(s)a$(s)" : dir-path
+ $* <'print $path.complete(a)' >"$~$(s)a" : untyped
+
+ echo $path.complete(a) > "$~$(s)a" : testscript
+}
+
+: canonicalize
+:
+{
+ $* <'print $canonicalize([path] a/b)' >"a$(s)b" : path
+ $* <'print $canonicalize([paths] a/b a/c)' >"a$(s)b a$(s)c" : paths
+ $* <'print $canonicalize([dir_path] a/b)' >"a$(s)b$s" : dir-path
+ $* <'print $canonicalize([dir_paths] a/b a/c/)' >"a$(s)b$s a$(s)c$s" : dir-paths
+ $* <'print $path.canonicalize(a/b)' >"a$(s)b" : untyped
+ $* <'print $path.canonicalize(a/b/ a/c)' >"a$(s)b$s a$(s)c" : mixed
+}
+
+: normalize
+:
+{
+ $* <'print $normalize([path] a/../b)' >"b" : path
+ $* <'print $normalize([paths] a/../b a/../c)' >"b c" : paths
+ $* <'print $normalize([dir_path] a/../b)' >"b$s" : dir-path
+ $* <'print $normalize([dir_paths] a/../b a/../c/)' >"b$s c$s" : dir-paths
+ $* <'print $path.normalize(a/../b)' >"b" : untyped
+ $* <'print $path.normalize(a/../b/ a/../c)' >"b$s c" : mixed
+}
+
+: try_normalize
+:
+{
+ $* <'print $try_normalize([path] a/../b)' >"b" : valid
+ $* <'print $path.try_normalize($root_directory($src_root)/..)' >"[null]" : invalid
+}
+
+: actualize
+:
+if! $posix
+{
+ mkdir Foo;
+ $* <'print $path.actualize($out_base/foo)' >~'/.+\\Foo/'
+}
+
: sort
:
{
diff --git a/tests/function/string/testscript b/tests/function/string/testscript
index 364ce42..8eb5760 100644
--- a/tests/function/string/testscript
+++ b/tests/function/string/testscript
@@ -25,6 +25,113 @@
}
}
+: contains
+:
+{
+ : basics
+ :
+ {
+ $* <'print $string.contains( abcd, bc)' >'true' : true
+ $* <'print $string.contains( abcd, ac)' >'false' : false
+ $* <'print $contains([string] abcd, cd)' >'true' : typed
+ }
+
+ : icase
+ :
+ {
+ $* <'print $string.contains(aBcD, bC, icase)' >'true' : true
+ }
+
+ : once
+ :
+ {
+ $* <'print $string.contains(abcdabcd, da, once)' >'true' : true
+ $* <'print $string.contains(abcdabcd, bc, once)' >'false' : false
+ }
+}
+
+: starts_with
+:
+{
+ : basics
+ :
+ {
+ $* <'print $string.starts_with( abcd, ab)' >'true' : true
+ $* <'print $string.starts_with( abcd, bc)' >'false' : false
+ $* <'print $starts_with([string] abcd, abcd)' >'true' : typed
+ }
+
+ : icase
+ :
+ {
+ $* <'print $string.starts_with(aBcD, Ab, icase)' >'true' : true
+ }
+}
+
+: ends_with
+:
+{
+ : basics
+ :
+ {
+ $* <'print $string.ends_with( abcd, cd)' >'true' : true
+ $* <'print $string.ends_with( abcd, bc)' >'false' : false
+ $* <'print $ends_with([string] abcd, abcd)' >'true' : typed
+ }
+
+ : icase
+ :
+ {
+ $* <'print $string.ends_with(aBcD, Cd, icase)' >'true' : true
+ }
+}
+
+: replace
+:
+{
+ : basics
+ :
+ {
+ $* <'print $string.replace( abcb, b, BB)' >'aBBcBB' : expand
+ $* <'print $string.replace( aabbccbb, bb, B)' >'aaBccB' : shrink
+ $* <'print $replace([string] abc, b, B)' >'aBc' : typed
+ $* <'print $replace([string] "", b, B)' >'' : empty
+ $* <'print $replace([string] bbb, b, "")' >'' : to-empty
+ $* <'print $replace([string] bb, b, Bb)' >'BbBb' : no-recursion
+ }
+
+ : icase
+ :
+ {
+ $* <'print $string.replace(abcB, b, X, icase)' >'aXcX'
+ }
+
+ : first
+ :
+ {
+ $* <'print $string.replace(babc, b, B, first_only)' >'Babc' : first
+ $* <'print $string.replace(abcb, b, B, first_only)' >'aBcb' : middle
+ $* <'print $string.replace(b, b, B, first_only)' >'B' : only
+ }
+
+ : last
+ :
+ {
+ $* <'print $string.replace(babc, b, B, last_only)' >'baBc' : middle
+ $* <'print $string.replace(abcb, b, B, last_only)' >'abcB' : last
+ $* <'print $string.replace(b, b, B, last_only)' >'B' : only
+ }
+
+ : first-and-last
+ :
+ {
+ $* <'print $string.replace(ac, b, B, first_only last_only)' >'ac' : zero
+ $* <'print $string.replace(abc, b, B, first_only last_only)' >'aBc' : one
+ $* <'print $string.replace(abcb, b, B, first_only last_only)' >'abcb' : two
+ $* <'print $string.replace(b, b, B, first_only last_only)' >'B' : only
+ }
+}
+
: trim
:
{
@@ -43,8 +150,11 @@
: size
:
{
- $* <'print $size([string] abc)' >'3' : basics
- $* <'print $size([string] )' >'0' : zero
+ $* <'print $size([string] abc)' >'3' : basics
+ $* <'print $size([string] )' >'0' : zero
+ $* <'print $size([strings] a b c)' >'3' : strings
+ $* <'print $size([string_set] a b b)' >'2' : string-set
+ $* <'print $size([string_map] a@1 b@2 b@3)' >'2' : string-map
}
: find
@@ -62,3 +172,7 @@
$* <'print $find_index([strings] x y z, Y)' >'3' : basics-false
$* <'print $find_index([strings] x y z, Y, icase)' >'1' : icase
}
+
+: keys
+:
+$* <'print $keys([string_map] a@1 b@2 c@3)' >'a b c'
diff --git a/tests/type/json/buildfile b/tests/type/json/buildfile
new file mode 100644
index 0000000..5bc6bf2
--- /dev/null
+++ b/tests/type/json/buildfile
@@ -0,0 +1,4 @@
+# file : tests/type/json/buildfile
+# license : MIT; see accompanying LICENSE file
+
+./: testscript $b
diff --git a/tests/type/json/testscript b/tests/type/json/testscript
new file mode 100644
index 0000000..36287b7
--- /dev/null
+++ b/tests/type/json/testscript
@@ -0,0 +1,504 @@
+# file : tests/type/json/testscript
+# license : MIT; see accompanying LICENSE file
+
+# See also tests in function/json/.
+
+.include ../../common.testscript
+
+: basics
+:
+{
+ : empty-null
+ :
+ $* <<EOI >>EOO
+ print ([json, null] )
+ print ([json] null)
+ print ([json] )
+ print ([json] "")
+ print ([json_array] )
+ print ([json_object] )
+ print ([json] one@null)
+ print ([json] one@) # @@ Would be more consistent if were null (type hints?)
+ print ([json] one@"")
+ EOI
+ [null]
+
+
+ ""
+ []
+ {}
+ {"one":null}
+ {"one":""}
+ {"one":""}
+ EOO
+
+ : reverse
+ :
+ $* <<EOI >>EOO
+ print ([json] null)
+ print ([json] true)
+ print ([json] 123)
+ print ([json] -123)
+ print ([json] 0xdecaf)
+ print ([json] abc) # @@ Ideally we would like this to be reversed unquoted.
+ print ([json] '"abc"') # @@ Ditto.
+ print (([json] abc)[0]) # @@ Workaround.
+ print ([json] dir/{file1 file2})
+ print ([json] ' ["dir/file1", "dir/file2"] ')
+ print ([json] zero@null one@1 two@abc three@([json] x@123 y@-123) four@([json] null true))
+ print ([json] '{"zero":null,"one":1,"two":"abc","three":{"x":123,"y":-123},"four":[null,true]}')
+ EOI
+
+ true
+ 123
+ -123
+ 0xdecaf
+ "abc"
+ "abc"
+ abc
+ ["dir/file1","dir/file2"]
+ ["dir/file1","dir/file2"]
+ {"zero":null,"one":1,"two":"abc","three":{"x":123,"y":-123},"four":[null,true]}
+ {"zero":null,"one":1,"two":"abc","three":{"x":123,"y":-123},"four":[null,true]}
+ EOO
+
+
+ : hex
+ :
+ $* <<EOI >>EOO
+ print ([json] 0xffffFFFF)
+
+ # These should be in the hexadecimal notation once we switch to JSON5.
+ #
+ print ([json] 0x0 0x01 0xff 0xFFFF)
+ print ([json] ff@0xff FFFF@0xFFFF)
+
+ # @@ This should start working once we switch to type hints in subscript.
+ #
+ #j = [json] ff@0xff
+ #print $value_type($j[ff], true)
+ print 'hexadecimal number'
+ EOI
+ 0xffffffff
+ [0,1,255,65535]
+ {"ff":255,"FFFF":65535}
+ hexadecimal number
+ EOO
+
+ : diagnostics-reverse-invalid
+ :
+ $* <<EOI 2>>EOE != 0
+ o = [json] '{"one":1, "two":}'
+ EOI
+ error: invalid json value in variable o: invalid json input: unexpected byte '}' in value
+ <stdin>:1:5: info: variable o value is assigned here
+ EOE
+
+ : diagnostics-duplicate-member
+ :
+ $* <<EOI 2>>EOE != 0
+ o = [json] one@1 one@2
+ EOI
+ error: invalid json value in variable o: duplicate json object member 'one'
+ <stdin>:1:5: info: variable o value is assigned here
+ EOE
+}
+
+: compare
+:
+{
+ : type
+ :
+ $* <<EOI >>EOO
+ print (([json] null) < ([json] true))
+ print (([json] true) < ([json] 0))
+ print (([json] 123) < ([json] '"0"'))
+ print (([json] abc) < ([json] xxx yyy))
+ print (([json] xxx yyy) < ([json] xxx@null yyy@null))
+ EOI
+ true
+ true
+ true
+ true
+ true
+ EOO
+
+ : simple
+ :
+ $* <<EOI >>EOO
+ print (([json] false) == ([json] false))
+ print (([json] false) < ([json] true))
+
+ print (([json] 123) == ([json] 123))
+ print (([json] -123) == ([json] -123))
+ print (([json] 0xff) == ([json] 255))
+ print (([json] 0) == ([json] -0))
+ print (([json] -1) < ([json] 0))
+ print (([json] 123) < ([json] 234))
+ print (([json] -234) < ([json] -123))
+
+ print (([json] abc) == ([json] abc))
+ print (([json] abc) < ([json] abz))
+ print (([json] abc) < ([json] abcd))
+ EOI
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ EOO
+
+ : array
+ :
+ $* <<EOI >>EOO
+ print (([json] 1 2 3) == ([json] 1 2 3))
+ print (([json] 1 2 3) < ([json] 1 2 4))
+ print (([json] 1 2 3) < ([json] 1 2 3 4))
+ EOI
+ true
+ true
+ true
+ EOO
+
+ : object
+ :
+ $* <<EOI >>EOO
+ print (([json] one@1 two@2 three@3) == ([json] three@3 one@1 two@2))
+ print (([json] one@1 two@2 three@3) < ([json] three@3 one@1 two@4))
+ print (([json] one@1 three@3) < ([json] three@3 one@1 two@2))
+ EOI
+ true
+ true
+ true
+ EOO
+}
+
+: append-prepend
+:
+{
+ : array
+ :
+ $* <<EOI >'[0,1,2,3,4,5,6,7,8]'
+ a = [json] 2 3
+ a += 4
+ a += 5 6
+ a += [json] 7 8
+ a =+ [json] 0 1
+ print $a
+ EOI
+
+ : array-type
+ :
+ $* <<EOI >'[1,2,3,4,5]'
+ [json_array] a =
+ a += 1
+ a += 2 3
+ a += [json_array] 4 5 # @@ Should be possible to use json.
+ print $a
+ EOI
+
+ : object
+ :
+ $* <<EOI >'{"zero":0,"one":6,"two":8,"three":3,"four":4,"five":5,"seven":7}'
+ o = [json] one@1 two@2 three@3
+ o += four@4
+ o += five@5 one@6
+ o += [json] seven@7 two@8
+ o =+ [json] zero@0 three@9
+ print $o
+ EOI
+
+ : object-type
+ :
+ $* <<EOI >'{"one":1,"two":2,"three":3,"four":4,"five":5}'
+ [json_object] o =
+ o += one@1
+ o += two@2 three@3
+ o += [json_object] four@4 five@5 # @@ Should be possible to use json.
+ print $o
+ EOI
+
+ : boolean
+ :
+ $* <<EOI >>EOO
+ b = [json] false
+ b += [json] true
+ print $b
+ EOI
+ true
+ EOO
+
+ : number
+ :
+ $* <<EOI >>EOO
+ n = [json] -2
+ print $value_type($n, true) $n
+ n += 1
+ print $value_type($n, true) $n
+ n += 1
+ print $value_type($n, true) $n
+ n += 1
+ print $value_type($n, true) $n
+ n += [json] -1
+ print $value_type($n, true) $n
+ n += [json] -1
+ print $value_type($n, true) $n
+ EOI
+ signed number -2
+ signed number -1
+ unsigned number 0
+ unsigned number 1
+ unsigned number 0
+ signed number -1
+ EOO
+
+ : string
+ :
+ $* <<EOI >>EOO
+ s = [json] yyy
+ s += [json] zzz
+ s =+ [json] xxx
+ print $s
+ EOI
+ "xxxyyyzzz"
+ EOO
+
+ : invalid
+ :
+ $* <<EOI 2>>EOE != 0
+ a = [json] 1 2 3
+ s = [json] str
+ s += $a
+ print $s
+ EOI
+ error: invalid json value in variable s: unable to append array to string
+ <stdin>:3:6: info: variable s value is assigned here
+ EOE
+}
+
+: subscript
+:
+{
+ : null
+ :
+ $* <<EOI >>EOO
+ j = [json] null
+ print ($j[0])
+ print ($j[one])
+ EOI
+ [null]
+ [null]
+ EOO
+
+ : array
+ :
+ $* <<EOI >>EOO
+ j = [json] 1 2 3 null
+ print ($j[1])
+ print ($j[3])
+ print ($j[4])
+ EOI
+ 2
+ [null]
+ [null]
+ EOO
+
+ : object-name
+ :
+ $* <<EOI >>EOO
+ j = [json] one@1 two@2 three@3 four@null
+ print ($j[two])
+ print ($j[four])
+ print ($j[five])
+ EOI
+ 2
+ [null]
+ [null]
+ EOO
+
+ : object-index
+ :
+ $* <<EOI >>EOO
+ j = [json] one@1 two@2 three@3
+ print ($j[([uint64] 1)])
+ EOI
+ {"two":2}
+ EOO
+
+ : nested
+ :
+ $* <<EOI >>EOO
+ o = [json] one@([json] 1 2 ([json] a@3 b@4) null) two@([json] x@x y@([json] 5 6))
+ print ($o[one][1])
+ print ($o[one][2][b])
+ print ($o[two][y][1])
+ print ($o[two][bogus][junk])
+ print ($o[two][bogus][junk][garbage])
+ print ($o[one][3][junk]) # JSON null
+ print ($o[one][3][junk][garbage])
+
+ a = [json] ([json] one@1 two@([json] 2 3)) ([json] 4 5) null
+ print ($a[0][one])
+ print ($a[0][two][1])
+ print ($a[1][1])
+ print ($a[1][123][junk])
+ print ($a[1][123][junk][garbage])
+ print ($a[2][junk]) # JSON null
+ print ($a[2][junk][garbage])
+ EOI
+ 2
+ 4
+ 6
+ [null]
+ [null]
+ [null]
+ [null]
+ 1
+ 3
+ 5
+ [null]
+ [null]
+ [null]
+ [null]
+ EOO
+
+ : reverse
+ :
+ $* <<EOI >>EOO
+ print (([json] one@null)[one])
+ print (([json] one@true)[one])
+ print (([json] one@123)[one])
+ print (([json] one@-123)[one])
+ print (([json] one@0xdecaf)[one])
+ print (([json] one@abc)[one])
+ EOI
+ [null]
+ true
+ 123
+ -123
+ 912559
+ abc
+ EOO
+
+ : diagnostics-not-object
+ :
+ $* <<EOI 2>>EOE != 0
+ j = [json] 1 2 3
+ print ($j[one])
+ EOI
+ <stdin>:2:11: error: invalid json value subscript: invalid uint64 value 'one'
+ info: json value type is array
+ <stdin>:2:9: info: use the '\[' escape sequence if this is a wildcard pattern
+ EOE
+}
+
+: iteration
+:
+{
+ : null
+ :
+ $* <<EOI
+ for v: ([json] null)
+ print $v
+ EOI
+
+ : simple
+ :
+ $* <<EOI >>EOO
+ for v: ([json] 123)
+ print $v
+ EOI
+ 123
+ EOO
+
+ : array
+ :
+ $* <<EOI >>EOO
+ for v: ([json] 1 2 3)
+ print $v
+ EOI
+ 1
+ 2
+ 3
+ EOO
+
+ : object
+ :
+ $* <<EOI >>EOO
+ for v: ([json] one@1 two@2 three@3)
+ print $v
+ EOI
+ {"one":1}
+ {"two":2}
+ {"three":3}
+ EOO
+
+ : reverse
+ :
+ $* <<EOI >>EOO
+ for v: ([json] null true 123 -123 0xdecaf abc)
+ print $v
+ EOI
+ [null]
+ true
+ 123
+ -123
+ 912559
+ abc
+ EOO
+}
+
+: json-map
+:
+{
+ : basics
+ :
+ $* <<EOI >>EOO
+ m = [json_map] 2@([json] a@1 b@2) 1@([json] 1 2) 0@([json] null) -1@null
+ print $m
+ for p: $m
+ print $first($p) $second($p)
+ print ($m[1])
+ print $type($m[1])
+ print ($m[2][b])
+ print ($m[0])
+ print ($m[-1])
+ EOI
+ -1@null 0@null 1@[1,2] 2@{"a":1,"b":2}
+ -1 null
+ 0 null
+ 1 [1,2]
+ 2 {"a":1,"b":2}
+ [1,2]
+ json
+ 2
+
+
+ EOO
+}
+
+: json-set
+:
+{
+ : basics
+ :
+ $* <<EOI >>EOO
+ s = [json_set] ([json] x@1 y@2) ([json] a@1 b@2)
+ print $s
+ for v: $s
+ print $type($v) $v
+ print ($s[([json] y@2 x@1)])
+ EOI
+ {"a":1,"b":2} {"x":1,"y":2}
+ json {"a":1,"b":2}
+ json {"x":1,"y":2}
+ true
+ EOO
+}
diff --git a/tests/type/map/buildfile b/tests/type/map/buildfile
new file mode 100644
index 0000000..7f2cdcf
--- /dev/null
+++ b/tests/type/map/buildfile
@@ -0,0 +1,4 @@
+# file : tests/type/map/buildfile
+# license : MIT; see accompanying LICENSE file
+
+./: testscript $b
diff --git a/tests/type/map/testscript b/tests/type/map/testscript
new file mode 100644
index 0000000..29f5ed4
--- /dev/null
+++ b/tests/type/map/testscript
@@ -0,0 +1,70 @@
+# file : tests/type/map/testscript
+# license : MIT; see accompanying LICENSE file
+
+# See also tests in function/*/ (size(), keys()), type/json/ (json_map).
+
+.include ../../common.testscript
+
+: basics
+:
+$* <<EOI >>EOO
+m = [string_map] a@0 b@2 a@1
+print $m
+m += c@3 b@0
+print $m
+m =+ d@4 b@1
+print $m
+EOI
+a@1 b@2
+a@1 b@0 c@3
+a@1 b@0 c@3 d@4
+EOO
+
+: type
+:
+$* <<EOI >>EOO
+m = [string_map]
+print $type($m)
+EOI
+string_map
+EOO
+
+: subscript
+:
+$* <<EOI >>EOO
+m = [string_map] a@1 b@2 c@3
+print ($m[b])
+print $type($m[b])
+print ($m[z])
+EOI
+2
+string
+[null]
+EOO
+
+: iteration
+:
+$* <<EOI >>EOO
+for p: [string_map] a@1 b@2 c@3
+ print $first($p) $second($p)
+
+for p: [string_map, null]
+ fail bad
+EOI
+a 1
+b 2
+c 3
+EOO
+
+: iteration-index
+:
+$* <<EOI >>EOO
+m = [string_map] a@1 b@2 c@3
+k = $keys($m)
+for i: $integer_sequence(0, $size($k))
+ print $i ($k[$i]) ($m[($k[$i])]) # @@ TMP: nested subscript
+EOI
+0 a 1
+1 b 2
+2 c 3
+EOO
diff --git a/tests/type/set/buildfile b/tests/type/set/buildfile
new file mode 100644
index 0000000..55b37bb
--- /dev/null
+++ b/tests/type/set/buildfile
@@ -0,0 +1,4 @@
+# file : tests/type/set/buildfile
+# license : MIT; see accompanying LICENSE file
+
+./: testscript $b
diff --git a/tests/type/set/testscript b/tests/type/set/testscript
new file mode 100644
index 0000000..aca4c2d
--- /dev/null
+++ b/tests/type/set/testscript
@@ -0,0 +1,55 @@
+# file : tests/type/set/testscript
+# license : MIT; see accompanying LICENSE file
+
+# See also tests in function/*/ (size()), type/json/ (json_set).
+
+.include ../../common.testscript
+
+: basics
+:
+$* <<EOI >>EOO
+s = [string_set] a b a
+print $s
+s += c b
+print $s
+s =+ d b
+print $s
+EOI
+a b
+a b c
+a b c d
+EOO
+
+: type
+:
+$* <<EOI >>EOO
+s = [string_set]
+print $type($s)
+EOI
+string_set
+EOO
+
+: subscript
+:
+$* <<EOI >>EOO
+s = [string_set] a b c
+print ($s[b])
+print ($s[z])
+EOI
+true
+false
+EOO
+
+: iteration
+:
+$* <<EOI >>EOO
+for s: [string_set] a b c
+ print $type($s) $s
+
+for s: [string_set, null]
+ fail bad
+EOI
+string a
+string b
+string c
+EOO
diff --git a/tests/type/vector/buildfile b/tests/type/vector/buildfile
new file mode 100644
index 0000000..5b2aa0e
--- /dev/null
+++ b/tests/type/vector/buildfile
@@ -0,0 +1,4 @@
+# file : tests/type/vector/buildfile
+# license : MIT; see accompanying LICENSE file
+
+./: testscript $b
diff --git a/tests/type/vector/testscript b/tests/type/vector/testscript
new file mode 100644
index 0000000..9b3aaba
--- /dev/null
+++ b/tests/type/vector/testscript
@@ -0,0 +1,57 @@
+# file : tests/type/vector/testscript
+# license : MIT; see accompanying LICENSE file
+
+# See also tests in function/*/ (size(), find(), etc).
+
+.include ../../common.testscript
+
+: basics
+:
+$* <<EOI >>EOO
+v = [strings] b c
+print $v
+v += d
+print $v
+v =+ a
+print $v
+EOI
+b c
+b c d
+a b c d
+EOO
+
+: type
+:
+$* <<EOI >>EOO
+v = [strings]
+print $type($v)
+EOI
+strings
+EOO
+
+: subscript
+:
+$* <<EOI >>EOO
+v = [strings] a b c
+print ($v[1])
+print $type($v[1])
+print ($v[3])
+EOI
+b
+string
+[null]
+EOO
+
+: iteration
+:
+$* <<EOI >>EOO
+for s: [strings] a b c
+ print $type($s) $s
+
+for s: [strings, null]
+ fail bad
+EOI
+string a
+string b
+string c
+EOO