New tests

added new tests,
modified old tests to have all non-japl code commented, so they can be
also ran using jpl
modified verbose to use the new -e flag instead of --stdout, so it
doesn't spam
This commit is contained in:
Productive2 2021-02-28 14:10:17 +01:00
parent 2e00dd181f
commit 88b4fa0d3a
47 changed files with 300 additions and 180 deletions

View File

@ -196,7 +196,7 @@ def build(path: str, flags: Optional[Dict[str, str]] = {}, options: Optional[Dic
logging.debug("Running tests")
start = time()
# TODO: Find a better way of running the test suite
process = run_command(f"{tests_path} {'--stdout' if verbose else ''}", mode="run", shell=True, stderr=PIPE)
process = run_command(f"{tests_path} {'-e' if verbose else ''}", mode="run", shell=True, stderr=PIPE)
if status != 0:
logging.error(f"Command '{command}' exited with non-0 exit code {status}, output below:\n{stderr.decode()}")
return False

View File

@ -1,6 +1,8 @@
/*
[Test: all]
[skip]
[source: mixed]
*/
//[source: mixed]
// Example file to test JAPL's syntax
// Mathematical expressions
@ -140,5 +142,5 @@ mark.greet();
"implicit start"[:5]; // From 0 to 5
"hello" + " world"; // Strings are immutable!
"hello" * 3; //hellohellohello
[end]
[end]
//[end]
//[end]

View File

@ -1,5 +1,5 @@
[Test: arithmetic]
[source: mixed]
//[Test: arithmetic]
//[source: mixed]
//int arithmetic
print(7+5); //stdout:12
@ -34,5 +34,5 @@ print(64/-64);//stdout:-1.0
print(8/0);//stdout:inf
print(8/-0);//stdout:inf
print(-8/0);//stdout:-inf
[end]
[end]
//[end]
//[end]

View File

@ -0,0 +1,8 @@
//[Test: assignment expressions]
//[source: mixed]
var x;
var a = x = 5;
print(x);//stdout:5
print(a);//stdout:5
//[end]
//[end]

View File

@ -1,5 +1,5 @@
[Test: bitwise]
[source: mixed]
//[Test: bitwise]
//[source: mixed]
print(~5 | 5);//stdout:-1
print(1 | 2);//stdout:3
print(1 & 2);//stdout:0
@ -9,5 +9,5 @@ print(32 | 64);//stdout:96
print(96 & 32);//stdout:32
print(~0);//stdout:-1
print(~356);//stdout:-357
[end]
[end]
//[end]
//[end]

View File

@ -1,5 +1,5 @@
[Test: booleans]
[source: mixed]
//[Test: booleans]
//[source: mixed]
print(2 or 3);//stdout:2
print(2 and 3);//stdout:3
print(false or true);//stdout:true
@ -21,5 +21,5 @@ print(not false);//stdout:true
print(not 1);//stdout:false
print(not 1 and not 2);//stdout:false
print(not (1 and false));//stdout:true
[end]
[end]
//[end]
//[end]

View File

@ -1,5 +1,7 @@
/*
[Test: callchain]
[source: mixed]
*/
//[source: mixed]
fun add2(x)
{
return x + 2;
@ -14,8 +16,10 @@ fun mul2(x)
}
print(add2(sub2(mul2(sub2(5)))));
//5-2=3
//3*2=6
//stdout:6
//[end]
/*
[stdout]
6
[end]
[end]
*/

View File

@ -1,5 +1,5 @@
[Test: comparisons]
[source: mixed]
//[Test: comparisons]
//[source: mixed]
var x = 4;
var y = 5;
var z = 6;
@ -42,5 +42,25 @@ if (8 <= z)
print("15");
else
print("16");//stdout:16
[end]
[end]
//[end]
//[end]
//[Test: multicomparisons]
//[skip]
//[source: mixed]
var x = 2 < 3 < 4;
print(x);//stdout:4
x = 1 > 3 < 5;
print(x);//stdout:false
x = 1 >= 0 >= 0;
print(x);//stdout:0
if ( 4 < x < 6 ) {
print("inside");
} else {
print("outside");//stdout:outside
}
//[end]
//[end]

View File

@ -1,5 +1,5 @@
[Test: compile_time_intern]
[source: mixed]
//[Test: compile_time_intern]
//[source: mixed]
//compile time interning
var a = "hello";
@ -11,6 +11,6 @@ print(a is b);//stdout:true
var x = "ex";
var y = "ey";
print(x is y);//stdout:false
[end]
[end]
//[end]
//[end]

View File

@ -1,8 +1,8 @@
[Test: read_in_own_init_regex]
[source: raw]
//[Test: read_in_own_init_regex]
//[source: raw]
var a = 1; { var a = a; }
[end]
[stderr: re]
[[^\-]*-> cannot read local variable in its own initializer
[end]
[end]
//[end]
//[end]

View File

@ -1,10 +1,12 @@
[Test: undefname_raw]
[source: raw]
//[Test: undefname_raw]
//[source: raw]
var a = b;
[end]
//[end]
/*
[stderr]
An unhandled exception occurred, traceback below:
File '''', line 1, in <module>:
ReferenceError: undefined name 'b'
[end]
[end]
*/
//[end]

View File

@ -1,10 +1,12 @@
[Test: unsup_binary_instr]
[source: raw]
//[Test: unsup_binary_instr]
//[source: raw]
var a = 2 + "hey";
[end]
//[end]
/*
[stderr]
An unhandled exception occurred, traceback below:
File '''', line 1, in <module>:
TypeError: unsupported binary operator '+' for objects of type 'integer' and 'string'
[end]
[end]
*/
//[end]

View File

@ -1,5 +1,5 @@
[Test: problem1]
[source: mixed]
//[Test: problem1]
//[source: mixed]
// Task: find the multiples of 3 and 5 below 1000, find their sum
var sum = 0;
@ -11,5 +11,5 @@ for (var x = 3; x < 1001; x = x + 1)
}
}
print(sum);//stdout:234168
[end]
[end]
//[end]
//[end]

View File

@ -1,5 +1,5 @@
[Test: problem2]
[source: mixed]
//[Test: problem2]
//[source: mixed]
// Sum of even valued fibonacci numbers that don't exceed 4M
var a = 1;
@ -16,5 +16,5 @@ while (a < 4000000)
b = c;
}
print(sum);//stdout:4613732
[end]
[end]
//[end]
//[end]

