Testing database source

	Setup: create root and sys

name root 1
name sys 0
name testobj1 2

object root

method foo
	$sys.log("  method foo called, sender " + toliteral(sender()));
.

--------------------
	testobj1

	This object, used by regression test 6, just provides a
	.parents() method to check the parents list before and after a
	chparents().

parent root
object testobj1

method parents
	return parents();
.

parent root
object sys

--------------------
	Set up the log method for the root object to call.

method log
	arg s;

	log(s);
.

--------------------
	Test 1: Language: comment
	Output: Comment statement test
eval
	log("Comment statement test");
	// comment 1
	// comment 2
.

--------------------
	Test 2: Language: empty statement
	Output: Empty statement test
eval
	log("Empty statement test");
	;
.

--------------------
	Test 3: Language: expression statement
	Output: Expression statement test
eval
	log("Expression statement test");
.

--------------------
	Test 4: Language: compound statement
	Output: Compound statement test
		  1
		  2
eval
	log("Compound statement test");
	{
	    log("  1");
	    log("  2");
	}
.

--------------------
	Test 5: Language: assignment statement
	Output: Assignment statement test
		  paramnf error resulted
eval
	var a;

	a = "Assignment statement test";
	log(a);
	catch ~paramnf {
	    foo = 3;
	} with handler {
	    log("  paramnf error resulted");
	}
.

--------------------
	Test 6: Language: if statement
	Output: If statement test
		  Test 1: reached body
eval
	log("If statement test");
	if (1)
	    log("  Test 1: reached body");
	if (0)
	    log("  Test 2: reached body");
.

--------------------
	Test 7: Language: if-else statement
	Output: If-else statement test
		  Test 1: reached true body
		  Test 2: reached false body
eval
	log("If-else statement test");
	if (1)
	    log("  Test 1: reached true body");
	else
	    log("  Test 1: reached false body");
	if (0)
	    log("  Test 2: reached true body");
	else
	    log("  Test 2: reached false body");
.

--------------------
	Test 8: Language: for-range statement
	Output: For-range statement test:
		  Iteration -4
		  Iteration -3
		  Iteration -2
		  Iteration -1
		  Iteration 0
		  Iteration 1
		  Iteration 2
		  Final value 2
		  Type error resulted
eval
	var i;

	log("For-range statement test:");
	for i in [-4..2]
	    log("  Iteration " + tostr(i));
	log("  Final value " + tostr(i));
	catch ~type {
	    for i in [-4.."foo"]
		;
	} with handler {
	    log("  Type error resulted");
	}
.

