X-Git-Url: https://ocean-lang.org/code/?a=blobdiff_plain;f=csrc%2Foceani-tests.mdc;h=5366bf92ddf60e1045c5b0ed3a9bc6bee6cc560f;hb=5b077f5f80cd36fed3b006dd5b0b1cc9025c1b22;hp=d5e60b739236ab9417b19fa11e329d49e1032a22;hpb=6f3c6db8d0e5c5bf244f9a101e72e5e498b5fb6d;p=ocean diff --git a/csrc/oceani-tests.mdc b/csrc/oceani-tests.mdc index d5e60b7..5366bf9 100644 --- a/csrc/oceani-tests.mdc +++ b/csrc/oceani-tests.mdc @@ -38,26 +38,30 @@ arguments separated from the name by commas. For each test, there is a section tests:: oceani_test_suite oceani_test_suite: oceani coverage_oceani + @echo -n Checking grammar ... + @./parsergen --report --LALR --tag Parser oceani.mdc | grep " - no conflicts" > /dev/null || \ + { echo "Grammar contains conflicts, please review" ; exit 1; } + @echo ok @rm -rf coverage; mkdir -p coverage @cp *.gcno coverage @for T in $(oceani_tests); do \ - echo -n "Test $$T ... "; \ + echo -n "Test $$T.. "; \ i="$$IFS"; IFS=,; set $$T; IFS="$$i"; t=$$1; shift; \ ./md2c oceani-tests.mdc "output: $$T" | grep -v '^#' > .tmp.want; \ ./oceani --section "test: $$t" oceani-tests.mdc $${1+"$$@"} > .tmp.have; \ if ! cmp -s .tmp.want .tmp.have; then \ echo "FAILED"; diff -u .tmp.want .tmp.have ; exit 1; fi ;\ - echo -n "passed ... "; \ - if ! valgrind ./oceani --section "test: $$t" oceani-tests.mdc $${1+"$$@"} \ - > /dev/null 2> .tmp.valg; then \ - echo "valgrind FAILED"; cat .tmp.valg; exit 1; fi ; \ - echo -n "valgrind passed ... "; \ + 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 ;\ if ! cmp -s .tmp.code1 .tmp.code2; then \ - echo "Printing Failed"; diff -u .tmp.code1 .tmp.code2; exit1 ; fi ; \ - echo "Printing passed"; \ + echo " Failed"; diff -u .tmp.code1 .tmp.code2; exit 1 ; fi ; \ + echo -n "exec-after-print.. "; \ + ./oceani .tmp.code1 $${1+"$$@"} > .tmp.have ; \ + if ! cmp -s .tmp.want .tmp.have; then \ + echo " FAILED"; diff -u .tmp.want .tmp.have; exit 1;fi; \ + echo " all passed"; \ ./coverage_oceani --print --section "test: $$t" oceani-tests.mdc $${1+"$$@"} > /dev/null ; \ ./coverage_oceani -tpbn --section "test: $$t" oceani-tests.mdc > /dev/null 2>&1; \ done @@ -66,12 +70,25 @@ arguments separated from the name by commas. For each test, there is a section @gcov -o coverage oceani.mdc > /dev/null 2> /dev/null @mv *.gcov coverage ; [ -f .gcov ] && mv .gcov coverage - @ awk '/^ *[1-9]/ {ran+=1} /^ *###/ {skip+=1} \ + @ awk '/NOTEST/ { next } /^ *[1-9]/ {ran+=1} /^ *###/ {skip+=1} \ END {printf "coverage: %6.2f%%\n", ran * 100 / (ran + skip); \ - if (ran < (ran + skip) *0.90) exit(1) }' \ + if (ran < (ran + skip) *0.94) exit(1) }' \ coverage/oceani.mdc.gcov @rm -f .tmp* + @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+"$$@"} \ + > /dev/null 2>&1 ; then \ + echo "FAILED"; cat .tmp.valg; exit 1; fi ; \ + if grep 'LEAK SUMMARY' .tmp.valg > /dev/null; then \ + echo "valgrind found LEAKS"; cat .tmp.valg ; exit 1 ; fi; \ + if grep 'in use at exit [1-9]' .tmp.valg > /dev/null; then \ + echo "valgrind found memory in use at exit"; cat .tmp.valg ; exit 1 ; fi; \ + echo " passed"; \ + done + coverage_oceani: oceani.c $(CC) $(CFLAGS) --coverage -fprofile-dir=coverage -o coverage_oceani oceani.c $(LDLIBS) @@ -83,7 +100,6 @@ calculations on them. ###### test list oceani_tests += "valvar" - ###### test: valvar program: @@ -100,6 +116,13 @@ calculations on them. aconst :: string = "unchanging" + // Check wrapping + print + a + b + + (a*2) + + b1 + + b + ###### output: valvar 23 12 35 11 276 1.91667 11 @@ -107,6 +130,7 @@ calculations on them. 23 12 12 -23 -12 12 False True True False False False This is a string field theory This is a string field theory + 81 Next we change the value of variables @@ -125,6 +149,50 @@ Next we change the value of variables ###### output: setvar 1.07374e+09 1 +Now some contants + +###### test list + oceani_tests += "consts" + +###### test: consts + const: + pi ::= 3.141 592 653 + four ::= 2 + 2 ; five ::= 10/2 + const pie ::= "I like Pie"; + cake ::= "The cake is" + ++ " a lie" + + program: + print "Hello World, what lovely oceans you have!" + print "are there", five, "?" + print pi, pie, "but", cake + +###### output: consts + Hello World, what lovely oceans you have! + are there 5 ? + 3.14159 I like Pie but The cake is a lie + +Test merging of variables from multiple cases + +###### test list + oceani_tests += varmerge + +###### test: varmerge + + program: + for i:=0; then i=i+1; while i < 5: + switch i + case 0: num:="zero" + case 1: num:="one" + case 2: num:="two" + case 3: num:="three" + else: num:="many" + print num,", ", + print + +###### output: varmerge + zero , one , two , three , many , + ## Conditions and Loops Now we need to test if/else and some different loops @@ -188,12 +256,12 @@ The demonstration code presented in the interpreted is suitable for the test sui Here I break it into two parts, keeping the array code separate. ###### test list - oceani_tests += "sayhello,55,33" - oceani_tests += "sayhello,12,60" + oceani_tests += "sayhello,55,33,hello,True" + oceani_tests += "sayhello,12,60,there,False" ###### test: sayhello - program A B: + program A B astr bbool: 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. @@ -240,6 +308,11 @@ Here I break it into two parts, keeping the array code separate. f2 = f3 print "" + if bbool: + print astr ++ " was the str" + else: + print "I found the str over " ++ astr + /* Binary search... */ for: lo:= 0; hi := 100 @@ -261,20 +334,22 @@ Here I break it into two parts, keeping the array code separate. case GiveUp: print "Closest I found was", mid -###### output: sayhello,55,33 +###### output: sayhello,55,33,hello,True Hello World, what lovely oceans you have! Is 55 bigger than 33 ? yes double 33 is 66 GCD of 55 and 33 is 11 Fibonacci: 1 1 2 3 5 8 13 21 34 55 89 144 + hello was the str Closest I found was 77.3438 -###### output: sayhello,12,60 +###### output: sayhello,12,60,there,False Hello World, what lovely oceans you have! Is 12 bigger than 60 ? no double 60 is 120 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 Closest I found was 77.3438 ###### test list @@ -283,7 +358,7 @@ Here I break it into two parts, keeping the array code separate. program: size::=55 list:[size]number - list[0] = 1234 + list[0] = 1_234 for i:=1; then i = i + 1; while i < size: n := list[i-1] * list[i-1] list[i] = (n / 100) % 10000 @@ -440,6 +515,46 @@ ad-hoc things array related. ###### output: arrays False True False False False +## Structures + +Time to test if structure declarations and accesses work correctly. + +###### test list + oceani_tests += structs + +###### test: structs + + struct foo: + size:[3]number + name:string + active:Boolean + + struct baz { a:number; b:Boolean; } + + program: + info:[4]foo + + for i:=0; then i=i+1; while i < 4: + switch i + case 2: nm:= "peter" + case 0: nm:= "bob" + case 1: nm:= "jane" + else: nm:= "janine" + + info[i].name = nm + info[i].size[0] = i*i + info[i].active = nm == "jane" + + for i:=0; then i=i+1; while i < 4: + print info[i].name, info[i].active, info[i].size[0] + +###### output: structs + + bob False 0 + jane True 1 + peter False 4 + janine False 9 + ## Test code with syntax errors Syntax errors aren't handled well yet - the result is almost always a @@ -480,7 +595,7 @@ separate file first, then run from there. if then else while do ###### output: syn1 - .tmp.code:3:11: error: unhandled parse error: then + .tmp.code:3:11: Syntax error in statement: then ###### test: tokerr program: @@ -574,6 +689,10 @@ various places that `type_err()` are called. ###### test: type_err3 + struct foo: + a: number + b:string = "hello" + program: c := "hello" c = c + 1 @@ -599,30 +718,38 @@ various places that `type_err()` are called. a4[1] = True c = a2[3] + bar:foo + foo.c = 43 + print c.foo + ###### output: type_err3 - .tmp.code:4:12: error: expected number but variable 'c' is string - .tmp.code:3:8: info: this is where 'c' was set to string - .tmp.code:4:12: error: Arithmetic returns number but string expected - .tmp.code:3:8: info: variable 'c' was set as string here. - .tmp.code:5:24: error: Boolean operation found where string expected - .tmp.code:6:12: error: Comparison returns Boolean but string expected - .tmp.code:3:8: info: variable 'c' was set as string here. - .tmp.code:7:21: error: Concat returns string but number expected - .tmp.code:8:8: error: string cannot be indexed - .tmp.code:8:8: error: string cannot be indexed - .tmp.code:17:13: error: expected number found string - .tmp.code:13:16: error: expected number, found string - .tmp.code:20:8: error: cannot assign value of type [5]number - .tmp.code:21:13: error: expected [5]number but variable 'a3' is [10]number - .tmp.code:19:36: info: this is where 'a3' was set to [10]number - .tmp.code:21:8: error: cannot assign value of type [5]number - .tmp.code:22:13: error: expected [5]number but variable 'a4' is [5]string - .tmp.code:19:51: info: this is where 'a4' was set to [5]string - .tmp.code:22:8: error: cannot assign value of type [5]number - .tmp.code:23:16: error: expected number found string - .tmp.code:24:16: error: expected string found Boolean - .tmp.code:25:12: error: have number but need string - .tmp.code:3:8: info: variable 'c' was set as string here. + .tmp.code:8:12: error: expected number but variable 'c' is string + .tmp.code:7:8: info: this is where 'c' was set to string + .tmp.code:8:12: error: Arithmetic returns number but string expected + .tmp.code:7:8: info: variable 'c' was set as string here. + .tmp.code:9:24: error: Boolean operation found where string expected + .tmp.code:10:12: error: Comparison returns Boolean but string expected + .tmp.code:7:8: info: variable 'c' was set as string here. + .tmp.code:11:21: error: Concat returns string but number expected + .tmp.code:12:8: error: string cannot be indexed + .tmp.code:12:8: error: string cannot be indexed + .tmp.code:21:13: error: expected number found string + .tmp.code:17:16: error: expected number, found string + .tmp.code:24:8: error: cannot assign value of type [5]number + .tmp.code:25:13: error: expected [5]number but variable 'a3' is [10]number + .tmp.code:23:36: info: this is where 'a3' was set to [10]number + .tmp.code:25:8: error: cannot assign value of type [5]number + .tmp.code:26:13: error: expected [5]number but variable 'a4' is [5]string + .tmp.code:23:51: info: this is where 'a4' was set to [5]string + .tmp.code:26:8: error: cannot assign value of type [5]number + .tmp.code:27:16: error: expected number found string + .tmp.code:28:16: error: expected string found Boolean + .tmp.code:29:12: error: have number but need string + .tmp.code:7:8: info: variable 'c' was set as string here. + .tmp.code:32:8: error: variable used but not declared: foo + .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 oceani: type error in program - not running. ###### test: type_err4 @@ -631,14 +758,43 @@ various places that `type_err()` are called. print a, b, c ###### output: type_err4 - .tmp.code:3:14: error: expected *unknown*type* (labels not permitted) but variable 'b' is label - .tmp.code:3:14: info: this is where 'b' was set to label - .tmp.code:3:16: error: expected label found number - .tmp.code:3:14: info: variable 'b' was set as label here. - .tmp.code:4:17: error: expected *unknown*type* (labels not permitted) but variable 'b' is label - .tmp.code:3:14: info: this is where 'b' was set to label + .tmp.code:3:14: error: variable used but not declared: b + .tmp.code:3:16: error: expected none found number + .tmp.code:3:14: info: variable 'b' was set as none here. oceani: type error in program - not running. +###### test list + oceani_failing_tests += type_err_const type_err_const1 + +###### test: type_err_const + const: + foo :: number = 45 + bar ::= "string" + 56 + const: + bar ::= "baz" + program: + foo := 4 + print foo, bar + +###### 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 + +###### test: type_err_const1 + const: + foo : number = 45 + bar := "string" + program: + foo := 4 + print foo, bar + +###### output: type_err_const1 + .tmp.code:3:12: Syntax error in constant: : + .tmp.code:4:8: Syntax error in constant: bar + ## Test erroneous command line args To improve coverage, we want to test correct handling of strange command @@ -661,7 +817,6 @@ command list possible. ./coverage_oceani $${1+"$$@"} > /dev/null 2>&1 ;\ done || true - ###### test list oceani_special_tests += "cmd" oceani_special_tests += "cmd,-zyx" @@ -684,4 +839,3 @@ command list possible. ###### output: cmd,--section,toast:nothing,oceani-tests.mdc oceani: cannot find section toast:nothing -