#! -c tests /* This is a simple test suite for the Q interpreter. This is by no means an exhaustive check of the interpreter's internals, but if one of these simple tests fails then there's surely a bug that needs to be fixed. */ /* factorization algorithm, used in one of the tests below */ private factor_from P N; factor 0 = []; factor N:Int = factor (-N) if N<0; = [(2,fact N 2)|factor_from 3 (rem N 2)] if N and 1 = 0; // even number = factor_from 3 N otherwise; factor_from P N = [] if P > N; = [(P,fact N P)|factor_from (P+2) (rem N P)] if N mod P = 0; // P divides N (must be prime) = factor_from (P+2) N otherwise; // not a factor, try the next one /* handle the case that clib fails to load */ exit N:Int = writes "*** ERROR: clib installation problem ***\n" || quit; /* test outcome checker */ test MSG EXPR EXPECT = writes "passed\n" if writes "TEST: " || writes MSG || writes " " || flush || eq EXPR EXPECT; = writes "FAILED\n" || writes "expected: " || write EXPECT || writes "\n" || writes "got: " || write EXPR || writes "\n" || writes "*** TEST FAILED, PLEASE CHECK INSTALLATION ***\n" || exit 1 otherwise; /* test sequence */ private pthread_tests; const a, b, c, x, y, z; var X, Y, I, J; tests = printf "Testing Q %s (%s)\n" (version,sysinfo) || test "local variables........." (2*U+V) 11 || test "arithmetic.............." (1+1,1-2,2*2.0,1/2,sqrt (16.3805*5)/.05) (2,-1,4.0,0.5,181.0) || test "bignums................." (prd [1..25]) 15511210043330985984000000 || test "logical................." (all (>0) [1,2,3] and then any (<0) [1,2-3]) true || test "strings................." ("abc"++"xyz",#"abc","abc"!1) ("abcxyz",3,"b") || test "lists..................." ([a,b,c]++[x,y,z],#[a,b,c],[a,b,c]!1) ([a,b,c,x,y,z],3,b) || test "tuples.................." ((a,b,c)++(x,y,z),#(a,b,c),(a,b,c)!1) ((a,b,c,x,y,z),3,b) || test "streams................." (scanl (+) 0 (iterate (/3) 1) ! 99) 1.5 || test "lambda.................." (lambda (X,Y) (2*X+Y) (3,5)) 11 || test "listof.................." (listof (2*I+J) ((I,J) in [(1,2),(3,4),(5,6)])) [4,10,16] || test "quicksort..............." (sort (<) [3,2,1]) [1,2,3] || test "random number generator." (seed 0 || drop 97 (map (lambda X random) [1..100])) [1863734801,3655850398,52532575] || test "prime test.............." (map isprime [1..15]) [false,true,true,false,true,false,true,false,false,false,true,false,true, false,false] || test "quadratic residues......" (filter (lambda X (jacobi X 7 = 1)) [1..6]) [1,2,4] || test "factorization..........." (factor 807699854836875) [(3,1),(5,4),(7,2),(11,5),(13,2),(17,1),(19,1)] || test "regular expressions....." (regex "g" "[[:space:]]+" "The little\t brown\n fox." regskip ++ [regskip]) ["The","little","brown","fox."] || pthread_tests || writes "*** ALL TESTS HAVE BEEN PASSED ***\n" || exit 0 where (U,V) = (3,5); /* multithreading tests */ try MUT:Mutex = false; pthread_tests = writes "no POSIX threads support, skipping tests\n" if not isthread (thread 1); = sleep 1 || writes "done\n" || test "thread creation........." (result T1) 2 || test "thread cancellation....." (cancel T2, result T2 || active T2, canceled T2) ((), false, true) || test "mutexes................." (lock MUT, try MUT, unlock MUT, try MUT, unlock MUT) ((), false, (), (), ()) || test "conditions.............." (signal COND, result T3) ((), ()) || test "semaphores.............." (do (post SEM) L, #SEM, listof (get SEM) (I in L)) ((), #L, L) where X = writes "preparing POSIX threads tests... " || flush, T1 = thread (return (1+1)), T2 = thread (sleep 5), MUT = mutex, COND = cond, T3 = thread (await COND), SEM = sem, L = [0..99];