View File

@ -1,6 +1,6 @@
[Test: problem4]
[skip]
[source: mixed]
//[Test: problem4]
//[skip]
//[source: mixed]
// Find the largest palindrome that is a product of two 3 digit numbers
fun isPalindrome(n)
@ -66,5 +66,5 @@ for (var i = 100; i < 1000; i = i + 1)
}
}
print(largest);
[end]
[end]
//[end]
//[end]

View File

@ -1,10 +1,10 @@
[Test: for]
[source: mixed]
//[Test: for]
//[source: mixed]
for (var x = 0; x < 2; x = x + 1)
{
print(x);
//stdout:0
//stdout:1
}
[end]
[end]
//[end]
//[end]

View File

@ -1,6 +1,6 @@
[Test: forwithfunction]
[skip]
[source: mixed]
//[Test: forwithfunction]
//[skip]
//[source: mixed]
var y = 0; //a global to keep track of state
//does not need closures for this to work yet
@ -84,5 +84,5 @@ for (var i = 0; i != -1; i = next(i))
// y = 9
//stdout:10
// y = 10
[end]
[end]
//[end]
//[end]

View File

@ -1,15 +1,17 @@
[Test: hellojapl]
[source: mixed]
//[Test: hellojapl]
//[source: mixed]
print("Hello, JAPL.");
//stdout:Hello, JAPL.
[end]
[end]
//[end]
//[end]
[Test: hello_second_way]
[source: raw]
//[Test: hello_second_way]
//[source: raw]
print("Hello, JAPL.");
[end]
//[end]
/*
[stdout]
Hello, JAPL.
[end]
[end]
*/
//[end]

View File

