summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/tests
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2009-05-16 00:19:13 +0000
committerKarl Berry <karl@freefriends.org>2009-05-16 00:19:13 +0000
commitbab45528d65eaafe68a705dbb2a57075c7b7cbd8 (patch)
tree10b4ae2b5195c8dede153ab89359ec00f55f325f /Build/source/utils/asymptote/tests
parent8643d90372e9c31e0f461c15c596b60a545bd7d3 (diff)
asymptote 1.72 sources (not integrated into build yet)
git-svn-id: svn://tug.org/texlive/trunk@13110 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/utils/asymptote/tests')
-rw-r--r--Build/source/utils/asymptote/tests/Makefile14
-rw-r--r--Build/source/utils/asymptote/tests/TestLib.asy15
-rw-r--r--Build/source/utils/asymptote/tests/arith/integer.asy15
-rw-r--r--Build/source/utils/asymptote/tests/arith/pair.asy20
-rw-r--r--Build/source/utils/asymptote/tests/arith/real.asy18
-rw-r--r--Build/source/utils/asymptote/tests/arith/roots.asy96
-rw-r--r--Build/source/utils/asymptote/tests/arith/transform.asy25
-rw-r--r--Build/source/utils/asymptote/tests/arith/triple.asy11
-rw-r--r--Build/source/utils/asymptote/tests/array/array.asy49
-rw-r--r--Build/source/utils/asymptote/tests/array/delete.asy41
-rw-r--r--Build/source/utils/asymptote/tests/array/determinant.asy18
-rw-r--r--Build/source/utils/asymptote/tests/array/slice.asy232
-rw-r--r--Build/source/utils/asymptote/tests/array/solve.asy35
-rw-r--r--Build/source/utils/asymptote/tests/array/transpose.asy55
-rw-r--r--Build/source/utils/asymptote/tests/bench/6000circles.asy17
-rw-r--r--Build/source/utils/asymptote/tests/frames/loop.asy29
-rw-r--r--Build/source/utils/asymptote/tests/frames/stat.asy14
-rw-r--r--Build/source/utils/asymptote/tests/frames/stat2.asy17
-rw-r--r--Build/source/utils/asymptote/tests/gc/array.asy5
-rw-r--r--Build/source/utils/asymptote/tests/gc/file.asy7
-rw-r--r--Build/source/utils/asymptote/tests/gc/funcall.asy6
-rw-r--r--Build/source/utils/asymptote/tests/gc/guide.asy5
-rw-r--r--Build/source/utils/asymptote/tests/gc/path.asy8
-rw-r--r--Build/source/utils/asymptote/tests/gc/pen.asy4
-rw-r--r--Build/source/utils/asymptote/tests/gc/string.asy6
-rw-r--r--Build/source/utils/asymptote/tests/gc/struct.asy7
-rw-r--r--Build/source/utils/asymptote/tests/gc/transform.asy6
-rw-r--r--Build/source/utils/asymptote/tests/imp/unravel.asy95
-rw-r--r--Build/source/utils/asymptote/tests/output/Makefile41
-rw-r--r--Build/source/utils/asymptote/tests/output/circle.asy1
-rw-r--r--Build/source/utils/asymptote/tests/output/line.asy1
-rw-r--r--Build/source/utils/asymptote/tests/string/erase.asy9
-rw-r--r--Build/source/utils/asymptote/tests/string/find.asy8
-rw-r--r--Build/source/utils/asymptote/tests/string/insert.asy5
-rw-r--r--Build/source/utils/asymptote/tests/string/length.asy6
-rw-r--r--Build/source/utils/asymptote/tests/string/rfind.asy8
-rw-r--r--Build/source/utils/asymptote/tests/string/substr.asy6
-rw-r--r--Build/source/utils/asymptote/tests/types/cast.asy13
-rw-r--r--Build/source/utils/asymptote/tests/types/constructor.asy271
-rw-r--r--Build/source/utils/asymptote/tests/types/ecast.asy11
-rw-r--r--Build/source/utils/asymptote/tests/types/guide.asy144
-rw-r--r--Build/source/utils/asymptote/tests/types/init.asy17
-rw-r--r--Build/source/utils/asymptote/tests/types/resolve.asy12
-rw-r--r--Build/source/utils/asymptote/tests/types/shadow.asy17
-rw-r--r--Build/source/utils/asymptote/tests/types/spec.asy61
45 files changed, 1501 insertions, 0 deletions
diff --git a/Build/source/utils/asymptote/tests/Makefile b/Build/source/utils/asymptote/tests/Makefile
new file mode 100644
index 00000000000..d05ae0a2169
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/Makefile
@@ -0,0 +1,14 @@
+TESTDIRS = string arith frames types imp array
+
+test: $(TESTDIRS)
+
+$(TESTDIRS)::
+ @echo
+ ../asy -dir ../base $@/*.asy
+
+clean: FORCE
+ rm -f *.eps
+
+distclean: FORCE clean
+
+FORCE:
diff --git a/Build/source/utils/asymptote/tests/TestLib.asy b/Build/source/utils/asymptote/tests/TestLib.asy
new file mode 100644
index 00000000000..a4a4b239927
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/TestLib.asy
@@ -0,0 +1,15 @@
+bool close(pair a, pair b)
+{
+ real norm=(b == 0) ? 1 : max(abs(a),abs(b));
+ return abs(a-b) <= 100*realEpsilon*norm;
+}
+
+void StartTest(string desc)
+{
+ write("Testing " + desc + "...",flush);
+}
+
+void EndTest()
+{
+ write("PASSED.");
+}
diff --git a/Build/source/utils/asymptote/tests/arith/integer.asy b/Build/source/utils/asymptote/tests/arith/integer.asy
new file mode 100644
index 00000000000..a402ca58955
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/arith/integer.asy
@@ -0,0 +1,15 @@
+// Integer arithmetic.
+import TestLib;
+StartTest("integer addition");
+assert(1+1==2);
+EndTest();
+StartTest("integer subtraction");
+assert(2-1==1);
+EndTest();
+StartTest("integer multiplication");
+assert(2*2==4);
+EndTest();
+StartTest("integer division");
+assert(4/2==2);
+EndTest();
+
diff --git a/Build/source/utils/asymptote/tests/arith/pair.asy b/Build/source/utils/asymptote/tests/arith/pair.asy
new file mode 100644
index 00000000000..c815f28b2fa
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/arith/pair.asy
@@ -0,0 +1,20 @@
+import TestLib;
+
+StartTest("complex addition");
+assert((1,0)+(0,1)==(1,1));
+EndTest();
+StartTest("complex subtraction");
+assert((1,0)-(0,1)==(1,-1));
+EndTest();
+StartTest("complex multiplication");
+assert((1,2)*(2,1)==(0,5));
+EndTest();
+StartTest("complex division");
+assert((0,5)/(2,1)==(1,2));
+EndTest();
+StartTest("length(pair)");
+assert(length((0.0,1.0)) == 1.0);
+EndTest();
+StartTest("conj()");
+assert(conj((0.0,1.0))==(0.0, -1.0));
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/arith/real.asy b/Build/source/utils/asymptote/tests/arith/real.asy
new file mode 100644
index 00000000000..1628258cf83
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/arith/real.asy
@@ -0,0 +1,18 @@
+// Real arithmetic.
+
+import TestLib;
+StartTest("real error");
+assert((1.0-1.0) < realEpsilon);
+EndTest();
+StartTest("real addition");
+assert((1.0+1.0) == (2.0));
+EndTest();
+StartTest("real subtraction");
+assert((2.0-1.0) == (1.0));
+EndTest();
+StartTest("real multiplication");
+assert((2.0*2.0) == (4.0));
+EndTest();
+StartTest("real division");
+assert((4.0/2.0) == (2.0));
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/arith/roots.asy b/Build/source/utils/asymptote/tests/arith/roots.asy
new file mode 100644
index 00000000000..d3e5d55f367
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/arith/roots.asy
@@ -0,0 +1,96 @@
+// Roots.
+
+import TestLib;
+real x;
+real[] r;
+
+StartTest("quadratic roots");
+
+r=quadraticroots(1,0,-8);
+assert(r.length == 2);
+r=sort(r);
+x=2sqrt(2);
+assert(close(r[0],-x));
+assert(close(r[1],x));
+
+r=quadraticroots(1,2,1);
+assert(r.length == 2);
+assert(close(r[0],-1));
+assert(close(r[1],-1));
+
+r=quadraticroots(1,0,8);
+assert(r.length == 0);
+
+r=quadraticroots(0,2,3);
+assert(r.length == 1);
+assert(close(r[0],-3/2));
+
+EndTest();
+
+StartTest("cubic roots");
+
+r=cubicroots(1,0,0,-8);
+assert(r.length == 1);
+assert(close(r[0],2));
+
+real[] r=cubicroots(1,3,3,1);
+assert(r.length == 3);
+assert(close(r[0],-1));
+assert(close(r[1],-1));
+assert(close(r[2],-1));
+
+real[] r=cubicroots(1,-3,3,-1);
+assert(r.length == 3);
+assert(close(r[0],1));
+assert(close(r[1],1));
+assert(close(r[2],1));
+
+r=cubicroots(1,0,0,0);
+assert(r.length == 3);
+assert(r[0] == 0);
+assert(r[1] == 0);
+assert(r[2] == 0);
+
+r=cubicroots(1,0,-15,-4);
+assert(r.length == 3);
+r=sort(r);
+assert(close(r[0],-2-sqrt(3)));
+assert(close(r[1],-2+sqrt(3)));
+assert(close(r[2],4));
+
+r=cubicroots(1,0,-15,4);
+assert(r.length == 3);
+r=sort(r);
+assert(close(r[0],-4));
+assert(close(r[1],2-sqrt(3)));
+assert(close(r[2],2+sqrt(3)));
+
+r=cubicroots(1,0,-15,0);
+assert(r.length == 3);
+r=sort(r);
+x=sqrt(15);
+assert(close(r[0],-x));
+assert(r[1] == 0);
+assert(close(r[2],x));
+
+r=cubicroots(1,1,1,0);
+assert(r.length == 1);
+assert(r[0] == 0);
+
+r=cubicroots(1,0,20,-4);
+assert(r.length == 1);
+x=cbrt(54+6sqrt(6081));
+assert(close(r[0],x/3-20/x));
+
+EndTest();
+
+StartTest("newton");
+
+real f(real x) {return cos(x);}
+real dfdx(real x) {return -sin(x);}
+
+assert(close(newton(f,dfdx,1),pi/2));
+assert(newton(f,dfdx,0) == realMax);
+assert(newton(f,dfdx,0,2) == pi/2);
+
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/arith/transform.asy b/Build/source/utils/asymptote/tests/arith/transform.asy
new file mode 100644
index 00000000000..e4e44e387b8
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/arith/transform.asy
@@ -0,0 +1,25 @@
+import TestLib;
+pair x = (1, 2);
+StartTest("identity transform");
+assert(identity()*x == x);
+EndTest();
+StartTest("shift transform");
+assert(shift((1,1))*x == (2, 3));
+assert(shift(1,1)*x == (2, 3));
+EndTest();
+StartTest("scaling transforms");
+assert(xscale(2)*x == (2, 2));
+assert(yscale(2)*x == (1, 4));
+assert(scale(2)*x == (2, 4));
+EndTest();
+StartTest("slant transform");
+assert(slant(1)*x == (3, 2));
+EndTest();
+StartTest("rotation transform");
+assert(length((rotate(90)*x) - (-2,1)) <= realEpsilon);
+assert(rotate(90, x)*x == x);
+EndTest();
+StartTest("reflect transform");
+assert(reflect((-1, -1), (1, 1))*x == (2, 1));
+EndTest();
+
diff --git a/Build/source/utils/asymptote/tests/arith/triple.asy b/Build/source/utils/asymptote/tests/arith/triple.asy
new file mode 100644
index 00000000000..135801b6330
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/arith/triple.asy
@@ -0,0 +1,11 @@
+import TestLib;
+triple t = (1,0,0);
+StartTest("polar()");
+assert(polar(t) == (pi / 2.0) );
+EndTest();
+StartTest("azimuth()");
+assert(azimuth(t) < realEpsilon);
+EndTest();
+StartTest("unit()");
+assert(length(t-unit(t)) < realEpsilon);
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/array/array.asy b/Build/source/utils/asymptote/tests/array/array.asy
new file mode 100644
index 00000000000..106856fd80b
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/array/array.asy
@@ -0,0 +1,49 @@
+import TestLib;
+
+StartTest("array");
+
+{
+ int[] x=array(10, 7);
+ assert(x.length == 10);
+ for (int i=0; i<x.length; ++i)
+ assert(x[i] == 7);
+}
+{
+ int[][] y=array(10, array(10, 7));
+ assert(y.length == 10);
+ for (int i=0; i<y.length; ++i) {
+ assert(y[i].length == 10);
+ for (int j=0; j<y[i].length; ++j)
+ assert(y[i][j] == 7);
+ }
+}
+{
+ int[][] y=array(10, array(10, 7));
+ y[4][5] = 9;
+ assert(y.length == 10);
+ for (int i=0; i<y.length; ++i) {
+ assert(y[i].length == 10);
+ for (int j=0; j<y[i].length; ++j)
+ if (i==4 && j==5)
+ assert(y[i][j] == 9);
+ else
+ assert(y[i][j] == 7);
+ }
+}
+{
+ int[][] y=array(10, array(10, 7), depth=0);
+ y[4][5] = 9;
+ assert(y.length == 10);
+ for (int i=0; i<y.length; ++i) {
+ assert(y[i].length == 10);
+ for (int j=0; j<y[i].length; ++j)
+ if (j==5)
+ assert(y[i][j] == 9);
+ else
+ assert(y[i][j] == 7);
+ }
+}
+
+
+
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/array/delete.asy b/Build/source/utils/asymptote/tests/array/delete.asy
new file mode 100644
index 00000000000..0b00e3f0e46
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/array/delete.asy
@@ -0,0 +1,41 @@
+import TestLib;
+import math;
+
+StartTest("delete");
+
+int[] a=sequence(4);
+a.delete(2);
+assert(all(a == new int[] {0,1,3}));
+
+int[] a=sequence(4);
+a.delete(0,2);
+assert(all(a == new int[] {3}));
+
+int[] a=sequence(4);
+a.delete(1,2);
+assert(all(a == new int[] {0,3}));
+
+int[] a=sequence(4);
+a.delete(2,2);
+assert(all(a == new int[] {0,1,3}));
+
+int[] a=sequence(4);
+a.delete(2,3);
+assert(all(a == new int[] {0,1}));
+
+int[] a=sequence(4);
+a.cyclic(true);
+a.delete(2,3);
+assert(all(a == new int[] {0,1}));
+
+int[] a=sequence(4);
+a.cyclic(true);
+a.delete(2,4);
+assert(all(a == new int[] {1}));
+
+int[] a=sequence(4);
+a.cyclic(true);
+a.delete(3,1);
+assert(all(a == new int[] {2}));
+
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/array/determinant.asy b/Build/source/utils/asymptote/tests/array/determinant.asy
new file mode 100644
index 00000000000..e6086d0b04f
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/array/determinant.asy
@@ -0,0 +1,18 @@
+import TestLib;
+import math;
+
+StartTest("determinant");
+assert(determinant(new real[][] {{0}}) == 0);
+assert(determinant(new real[][] {{1}}) == 1);
+assert(determinant(new real[][] {{1,2},{3,4}}) == -2);
+real e=1e-20;
+assert(close(determinant(new real[][] {{1e,2e},{3e,4e}}),-2e-40));
+assert(close(determinant(new real[][] {{1,2,3},{4,5,6},{7,8,9}}),0));
+assert(close(determinant(new real[][] {{1,2},{1,2}}),0));
+assert(close(determinant(new real[][] {{1,2,3,4},
+ {5,6,7,8},{9,10,11,12},{13,14,15,16}}),0));
+assert(close(determinant(new real[][] {{1,2,3,4},
+ {5,0,7,8},{9,10,0,12},{13,14,15,16}}),-2376));
+assert(close(determinant(new real[][]{{1,-2,3,0},{4,-5,6,2},{-7,-8,10,5},
+ {1,50,1,-2}}),-4588));
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/array/slice.asy b/Build/source/utils/asymptote/tests/array/slice.asy
new file mode 100644
index 00000000000..709263504ce
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/array/slice.asy
@@ -0,0 +1,232 @@
+import TestLib;
+
+StartTest("slice");
+
+int[] x={0,1,2,3,4,5,6,7,8,9};
+
+// Non-cyclic cases.
+assert(all(x[:] == x));
+assert(!alias(x[:],x));
+
+assert(all(x[0:4] == new int[] {0,1,2,3} ));
+assert(all(x[2:4] == new int[] {2,3} ));
+
+assert(all(x[5:] == new int[] {5,6,7,8,9} ));
+assert(all(x[:5] == new int[] {0,1,2,3,4} ));
+
+assert(all(x[3:3] == new int[] {} ));
+assert(all(x[3:4] == new int[] {3} ));
+assert(all(x[98:99] == new int[] {} ));
+
+assert(x[:].cyclicflag == false);
+assert(x[2:].cyclicflag == false);
+assert(x[:7].cyclicflag == false);
+assert(x[3:3].cyclicflag == false);
+assert(x[2:9].cyclicflag == false);
+
+// Cyclic cases
+x.cyclic(true);
+
+assert(all(x[:] == new int[] {0,1,2,3,4,5,6,7,8,9} ));
+assert(all(x[0:4] == new int[] {0,1,2,3} ));
+assert(all(x[2:4] == new int[] {2,3} ));
+
+assert(all(x[5:] == new int[] {5,6,7,8,9} ));
+assert(all(x[-5:] == new int[] {5,6,7,8,9,0,1,2,3,4,5,6,7,8,9} ));
+assert(all(x[:5] == new int[] {0,1,2,3,4} ));
+
+assert(all(x[3:3] == new int[] {} ));
+assert(all(x[3:4] == new int[] {3} ));
+
+assert(all(x[-1:1] == new int[] {9,0} ));
+assert(all(x[9:11] == new int[] {9,0} ));
+assert(all(x[9:21] == new int[] {9,0,1,2,3,4,5,6,7,8,9,0} ));
+assert(all(x[-15:15] == new int[] {5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,
+ 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4}));
+assert(all(x[6728:6729] == new int[] {8} ));
+assert(all(x[-6729:-6728] == new int[] {1} ));
+
+assert(x[:].cyclicflag == false);
+assert(x[2:].cyclicflag == false);
+assert(x[:7].cyclicflag == false);
+assert(x[3:3].cyclicflag == false);
+assert(x[2:9].cyclicflag == false);
+assert(x[5:100].cyclicflag == false);
+
+pair[] z={(1,2), (3,4), (5,6)};
+assert(all(z[1:1] == new pair[] {}));
+assert(all(z[:1] == new pair[] {(1,2)}));
+assert(all(z[1:] == new pair[] {(3,4), (5,6)}));
+assert(all(z[:] == z));
+assert(all(z[1:2] == new pair[] {(3,4)}));
+
+// Writing tests.
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ int[] z={56,67,78};
+
+ y[:] = z;
+ assert(all(y == z));
+ assert(!alias(y,z));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ int[] z={56,67,78};
+ z.cyclic(true);
+
+ y[:] = z;
+ assert(all(y == z));
+ assert(!alias(y,z));
+ assert(y.cyclicflag == false);
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+
+ y[2:3] = y[5:6] = new int[] {77};
+ assert(all(y == new int[] {0,1,77,3,4,77,6,7,8,9}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+
+ y[:3] = y[7:] = new int[] {};
+ assert(all(y == new int[] {3,4,5,6}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+
+ y[3:5] = new int[] {13,14,15,16,17};
+ assert(all(y == new int[] {0,1,2,13,14,15,16,17,5,6,7,8,9}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic(true);
+ int[] z={56,67,78};
+
+ y[:] = z;
+ assert(all(y == z));
+ assert(!alias(y,z));
+ assert(y.cyclicflag == true);
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic(true);
+ int[] z={56,67,78};
+ z.cyclic(true);
+
+ y[:] = z;
+ assert(all(y == z));
+ assert(!alias(y,z));
+ assert(y.cyclicflag == true);
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic(true);
+
+ y[2:3] = y[5:6] = new int[] {77};
+ assert(all(y == new int[] {0,1,77,3,4,77,6,7,8,9}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic(true);
+
+ y[:3] = y[7:] = new int[] {};
+ assert(all(y == new int[] {3,4,5,6}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic(true);
+
+ y[8:] = new int[] {18,19,20,21,22};
+ assert(all(y == new int[] {0,1,2,3,4,5,6,7,18,19,20,21,22}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic(true);
+
+ y[-2:0] = new int[] {18,19,20,21,22};
+ assert(all(y == new int[] {0,1,2,3,4,5,6,7,18,19,20,21,22}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic(true);
+
+ y[18:20] = new int[] {18,19,20,21,22};
+ assert(all(y == new int[] {0,1,2,3,4,5,6,7,18,19,20,21,22}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic(true);
+
+ y[3:5] = new int[] {13,14,15,16,17};
+ assert(all(y == new int[] {0,1,2,13,14,15,16,17,5,6,7,8,9}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic(true);
+
+ y[13:15] = new int[] {13,14,15,16,17};
+ assert(all(y == new int[] {0,1,2,13,14,15,16,17,5,6,7,8,9}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic(true);
+
+ y[3-10:5-10] = new int[] {13,14,15,16,17};
+ assert(all(y == new int[] {0,1,2,13,14,15,16,17,5,6,7,8,9}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic(true);
+
+ y[8:12] = new int[] {18,19,20,21};
+ assert(all(y == new int[] {20,21,2,3,4,5,6,7,18,19}));
+}
+{
+ int[] y={0,1,2,3,4,5,6,7,8,9};
+ y.cyclic(true);
+
+ y[-2:2] = new int[] {18,19,20,21};
+ assert(all(y == new int[] {20,21,2,3,4,5,6,7,18,19}));
+}
+
+// Side Effect Test
+{
+ int state=0;
+ int[] x={0,1,2,3,4,5,6,7,8,9};
+
+ int[] a() {
+ assert(state==0);
+ ++state;
+
+ return x;
+ }
+
+ int l() {
+ assert(state==1);
+ ++state;
+
+ return 2;
+ }
+
+ int r() {
+ assert(state==2);
+ ++state;
+
+ return 6;
+ }
+
+ int[] b() {
+ assert(state==3);
+ ++state;
+
+ return new int[] {77,77};
+ }
+
+ assert(state==0);
+ a()[l():r()]=b();
+ assert(state==4);
+ assert(all(x == new int[] {0,1,77,77,6,7,8,9}));
+}
+
+
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/array/solve.asy b/Build/source/utils/asymptote/tests/array/solve.asy
new file mode 100644
index 00000000000..ec1c4416ba4
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/array/solve.asy
@@ -0,0 +1,35 @@
+import TestLib;
+
+StartTest("solve");
+real[][] a=new real[][] {{1,1,1},{1,2,2},{0,0,1}};
+real[][] b=new real[][] {{3,9},{5,11},{1,3}};
+real[][] x=new real[][] {{1,7},{1,-1,},{1,3}};
+real[][] c=solve(a,b);
+for(int i=0; i < c.length; ++i)
+ for(int j=0; j < c[i].length; ++j)
+ assert(close(c[i][j],x[i][j]));
+
+real[][] a={{1,-2,3,0},{4,-5,6,2},{-7,-8,10,5},{1,50,1,-2}};
+real[] b={7,19,33,3};
+real[] x=solve(a,b);
+real[] c=a*x;
+for(int i=0; i < c.length; ++i)
+ assert(close(c[i],b[i]));
+EndTest();
+
+StartTest("inverse");
+real[][] a=new real[][] {{1,1,1},{1,2,2},{0,0,1}};
+real[][] ainverse=new real[][] {{2,-1,0},{-1,1,-1},{0,0,1}};
+real[][] d=inverse(a);
+real[][] l=d*a;
+real[][] r=a*d;
+real[][] I=identity(a.length);
+for(int i=0; i < d.length; ++i) {
+ for(int j=0; j < d[i].length; ++j) {
+ assert(close(d[i][j],ainverse[i][j]));
+ assert(I[i][j] == (i == j ? 1 : 0));
+ assert(close(l[i][j],I[i][j]));
+ assert(close(r[i][j],I[i][j]));
+ }
+}
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/array/transpose.asy b/Build/source/utils/asymptote/tests/array/transpose.asy
new file mode 100644
index 00000000000..f0366ba8fd1
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/array/transpose.asy
@@ -0,0 +1,55 @@
+import TestLib;
+import math;
+
+StartTest("transpose");
+int n=3;
+real[][] a=new real[n][n];
+real[][] b=new real[n][n];
+for(int i=0; i < n; ++i) {
+ for(int j=0; j < n; ++j) {
+ a[i][j]=b[j][i]=rand();
+ }
+}
+
+bool operator == (real[][] a, real[][] b)
+{
+ int n=a.length;
+ for(int i=0; i < n; ++i)
+ if(!all(a[i] == b[i])) return false;
+ return true;
+}
+
+bool operator == (real[][][] a, real[][][] b)
+{
+ int n=a.length;
+ for(int i=0; i < n; ++i) {
+ real[][] ai=a[i];
+ real[][] bi=b[i];
+ int m=ai.length;
+ for(int j=0; j < m; ++j) {
+ if(!all(ai[j] == bi[j])) return false;
+ }
+ }
+ return true;
+}
+
+assert(a == transpose(b));
+
+int n=3;
+real[][][] a=new real[n][n][n];
+real[][][] b=new real[n][n][n];
+real[][][] c=new real[n][n][n];
+real[][][] d=new real[n][n][n];
+for(int i=0; i < n; ++i) {
+ for(int j=0; j < n; ++j) {
+ for(int k=0; k < n; ++k) {
+ a[i][j][k]=b[j][i][k]=c[i][k][j]=d[k][j][i]=rand();
+ }
+ }
+}
+
+assert(a == transpose(b,new int[] {1,0,2}));
+assert(a == transpose(c,new int[] {0,2,1}));
+assert(a == transpose(d,new int[] {2,1,0}));
+
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/bench/6000circles.asy b/Build/source/utils/asymptote/tests/bench/6000circles.asy
new file mode 100644
index 00000000000..53ebecce27a
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/bench/6000circles.asy
@@ -0,0 +1,17 @@
+size(0,100);
+import math;
+import stats;
+
+currentpen=magenta;
+// A centered random number
+real crand() {return unitrand()*5;}
+
+real r1;
+pair pcenter;
+
+for(int i=0; i < 6000; ++i) {
+
+r1 = unitrand()/10;
+pcenter = ( crand(), crand());
+Draw(circle(pcenter,r1));
+}
diff --git a/Build/source/utils/asymptote/tests/frames/loop.asy b/Build/source/utils/asymptote/tests/frames/loop.asy
new file mode 100644
index 00000000000..ceb65a1ff56
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/frames/loop.asy
@@ -0,0 +1,29 @@
+import TestLib;
+StartTest("loop");
+
+int f();
+for (int i=0; i<10; ++i) {
+ int x=i;
+ for (int j=0; j<10; ++j) {
+ int y=j;
+ if (i==5 && j==7) {
+ f = new int () { return x*y; };
+ }
+ }
+}
+assert(f()==35);
+
+int f();
+
+for (int i=0; i<10; ++i) {
+ int x=i;
+ for (int j=0; j<10; ++j) {
+ int y=j;
+ if (i==5 && j==7) {
+ f = new int () { return i*y; };
+ }
+ }
+}
+assert(f()==70);
+
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/frames/stat.asy b/Build/source/utils/asymptote/tests/frames/stat.asy
new file mode 100644
index 00000000000..d366b193e0d
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/frames/stat.asy
@@ -0,0 +1,14 @@
+import TestLib;
+StartTest("stat");
+struct T {
+ int x;
+ static void f(T t) {
+ t.x=2;
+ }
+}
+
+T t=new T;
+assert(t.x==0);
+T.f(t);
+assert(t.x==2);
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/frames/stat2.asy b/Build/source/utils/asymptote/tests/frames/stat2.asy
new file mode 100644
index 00000000000..ea5863b081a
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/frames/stat2.asy
@@ -0,0 +1,17 @@
+import TestLib;
+StartTest("stat2");
+struct T {
+ int x;
+ static void f(T t) {
+ static void g(T t) {
+ t.x=2;
+ }
+ g(t);
+ }
+}
+
+T t=new T;
+assert(t.x==0);
+T.f(t);
+assert(t.x==2);
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/gc/array.asy b/Build/source/utils/asymptote/tests/gc/array.asy
new file mode 100644
index 00000000000..4b903ad95df
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/gc/array.asy
@@ -0,0 +1,5 @@
+real[] a;
+for (int i = 0; i < 1e7; ++i)
+{
+ a=new real[10];
+}
diff --git a/Build/source/utils/asymptote/tests/gc/file.asy b/Build/source/utils/asymptote/tests/gc/file.asy
new file mode 100644
index 00000000000..5e43b5b6603
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/gc/file.asy
@@ -0,0 +1,7 @@
+for (int i = 0; i < 1e5; ++i)
+{
+ file a=output("out/"+(string) i);
+ write(a,i,endl);
+ close(a);
+}
+
diff --git a/Build/source/utils/asymptote/tests/gc/funcall.asy b/Build/source/utils/asymptote/tests/gc/funcall.asy
new file mode 100644
index 00000000000..d565525420a
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/gc/funcall.asy
@@ -0,0 +1,6 @@
+void g()
+{}
+for (int i = 0; i < 1e7; ++i)
+{
+ g();
+}
diff --git a/Build/source/utils/asymptote/tests/gc/guide.asy b/Build/source/utils/asymptote/tests/gc/guide.asy
new file mode 100644
index 00000000000..af7af28a86a
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/gc/guide.asy
@@ -0,0 +1,5 @@
+guide a=(0,0);
+for (int i = 0; i < 1e7; ++i)
+{
+ guide b=a--a;
+}
diff --git a/Build/source/utils/asymptote/tests/gc/path.asy b/Build/source/utils/asymptote/tests/gc/path.asy
new file mode 100644
index 00000000000..118826eba10
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/gc/path.asy
@@ -0,0 +1,8 @@
+guide a;
+for (int i = 0; i < 1e7; ++i)
+{
+// guide a=a--(1.0,2.0);
+ path p=(1.0,2.0);
+ path q=(3.0,4.0);
+ path a=p--q;
+}
diff --git a/Build/source/utils/asymptote/tests/gc/pen.asy b/Build/source/utils/asymptote/tests/gc/pen.asy
new file mode 100644
index 00000000000..7b8d48dfcec
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/gc/pen.asy
@@ -0,0 +1,4 @@
+for (int i = 0; i < 1e7; ++i)
+{
+ pen p = linetype("test");
+}
diff --git a/Build/source/utils/asymptote/tests/gc/string.asy b/Build/source/utils/asymptote/tests/gc/string.asy
new file mode 100644
index 00000000000..f379b862249
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/gc/string.asy
@@ -0,0 +1,6 @@
+string a="abc";
+for (int i = 0; i < 1e7; ++i)
+{
+ "a"+"b";
+ a=reverse(a);
+}
diff --git a/Build/source/utils/asymptote/tests/gc/struct.asy b/Build/source/utils/asymptote/tests/gc/struct.asy
new file mode 100644
index 00000000000..db3a22280ac
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/gc/struct.asy
@@ -0,0 +1,7 @@
+for (int i = 0; i < 1e7; ++i)
+{
+ picture pic;
+ unitsize(pic, 0.02mm, 0.04mm);
+ draw(pic,unitcircle);
+ shipout(pic);
+}
diff --git a/Build/source/utils/asymptote/tests/gc/transform.asy b/Build/source/utils/asymptote/tests/gc/transform.asy
new file mode 100644
index 00000000000..abeef056564
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/gc/transform.asy
@@ -0,0 +1,6 @@
+path p=unitsquare;
+
+for (int i = 0; i < 1e7; ++i)
+{
+ scale(2.0)*p;
+}
diff --git a/Build/source/utils/asymptote/tests/imp/unravel.asy b/Build/source/utils/asymptote/tests/imp/unravel.asy
new file mode 100644
index 00000000000..0f61326fd66
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/imp/unravel.asy
@@ -0,0 +1,95 @@
+import TestLib;
+StartTest("unravel");
+{
+ struct A {
+ int x=1, y=2, z=3;
+ int y() { return 7; }
+ }
+
+ A a=new A;
+ unravel a;
+ assert(x==1);
+ assert(y==2);
+ assert(z==3);
+ assert(y()==7);
+}
+{
+ struct A {
+ private int x=1;
+ int y=2, z=3;
+ int y() { return 7; }
+ }
+
+ int x=5;
+ A a=new A;
+ unravel a;
+ assert(x==5);
+ assert(y==2);
+ assert(z==3);
+}
+{
+ struct A {
+ public int x=1;
+ int y=2, z=3;
+ int y() { return 7; }
+ }
+
+ int z=5;
+ A a=new A;
+ from a unravel x,y;
+ assert(x==1);
+ assert(y==2);
+ assert(z==5);
+ assert(y()==7);
+}
+{
+ struct A {
+ public int x=1;
+ int y=2, z=3;
+ int y() { return 7; }
+ }
+
+ int y=4;
+ int z=5;
+ A a=new A;
+ from a unravel x,y as blah;
+ assert(x==1);
+ assert(y==4);
+ assert(blah==2);
+ assert(z==5);
+ assert(blah()==7);
+}
+{
+ struct A {
+ struct B {
+ static int x=4;
+ }
+ }
+ A a=new A;
+ int x=3;
+ from a.B unravel x;
+ assert(x==4);
+}
+{
+ struct A {
+ struct B {
+ static int x=4;
+ }
+ }
+ A a=new A;
+ A.B b=new a.B;
+ int x=3;
+ from b unravel x;
+ assert(x==4);
+}
+{
+ struct A {
+ static struct B {
+ static int x=4;
+ }
+ }
+ int x=3;
+ from A.B unravel x;
+ assert(x==4);
+}
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/output/Makefile b/Build/source/utils/asymptote/tests/output/Makefile
new file mode 100644
index 00000000000..2462ea1cae5
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/output/Makefile
@@ -0,0 +1,41 @@
+# Automated testing to see if the output of Asymptote scripts changes when the
+# program is modified.
+
+# How to call asy from the tests/output/name.out directory
+ASY=../../../asy
+
+TESTS=$(basename $(wildcard *.asy))
+
+# This command performs the testing on all scripts.
+diff: $(TESTS:=.diff)
+
+# This builds the reference copies of the output using a trusted version of asy
+ref: $(TESTS:=.ref)
+
+$(TESTS:=.ref) $(TESTS:=.out): %:
+ @echo Generating $@
+ @rm -rf $@
+ @mkdir $@
+ @cd $@; \
+ $(ASY) -v -v -keep ../$(basename $@) \
+ >$(basename $@).stdout 2>$(basename $@).stderr; \
+ ls >$(basename $@).ls; \
+ rm -f *.dvi *.pdf *.gif *.jpg *.jpeg *.png
+
+# Ignore lines with timestamps of the form hh:mm, since the time changes between
+# runs. This regex is fairly broad and it may need to be narrowed.
+$(TESTS:=.diff): %.diff: %.out
+ diff -I "[0-9][0-9]:[0-9][0-9]" -u $(@:.diff=.ref) $(@:.diff=.out)
+
+clean:
+ rm -rf *.out
+
+# The reference copies should only be built at the start, or when the behaviour
+# of Asymptote is intentionally changed, so they are not usually removed by make
+# clean.
+veryclean: clean
+ rm -rf *.ref
+
+# This tells make to build every dependency from scratch, ignoring the dates on
+# files.
+.PHONY: $(TESTS:=.ref) $(TESTS:=.out) $(TESTS:=.diff) diff ref clean veryclean
diff --git a/Build/source/utils/asymptote/tests/output/circle.asy b/Build/source/utils/asymptote/tests/output/circle.asy
new file mode 100644
index 00000000000..e0300acdb8d
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/output/circle.asy
@@ -0,0 +1 @@
+draw(unitcircle);
diff --git a/Build/source/utils/asymptote/tests/output/line.asy b/Build/source/utils/asymptote/tests/output/line.asy
new file mode 100644
index 00000000000..21acd4fc4e5
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/output/line.asy
@@ -0,0 +1 @@
+draw((0,0)--(100,0));
diff --git a/Build/source/utils/asymptote/tests/string/erase.asy b/Build/source/utils/asymptote/tests/string/erase.asy
new file mode 100644
index 00000000000..2b38b61f359
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/string/erase.asy
@@ -0,0 +1,9 @@
+import TestLib;
+StartTest("erase");
+string s = "abcdef";
+assert(erase(s,2,2) == "abef");
+assert(erase(s,-1,2) == "abcdef");
+assert(erase(s,7,1) == "abcdef");
+assert(erase(s,3,0) == "abcdef");
+assert(erase(s,5,2) == "abcde");
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/string/find.asy b/Build/source/utils/asymptote/tests/string/find.asy
new file mode 100644
index 00000000000..cdf6dc6740f
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/string/find.asy
@@ -0,0 +1,8 @@
+import TestLib;
+StartTest("find");
+string s = "abcdefab";
+assert(find(s,"cd") == 2);
+assert(find(s,"cd",3) == -1);
+assert(find(s,"ab") == 0);
+assert(find(s,"ab",1) == 6);
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/string/insert.asy b/Build/source/utils/asymptote/tests/string/insert.asy
new file mode 100644
index 00000000000..2c11a2ef00f
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/string/insert.asy
@@ -0,0 +1,5 @@
+import TestLib;
+StartTest("insert");
+string sub = insert("abef",2,"cd");
+assert(sub == "abcdef");
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/string/length.asy b/Build/source/utils/asymptote/tests/string/length.asy
new file mode 100644
index 00000000000..dafb5d56b91
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/string/length.asy
@@ -0,0 +1,6 @@
+import TestLib;
+StartTest("length");
+assert(length("") == 0);
+assert(length("abc") == 3);
+assert(length("abcdef") == 6);
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/string/rfind.asy b/Build/source/utils/asymptote/tests/string/rfind.asy
new file mode 100644
index 00000000000..2291097a7ed
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/string/rfind.asy
@@ -0,0 +1,8 @@
+import TestLib;
+StartTest("rfind");
+string s = "abcdefab";
+assert(rfind(s,"cd") == 2);
+assert(rfind(s,"cd",1) == -1);
+assert(rfind(s,"ab") == 6);
+assert(rfind(s,"ab",5) == 0);
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/string/substr.asy b/Build/source/utils/asymptote/tests/string/substr.asy
new file mode 100644
index 00000000000..6426895aa39
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/string/substr.asy
@@ -0,0 +1,6 @@
+import TestLib;
+StartTest("substr");
+string s = "abcdef";
+string sub = substr(s,2,2);
+assert(sub == "cd");
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/types/cast.asy b/Build/source/utils/asymptote/tests/types/cast.asy
new file mode 100644
index 00000000000..b1191637554
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/types/cast.asy
@@ -0,0 +1,13 @@
+import TestLib;
+StartTest("cast");
+struct A {
+ public int x;
+}
+A operator cast(int x) {
+ A a=new A;
+ a.x=x;
+ return a;
+}
+A a=7;
+assert(a.x==7);
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/types/constructor.asy b/Build/source/utils/asymptote/tests/types/constructor.asy
new file mode 100644
index 00000000000..7dd13447cfd
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/types/constructor.asy
@@ -0,0 +1,271 @@
+import TestLib;
+StartTest("constructor");
+
+{ // Basic usage. {{{1
+ struct Foo {
+ int x;
+ int y;
+
+ void operator init() {
+ x=2; y=3;
+ }
+
+ void operator init(int x, int y=2x) {
+ this.x=x; this.y=y;
+ }
+
+ void operator init(string s ... int[] vals) {
+ for (int i=0; i<vals.length; ++i)
+ x+=vals[i];
+ y=vals.length;
+ }
+
+ static {
+ {
+ Foo f=new Foo;
+ assert(f.x==0);
+ assert(f.y==0);
+ }
+ {
+ Foo f=Foo();
+ assert(f.x==2);
+ assert(f.y==3);
+ }
+ {
+ Foo f=Foo(7);
+ assert(f.x==7);
+ assert(f.y==14);
+ }
+ {
+ Foo f=Foo(5,40);
+ assert(f.x==5);
+ assert(f.y==40);
+ }
+ {
+ Foo f=Foo(y=5,x=40);
+ assert(f.x==40);
+ assert(f.y==5);
+ }
+ {
+ Foo f=Foo("hello", 1,2,3,4);
+ assert(f.x==10);
+ assert(f.y==4);
+ }
+ }
+ }
+
+ {
+ Foo f=new Foo;
+ assert(f.x==0);
+ assert(f.y==0);
+ }
+ {
+ Foo f=Foo();
+ assert(f.x==2);
+ assert(f.y==3);
+ }
+ {
+ Foo f=Foo(7);
+ assert(f.x==7);
+ assert(f.y==14);
+ }
+ {
+ Foo f=Foo(5,40);
+ assert(f.x==5);
+ assert(f.y==40);
+ }
+ {
+ Foo f=Foo(y=5,x=40);
+ assert(f.x==40);
+ assert(f.y==5);
+ }
+ {
+ Foo f=Foo("hello", 1,2,3,4);
+ assert(f.x==10);
+ assert(f.y==4);
+ }
+}
+
+{ // Assignment {{{1
+ struct Foo {
+ int x;
+
+ static int Foo() {
+ return 7;
+ }
+
+ static assert(Foo()==7);
+
+ void five() {
+ x=5;
+ }
+
+ void six(string s) {
+ x=6;
+ }
+
+ void operator init()=five;
+
+ void operator init(string s) {
+ assert(false);
+ }
+ operator init=six;
+
+ static {
+ assert(Foo().x==5);
+ assert(Foo("milk").x==6);
+ }
+
+ void operator init(int x) {
+ this.x=2x;
+ }
+
+ static Foo constructor(int)=Foo;
+
+ static {
+ assert(constructor(5).x==10);
+ }
+ }
+
+ assert(Foo().x==5);
+ assert(Foo("milk").x==6);
+ assert(Foo.constructor(5).x==10);
+}
+
+{ // Permission {{{1
+ int Foo() {
+ return 3;
+ }
+
+ struct Foo {
+ int x;
+
+ private void operator init() {
+ x=2;
+ }
+ }
+ // The implicit constructor should not be unravelled, as it is private.
+ assert(Foo()==3);
+}
+{ // Shadowing {{{1
+ struct Foo {
+ static Foo Foo() {
+ return null;
+ }
+
+ static assert(Foo()==null);
+
+ void operator init() {
+ }
+
+ static assert(Foo()!=null);
+ }
+
+ assert(Foo()!=null);
+
+ // Can't use Bar because of conflicts with the drawing command.
+ struct Barr {
+ void operator init() {
+ }
+
+ static assert(Barr()!=null);
+
+ static Barr Barr() {
+ return null;
+ }
+
+ static assert(Barr()==null);
+ }
+
+ assert(Barr()!=null);
+
+ struct Blah {
+ void operator init() {
+ }
+
+ static assert(Blah()!=null);
+
+ static Blah Blah() {
+ return null;
+ }
+
+ static assert(Blah()==null);
+ }
+ from Blah unravel Blah;
+
+ assert(Blah()==null);
+}
+
+{ // Static {{{1
+ struct Foo {
+ static int Foo() {
+ return 7;
+ }
+
+ static void operator init() {
+ }
+
+ static assert(Foo()==7);
+ }
+
+ struct Barr {
+ int x;
+
+ void operator init() {
+ x=77;
+ }
+
+ static assert(Barr().x==77);
+
+ static void operator init() {
+ assert(false);
+ }
+
+ static assert(Barr().x==77);
+ }
+
+ assert(Barr().x==77);
+}
+
+{ // Struct name shadowing. {{{1
+ struct Foo {
+ int x;
+ typedef int Foo;
+
+ void operator init() {
+ x=89;
+ }
+
+ static assert(Foo().x==89);
+ }
+
+ assert(Foo().x==89);
+
+ struct Barr {
+ int x;
+ struct Barr {
+ }
+
+ void operator init() {
+ x=89;
+ }
+
+ static assert(Barr().x==89);
+ }
+
+ assert(Barr().x==89);
+}
+
+// File-level {{{1
+// This assumes the file is named constructor.asy
+
+int constructor() {
+ return 44;
+}
+void operator init() {
+ assert(false);
+}
+assert(constructor()==44);
+
+EndTest(); // {{{1
+
diff --git a/Build/source/utils/asymptote/tests/types/ecast.asy b/Build/source/utils/asymptote/tests/types/ecast.asy
new file mode 100644
index 00000000000..d16d7bc4494
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/types/ecast.asy
@@ -0,0 +1,11 @@
+import TestLib;
+StartTest("ecast");
+struct A {
+ public int x;
+}
+int operator ecast(A a) {
+ return a.x;
+}
+A a=new A; a.x=5;
+assert((int)a==5);
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/types/guide.asy b/Build/source/utils/asymptote/tests/types/guide.asy
new file mode 100644
index 00000000000..77400fcfbbf
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/types/guide.asy
@@ -0,0 +1,144 @@
+import TestLib;
+StartTest("guide");
+
+guide g;
+assert(size(g) == 0);
+assert(length(g) == -1);
+
+guide g=(0,0){curl 2}..(1,1){W}..tension 5 and 6 ..{N}(4,2)..{curl 3}(0,1);
+
+g=reverse(reverse(g));
+
+assert(size(g) == 4);
+assert(length(g) == 3);
+
+assert(size((path) g) == 4);
+assert(length((path) g) == 3);
+
+assert(size((guide) (path) g) == 4);
+assert(length((guide) (path) g) == 3);
+
+assert(close(point(g,-1),(0,0)));
+assert(close(point(g,0),(0,0)));
+assert(close(point(g,1),(1,1)));
+assert(close(point(g,3),(0,1)));
+assert(close(point(g,4),(0,1)));
+
+tensionSpecifier t=tensionSpecifier(g,1);
+assert(close(t.out,5));
+assert(close(t.in,6));
+assert(t.atLeast == false);
+
+pair[] z=dirSpecifier(g,0);
+assert(close(z[0],0));
+assert(close(z[1],0));
+
+pair[] z=dirSpecifier(g,1);
+assert(close(z[0],W));
+assert(close(z[1],N));
+
+real[] x=curlSpecifier(g,0);
+assert(close(x[0],2));
+assert(close(x[1],1));
+
+real[] x=curlSpecifier(g,length(g)-1);
+assert(close(x[0],1));
+assert(close(x[1],3));
+
+assert(!cyclic(g));
+assert(!cyclic((path) g));
+assert(!cyclic((guide) (path) g));
+
+guide g=(0,0)..controls (3,5)..(1,1){W}..tension atleast 5 and 6 ..{N}(4,2)..
+controls(1,2) and (2,4).. (0,1)..cycle;
+
+g=reverse(reverse(g));
+
+assert(size(g) == 4);
+assert(length(g) == 4);
+
+assert(size((path) g) == 4);
+assert(length((path) g) == 4);
+
+assert(size((guide) (path) g) == 4);
+assert(length((guide) (path) g) == 4);
+
+tensionSpecifier t=tensionSpecifier(g,1);
+assert(close(t.out,5));
+assert(close(t.in,6));
+assert(t.atLeast == true);
+
+pair[] z=controlSpecifier(g,0);
+assert(close(z[0],(3,5)));
+assert(close(z[1],(3,5)));
+
+pair[] z=controlSpecifier(g,2);
+assert(close(z[0],(1,2)));
+assert(close(z[1],(2,4)));
+
+real[] x=curlSpecifier(g,0);
+assert(close(x[0],1));
+assert(close(x[1],1));
+
+real[] x=curlSpecifier(g,length(g)-1);
+assert(close(x[0],1));
+assert(close(x[1],1));
+
+assert(cyclic(g));
+assert(cyclic((path) g));
+assert(cyclic((guide) (path) g));
+
+guide g=(0,0)..controls (3,5)..(1,1){W}..tension atleast 5 and 6 ..{N}(4,2)..
+cycle..controls(1,2) and (2,4)..(0,1)..cycle;
+
+assert(size(g) == 5);
+assert(length(g) == 5);
+
+assert(size((path) g) == 5);
+assert(length((path) g) == 5);
+
+assert(size((guide) (path) g) == 5);
+assert(length((guide) (path) g) == 5);
+
+pair[] z=dirSpecifier(g,0);
+assert(close(z[0],0));
+assert(close(z[1],0));
+
+pair[] z=dirSpecifier(g,1);
+assert(close(z[0],W));
+assert(close(z[1],N));
+
+tensionSpecifier t=tensionSpecifier(g,1);
+assert(close(t.out,5));
+assert(close(t.in,6));
+assert(t.atLeast == true);
+
+pair[] z=controlSpecifier(g,0);
+assert(close(z[0],(3,5)));
+assert(close(z[1],(3,5)));
+
+real[] x=curlSpecifier(g,0);
+assert(close(x[0],1));
+assert(close(x[1],1));
+
+real[] x=curlSpecifier(g,length(g)-1);
+assert(close(x[0],1));
+assert(close(x[1],1));
+
+assert(cyclic(g));
+assert(cyclic((path) g));
+assert(cyclic((guide) (path) g));
+
+guide g=(0,0)..controls (3,5) and (4,6)..cycle;
+
+g=reverse(g);
+
+assert(size(g) == 1);
+assert(length(g) == 1);
+
+pair[] z=controlSpecifier(g,0);
+assert(close(z[0],(4,6)));
+assert(close(z[1],(3,5)));
+
+EndTest();
+
diff --git a/Build/source/utils/asymptote/tests/types/init.asy b/Build/source/utils/asymptote/tests/types/init.asy
new file mode 100644
index 00000000000..5557bd0676c
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/types/init.asy
@@ -0,0 +1,17 @@
+import TestLib;
+StartTest("init");
+int operator init() { return 7; }
+int x;
+assert(x==7);
+
+struct A {
+ int x=3;
+}
+A a;
+assert(a!=null);
+assert(a.x==3);
+
+A operator init() { return null; }
+A aa;
+assert(aa==null);
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/types/resolve.asy b/Build/source/utils/asymptote/tests/types/resolve.asy
new file mode 100644
index 00000000000..e20962bbd21
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/types/resolve.asy
@@ -0,0 +1,12 @@
+import TestLib;
+StartTest("resolve");
+struct A {} struct B {} struct C {}
+
+int f(B, real) { return 1; }
+int f(C, int) { return 2; }
+B operator cast(A) { return new B; }
+
+assert(f(new A, 3) == 1);
+C operator cast(A) { return new C; }
+assert(f(new A, 3) == 2);
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/types/shadow.asy b/Build/source/utils/asymptote/tests/types/shadow.asy
new file mode 100644
index 00000000000..09d73abc020
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/types/shadow.asy
@@ -0,0 +1,17 @@
+import TestLib;
+StartTest("shadow");
+int x = 1;
+int getX() { return x; }
+void setX(int value) { x=value; }
+
+// Shadow x with another int, but x should still be in memory.
+int x = 2;
+assert(x==2);
+assert(getX()==1);
+x = 4;
+assert(x==4);
+assert(getX()==1);
+setX(7);
+assert(x==4);
+assert(getX()==7);
+EndTest();
diff --git a/Build/source/utils/asymptote/tests/types/spec.asy b/Build/source/utils/asymptote/tests/types/spec.asy
new file mode 100644
index 00000000000..90936446404
--- /dev/null
+++ b/Build/source/utils/asymptote/tests/types/spec.asy
@@ -0,0 +1,61 @@
+import TestLib;
+StartTest("spec");
+
+// Test if the cycle keyword can be used in different contexts.
+{
+ int operator cast(cycleToken) {
+ return 55;
+ }
+ int x=cycle;
+ assert(x==55);
+}
+
+// Test the tensionSpecifier type.
+{
+ tensionSpecifier operator ..(string a, tensionSpecifier t, string b) {
+ return t;
+ }
+ tensionSpecifier t="hello" .. tension 2 .. "joe";
+ assert(t.out==2);
+ assert(t.in==2);
+ assert(t.atLeast==false);
+
+ tensionSpecifier t="hello" .. tension 3 and 2 .. "joe";
+ assert(t.out==3);
+ assert(t.in==2);
+ assert(t.atLeast==false);
+
+ tensionSpecifier t="hello" .. tension atleast 7 .. "joe";
+ assert(t.out==7);
+ assert(t.in==7);
+ assert(t.atLeast==true);
+
+ tensionSpecifier t="hello" .. tension atleast 3 and 2 .. "joe";
+ assert(t.out==3);
+ assert(t.in==2);
+ assert(t.atLeast==true);
+}
+
+// Test the curlSpecifier type.
+{
+ curlSpecifier operator ..(curlSpecifier spec, string b) {
+ return spec;
+ }
+ curlSpecifier operator ..(string a, curlSpecifier spec) {
+ return spec;
+ }
+ curlSpecifier operator ..(string a, curlSpecifier spec, string b) {
+ return spec;
+ }
+
+ curlSpecifier spec="hello"{curl 3}.."joe";
+ assert(spec.value==3);
+ assert(spec.side==JOIN_OUT);
+
+ curlSpecifier spec="hello"..{curl 7}"joe";
+ assert(spec.value==7);
+ assert(spec.side==JOIN_IN);
+}
+
+EndTest();
+