--------------------
	Test 9: Language: for-list statement
	Output: For-list statement test:
		  Iteration 1
		  Iteration 'foo
		  Iteration ['bar, 3]
		  Iteration ~crayons
		  Final value ~crayons
		  Iteration ["foo", "bar"]
		  Iteration [3, 'foo]
		  Iteration [~baz, [3, 4]]
		  Final value [~baz, [3, 4]]
		  Type error resulted
eval
	var i;

	log("For-list statement test:");
	for i in ([1, 'foo, ['bar, 3], ~crayons])
	    log("  Iteration " + toliteral(i));
	log("  Final value " + toliteral(i));
	for i in (#[["foo", "bar"], [3, 'foo], [~baz, [3, 4]]])
	    log("  Iteration " + toliteral(i));
	log("  Final value " + toliteral(i));
	catch ~type {
	    for i in (3)
		;
	} with handler {
	    log("  Type error resulted");
	}
.

--------------------
	Test 10: Language: while statement
	Output: While statement test:
		  Iteration 3
		  Iteration 4
		  Iteration 5
		  Iteration 6
		  Final value 7
eval
	var i;

	log("While statement test:");
	i = 3;
	while (i < 7) {
	    log("  Iteration " + tostr(i));
	    i = i + 1;
	}
	log("  Final value " + tostr(i));
.

--------------------
	Test 11: Language: switch
	Output: Switch statement test
		  Test 1: 1
		  Test 2: 0..7
		  Test 3: 0..7
		  Test 4: "foo"
		  Test 5: default
		  Test 8: "a".."z"
		  Type error resulted
eval
	var i, count;

	log("Switch statement test");
	count = 1;
	for i in ([1, 3, 7, "foo", 'foo]) {
	    switch (i) {
		case 1:
		    log("  Test " + tostr(count) + ": 1");
		case 0..7:
		    log("  Test " + tostr(count) + ": 0..7");
		case "foo":
		    log("  Test " + tostr(count) + ": \"foo\"");
		default:
		    log("  Test " + tostr(count) + ": default");
	    }
	    count = count + 1;
	}
	for i in ([1, 7, "foo", 'foo, 9]) {
	    switch (i) {
		case 'baz:
		    log("  Test " + tostr(count) + ": 1");
		case "a".."z":
		    log("  Test " + tostr(count) + ": \"a\"..\"z\"");
		case "foo":
		    log("  Test " + tostr(count) + ": \"foo\"");
	    }
	    count = count + 1;
	}
	catch ~type {
	    switch (3) {
		case 'baz:
		    ;
		case "foo"..3:
		    log("WRONG");
	    }
	} with handler {
	    log("  Type error resulted");
	}
.

--------------------
	Test 12: Language: break
	Output: Break statement test: for-range loop
		  Iteration 7 start
		  Iteration 7 finish
		  Iteration 8 start
		  Iteration 8 finish
		  Iteration 9 start
		  Final value 9
		Break statement test: for-list loop
		  Iteration 'foo start
		  Iteration 'foo finish
		  Iteration 3 start
		  Final value 3
		Break statement test: while loop
		  Iteration 3 start
		  Iteration 3 finish
		  Iteration 4 start
		  Iteration 4 finish
		  Iteration 5 start
		  Final value 5
eval
	var i;

	log("Break statement test: for-range loop");
	for i in [7..12] {
	    log("  Iteration " + tostr(i) + " start");
	    if (i == 9)
		break;
	    log("  Iteration " + tostr(i) + " finish");
	}
	log("  Final value " + tostr(i));
	log("Break statement test: for-list loop");
	for i in (['foo, 3, ~bar]) {
	    log("  Iteration " + toliteral(i) + " start");
	    if (i == 3)
		break;
	    log("  Iteration " + toliteral(i) + " finish");
	}
	log("  Final value " + toliteral(i));
	log("Break statement test: while loop");
	i = 3;
	while (i < 7) {
	    log("  Iteration " + tostr(i) + " start");
	    if (i == 5)
		break;
	    log("  Iteration " + tostr(i) + " finish");
	    i = i + 1;
	}
	log("  Final value " + tostr(i));
.


--------------------
	Test 13: Language: continue
	Output: Continue statement test: for-range loop
		  Iteration 7 start
		  Iteration 7 finish
		  Iteration 8 start
		  Iteration 8 finish
		  Iteration 9 start
		  Iteration 10 start
		  Iteration 10 finish
		  Iteration 11 start
		  Iteration 11 finish
		  Iteration 12 start
		  Iteration 12 finish
		  Final value 12
		Continue statement test: for-list loop
		  Iteration 'foo start
		  Iteration 'foo finish
		  Iteration 3 start
		  Iteration ~bar start
		  Iteration ~bar finish
		  Final value ~bar
		Continue statement test: while loop
		  Iteration 3 start
		  Iteration 3 finish
		  Iteration 4 start
		  Iteration 4 finish
		  Iteration 5 start
		  Iteration 6 start
		  Iteration 6 finish
		  Final value 7
eval
	var i;

	log("Continue statement test: for-range loop");
	for i in [7..12] {
	    log("  Iteration " + tostr(i) + " start");
	    if (i == 9)
		continue;
	    log("  Iteration " + tostr(i) + " finish");
	}
	log("  Final value " + tostr(i));
	log("Continue statement test: for-list loop");
	for i in (['foo, 3, ~bar]) {
	    log("  Iteration " + toliteral(i) + " start");
	    if (i == 3)
		continue;
	    log("  Iteration " + toliteral(i) + " finish");
	}
	log("  Final value " + toliteral(i));
	log("Continue statement test: while loop");
	i = 3;
	while (i < 7) {
	    log("  Iteration " + tostr(i) + " start");
	    i = i + 1;
	    if (i == 6)
		continue;
	    log("  Iteration " + tostr(i - 1) + " finish");
	}
	log("  Final value " + tostr(i));
.

--------------------
	Test 14: Language: return
	Output: Return statement test
		  Before
eval
	log("Return statement test");
	log("  Before");
	return;
	log("  After");
.

--------------------
	Test 15: Language: catch and catch-with-handler
	Output: Catch statement test
		  Test 1: before error
		  Test 1: after catch
		  Test 2: before error
		  Test 2: in handler
		  Test 2: after catch
		  Test 3: before error
eval
	log("Catch statement test");
	catch ~div {
	    log("  Test 1: before error");
	    1 / 0;
	    log("  Test 1: after error");
	}
	log("  Test 1: after catch");
	catch any {
	    log("  Test 2: before error");
	    1 / 0;
	    log("  Test 2: after error");
	} with handler {
	    log("  Test 2: in handler");
	}
	log("  Test 2: after catch");
	catch ~div {
	    log("  Test 3: before error");
	    "ab" + 3;
	    log("  Test 3: after error");
	} with handler {
	    log("  Test 3: in handler");
	}
	log("  Test 3: after catch");
.

--------------------
	Test 16: Language: literals
	Output: Literal expression test
		  1
		  "foo"
		  #26
		  'foo
		  ~foo
eval
	log("Literal expression test");
	log("  " + toliteral(1));
	log("  " + toliteral("foo"));
	log("  " + toliteral(#26));
	log("  " + toliteral('foo));
	log("  " + toliteral(~foo));
.

--------------------
	Test 17: Language: function call
	Output: Function call test
		  6
eval
	log("Function call test");
	log("  " + tostr(strlen(substr(strsub("foobar", "ob", "oqqqq"), 4, 6))));
.

--------------------
	Test 18: Language: pass
	Output: Pass expression test
		  method foo called, sender #0
		  Completed
method foo
	log("Pass expression test");
	pass();
	log("  Completed");
.

eval
	.foo();
.

--------------------
	Test 19: Language: messages
	Output: Message expression test
		  method foo called, sender #0
		  .foo(3) ==> ~numargs
		  #36.foo() ==> ~objnf
		  .blarg() ==> ~methodnf
eval
	log("Message expression test");
	$root.foo();
	log("  .foo(3) ==> " + toliteral((| .foo(3) |)));
	log("  #36.foo() ==> " + toliteral((| #36.foo() |)));
	log("  .blarg() ==> " + toliteral((| .blarg() |)));
.

--------------------
	Test 20: Language: expr-messages
	Output: Expr-message expression test
		  method foo called, sender #0
		  .("foo")() ==> ~type
		  .('foo)(3) ==> ~numargs
		  #36.('foo)() ==> ~objnf
		  .('blarg)() ==> ~methodnf
eval
	log("Expr-message expression test");
	$root.('foo)();
	log("  .(\"foo\")() ==> " + toliteral((| .("foo")() |)));
	log("  .('foo)(3) ==> " + toliteral((| .('foo)(3) |)));
	log("  #36.('foo)() ==> " + toliteral((| #36.('foo)() |)));
	log("  .('blarg)() ==> " + toliteral((| .('blarg)() |)));
.

--------------------
	Test 21: Language: List, dictionary, frob construction
	Output: Constructor expression test
		  List: ['foo, 5, 'bar]
		  Dictionary: #[['foo, ~bar], ["barc", 9]]
		  Frob: <#14, #[['foo, ~bar], ["bar", 1]]>
		  Invalid dictionary (association with three elements): ~type
		  Invalid frob (association not a list): ~type
eval
	log("Constructor expression test");
	log("  List: " + toliteral(['foo, 2 + 3, 'bar]));
	log("  Dictionary: " + toliteral(#[['foo, ~bar], ["bar" + "c", 3 + 6]]));
	log("  Frob: " + toliteral(<#14, #[['foo, ~bar], ["bar", 3 - 2]]>));
	log("  Invalid dictionary (association with three elements): " + toliteral((| #[['foo, ~bar], ["foo", "bar", "baz"]] |)));
	log("  Invalid frob (association not a list): " + toliteral((| #[['foo, ~bar], "foo"] |)));
.

--------------------
	Test 22: Language: Index expression
	Output: Index expression test
		  [2, 3, 4][3] ==> 4
		  #[["foo", 7], [~bar, 'baz]]["fOo"] ==> 7
		  'foo[3] ==> ~type
		  [2, 3, 4][7] ==> ~range
		  [2, 3, 4][0] ==> ~range
		  #[[7, 'foo], [~baz, "foo"]][~BAZ] ==> ~keynf
eval
	log("Index expression test");
	log("  [2, 3, 4][3] ==> " + toliteral([2, 3, 4][3]));
	log("  #[[\"foo\", 7], [~bar, 'baz]][\"fOo\"] ==> " + toliteral(#[["foo", 7], [~baz, 'baz]]["fOo"]));
	log("  'foo[3] ==> " + toliteral((| 'foo[3] |)));
	log("  [2, 3, 4][7] ==> " + toliteral((| [2, 3, 4][7] |)));
	log("  [2, 3, 4][0] ==> " + toliteral((| [2, 3, 4][0] |)));
	log("  #[[7, 'foo], [~baz, \"foo\"]][~BAZ] ==> " + toliteral((| #[[7, 'foo], [~baz, "foo"]][~BAZ] |)));
.

--------------------
	Test 23: Language: unary operators
	Output: Unary operator expression test
		  -(2 + 3) ==> -5
		  +(2 + 3) ==> 5
		  !0 ==> 1
		  !1 ==> 0
		  -"foo" ==> ~type
eval
	log("Unary operator expression test");
	log("  -(2 + 3) ==> " + toliteral(-(2 + 3)));
	log("  +(2 + 3) ==> " + toliteral(+(2 + 3)));
	log("  !0 ==> " + toliteral(!0));
	log("  !1 ==> " + toliteral(!1));
	log("  -\"foo\" ==> " + toliteral((| -"foo" |)));
.

--------------------
	Test 24: Language: binary operators
	Output: Binary operator expression test
		  2 * 8 ==> 16
		  9 / 4 ==> 2
		  143 % 15 ==> 8
		  2 + 2 ==> 4
		  "foo" + "bar" ==> "foobar"
		  "oo" + "rb" ==> "oorb"
		  [1, 2, 3] + [4, 5, 6] ==> [1, 2, 3, 4, 5, 6]
		  [2, 3] + [5, 6] ==> [2, 3, 5, 6]
		  3 == 3 ==> 1
		  3 == 4 ==> 0
		  "foo" == "foo" ==> 1
		  "foo" == "fOo" ==> 1
		  "foo" == "bar" ==> 0
		  [1, 2, 3] == [1, 2, 3] ==> 1
		  'foo == 'foo ==> 1
		  'foo == 'fOo ==> 0
		  #[[1, 2], ['bar, "baz"]] == #[[1, 2], ['bar, "baZ"]] ==> 1
		  <#12, #[]> == <#12, #[[1, 2]]> ==> 0
		  ~foo == ~bar ==> 0
		  [1, 2, 3] != [4, 5, 6] ==> 1
		  4 > 2 ==> 1
		  4 > 5 ==> 0
		  "Foo" > "bar" ==> 1
		  "foo" <= "foo" ==> 1
		  4 in [1, 2, 3] ==> 0
		  'foo in [4, 'foo, 6] ==> 2
		  1 && 1 ==> 1
		  1 && 0 ==> 0
		  1 || log("foo") ==> 1
		  1 ? "foo" | "bar" ==> "foo"
		  0 ? "foo" | "bar" ==> "bar"
		  3 * 'foo ==> ~type
		  3 / [3] ==> ~type
		  [3] % 4 ==> ~type
		  ~foo + "bar" ==> ~type
		  [3] - [5] ==> ~type
		  'foo > 'bar ==> ~type
		  ~foo <= ~bar ==> ~type
		  4 in 'foo ==> ~type
eval
	log("Binary operator expression test");
	log("  2 * 8 ==> " + toliteral(2 * 8));
	log("  9 / 4 ==> " + toliteral(9 / 4));
	log("  143 % 15 ==> " + toliteral(143 % 15));
	log("  2 + 2 ==> " + toliteral(2 + 2));
	log("  \"foo\" + \"bar\" ==> " + toliteral("foo" + "bar"));
	log("  \"oo\" + \"rb\" ==> " + toliteral(substr("foobar", 2, 2) + substr("barbaz", 3, 2)));
	log("  [1, 2, 3] + [4, 5, 6] ==> " + toliteral([1, 2, 3] + [4, 5, 6]));
	log("  [2, 3] + [5, 6] ==> " + toliteral(sublist([1, 2, 3, 4], 2, 2) + sublist([4, 5, 6], 2, 2)));
	log("  3 == 3 ==> " + toliteral(3 == 3));
	log("  3 == 4 ==> " + toliteral(3 == 4));
	log("  \"foo\" == \"foo\" ==> " + toliteral("foo" == "foo"));
	log("  \"foo\" == \"fOo\" ==> " + toliteral(substr("foobar", 1, 3) == substr("afooa", 2, 3)));
	log("  \"foo\" == \"bar\" ==> " + toliteral("foo" == "bar"));
	log("  [1, 2, 3] == [1, 2, 3] ==> " + toliteral(sublist([1, 2, 3, 4], 1, 3) == sublist([0, 1, 2, 3, 4], 2, 3)));
	log("  'foo == 'foo ==> " + toliteral('foo == 'foo));
	log("  'foo == 'fOo ==> " + toliteral('foo == 'fOo));
	log("  #[[1, 2], ['bar, \"baz\"]] == #[[1, 2], ['bar, \"baZ\"]] ==> " + toliteral(#[[1, 2], ['bar, "baz"]] == #[[1, 2], ['bar, "baZ"]]));
	log("  <#12, #[]> == <#12, #[[1, 2]]> ==> " + toliteral(<#12, #[]> == <#12, #[[1, 2]]>));
	log("  ~foo == ~bar ==> " + toliteral(~foo == ~bar));
	log("  [1, 2, 3] != [4, 5, 6] ==> " + toliteral([1, 2, 3] != [4, 5, 6]));
	log("  4 > 2 ==> " + toliteral(4 > 2));
	log("  4 > 5 ==> " + toliteral(4 > 5));
	log("  \"Foo\" > \"bar\" ==> " + toliteral("foo" > "bar"));
	log("  \"foo\" <= \"foo\" ==> " + toliteral("foo" <= "foo"));
	log("  4 in [1, 2, 3] ==> " + toliteral(4 in [1, 2, 3]));
	log("  'foo in [4, 'foo, 6] ==> " + toliteral('foo in [4, 'foo, 6]));
	log("  1 && 1 ==> " + toliteral(1 && 1));
	log("  1 && 0 ==> " + toliteral(1 && 0));
	log("  1 || log(\"foo\") ==> " + toliteral(1 || log("foo")));
	log("  1 ? \"foo\" | \"bar\" ==> " + toliteral(1 ? "foo" | "bar"));
	log("  0 ? \"foo\" | \"bar\" ==> " + toliteral(0 ? "foo" | "bar"));
	log("  3 * 'foo ==> " + toliteral((| 3 * 'foo |)));
	log("  3 / [3] ==> " + toliteral((| 3 / [3] |)));
	log("  [3] % 4 ==> " + toliteral((| [3] / 4 |)));
	log("  ~foo + \"bar\" ==> " + toliteral((| ~foo + "bar" |)));
	log("  [3] - [5] ==> " + toliteral((| [3] - [5] |)));
	log("  'foo > 'bar ==> " + toliteral((| 'foo > 'bar |)));
	log("  ~foo <= ~bar ==> " + toliteral((| ~foo <= ~bar |)));
	log("  4 in 'foo ==> " + toliteral((| 4 in 'foo |)));
.

--------------------
	Test 25: Language: Propagation expressions and critical expressions
	Output: Propagation expression and critical expression test
		  .proptest1() ==> ~div
		  .proptest2() ==> ~methoderr
method proptest1
	(> 1 / 0 <);
.

method proptest2
	1 / 0;
.

eval
	log("Propagation expression and critical expression test");
	log("  .proptest1() ==> " + toliteral((| .proptest1() |)));
	log("  .proptest2() ==> " + toliteral((| .proptest2() |)));
.

--------------------
	Test 26: Language: Splicing
	Output: Splicing test
		  [1, @foo, 7] ==> [1, 3, 4, 5, 7]
eval
	var foo;

	log("Splicing test");
	foo = [3, 4, 5];
	log("  [1, @foo, 7] ==> " + toliteral([1, @foo, 7]));
.

--------------------
	Test 27: Data: Operations on integers
	Output:
eval
.

--------------------
	Regression test 1

	Bug: setadd() and setremove() were corrupting lists.

	Fixed: 0.5

	Testing method: exercise setadd() and setremove().

	Output: Regression test 1
		  ["foo", 4, "bar"]

eval
	var a;

	a = setadd([2, "foo", 4], 4);
	a = setadd(a, "bar");
	a = setremove(a, 2);
	a = setremove(a, 10);
	a = setadd(a, "foo");
	log("Regression test 1");
	log("  " + toliteral(a));
.

--------------------
	Regression test 2

	Bug: empty substrings and sublists were coming up true if they
	     were of non-empty strings or lists.

	Fixed: 0.5

	Testing method: Create empty substrings and sublists of non-empty
			strings and lists, and check truth.

	Output: Regression test 2
		  false
		  false

eval
	var a, b;

	a = substr("foo", 1, 0);
	b = sublist([1, 2, 3], 1, 0);
	log("Regression test 2");
	log("  " + (a ? "true" | "false"));
	log("  " + (b ? "true" | "false"));
.

--------------------
	Regression test 3

	Bug: rethrow() dumped core.

	Fixed: 0.5

	Testing method: Catch an error and do a rethrow() in the handler.

	Output: Regression test 3

eval
	log("Regression test 3");
	catch ~div {
	    1 / 0;
	} with handler {
	   rethrow(~foo);
	}
.

--------------------
	Regression test 4

	Bug: delete() was corrupting lists.

	Fixed: 0.7

	Testing method: Exercise delete()

	Output: Regression test 4
		  [3, 5]

eval
	var a;

	a = delete([2, 3, 4, 5, 6], 1);
	a = delete(a, 2);
	a = delete(a, 3);
	log("Regression test 4");
	log("  " + toliteral(a));
.


--------------------
	Regression test 5

	Bug: chparents() had a series of problems, including: it was
	     crashing the server, it wasn't checking for an empty parents
	     list.

	Fixed: 0.7

	Testing method: Test chparents() on an empty list, and exercise it
			normally.

	Objects: testobj1

	Output: Regression test 5
		  ~perm
		  Parents of $testobj1: [#1]
		  Parents of $testobj1: [#0]

eval
	log("Regression test 5");
	log("  " + toliteral((| chparents($testobj1, []) |)));
	log("  Parents of $testobj1: " + toliteral($testobj1.parents()));
	chparents($testobj1, [$sys]);
	log("  Parents of $testobj1: " + toliteral($testobj1.parents()));
.

--------------------
	Regression test 6

	Bug: Removing a method while it was running could have caused
	     crashes.

	Fixed: 0.7

	Testing method: Remove a method while it's running.

	Output: Regression test 6
		  Before removal
		  After removal: 'regtest6 in methods() ==> 0

method regtest6
	log("Regression test 6");
	log("  Before removal");
	del_method('regtest6);
	log("  After removal: 'regtest6 in methods() ==> " + toliteral('regtest6 in methods()));
.

eval
	.regtest6();
.

--------------------
	Regression test 7

	Bug: replace() was mutating its argument list

	Fixed: 0.7

	Testing method: Call replace() on a list, see if it changes

	Output: Regression test 7
		  a ==> [2, 'foo, 4]
		  a ==> [2, 'foo, 4]

eval
	var a;

	log("Regression test 7");
	a = [2, 'foo, 4];
	log("  a ==> " + toliteral(a));
	replace(a, 2, 3);
	replace(a, 1, 4);
	log("  a ==> " + toliteral(a));
.

--------------------
	Regression test 8

	Bug: String comparison was comparing strings instead of
	     substrings.

	Fixed: 0.7

	Testing method: Create substrings and compare them, making
			sure that text before and after a substring
			doesn't come into play.

	Output: Regression test 8
		  a == b ==> 1
		  a == c ==> 0
		  a == d ==> 0
		  a == e ==> 0
		  b == e ==> 0

eval
	var a, b, c, d, e;

	a = "foobar";
	b = substr(" foobar ", 2, 6);
	c = substr("foobar", 2, 5);
	d = substr("foobar", 1, 5);
	e = substr("foobar", 3, 3);
	log("Regression test 8");
	log("  a == b ==> " + toliteral(a == b));
	log("  a == c ==> " + toliteral(a == c));
	log("  a == d ==> " + toliteral(a == d));
	log("  a == e ==> " + toliteral(a == e));
	log("  b == e ==> " + toliteral(b == e));
.

--------------------
	Regression test 9

	Bug: 0.6-1

	Testing method: Compare equal and unequal dictionaries

	Output: Regression test 9
		  #[] == #[] ==> 1
		  #[[1, 2]] == #[[1, 2]] ==> 1
		  #[[1, 2]] == #[[3, 2]] ==> 0
		  #[[1, 2]] == #[[3, 4]] ==> 0

eval
	log("Regression test 9");
	log("  #[] == #[] ==> " + toliteral(#[] == #[]));
	log("  #[[1, 2]] == #[[1, 2]] ==> " + toliteral(#[[1, 2]] == #[[1, 2]]));
	log("  #[[1, 2]] == #[[3, 2]] ==> " + toliteral(#[[1, 2]] == #[[3, 2]]));
	log("  #[[1, 2]] == #[[3, 4]] ==> " + toliteral(#[[1, 2]] == #[[3, 4]]));
.


--------------------
	Regression test 10

	Bug: 0.6-2

	Testing method: Compare equal and unequal frobs

	Output: Regression test 10
		  <#19, #[]> == <#19, #[]> ==> 1
		  <#19, #[[1, 2]]> == <#19, #[]> ==> 0
		  <#19, #[[1, 2]]> == <#19, #[[1, 2]]> ==> 1
		  <#19, #[[1, 2]]> == <#19, #[[3, 4]]> ==> 0
		  <#19, #[[1, 2]]> == <#19, #[[3, 2]]> ==> 0

eval
	log("Regression test 10");
	log("  <#19, #[]> == <#19, #[]> ==> " + toliteral(<#19, #[]> == <#19, #[]>));
	log("  <#19, #[[1, 2]]> == <#19, #[]> ==> " + toliteral(<#19, #[[1, 2]]> == <#19, #[]>));
	log("  <#19, #[[1, 2]]> == <#19, #[[1, 2]]> ==> " + toliteral(<#19, #[[1, 2]]> == <#19, #[[1, 2]]>));
	log("  <#19, #[[1, 2]]> == <#19, #[[3, 4]]> ==> " + toliteral(<#19, #[[1, 2]]> == <#19, #[[3, 4]]>));
	log("  <#19, #[[1, 2]]> == <#19, #[[3, 2]]> ==> " + toliteral(<#19, #[[1, 2]]> == <#19, #[[3, 2]]>));
.

--------------------
	Regression test 11

	Bug: 0.7-2

	Testing method: Call size method twice in two methods, to see
			if the result changes.

	Output: Regression test 11
		  size1 - size2 ==> 0

var sys size1 0
var sys size2 0

eval
	size1 = .size();
.

eval
	size2 = .size();
.

eval
	log("Regression test 11");
	log("  size1 - size2 ==> " + toliteral(size1 - size2));
.

--------------------
	Regression test 12

	Bug: 0.7-8

	Testing method: Exercise splicing optimization, and verify that
			splicing a list into the end of a list constructor
			works.

	Output: Regression test 12
		  [1, 2, 3, 4, 5, 6]
		  [1, 2, 3, 4, 5, 6]

eval
	log("Regression test 12");
	log("  " + toliteral([@[1, 2, 3], 4, 5, 6]));
	log("  " + toliteral([1, 2, 3, @[4, 5, 6]]));
.

--------------------
	Regression test 13

	Bug: 0.7-9

	Testing method: Cause an error after a catch handler, and
	check the line number.

	Output: Regression test 13
		  Error on line: 7

method regtest13
	catch any {
	} with handler {
	    // Comment 1
	    // Comment 2
	    // Comment 3
	}
	.error("Line 7");
.

eval
	var str;

	log("Regression test 13");
	catch any {
	    .regtest13();
	} with handler {
            log("  Error on line: " + tostr(traceback()[3][5]));
	}
.

--------------------
	Regression test 14

	Bug: 0.7-11

	Testing method: Exercise union() with empty lists.

	Output: Regression test 14
		  1
		  2
		  3

eval
	var x;

	log("Regression test 14");
	for x in ([1, 2, 3]) {
	    union([], []);
	    log("  " + toliteral(x));
	}
.

--------------------
	Regression test 15

	Bug: 0.7.1-1

	Testing method: Decompile a method with a self-message.

	Output: Regression test 15
		  .foo("bar");

method regtest15
    .foo("bar");
.

eval
    log("Regression test 15");
    log("  " + list_method('regtest15)[1]);
.

--------------------
	Regression test 16

	Bug: 0.8-1

	Testing method: Use chparents(), destroy(), conn_assign() in a
			for-list loop.

	Output: Regression test 16
		  Done.

eval
	var i, obj;

	log("Regression test 16");
	for i in [1 .. 3] {
	    obj = create([$root]);
	    chparents(obj, [$root]);
	    destroy(obj);
	}
	log("  Done.");
.

--------------------
	Regression test 17

	Bug: 0.8-2

	Testing method: Read in a frob with a 'var' declaration.

	Output: Regression test 17
		  <#15, #[['type, 'true]]>

var sys regtest17 <#15, #[['type, 'true]]>

eval
	log("Regression test 17");
	log("  " + toliteral(regtest17));
.

--------------------
	Regression test 18

	Bug: 0.8.1-3

	Testing method: Exercise has_ancestor().

	Output: Regression test 18
		  1
		  1
		  0

eval
	log("Regression test 18");
	log("  " + tostr(has_ancestor($sys)));
	log("  " + tostr(has_ancestor($root)));
	log("  " + tostr(has_ancestor(#56)));
.

--------------------
	Regression test 19

	Bug: 0.9-3

	Testing method: Test explode() on the failure case.

	Output: Regression test 19
		  ["foo bar ", " quux"]

eval
	log("Regression test 19");
	log("  " + toliteral(explode("foo bar baz quux", "baz")));
.

--------------------
	Regression test 20

	Bug: 0.9-4

	Testing method: Test chparents() on root.  Also test
		chparents() on setting an object to have itself as a
		parent.

	Output: Regression test 20
		  chparents($root, [$testobj1]) --> ~perm
		  chparents($testobj1, [$testobj1]) --> ~parent

eval
	log("Regression test 20");
	log("  chparents($root, [$testobj1]) --> " + toliteral((| chparents($root, [$testobj1]) |)));
	log("  chparents($testobj1, [$testobj1]) --> " + toliteral((| chparents($testobj1, [$testobj1]) |)));
.

--------------------
	Regression test 21

	Bug: 0.9-5

	Testing method: Test explode() with a zero-length separator.

	Output: Regression test 21
		  explode("foo bar", "") --> ~range

eval
	log("Regression test 21");
	log("  explode(\"foo bar\", \"\") --> " + toliteral((| explode("foo bar", "") |)));
.

--------------------
	Regression test 22

	Bug: 0.9-6

	Testing method: Run tostr() on a dictionary.

	Output: Regression test 22
		  tostr(#[]) --> "<dict>"

eval
	log("Regression test 22");
	log("  tostr(#[]) --> " + toliteral(tostr(#[])));
.

--------------------
	Regression test 23

	Bug: 0.9-7

	Testing method: Run the failure case.

	Output: Regression test 23
		  2
eval
	var a, b;

	log("Regression test 23");
	a = dict_add(#[], 1, 2);
	b = a;
	b = dict_del(b, 1);
	log("  " + toliteral(a[1]));
.

--------------------
	Regression test 24

	Bug: 0.9-8

	Testing method: Run echo(), look at result.

	Output: Regression test 24
		  echo(`[1, 2]) --> 1

eval
	log("Regression test 24");
	log("  echo(`[1, 2]) --> " + toliteral(echo(`[1, 2])));
.

--------------------
	Regression test 25

	Bug: 0.9-14

	Testing method: Exercise delete() on a sublist.

	Output: Regression test 25
		  [2, 4, 5]
eval
	log("Regression test 25");
	log("  " + toliteral(delete(sublist([1, 2, 3, 4, 5], 2), 2)));
.

--------------------
	Regression test 26

	Bug: 0.9-15

	Testing method: Build a dictionary with duplicates.

	Output: Regression test 26
		  #[[1, 2], [2, 3], [3, 4]]

eval
	log("Regression test 26");
	log("  " + toliteral(#[[1, 2], [1, 3], [2, 3], [3, 4]]));
.

--------------------
	Shut down the server
eval
	shutdown();
.