Split up some of the native testing code.
Makes running specific tests a little cleaner.
This commit is contained in:
parent
54410030f7
commit
80255af52e
111
src/env.c
111
src/env.c
|
@ -115,14 +115,19 @@ struct Environment envForLambda(const Object* params, const Object* arguments, i
|
||||||
.refs = 1,
|
.refs = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Evaluate the `argument` list
|
||||||
|
const Object* param = params->list;
|
||||||
const Object* argument = arguments;
|
const Object* argument = arguments;
|
||||||
for (int i = 0; i < paramCount; i++) {
|
for (int i = 0; i < paramCount && param; i++) {
|
||||||
const char* paramName = itemAt(params, i)->string;
|
Object newEnvObj = eval(argument, outer);
|
||||||
// Eval the `argument` list
|
|
||||||
Object newEnvObj = argument ? eval(argument, outer) : errorWithContext(NOT_ENOUGH_ARGUMENTS, paramName);
|
const char* paramName = param->string;
|
||||||
addToEnv(&env, paramName, newEnvObj); // Could use eval_forms?
|
addToEnv(&env, paramName, newEnvObj);
|
||||||
|
|
||||||
cleanObject(&newEnvObj);
|
cleanObject(&newEnvObj);
|
||||||
|
|
||||||
argument = argument ? argument->forward : NULL;
|
argument = argument ? argument->forward : NULL;
|
||||||
|
param = param->forward;
|
||||||
}
|
}
|
||||||
env.outer = outer;
|
env.outer = outer;
|
||||||
|
|
||||||
|
@ -224,8 +229,7 @@ struct Environment defaultEnv()
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned i;
|
for (unsigned i = 0; i < sizeof(symFuncs) / sizeof(symFuncs[0]); i++) {
|
||||||
for (i = 0; i < sizeof(symFuncs) / sizeof(symFuncs[0]); i++) {
|
|
||||||
addFunc(symFuncs[i].sym, symFuncs[i].func, &e);
|
addFunc(symFuncs[i].sym, symFuncs[i].func, &e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,7 +395,9 @@ Object help(Object* params, int length, struct Environment* env)
|
||||||
}
|
}
|
||||||
for (int i = 0; i < currentHelp; i++) {
|
for (int i = 0; i < currentHelp; i++) {
|
||||||
struct helpText h = helpTexts[i];
|
struct helpText h = helpTexts[i];
|
||||||
if (strcmp(symbol, h.symbol) == 0) {
|
if (strcmp(symbol, h.symbol) != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
Object text = withLen(1024, TYPE_STRING);
|
Object text = withLen(1024, TYPE_STRING);
|
||||||
char* textCursor = text.string;
|
char* textCursor = text.string;
|
||||||
textCursor += sprintf(textCursor, "%s", h.help);
|
textCursor += sprintf(textCursor, "%s", h.help);
|
||||||
|
@ -411,7 +417,6 @@ Object help(Object* params, int length, struct Environment* env)
|
||||||
}
|
}
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < dictionary.structCount; i++) {
|
for (int i = 0; i < dictionary.structCount; i++) {
|
||||||
if (strcmp(dictionary.structDefs[i].name, symbol) == 0) {
|
if (strcmp(dictionary.structDefs[i].name, symbol) == 0) {
|
||||||
|
@ -438,37 +443,9 @@ Object help(Object* params, int length, struct Environment* env)
|
||||||
return nullTerminated("Help not found!");
|
return nullTerminated("Help not found!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns number of failures, or -1 if the requested specificTest is invalid
|
/// Returns 1 if the test passed, or 0 if it failed
|
||||||
int runTests(int detailed, int specificTest)
|
int runTest(const char* test, const char* expected, int detailed)
|
||||||
{
|
{
|
||||||
int isSpecific = specificTest != -1;
|
|
||||||
if (specificTest >= currentHelp) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isSpecific) {
|
|
||||||
printf("[35;1m::NATIVE TESTS::[0m\n");
|
|
||||||
}
|
|
||||||
int failureCount = 0;
|
|
||||||
int passCount = 0;
|
|
||||||
int start = isSpecific ? specificTest : 0;
|
|
||||||
int end = isSpecific ? specificTest + 1 : currentHelp;
|
|
||||||
for (int hi = start; hi < end; hi++) {
|
|
||||||
struct helpText h = helpTexts[hi];
|
|
||||||
if (h.tests) {
|
|
||||||
if (detailed && h.testCount > 0) {
|
|
||||||
if (isSpecific) {
|
|
||||||
printf("[0m`%s` ", h.symbol);
|
|
||||||
} else {
|
|
||||||
printf("[0m `%s` ", h.symbol);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int ti = 0; ti < h.testCount; ti += 2) {
|
|
||||||
const char* test = h.tests[ti];
|
|
||||||
const char* expected = h.tests[ti + 1];
|
|
||||||
if (test[0] == ';') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
struct Environment env = defaultEnv();
|
struct Environment env = defaultEnv();
|
||||||
Object o = parseEval(test, &env);
|
Object o = parseEval(test, &env);
|
||||||
size_t length;
|
size_t length;
|
||||||
|
@ -478,8 +455,9 @@ int runTests(int detailed, int specificTest)
|
||||||
while (expected[expectedLen] && expected[expectedLen] != ';') {
|
while (expected[expectedLen] && expected[expectedLen] != ';') {
|
||||||
expectedLen++;
|
expectedLen++;
|
||||||
}
|
}
|
||||||
|
int ret;
|
||||||
if (strncmp(result, expected, expectedLen) != 0) {
|
if (strncmp(result, expected, expectedLen) != 0) {
|
||||||
failureCount++;
|
ret = 0;
|
||||||
printf("Test failed!\n");
|
printf("Test failed!\n");
|
||||||
printf("%s\n", test);
|
printf("%s\n", test);
|
||||||
printf("Expected '%s' but received '%s'\n", expected, result);
|
printf("Expected '%s' but received '%s'\n", expected, result);
|
||||||
|
@ -487,30 +465,69 @@ int runTests(int detailed, int specificTest)
|
||||||
if (detailed) {
|
if (detailed) {
|
||||||
printf("[32;1m✓");
|
printf("[32;1m✓");
|
||||||
}
|
}
|
||||||
passCount++;
|
ret = 1;
|
||||||
}
|
}
|
||||||
free(result);
|
free(result);
|
||||||
deleteEnv(&env);
|
deleteEnv(&env);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void runHelpTests(struct helpText h, int detailed, int* failureCount, int* passCount)
|
||||||
|
{
|
||||||
|
if (!h.tests) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (detailed && h.testCount > 0) {
|
||||||
|
printf("[0m `%s` ", h.symbol);
|
||||||
|
}
|
||||||
|
for (int ti = 0; ti < h.testCount; ti += 2) {
|
||||||
|
const char* test = h.tests[ti];
|
||||||
|
const char* expected = h.tests[ti + 1];
|
||||||
|
if (test[0] == ';') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int* outcome = runTest(test, expected, detailed) ? passCount : failureCount;
|
||||||
|
*outcome = *outcome + 1;
|
||||||
}
|
}
|
||||||
if (detailed && h.testCount > 0) {
|
if (detailed && h.testCount > 0) {
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns number of failures, or -1 if the requested specificTest is invalid
|
||||||
|
int runTests(int detailed, int specificTest)
|
||||||
|
{
|
||||||
|
if (specificTest >= currentHelp) {
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int failureCount = 0;
|
||||||
|
int passCount = 0;
|
||||||
|
|
||||||
|
int isSpecificTest = specificTest != -1;
|
||||||
|
if(isSpecificTest) {
|
||||||
|
struct helpText h = helpTexts[specificTest];
|
||||||
|
runHelpTests(h, detailed, &failureCount, &passCount);
|
||||||
|
return failureCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("[35;1m::NATIVE TESTS::[0m\n");
|
||||||
|
|
||||||
|
for (int hi = 0; hi < currentHelp; hi++) {
|
||||||
|
runHelpTests(helpTexts[hi], detailed, &failureCount, &passCount);
|
||||||
|
}
|
||||||
|
|
||||||
if (passCount > 0) {
|
if (passCount > 0) {
|
||||||
printf("[32;1m");
|
printf("[32;1m");
|
||||||
}
|
}
|
||||||
if (!isSpecific) {
|
|
||||||
printf("%d tests passed![0m\n", passCount);
|
printf("%d tests passed![0m\n", passCount);
|
||||||
}
|
|
||||||
if (failureCount > 0) {
|
if (failureCount > 0) {
|
||||||
printf("[31m");
|
printf("[31m%d tests failed![0m\n", failureCount);
|
||||||
}
|
|
||||||
if (!isSpecific || failureCount != 0) {
|
|
||||||
printf("%d tests failed![0m\n", failureCount);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// fprintf(stderr, "TOTAL ALLOCATIONS: %d\n", getAllocations());
|
// fprintf(stderr, "TOTAL ALLOCATIONS: %d\n", getAllocations());
|
||||||
// fprintf(stderr, "TOTAL BYTES: %zu\n", getBytes());
|
// fprintf(stderr, "TOTAL BYTES: %zu\n", getBytes());
|
||||||
|
|
||||||
return failureCount;
|
return failureCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,10 +59,6 @@ void printColored(const char* code);
|
||||||
|
|
||||||
int runTests(int detailed, int specificTest);
|
int runTests(int detailed, int specificTest);
|
||||||
|
|
||||||
int getTotalSearchDepth();
|
|
||||||
|
|
||||||
int getTotalSearches();
|
|
||||||
|
|
||||||
#define unused __attribute__((unused))
|
#define unused __attribute__((unused))
|
||||||
|
|
||||||
#define array_length(_array) (sizeof(_array) / sizeof((_array)[0]))
|
#define array_length(_array) (sizeof(_array) / sizeof((_array)[0]))
|
||||||
|
@ -91,7 +87,9 @@ fn(help, "?",
|
||||||
" (? Output) => \"{ stdout stderr }\"\n"
|
" (? Output) => \"{ stdout stderr }\"\n"
|
||||||
"\n"
|
"\n"
|
||||||
" Other objects:\n"
|
" Other objects:\n"
|
||||||
" (? \"Hello\") => \"Hello\""
|
" (? \"Hello\") => \"Hello\"\n"
|
||||||
|
"\n"
|
||||||
|
"Note: The included repl allows you to drop the parentheses."
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue