Added primitive unit testing.

This commit is contained in:
Simon Brooke 2017-01-07 10:48:28 +00:00
parent 85cc542d74
commit 8026138b9c
8 changed files with 180 additions and 63 deletions

View file

@ -152,13 +152,7 @@ struct cons_pointer allocate_cell( char* tag) {
if ( strncmp( &cell->tag.bytes[0], FREETAG, TAGLENGTH) == 0) { if ( strncmp( &cell->tag.bytes[0], FREETAG, TAGLENGTH) == 0) {
freelist = cell->payload.free.cdr; freelist = cell->payload.free.cdr;
fprintf( stderr, "Before: %c%c%c%c (%d)\n",
cell->tag.bytes[0], cell->tag.bytes[1], cell->tag.bytes[2],
cell->tag.bytes[3], cell->tag.value);
strncpy( &cell->tag.bytes[0], tag, 4); strncpy( &cell->tag.bytes[0], tag, 4);
fprintf( stderr, "After: %c%c%c%c (%d)\n",
cell->tag.bytes[0], cell->tag.bytes[1], cell->tag.bytes[2],
cell->tag.bytes[3], cell->tag.value);
cell->count = 0; cell->count = 0;
cell->payload.cons.car = NIL; cell->payload.cons.car = NIL;

View file

@ -18,17 +18,15 @@
#include "read.h" #include "read.h"
int main (int argc, char *argv[]) { int main (int argc, char *argv[]) {
printf( "Post scarcity software environment version %s\n", VERSION); // printf( "Post scarcity software environment version %s\n", VERSION);
initialise_cons_pages(); initialise_cons_pages();
printf( "Ready\n>> ");
struct cons_pointer input = read( stdin); struct cons_pointer input = read( stdin);
inc_ref( input); //inc_ref( input);
printf( "\n:: "); //printf( "\n:: ");
print( stdout, input); print( stdout, input);
dump_pages(stdout); // dump_pages(stdout);
// printf( "Tag2uint(\"FREE\") = %d\n", tag2uint("FREE")); // printf( "Tag2uint(\"FREE\") = %d\n", tag2uint("FREE"));
return(0); return(0);

View file

@ -39,7 +39,11 @@ void print( FILE* output, struct cons_pointer pointer) {
for (struct cons_pointer p = pointer; stringp( p); for (struct cons_pointer p = pointer; stringp( p);
p = pointer2cell( p).payload.string.cdr) { p = pointer2cell( p).payload.string.cdr) {
// TODO: That's potentially a UTF character, needs more handling. // TODO: That's potentially a UTF character, needs more handling.
fprintf( output, "%c", (char)pointer2cell( p).payload.string.character); char c = (char)pointer2cell( p).payload.string.character;
if ( c != '\0') {
fprintf( output, "%c", c);
}
} }
fputc( '"', output); fputc( '"', output);
} else if ( check_tag( pointer, TRUETAG)) { } else if ( check_tag( pointer, TRUETAG)) {

View file

@ -9,6 +9,7 @@
*/ */
#include <ctype.h> #include <ctype.h>
#include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include "consspaceobject.h" #include "consspaceobject.h"
@ -21,67 +22,29 @@
lists lists
Can't read atoms because I don't yet know what an atom is or how it's stored. */ Can't read atoms because I don't yet know what an atom is or how it's stored. */
/** struct cons_pointer read_number( FILE* input, char initial);
* read a number from this input stream, given this initial character. struct cons_pointer read_list( FILE* input, char initial);
*/ struct cons_pointer read_string( FILE* input, char initial);
struct cons_pointer read_number( FILE* input, char initial) {
int accumulator = 0;
char c;
for (c = initial; isdigit( c); c = fgetc( input)) {
int digitvalue = (int)c - (int)'0';
accumulator = accumulator * 10 + digitvalue;
}
/* push back the character read which was not a digit */
fputc( c, input);
return make_integer( accumulator);
}
struct cons_pointer read_list( FILE* input) {
struct cons_pointer car = read( input);
struct cons_pointer cdr = NIL;
char c = fgetc( input);
if ( c != ')' ) {
cdr = read_list( input);
}
return make_cons( car, cdr);
}
struct cons_pointer read_string( FILE* input) {
struct cons_pointer cdr = NIL;
struct cons_pointer result= NIL;
char c = fgetc( input);
if ( c != '"' ) {
result = make_string( c, read_string( input));
}
return result;
}
/** /**
* read the next object on this input stream and return a cons_pointer to it. * Read the next object on this input stream and return a cons_pointer to it,
* treating this initial character as the first character of the object
* representation.
*/ */
struct cons_pointer read( FILE* input) { struct cons_pointer read_continuation( FILE* input, char initial) {
struct cons_pointer result = NIL; struct cons_pointer result = NIL;
char c; char c;
for (c = fgetc( input); isblank( c); c = fgetc( input)); for (c = initial; c == '\0' || isblank( c); c = fgetc( input));
switch( c) { switch( c) {
case '(' : result = read_list(input); case '(' :
case ')':
result = read_list(input, fgetc( input));
break; break;
case '"': result = read_string(input); case '"': result = read_string(input, fgetc( input));
break; break;
case '0': case '0':
case '1': case '1':
@ -104,5 +67,91 @@ struct cons_pointer read( FILE* input) {
} }
/**
* read a number from this input stream, given this initial character.
*/
struct cons_pointer read_number( FILE* input, char initial) {
int accumulator = 0;
int places_of_decimals = 0;
bool seen_period = false;
char c;
fprintf( stderr, "read_number starting '%c' (%d)\n", initial, initial);
for (c = initial; isdigit( c); c = fgetc( input)) {
if ( c == '.') {
seen_period = true;
} else {
accumulator = accumulator * 10 + ((int)c - (int)'0');
if ( seen_period) {
places_of_decimals ++;
}
}
}
/* push back the character read which was not a digit */
fputc( c, input);
return make_integer( accumulator);
}
/**
* Read a list from this input stream, which no longer contains the opening
* left parenthesis.
*/
struct cons_pointer read_list( FILE* input, char initial) {
struct cons_pointer cdr = NIL;
struct cons_pointer result= NIL;
fprintf( stderr, "read_list starting '%c' (%d)\n", initial, initial);
if ( initial != ')' ) {
struct cons_pointer car = read_continuation( input, initial);
cdr = read_list( input, fgetc( input));
result = make_cons( car, cdr);
}
return result;
}
/**
* Read a string from this input stream, which no longer contains the opening
* double quote. Note that there is (for now) a problem with the list
* representation of a string, which is that there's no obvious representation of
* an empty string.
*/
struct cons_pointer read_string( FILE* input, char initial) {
struct cons_pointer cdr = NIL;
struct cons_pointer result;
fprintf( stderr, "read_string starting '%c' (%d)\n", initial, initial);
switch ( initial) {
case '\0':
result = make_string( initial, NIL);
break;
case '"':
result = make_string( '\0', NIL);
break;
default:
result = make_string( initial, read_string( input, fgetc( input)));
break;
}
return result;
}
/**
* Read the next object on this input stream and return a cons_pointer to it.
*/
struct cons_pointer read( FILE* input) {
return read_continuation( input, '\0');
}

33
unit-tests.sh Executable file
View file

@ -0,0 +1,33 @@
#!/bin/bash
# Early stage unit test runner for post-scarcity software environment.
# Uses bash to run every file in the unit-tests subdirectory; expects these
# to return 0 on success, anything else on fail.
# (c) 2017 Simon Brooke <simon@journeyman.cc>
# Licensed under GPL version 2.0, or, at your option, any later version.
tests=0
pass=0
fail=0
for file in unit-tests/*
do
echo ${file}
bash ${file}
if [ $? -eq 0 ]
then
pass=$((${pass} + 1))
else
fail=$((${fail} + 1))
fi
tests=$((${tests} + 1))
done
echo
echo "Tested ${tests}, passed ${pass}, failed ${fail}"
exit ${fail}

View file

@ -0,0 +1,13 @@
#!/bin/bash
expected="\"\""
actual=`echo '""' | target/psse 2> /dev/null`
if [ "$expected" = "$actual" ]
then
echo "OK"
exit 0
else
echo "Expected '$expected', got '$actual'"
exit 1
fi

13
unit-tests/fred.sh Normal file
View file

@ -0,0 +1,13 @@
#!/bin/bash
expected=\"Fred\"
actual=`echo '"Fred"' | target/psse 2> /dev/null`
if [ "$expected" = "$actual" ]
then
echo "OK"
exit 0
else
echo "Expected '$expected', got '$actual'"
exit 1
fi

13
unit-tests/nil.sh Normal file
View file

@ -0,0 +1,13 @@
#!/bin/bash
expected=NIL
actual=`echo '()' | target/psse 2> /dev/null`
if [ "${expected}" = "${actual}" ]
then
echo "OK"
exit 0
else
echo "Expected '${expected}', got '${actual}'"
exit 1
fi