Skip to content

Commit

Permalink
Merge pull request #26 from JakeRoggenbuck/testing
Browse files Browse the repository at this point in the history
Testing
  • Loading branch information
JakeRoggenbuck authored Jun 22, 2024
2 parents dd50611 + d417078 commit 10b816a
Show file tree
Hide file tree
Showing 9 changed files with 130 additions and 20 deletions.
22 changes: 20 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
cmake_minimum_required(VERSION 3.10)
set (CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD 11)
project(jccc)
add_compile_options(-O0 -Wall -Wpedantic -g -Wno-gnu-zero-variadic-macro-arguments)

file(GLOB_RECURSE SOURCES src/*.c)
add_executable(jccc ${SOURCES})
list(FILTER SOURCES EXCLUDE REGEX ".*\/(driver\/main|testing\/main)\.c$")

# Create a main file for the actual jccc executable
set(MAIN_DRIVER "src/driver/main.c")

add_executable(jccc ${SOURCES} ${MAIN_DRIVER})
target_include_directories(jccc PRIVATE src)

enable_testing()

file(GLOB_RECURSE TEST_SOURCES src/test_*.c)

# Set a main function for testing
set(TEST_MAIN "src/testing/main.c")

add_executable(test_jccc ${SOURCES} ${TEST_SOURCES} ${TEST_MAIN})
target_include_directories(test_jccc PRIVATE src)

add_test(NAME TestJccc COMMAND test_jccc)
28 changes: 14 additions & 14 deletions src/lexer/lex.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "lex.h"
#include <testing/tassert.h> // tassert

#include <assert.h> // assert
#include <ctype.h>
#include <string.h> // memcpy

Expand Down Expand Up @@ -464,7 +464,7 @@ static const char *ttype_names[] = {
"->",
"<<=",
">>=",
// All 32 C keywords
// All 32 C keywords
"auto",
"break",
"char",
Expand Down Expand Up @@ -502,23 +502,23 @@ static const char *ttype_names[] = {
const char *ttype_name(TokenType tt) { return ttype_names[tt]; }

int test_ttype_from_string() {
assert(ttype_from_string("1") == TT_LITERAL);
assert(ttype_from_string("1.2") == TT_LITERAL);
tassert(ttype_from_string("1") == TT_LITERAL);
tassert(ttype_from_string("1.2") == TT_LITERAL);

assert(ttype_from_string("1u") == TT_LITERAL);
assert(ttype_from_string("1.2f") == TT_LITERAL);
assert(ttype_from_string("1.f") == TT_LITERAL);
tassert(ttype_from_string("1u") == TT_LITERAL);
tassert(ttype_from_string("1.2f") == TT_LITERAL);
tassert(ttype_from_string("1.f") == TT_LITERAL);

assert(ttype_from_string("\"Planck\"") == TT_LITERAL);
assert(ttype_from_string("'Language'") == TT_LITERAL);
tassert(ttype_from_string("\"Planck\"") == TT_LITERAL);
tassert(ttype_from_string("'Language'") == TT_LITERAL);

assert(ttype_from_string("Jaba") == TT_IDENTIFIER);
assert(ttype_from_string("cat_") == TT_IDENTIFIER);
tassert(ttype_from_string("Jaba") == TT_IDENTIFIER);
tassert(ttype_from_string("cat_") == TT_IDENTIFIER);

assert(ttype_from_string("(") == TT_OPAREN);
assert(ttype_from_string("}") == TT_CBRACE);
tassert(ttype_from_string("(") == TT_OPAREN);
tassert(ttype_from_string("}") == TT_CBRACE);

assert(ttype_from_string(";") == TT_SEMI);
tassert(ttype_from_string(";") == TT_SEMI);

return 0;
}
11 changes: 7 additions & 4 deletions src/lexer/lex.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@
// This is a lexer structure, which will contain all of the information about
// the state of a lexer.
typedef struct {
FILE * fp; // The file we are reading from.
FILE *fp; // The file we are reading from.
Token unlexed[TOKEN_PUTBACKS];
unsigned unlexed_count;
} Lexer;

// Takes an open file pointer, and a token as input. It fills the token struct
// with the next available token from the file.
int lex(Lexer * l, Token * token);
int lex(Lexer *l, Token *token);

// Put a token back to be lexed again in the future.
int unlex(Lexer * l, Token * token);
int unlex(Lexer *l, Token *token);

// Find token type for single char
TokenType ttype_one_char(char c);
Expand All @@ -36,4 +36,7 @@ int skip_to_token(Lexer *l);

// Get the string representation of a token type.
// E.g. TT_EOF -> "end of file", TT_LITERAL -> "literal", etc.
const char* ttype_name(TokenType tt);
const char *ttype_name(TokenType tt);

// Test for ttype_from_string
int test_ttype_from_string();
15 changes: 15 additions & 0 deletions src/lexer/test_lexer.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Run all of the tests at the end of each C file in the lexer module
*/

#include "lex.h"
#include <testing/test_utils.h>

int test_lexer() {
testing_setup();

test_ttype_from_string();

testing_cleanup();
return 0;
}
6 changes: 6 additions & 0 deletions src/lexer/test_lexer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/*
* Run all of the tests at the end of each C file in the lexer module */

#include "lex.h"

int test_lexer();
7 changes: 7 additions & 0 deletions src/testing/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include "lexer/test_lexer.h"

int main() {
test_lexer();

return 0;
}
5 changes: 5 additions & 0 deletions src/testing/tassert.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include <assert.h>

#define tassert(e) ((void)((e) ? 0 : __assert(#e, __FILE__, __LINE__)))
#define __assert(e, file, line) \
((void)printf("%s:%u: failed assertion `%s'\n", file, line, e), 0)
16 changes: 16 additions & 0 deletions src/testing/test_utils.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include <stdio.h>
#include <util/out.h>

void testing_setup_internal(const char *func_name) {
printf("Running test ");
fflush(stdout);
PRINT_WITH_COLOR(CODE_GREEN, "\"%s\"", func_name);
printf(" ...\n");
}

void testing_cleanup_internal(const char *func_name) {
printf("Concluded test ");
fflush(stdout);
PRINT_WITH_COLOR(CODE_GREEN, "\"%s\"", func_name);
printf("\n");
}
40 changes: 40 additions & 0 deletions src/testing/test_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/* Testing utility
* Here is an example usage of the testing
*
* This is from "lexer/test_lexer.c"
*
* For each module of code, create a test_{module_name} file.
* This file should include a test_{module_name} function that includes the
* testing_setup and the testing_cleanup functions.
#include "lex.h"
#include <testing/test_utils.h>
int test_lexer() {
testing_setup();
test_ttype_from_string();
testing_cleanup();
return 0;
}
* After this, include a call to this function in the "testing/main.c" file like how it's done for test_lexer.
#include "lexer/test_lexer.h"
int main() {
test_lexer();
return 0;
}
*/

#define testing_setup() testing_setup_internal(__func__)

#define testing_cleanup() testing_cleanup_internal(__func__)

void testing_setup_internal(const char *func_name);

void testing_cleanup_internal(const char *func_name);

0 comments on commit 10b816a

Please sign in to comment.