From aa1914c32f7a14053c21c3a58091cf474af7ceb0 Mon Sep 17 00:00:00 2001 From: Aaron Taylor Date: Sat, 28 Mar 2020 00:33:05 -0700 Subject: [PATCH] Updates to `stdlib_tests/` for release. Added stdlib function to print the version of the stdlib. Added test early in the test sequence to check stdlib version. Added license headers to relevant files. Updated `vv_test.py` to print more information when a test fails. Added comments and updated README. --- stdlib/README.md | 1 + stdlib/debug.pvvs | 15 +++ stdlib_tests/0002_stdlib_version.pvvs | 6 + ...{0002_dumpheap.pvvs => 0003_dumpheap.pvvs} | 0 stdlib_tests/Makefile | 2 +- stdlib_tests/README.md | 113 +++++++++++++++++- stdlib_tests/vv_test.py | 20 +++- 7 files changed, 149 insertions(+), 8 deletions(-) create mode 100644 stdlib_tests/0002_stdlib_version.pvvs rename stdlib_tests/{0002_dumpheap.pvvs => 0003_dumpheap.pvvs} (100%) diff --git a/stdlib/README.md b/stdlib/README.md index eb92964..ebf8323 100644 --- a/stdlib/README.md +++ b/stdlib/README.md @@ -71,6 +71,7 @@ header comment for each function to learn the call and return stack. 111011 ----- print magnitude (debug.pvvs) 111100 ----- print string (debug.pvvs) 111101 ----- print signed number (debug.pvvs) + 111110 ----- stdlib version (debug.pvvs) 1xxxxxx - reserved for less common entry points 1000000 ----- lowbitand (logic.pvvs) 1000001 ----- diff --git a/stdlib/debug.pvvs b/stdlib/debug.pvvs index 4114d22..d272b6c 100644 --- a/stdlib/debug.pvvs +++ b/stdlib/debug.pvvs @@ -221,4 +221,19 @@ NSTTTTSTSN | JSR > 111010 (debug:printsign) NSTTTTSTTN | JSR > 111011 (debug:printmagnitude) NTN | RTS +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@ Name: +@ stdlib_version (111110) +@ Description: +@ Returns the version of the stdlib. +@ The version number should be a monotonically increasing integer. +@ Call Stack: +@ <-- TOS +@ Return Stack: +@ version_number <-- TOS +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +NSSVTTTTTSN | Mark: 111110 (debug:printsignednumber) +SSSTN | PUSH 1 (version) +NTN | RTS + #endif diff --git a/stdlib_tests/0002_stdlib_version.pvvs b/stdlib_tests/0002_stdlib_version.pvvs new file mode 100644 index 0000000..be77436 --- /dev/null +++ b/stdlib_tests/0002_stdlib_version.pvvs @@ -0,0 +1,6 @@ +NSTTTTTTSN | JSR > 111110 (stdlib_version) +SSSTN | PUSH 1 (count) +NSTTTTSSTN | JSR > 111001 (dumpstack) +NNN | DIE + +#include diff --git a/stdlib_tests/0002_dumpheap.pvvs b/stdlib_tests/0003_dumpheap.pvvs similarity index 100% rename from stdlib_tests/0002_dumpheap.pvvs rename to stdlib_tests/0003_dumpheap.pvvs diff --git a/stdlib_tests/Makefile b/stdlib_tests/Makefile index b55caaa..e96a7b6 100644 --- a/stdlib_tests/Makefile +++ b/stdlib_tests/Makefile @@ -1,5 +1,5 @@ # (c) 2019 Aaron Taylor -# All rights reserved. +# See LICENSE.txt file for copyright and license details. all: test diff --git a/stdlib_tests/README.md b/stdlib_tests/README.md index 7db3ffc..146cddc 100644 --- a/stdlib_tests/README.md +++ b/stdlib_tests/README.md @@ -1,3 +1,112 @@ -This folder contains tests for the VVS stdlib that are called from `vv_test.py`. +# Overview # + +This folder contains tests for the VVhitespace standard library ('stdlib'). + + +# Instructions # + +Edit the shebang in `vv_test.py` to match your environment. For example: + + FreeBSD 12: #!/usr/local/bin/python3.6 + Debian 9 : #!/usr/bin/python3 + +Build `vvc` and `vvi` in the source tree, if you haven't already. + + vvs-repo/stdlib_tests % cd .. && make clean all && cd stdlib_tests + cc -Wall -std=c99 -o vvc vv_compiler.c + cc -Wall -std=c99 -o vvi vv_interpreter.c + vvs-repo/stdlib_tests % + +Alternatively, edit the configuration block in `vv_test.py` to provide +appropriate paths relative to this `stdlib_tests` folder. + + compiler_path = '../vvc' + interpreter_path = '../vvi' + include_path = '-I../stdlib' + +With configuration now complete, execute the tests via `make test`. A dot will +appear for every successfully completed test. For example: + + vvs-repo/stdlib_tests % make test + Testing stdlib: + .................................. + vvs-repo/stdlib_tests % + +If a test should fail, the name of the test will be printed in place of its +dot. For example, by breaking the `and` subroutine, the corresponding test +fails for `and` and for all subroutines which depend on `and`. + + vvs-repo/stdlib_tests % make test + Testing stdlib: + ................ + 3004_and + Expected: +0+0+1+1+42 + Received: +3+3+4+4+45 + + 3005_or + Expected: +0+1+1-1-1 + Received: -3-2-2-4-4 + + 3006_xor + Expected: +0+1+0-2-1 + Received: -1-1-3-5-1 + ............... + vvs-repo/stdlib_tests % + +If testing is aborted prematurely, say by a Ctrl-C initiated SIGINT, use `make +clean` to remove any temporary files. + + +# Add New Test # + +Most tests consist of four basic parts: + + 1. Perform a test. + 2. Print a result. + 3. Die. + 4. Dependencies + +With that framework in mind, consider `0001_dumpstack.pvvs`, the first test, +with line numbers for reference. + + 1: SSSTTTTTTTTN | PUSH 255 + 2: SSSTSTSTSN | PUSH 42 + 3: SSSTSN | PUSH 2 (count) + 4: NSTTTTSSTN | JSR > 111001 (dumpstack) + 5: NNN | DIE + 6: + 7: #include + +Comparing this to the four part framework, we see that lines 1-4 perform the +test and print the result, combined in this case since our test function's goal +is to print something. Line 5 then terminates the program, after which the +dependencies are included on line 7. + +Once you have written a test of this form, add it to the `tests` array in the +file `vv_test.py`. The three fields are: + + ['filename_without_extension', 'string for stdin', 'string for expected stdout'] + +Continuing with the same example: + + ['0001_dumpstack', '', 'TOS:\n2:\t+42\n1:\t+255\n'], + +Note that the first field was the name of the file in which our test was saved, +minus the extension. These filenames should be numbered, grouped by category +and ordered by dependency. + +The second field is empty since our test doesn't require any simulated input +from the user. + +The final field is the expected output from our test. In this example, with +tabs and newlines expanded: + + TOS: + 2: +42 + 1: +255 + +Each time the test is executed by `vv_test.py` it will be fed the input from +the second field and the output will be compared against the third field. If +there is any mismatch, the test has failed and the user will be alerted with an +error. -All tests assume the stdlib uses the default 16 word heap allocation. diff --git a/stdlib_tests/vv_test.py b/stdlib_tests/vv_test.py index 045f81c..a10696f 100755 --- a/stdlib_tests/vv_test.py +++ b/stdlib_tests/vv_test.py @@ -1,12 +1,13 @@ #!/usr/local/bin/python3.6 # (c) 2019 Aaron Taylor -# All rights reserved. +# See LICENSE.txt file for copyright and license details. # Quick and dirty tests for the VVhitespace stdlib. +# Invoke directly or see README.md in this folder for more details. -import os, subprocess - +# Configuration Options +# All paths are relative to the PWD environment variable of the invoked script. preprocessor = 'cpp' include_path = '-I../stdlib' cpp_temp_file = 'test.pvvs' @@ -16,10 +17,13 @@ temp_file = './test.vvs' path_to_tests = './' src_extension = '.pvvs' +# List of tests to perform. +# Tests should be ordered such that later tests rely exclusively on previously tested commands. +# Format: ['filename_without_extension', 'string for stdin', 'string for expected stdout'] tests = [ - # Format: ['filename_without_extension', 'string for stdin', 'string for expected stdout'] ['0001_dumpstack', '', 'TOS:\n2:\t+42\n1:\t+255\n'], - ['0002_dumpheap', '', '32:\t+255\n33:\t+42\n'], + ['0002_stdlib_version', '', 'TOS:\n1:\t+1\n'], + ['0003_dumpheap', '', '32:\t+255\n33:\t+42\n'], ['1001_stackrotate', '', 'TOS:\n14:\t+1\n13:\t+244\n12:\t+1\n11:\t+1\n10:\t+1\n9:\t+1\n8:\t+1\n7:\t+243\n6:\t+1\n5:\t+1\n4:\t+1\n3:\t+1\n2:\t+1\n1:\t+242\n'], ['1002_stackrotatereverse', '', 'TOS:\n14:\t+1\n13:\t+244\n12:\t+1\n11:\t+1\n10:\t+1\n9:\t+1\n8:\t+1\n7:\t+1\n6:\t+1\n5:\t+1\n4:\t+1\n3:\t+1\n2:\t+1\n1:\t+1\n'], ['1003_deepdup', '', 'TOS:\n15:\t+1\n14:\t+244\n13:\t+1\n12:\t+1\n11:\t+1\n10:\t+1\n9:\t+1\n8:\t+1\n7:\t+1\n6:\t+1\n5:\t+1\n4:\t+1\n3:\t+1\n2:\t+1\n1:\t+244\n'], @@ -53,12 +57,18 @@ tests = [ ['7001_atoi', '', '+42+42-42+0+0+0'], ] +# ------------------------------------------------------------------------------ + +import os, subprocess + for test in tests: subprocess.run([preprocessor, include_path, "-o", cpp_temp_file, path_to_tests + test[0] + src_extension]) subprocess.run([compiler_path, '-i', cpp_temp_file, '-o', temp_file]) result = subprocess.run([interpreter_path, '-i', temp_file], stdout=subprocess.PIPE, input=test[1].encode('utf-8')) if result.stdout.decode('utf-8') != test[2]: print('\n' + test[0]) + print('\tExpected: ' + test[2]) + print('\tReceived: ' + result.stdout.decode('utf-8')) else: print('.', end='', flush=True) os.remove(cpp_temp_file) -- 2.20.1