X-Git-Url: https://ocean-lang.org/code/?p=ocean;a=blobdiff_plain;f=csrc%2Foceani-tests.mdc;h=dccfb2a47bc2bdb50f7f3a39e7c3adf09ccf1b01;hp=8a5e74708e9385f77fbec661823233a824dd246a;hb=84f4783c47a0fcb74b7f46d3ff96fe8a3ad1b278;hpb=712fec2bb9a25d6f196e2d3565f51234e9f8cfd0 diff --git a/csrc/oceani-tests.mdc b/csrc/oceani-tests.mdc index 8a5e747..dccfb2a 100644 --- a/csrc/oceani-tests.mdc +++ b/csrc/oceani-tests.mdc @@ -54,9 +54,16 @@ arguments separated from the name by commas. For each test, there is a section echo -n "printing.. "; \ echo '``````' > .tmp.code1; echo '``````' > .tmp.code2 ;\ ./oceani --noexec --print --section "test: $$t" oceani-tests.mdc >> .tmp.code1; \ - ./oceani --noexec --print .tmp.code1 >> .tmp.code2 ;\ + ./oceani --noexec --print .tmp.code1 >> .tmp.code2 || exit 1;\ if ! cmp -s .tmp.code1 .tmp.code2; then \ echo " Failed"; diff -u .tmp.code1 .tmp.code2; exit 1 ; fi ; \ + echo -n "extra-newlines.. "; \ + sed -e 'i\ + ' .tmp.code1 > .tmp.code1a; \ + echo '``````' > .tmp.code2a ;\ + ./oceani --noexec --print .tmp.code1a >> .tmp.code2a || exit 1;\ + if ! cmp -s .tmp.code1 .tmp.code2a; then \ + echo " Failed"; diff -u .tmp.code1 .tmp.code2a; exit 1; fi ; \ echo -n "exec-after-print.. "; \ ./oceani .tmp.code1 $${1+"$$@"} > .tmp.have ; \ if ! cmp -s .tmp.want .tmp.have; then \ @@ -68,15 +75,16 @@ arguments separated from the name by commas. For each test, there is a section ## test code + @for i in coverage/#*.gcda; do mv $$i coverage/$${i##*#}; done @gcov -o coverage oceani.mdc > /dev/null 2> /dev/null - @mv *.gcov coverage ; [ -f .gcov ] && mv .gcov coverage + @mv *.gcov coverage ; [ -f .gcov ] && mv .gcov coverage || true @ awk '/NOTEST/ { next } /^ *[1-9]/ {ran+=1} /^ *###/ {skip+=1} \ END {printf "coverage: %6.2f%%\n", ran * 100 / (ran + skip); \ - if (ran < (ran + skip) *0.94) exit(1) }' \ + if (ran < (ran + skip) *0.959) exit(1) }' \ coverage/oceani.mdc.gcov @rm -f .tmp* - @for T in $(oceani_tests); do \ + @[ -n "$$SKIP_VALGRIND" ] || for T in $(oceani_tests); do \ echo -n "Valgrind $$T.. "; \ i="$$IFS"; IFS=,; set $$T; IFS="$$i"; t=$$1; shift; \ if ! valgrind --error-exitcode=1 --log-file=.tmp.valg ./oceani --section "test: $$t" oceani-tests.mdc $${1+"$$@"} \ @@ -102,7 +110,9 @@ calculations on them. ###### test: valvar - program: + func main + argv:[argc::]string + do a := 23; b:=12 ; b1 := -b print a, b, a+b, a-b, a*b, a/b, a%b print ab, a>=b, a 0.000000001 - do: + do guess = (guess + (target / guess) ) / 2 print count, guess count = count + 1 @@ -228,13 +251,30 @@ Now we need to test if/else and some different loops for j:=0; then j = j+3 ; while j < 10: if j != 0 and then 20 / j > 3: print "20 /", j," =", 20 / j - else: + else print "I won't calculate 20 /", j pi ::= 3.1415926535897 if 355/113 == pi or else +(pi - 355/113) < 0.001: print "Close enough" print "lower" if 355/113 < pi else "higher" + if pi > 3 then print "pi exceeds three"; else print "need more pie" + if (pi < 3) { print "not enough pi" } else { print "pi sufficient" } + for { i := 0; sum := 0 } + then { i = i+1 } + while i <= 10: + sum = sum + i + else + pass + print "sum 1..10 is", sum + if + PI1 := 22/7 + use PI1 < pi + then + print "Smaller" + else + print 'larger' + ###### output: cond_loop Success 1 2 4 8 16 32 64 @@ -249,6 +289,10 @@ Now we need to test if/else and some different loops I won't calculate 20 / 9 Close enough higher + pi exceeds three + pi sufficient + sum 1..10 is 55 + larger ## Say Hello @@ -261,14 +305,17 @@ Here I break it into two parts, keeping the array code separate. ###### test: sayhello - program A B astr bbool: + func main(av:[ac::number]string) + A := $av[1]; B := $av[2] + astr := av[3] + bbool := av[ac-1] == "True" print "Hello World, what lovely oceans you have!" /* When a variable is defined in both branches of an 'if', * and used afterwards, the variables are merged. */ if A > B: bigger := "yes" - else: + else bigger := "no" print "Is", A, "bigger than", B,"? ", bigger /* If a variable is not used after the 'if', no @@ -277,26 +324,27 @@ Here I break it into two parts, keeping the array code separate. if A > B * 2: double:string = "yes" print A, "is more than twice", B, "?", double - else: + else double := B*2 print "double", B, "is", double a : number a = A; b:number = B + print "still", bigger // check for regression in scoping if a > 0 and b > 0: while a != b: if a < b: b = b - a - else: + else a = a - b print "GCD of", A, "and", B,"is", a else if a <= 0: print a, "is not positive, cannot calculate GCD" - else: + else print b, "is not positive, cannot calculate GCD" - for: + for togo := 10 f1 := 1; f2 := 1 print "Fibonacci:", f1,f2, @@ -310,34 +358,36 @@ Here I break it into two parts, keeping the array code separate. if bbool: print astr ++ " was the str" - else: + else print "I found the str over " ++ astr /* Binary search... */ - for: + for lo:= 0; hi := 100 target := 77 - while: + while mid := (lo + hi) / 2 if mid == target: use Found if mid < target: lo = mid - else: + else hi = mid if hi - lo < 1: + lo = mid use GiveUp use True - do: pass + do pass case Found: print "Yay, I found", target case GiveUp: - print "Closest I found was", mid + print "Closest I found was", lo ###### output: sayhello,55,33,hello,True Hello World, what lovely oceans you have! Is 55 bigger than 33 ? yes double 33 is 66 + still yes GCD of 55 and 33 is 11 Fibonacci: 1 1 2 3 5 8 13 21 34 55 89 144 hello was the str @@ -347,6 +397,7 @@ Here I break it into two parts, keeping the array code separate. Hello World, what lovely oceans you have! Is 12 bigger than 60 ? no double 60 is 120 + still no GCD of 12 and 60 is 12 Fibonacci: 1 1 2 3 5 8 13 21 34 55 89 144 I found the str over there @@ -355,7 +406,7 @@ Here I break it into two parts, keeping the array code separate. ###### test list oceani_tests += "insert_sort" ###### test: insert_sort - program: + func main() size::=55 list:[size]number list[0] = 1_234 @@ -501,7 +552,7 @@ ad-hoc things array related. ###### test: arrays - program: + func main() bools:[5]Boolean strings:[4]string @@ -509,11 +560,15 @@ ad-hoc things array related. bools[1] = strings[2] <= "there" for i:=0; then i=i+1; while i<5: - print '', bools[i], + j ::= i + ra:[j]number + ra[i-1] = i*i + ra[6] = 42 // mustn't crash + print '', bools[i], ra[j-1], print ###### output: arrays - False True False False False + False 0 True 1 False 4 False 9 False 16 ## Structures @@ -524,14 +579,16 @@ Time to test if structure declarations and accesses work correctly. ###### test: structs - struct foo: - size:[3]number + const three ::= 3 + struct foo + size:[three]number name:string - active:Boolean + active:Boolean = True struct baz { a:number; b:Boolean; } - program: + func main + do info:[4]foo for i:=0; then i=i+1; while i < 4: @@ -539,11 +596,12 @@ Time to test if structure declarations and accesses work correctly. case 2: nm:= "peter" case 0: nm:= "bob" case 1: nm:= "jane" - else: nm:= "janine" + else nm:= "janine" info[i].name = nm info[i].size[0] = i*i - info[i].active = nm == "jane" + if nm != "jane": + info[i].active = False for i:=0; then i=i+1; while i < 4: print info[i].name, info[i].active, info[i].size[0] @@ -591,14 +649,14 @@ separate file first, then run from there. ###### test: syn1 - program: + func main() if then else while do ###### output: syn1 .tmp.code:3:11: Syntax error in statement: then ###### test: tokerr - program: + func main() a := 1i // imaginary numbers aren't understood b:[2i]number // array sizes are handled separately c:[3.14159]Boolean // array sizes must be integers @@ -648,7 +706,7 @@ various places that `type_err()` are called. ###### test: type_err1 - program: + func main() print "hello" ++ 5, 5 ++ "hello" b ::= 3 @@ -668,7 +726,7 @@ various places that `type_err()` are called. ###### test: type_err2 - program: + func main() a := 1 a := 2 a ::= 3 @@ -689,11 +747,11 @@ various places that `type_err()` are called. ###### test: type_err3 - struct foo: + struct foo a: number b:string = "hello" - program: + func main() c := "hello" c = c + 1 c = "hello" ++ (True and False) @@ -701,11 +759,11 @@ various places that `type_err()` are called. print 45 + ( "Hello" ++ "there") c[5] = 1 - while: + while use 1 use True use "Hello" - do: + do print case 1: print "one" case "Hello": print "Hello" @@ -721,6 +779,14 @@ various places that `type_err()` are called. bar:foo foo.c = 43 print c.foo + print bar.c + print bar.b + 42 + + + // trigger 'labels not permitted' error message + while 1 if True else False: + print + case 2: print "two" ###### output: type_err3 .tmp.code:8:12: error: expected number but variable 'c' is string @@ -750,10 +816,13 @@ various places that `type_err()` are called. .tmp.code:32:8: error: field reference attempted on none, not a struct .tmp.code:32:16: error: expected none found number .tmp.code:33:14: error: field reference attempted on string, not a struct + .tmp.code:34:14: error: cannot find requested field in foo + .tmp.code:35:17: error: have string but need number + .tmp.code:39:29: error: expected number (labels not permitted) found Boolean oceani: type error in program - not running. ###### test: type_err4 - program: + func main() a:=1; b=2; c::=3 print a, b, c @@ -764,30 +833,38 @@ various places that `type_err()` are called. oceani: type error in program - not running. ###### test list - oceani_failing_tests += type_err_const type_err_const1 + oceani_failing_tests += type_err_const type_err_const1 missing_program ###### test: type_err_const - const: + const foo :: number = 45 bar ::= "string" + 56 - const: + const bar ::= "baz" - program: + func main() foo := 4 print foo, bar + // trigger duplicate-main error + func main() + foo := 6 + print bar, foo + ###### output: type_err_const .tmp.code:4:16: error: expected number found string .tmp.code:6:8: error: name already declared: bar .tmp.code:4:8: info: this is where 'bar' was first declared .tmp.code:8:8: error: variable 'foo' redeclared .tmp.code:3:8: info: this is where 'foo' was first declared + .tmp.code:13:8: error: variable 'foo' redeclared + .tmp.code:3:8: info: this is where 'foo' was first declared + .tmp.code:13:8: "main" defined a second time ###### test: type_err_const1 - const: + const foo : number = 45 bar := "string" - program: + func main() foo := 4 print foo, bar @@ -795,6 +872,13 @@ various places that `type_err()` are called. .tmp.code:3:12: Syntax error in constant: : .tmp.code:4:12: Syntax error in constant: : +###### test: missing_program + const + foo::="bar" + +###### output: missing_program + oceani: no main function found. + ## Test erroneous command line args To improve coverage, we want to test correct handling of strange command @@ -829,7 +913,7 @@ command list possible. ###### output: cmd,-zyx ./oceani: invalid option -- 'z' - Usage: oceani --trace --print --noexec --brackets--section=SectionName prog.ocn + Usage: oceani --trace --print --noexec --brackets --section=SectionName prog.ocn ###### output: cmd,nofile oceani: cannot open nofile