@ -1,5 +1,5 @@
[Test: if]
[source: mixed]
//[Test: if]
//[source: mixed]
var x = 5;
if (x > 2)
{
@ -28,5 +28,5 @@ if (2 == x)
print("2");
else
print("not 2");//stdout:not 2
[end]
[end]
//[end]
//[end]

View File

@ -1,5 +1,5 @@
[Test: ifchain]
[source: mixed]
//[Test: ifchain]
//[source: mixed]
fun printInt(x) {
if (x == 1)
print("one");
@ -22,5 +22,5 @@ x = 7;
printInt(x);
x = 1;
printInt(x);//stdout:one
[end]
[end]
//[end]
//[end]

View File

@ -1,8 +1,10 @@
/*
[Test: inputtesttwo]
[source: raw]
*/
//[source: raw]
print(readLine());
[end]
//[end]
/*
[stdin]
Hello world!
[end]
@ -11,3 +13,4 @@ Hello world!
Hello world!
[end]
[end]
*/

View File

@ -1,5 +1,5 @@
[Test: is]
[source:mixed]
//[Test: is]
//[source:mixed]
var x = 4;
var y = x;
@ -21,5 +21,5 @@ print((l is z) is l);//stdout:true
var k;
print(k is nil);//stdout:true
[end]
[end]
//[end]
//[end]

View File

@ -1,21 +0,0 @@
[Test: lambdachain]
[source: mixed]
var add2 = lambda(x)
{
return x + 2;
};
var sub2 = lambda(x)
{
return x - 2;
};
var mul2 = lambda(x)
{
return x * 2;
};
print(add2(sub2(mul2(sub2(5)))));
//5-2=3
//3*2=6
//stdout:6
[end]
[end]

50
tests/japl/lambdas.jpl Normal file
View File

@ -0,0 +1,50 @@
/*
[Test: lambdachain]
*/
//[source: raw]
var add2 = lambda(x)
{
return x + 2;
};
var sub2 = lambda(x)
{
return x - 2;
};
var mul2 = lambda(x)
{
return x * 2;
};
print(add2(sub2(mul2(sub2(5)))));
//[end]
/*
[stdout]
6
[end]
[end]
[Test: simple lambdas]
*/
//[source: raw]
var identity = lambda(x) { return x; };
var comparison = lambda(x, y) {
if (x > y) {
return x;
} else {
return y;
}
};
var max = lambda(x, y, z) { return identity(comparison(comparison(x, y), z)); };
print(max(1, 5, 6));
print(max(6, 2, 9));
print(max(1.3, 7, 9.0));
print(max(-4, 3, 2));
//[end]
/*
[stdout]
6
9
9.0
3
[end]
[end]
*/

View File

@ -1,5 +1,5 @@
[Test: constant_long]
[source: mixed]
//[Test: constant_long]
//[source: mixed]
// Test for constants
var v_1 = 1;
@ -130,5 +130,5 @@ var v_125 = 1;
var v_126 = 1;
var v_127 = 1;
var v_128 = 1;
[end]
[end]
//[end]
//[end]

View File

@ -1,5 +1,5 @@
[Test: glob_assgn_read]
[source: mixed]
//[Test: glob_assgn_read]
//[source: mixed]
var a0 = 451;
var a1 = 5098;
var a2 = 469;
@ -1501,5 +1501,5 @@ print(a151);//stdout:4839
print(a975);//stdout:7651
print(a7);//stdout:2979
print(a661);//stdout:8235
[end]
[end]
//[end]
//[end]

View File

@ -1,5 +1,5 @@
[Test: glob_with_sets]
[source: mixed]
//[Test: glob_with_sets]
//[source: mixed]
var a0 = 829;
var a1 = 6820;
var a2 = 114;
@ -5238,5 +5238,5 @@ print(a87);//stdout:1282
print(a445);//stdout:1726
print(a790);//stdout:1140
print(a961);//stdout:1708
[end]
[end]
//[end]
//[end]

View File

@ -1,5 +1,5 @@
[Test: loc_assgn_read]
[source: mixed]
//[Test: loc_assgn_read]
//[source: mixed]
{
var a0 = 9103;
var a1 = 4565;
@ -1503,5 +1503,5 @@ print(a722);//stdout:5380
print(a538);//stdout:8625
print(a809);//stdout:4506
}
[end]
[end]
//[end]
//[end]

View File

@ -1,5 +1,5 @@
[Test: loc_with_sets]
[source: mixed]
//[Test: loc_with_sets]
//[source: mixed]
{
var a0 = 8313;
var a1 = 3509;
@ -5186,5 +5186,5 @@ print(a380);//stdout:2145
print(a125);//stdout:4280
print(a55);//stdout:6992
}
[end]
[end]
//[end]
//[end]

View File

@ -1,4 +1,4 @@
/*
[; This is a comment
This is a comment as well.
@ -17,3 +17,4 @@ the test builder, but it should be a test with
the name "".
[end]
*/

View File

@ -1,19 +1,21 @@
/*
[test: mixed]
[source: mixed]
*/
//[source: mixed]
print("Hello", readLine());
//stdout:Hello world
//stdin:world
print("aaaaaa");
//stdoutre:a*
//matchout:a*
printErr("Hello", readLine());
//stderr:Hello error
//stdin:error
printErr("bbbbbb");
//stderrre:b*
[end]
[end]
//matcherr:b*
//[end]
//[end]

View File

@ -1,12 +1,13 @@
[Test: nw]
[source]
//[Test: nw]
//[source]
print("hey");
print("second line");
printErr("hey there");
print("abcde");
printErr("12345");
printErr("0123456789.");
[end]
//[end]
/*
[stdout: nw]
hey
second line
@ -21,4 +22,5 @@ printErr("0123456789.");
[[0-9]*
[0-9]*.
[end]
[end]
*/
//[end]

View File

@ -1,11 +1,12 @@
[Test: raw]
[source: raw]
//[Test: raw]
//[source: raw]
print("Hi", readLine());
print("aaaaaaa");
printErr("Bye", readLine());
printErr("bbbbbbb");
//stdout:This is not a part of the expected output
[end]
//[end]
/*
[stdin]
person
very important person
@ -23,3 +24,4 @@ Bye very important person
b*
[end]
[end]
*/

View File

@ -1,7 +1,8 @@
[test: skipped]
[skip]
//[test: skipped]
//[skip]
/*
[stdout]
Hello this text won't be matched.
[end]
[end]
*/
//[end]

View File

@ -1,9 +1,11 @@
[Test: nan]
[source: raw]
//[Test: nan]
//[source: raw]
print((5/0)*0);
[end]
//[end]
/*
[stdout]
nan
[end]
[end]
*/
//[end]

13
tests/japl/nested.jpl Normal file
View File

@ -0,0 +1,13 @@
//[Test: nested multiline comments]
//[source: raw]
/* first
/* second
/* third
/* fourth
*/
*/
*/
*/
//[end]
//[end]

13
tests/japl/procedures.jpl Normal file
View File

@ -0,0 +1,13 @@
//[Test: functions without parentheses]
//[source: mixed]
fun sayhi {
print("hi");
}
fun saybye {
print("bye");
}
sayhi();//stdout:hi
saybye();//stdout:bye
//[end]
//[end]

View File

@ -1,5 +1,5 @@
[Test: reassignment]
[source: mixed]
//[Test: reassignment]
//[source: mixed]
{
var x = 5;
var y = x;
@ -25,5 +25,5 @@ fun resetter(x) {
var q = 5;
resetter(q);//stdout:7
print(q);//stdout:5
[end]
[end]
//[end]
//[end]

View File

@ -1,6 +1,6 @@
[Test: runtimeinterning]
[skip]
[source: mixed]
//[Test: runtimeinterning]
//[skip]
//[source: mixed]
//runtime interning
var f = "leafy";
@ -14,5 +14,5 @@ print(h is j);//stdout:true
var x = "ex";
var y = "ey";
print(x is y);//stdout:false
[end]
[end]
//[end]
//[end]

View File

@ -1,5 +1,5 @@
[Test: shadowing]
[source: mixed]
//[Test: shadowing]
//[source: mixed]
//similar to vars.jpl, but more focused on shadowing
// simple shadowing
@ -76,5 +76,5 @@ eat();//stdout:nom nom nom
print(eat);//stdout:5
}
eat();//stdout:nom nom nom
[end]
[end]
//[end]
//[end]

View File

@ -1,5 +1,5 @@
[Test: strings]
[source: mixed]
//[Test: strings]
//[source: mixed]
var left = "left";
var right = "right";
var directions = left + " " + right;
@ -12,5 +12,15 @@ left = left + " side";
print(left);//stdout:left side
right = "side: " + right;
print(right);//stdout:side: right
[end]
[end]
//[end]
//[end]
//[Test: string slicing]
//[skip]
//[source: mixed]
var longstring = "a very long string that will be sliced";
var part = longstring[0:5];
print(part);//stdout:a ver
var part2 = longstring[0..4];
print(part2);//stdout:a ver
//[end]
//[end]

View File

@ -1,5 +1,5 @@
[Test: vars]
[source: mixed]
//[Test: vars]
//[source: mixed]
var x = 1;
var y = 2;
print(x);//stdout:1
@ -30,5 +30,5 @@ longName = "hello";
print(longName); //stdout:hello
longName = longName + " world";
print(longName); //stdout:hello world
[end]
[end]
//[end]
//[end]

View File

@ -1,5 +1,5 @@
[Test: while]
[source: mixed]
//[Test: while]
//[source: mixed]
var x = 5;
while (x > 0)
{
@ -20,5 +20,5 @@ while (x < 10)
string = string + "A";
}
print(string);//stdout:hAAAAAAAAAA
[end]
[end]
//[end]
//[end]

View File

@ -107,6 +107,7 @@ type Buffer* = ref object
## Represents an updateable line on the terminal
contents: string
previous: string
termwidth: int
proc newBuffer*: Buffer =
## Creates a Buffer, hides the cursor
@ -131,6 +132,8 @@ proc updateProgressBar*(buf: Buffer, text: string, total: int, current: int) =
let w = terminalWidth()
if w > newline.len():
newline &= " ".repeat(w - newline.len() - 1)
else:
newline = newline[0..w-2]
buf.contents = newline
proc clearLineAndWrite(text: string, oldsize: int) =

View File

@ -194,8 +194,7 @@ proc buildTests*(testDir: string): seq[Test] =
else:
fatal "test dir/file doesn't exist"
for candidateObj in walkDir(testDir):
let candidate = candidateObj.path
for kind, candidate in walkDir(testDir):
if dirExists(candidate):
log(LogLevel.Debug, &"Descending into dir {candidate}")
result &= buildTests(candidate)

View File

@ -147,13 +147,13 @@ added to add lines to the expected stdout/stderr or
the stdin of the test using the legacy test format.
They are defined by the sequences `//stdout:`,
`//stderr:`, `//stdin:`, `//stdoutre:` and
`//stderrre:`. Every character after the colon and
`//stderr:`, `//stdin:`, `//matchout:` and
`//matcherr:`. Every character after the colon and
before the end of the line is appended to the respective
field of the test. `stdout` adds a raw line to be
matched to the expected stdout of the test. `stdoutre`
matched to the expected stdout of the test. `matchout`
adds a regex to match a line of the stdout of the test.
`stderr` and `stderrre` are the stderr equivalents.
`stderr` and `matcherr` are the stderr equivalents.
`stdin` adds a line to the stdin that the JAPL source
can read from.

View File

@ -71,10 +71,10 @@ proc compileExpectedOutput(source: string, rawkw: string, rekw: string): seq[Exp
result &= genEL(matches[0], ExpectedLineKind.Regex)
proc compileExpectedOutput(source: string): seq[ExpectedLine] =
compileExpectedOutput(source, "stdout", "stdoutre")
compileExpectedOutput(source, "stdout", "matchout")
proc compileExpectedError(source: string): seq[ExpectedLine] =
compileExpectedOutput(source, "stderr", "stderrre")
compileExpectedOutput(source, "stderr", "matcherr")
proc compileInput(source: string): string =
for line in source.split('\n'):