Last active
October 9, 2016 03:50
-
-
Save dkinzer/1ad4dfefd1e48fdb4c7d8a52d2ea3b07 to your computer and use it in GitHub Desktop.
Unit tests for cs50 pset6
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* A sensible string comparison equation. | |
*/ | |
bool str_equal(const char* str1, const char* str2) { | |
if (str1 == NULL || str2 == NULL) | |
{ | |
return false; | |
} | |
if (strcasecmp(str1, str2) == 0) | |
{ | |
return true; | |
} | |
return false; | |
} | |
/** | |
* Tests the lookup() function. | |
*/ | |
void test_lookup() | |
{ | |
const char* path = "randomstring"; | |
const char* expected = NULL; | |
const char* actual = lookup(path); | |
// setup test dir and files | |
mkdir("test", 0777); | |
FILE* fp = fopen("test/my.css", "w"); | |
fclose(fp); | |
fp = fopen("test/my.css", "w"); | |
fclose(fp); | |
fp = fopen("test/my.html", "w"); | |
fclose(fp); | |
fp = fopen("test/my.gif", "w"); | |
fclose(fp); | |
fp = fopen("test/my.ico", "w"); | |
fclose(fp); | |
fp = fopen("test/my.jpg", "w"); | |
fclose(fp); | |
fp = fopen("test/my.js", "w"); | |
fclose(fp); | |
fp = fopen("test/my.php", "w"); | |
fclose(fp); | |
fp = fopen("test/my.png", "w"); | |
fclose(fp); | |
// expect null by default or file does not exist | |
if (actual != expected) | |
{ | |
printf("Fail: expect lookup() to return NULL by default"); | |
} | |
// expect if we end with a period | |
path = "test/my."; | |
expected = NULL; | |
actual = lookup(path); | |
if (actual != expected) | |
{ | |
printf("Fail: expect lookup(\"test/my.\") to return NULL by default"); | |
} | |
path = "test/my.css"; | |
actual = lookup(path); | |
expected = "text/css"; | |
if (!str_equal(actual, expected)) | |
{ | |
printf("Fail: lookup(\"test/my.css\") - actual: %s\n", actual); | |
} | |
path = "test/my.CSS"; | |
actual = lookup(path); | |
expected = "text/css"; | |
if (!str_equal(actual, expected)) | |
{ | |
printf("Fail: lookup(\"test/my.CSS\") - actual: %s\n", actual); | |
} | |
path = "test/my.html"; | |
actual = lookup(path); | |
expected = "text/html"; | |
if (!str_equal(actual, expected)) | |
{ | |
printf("Fail: lookup(\"test/my.html\") - actual: %s\n", actual); | |
} | |
path = "test/my.gif"; | |
actual = lookup(path); | |
expected = "image/gif"; | |
if (!str_equal(actual, expected)) | |
{ | |
printf("Fail: lookup(\"test/my.gif\") - actual: %s\n", actual); | |
} | |
path = "test/my.ico"; | |
actual = lookup(path); | |
expected = "image/x-icon"; | |
if (!str_equal(actual, expected)) | |
{ | |
printf("Fail: lookup(\"test/my.ico\") - actual: %s\n", actual); | |
} | |
path = "test/my.jpg"; | |
actual = lookup(path); | |
expected = "image/jpeg"; | |
if (!str_equal(actual, expected)) | |
{ | |
printf("Fail: lookup(\"test/my.jpg\") - actual: %s\n", actual); | |
} | |
path = "test/my.js"; | |
actual = lookup(path); | |
expected = "text/javascript"; | |
if (!str_equal(actual, expected)) | |
{ | |
printf("Fail: lookup(\"test/my.js\") - actual: %s\n", actual); | |
} | |
path = "test/my.php"; | |
actual = lookup(path); | |
expected = "text/x-php"; | |
if (!str_equal(actual, expected)) | |
{ | |
printf("Fail: lookup(\"test/my.php\") - actual: %s\n", actual); | |
} | |
path = "test/my.png"; | |
actual = lookup(path); | |
expected = "image/png"; | |
if (!str_equal(actual, expected)) | |
{ | |
printf("Fail: lookup(\"test/my.PNG\") - actual: %s\n", actual); | |
} | |
remove("test/my.css"); | |
remove("test/my.html"); | |
remove("test/my.gif"); | |
remove("test/my.ico"); | |
remove("test/my.jpg"); | |
remove("test/my.js"); | |
remove("test/my.php"); | |
remove("test/my.png"); | |
rmdir("assets"); | |
} | |
/** | |
* Test parse function. | |
*/ | |
void test_parse(void) | |
{ | |
// allow when method is GET | |
char* line; | |
char abs_path[LimitRequestLine + 1]; | |
char query[LimitRequestLine + 1]; | |
line = "GET /test?a=david HTTP/1.1\r\n"; | |
if (!parse(line, abs_path, query)) | |
{ | |
printf("Fail: parse(%s...)\n", line); | |
} | |
// only accept GET method | |
line = "POST /test?a=david HTTP/1.1\r\n"; | |
if (parse(line, abs_path, query)) | |
{ | |
printf("Fail: parse(%s...)\n", line); | |
} | |
line = "BOGUS /test?a=david HTTP/1.1\r\n"; | |
if (parse(line, abs_path, query)) | |
{ | |
printf("Fail: parse(%s...)\n", line); | |
} | |
// disallow if request_target does not begin with '/' | |
line = "GET test?a=david HTTP/1.1\r\n"; | |
if (parse(line, abs_path, query)) | |
{ | |
printf("Fail: parse(%s...)\n", line); | |
} | |
// disallow if request_target includes '"' | |
line = "GET /test?a=\"david\" HTTP/1.1\r\n"; | |
if (parse(line, abs_path, query)) | |
{ | |
printf("Fail: parse(%s...)\n", line); | |
} | |
// disallow if version not = HTTP/1.1 | |
line = "GET /test?a=david HTTP/1.2\r\n"; | |
if (parse(line, abs_path, query)) | |
{ | |
printf("Fail: parse(%s...)\n", line); | |
} | |
line = "GET /test?a=david HTTP/1.0\r\n"; | |
if (parse(line, abs_path, query)) | |
{ | |
printf("Fail: parse(%s...)\n", line); | |
} | |
line = "GET /test?a=david HTTP/1\r\n"; | |
if (parse(line, abs_path, query)) | |
{ | |
printf("Fail: parse(%s...)\n", line); | |
} | |
// disallow if ctrl-f is not last token | |
line = "GET /test?a=david HTTP/1.1"; | |
if (parse(line, abs_path, query)) | |
{ | |
printf("Fail: parse(%s...)\n", line); | |
} | |
line = "GET /test?a=david HTTP/1.1 bogus"; | |
if (parse(line, abs_path, query)) | |
{ | |
printf("Fail: parse(%s...)\n", line); | |
} | |
line = "GET /test?a=david HTTP/1.1\r\n\r\n"; | |
if (parse(line, abs_path, query)) | |
{ | |
printf("Fail: parse(%s...)\n", line); | |
} | |
line = "GET /test?a=david HTTP/1.1\r\n"; | |
parse(line, abs_path, query); | |
if (!str_equal(abs_path, "/test")) | |
{ | |
printf("Fail: expect abs_path to be '/test': %s\n", abs_path); | |
} | |
if (!str_equal(query, "a=david")) | |
{ | |
printf("Fail: expect query to be '': %s\n", query); | |
} | |
line = "GET /test? HTTP/1.1\r\n"; | |
parse(line, abs_path, query); | |
if (!str_equal(abs_path, "/test")) | |
{ | |
printf("Fail: expect abs_path to be '/test': %s\n", abs_path); | |
} | |
if (!str_equal(query, "")) | |
{ | |
printf("Fail: expect query to be '': %s\n", query); | |
} | |
line = "GET /test HTTP/1.1\r\n"; | |
parse(line, abs_path, query); | |
if (!str_equal(abs_path, "/test")) | |
{ | |
printf("Fail: expect abs_path to be '/test': %s\n", abs_path); | |
} | |
if (!str_equal(query, "")) | |
{ | |
printf("Fail: expect query to be '': %s\n", query); | |
} | |
return; | |
} | |
/** | |
* Test the load() function. | |
*/ | |
void test_load(void) | |
{ | |
BYTE* content = NULL; | |
size_t length = 0; | |
FILE* fp = NULL; | |
if (load(fp, &content, &length)) | |
{ | |
printf("Fail: expect default behavior to return false."); | |
} | |
// pass working file but null content and null length | |
fp = fopen("test_content.txt", "w"); | |
if (load(fp, NULL, &length)) | |
{ | |
printf("Fail: expect false if either content or length are NULL."); | |
} | |
if (load(fp, &content, NULL)) | |
{ | |
printf("Fail: expect false if either content or length are NULL."); | |
} | |
// setup | |
fwrite("hello world", sizeof(BYTE), 11, fp); | |
fclose(fp); | |
// reads correctly | |
fp = fopen("test_content.txt", "r"); | |
if (!load(fp, &content, &length)) | |
{ | |
printf("Fail: expect true when all values are valid."); | |
} | |
fclose(fp); | |
if (!str_equal(content, "hello world")) | |
{ | |
printf("Fail: expect content to equal 'hello world': %s\n", content); | |
} | |
if (length != 11) | |
{ | |
printf("Fail: expect length to equal 11: %i\n", (int) length); | |
} | |
free(content); | |
content = NULL; | |
// can handle multiple reads correctly | |
fp = fopen("test_content_test2.txt", "w"); | |
fclose(fp); | |
fp = fopen("test_content_test2.txt", "a"); | |
BYTE test_content[1024]; | |
for(int i = 0; i < 1022; i++) | |
{ | |
test_content[i] = 'a'; | |
fwrite("a", sizeof(BYTE), 1, fp); | |
} | |
test_content[1022] = 'x'; | |
test_content[1023] = '\0'; | |
fwrite("x", sizeof(BYTE), 1, fp); | |
fwrite("\0", sizeof(BYTE), 1, fp); | |
fclose(fp); | |
fp = fopen("test_content_test2.txt", "r"); | |
load(fp, &content, &length); | |
fclose(fp); | |
if (!str_equal(content, test_content)) | |
{ | |
printf("Fail: expect content to equal test_content: %s\n", content); | |
printf("\n"); | |
} | |
if (length != 1024) | |
{ | |
printf("Fail: expect length to equal 1024: %i\n", (int) length); | |
} | |
free(content); | |
content = NULL; | |
remove("test_content_test2.txt"); | |
remove("test_content.txt"); | |
} | |
/** | |
* Test the indexes() function. | |
*/ | |
void test_indexes(void) | |
{ | |
// expect NULL by default | |
if (indexes(NULL) != NULL) | |
{ | |
printf("Fail: expect indexes(NULL) to be NULL"); | |
} | |
// expect NULL when we send non existent path | |
if (indexes("some/path") != NULL) | |
{ | |
printf("Fail: expect indexes(\"some/path\") to be NULL"); | |
} | |
// create a directory. | |
mkdir("assets", 0777); | |
// with index.php only | |
FILE* fp = fopen("assets/index.php", "w"); | |
fclose(fp); | |
char* expected = "assets/index.php"; | |
char* actual = indexes("assets"); | |
if (!str_equal(actual, expected)) | |
{ | |
printf("Fail: expect indexes(\"assets\") = %s : %s\n", expected, actual); | |
} | |
free(actual); | |
expected = NULL; | |
actual = NULL; | |
remove("assets/index.php"); | |
// with index.html only | |
fp = fopen("assets/index.html", "w"); | |
fclose(fp); | |
expected = "assets/index.html"; | |
actual = indexes("assets"); | |
if (!str_equal(actual, expected)) | |
{ | |
printf("Fail: expect indexes(\"assets\") = %s : %s\n", expected, actual); | |
} | |
free(actual); | |
expected = NULL; | |
actual = NULL; | |
remove("assets/index.html"); | |
// with both file at the same time | |
fp = fopen("assets/index.php", "w"); | |
fclose(fp); | |
fp = fopen("assets/index.html", "w"); | |
fclose(fp); | |
expected = "assets/index.php"; | |
actual = indexes("assets"); | |
if (!str_equal(actual, expected)) | |
{ | |
printf("Fail: expect indexes(\"assets\") = %s when both options available : %s\n", expected, actual); | |
} | |
free(actual); | |
actual = NULL; | |
remove("assets/index.html"); | |
remove("assets/index.php"); | |
rmdir("assets"); | |
} | |
/** | |
* Run test functions for pset6. | |
*/ | |
void test_pset6(void) | |
{ | |
test_parse(); | |
test_lookup(); | |
test_load(); | |
test_indexes(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment