I now have files with the infinitely imaginative names requestrespons.{c,h,test.c}.master
parent
0e2b9dae2b
commit
48e3092317
9 changed files with 533 additions and 70 deletions
@ -0,0 +1,106 @@ |
|||||||
|
#include "requestresponse.h" |
||||||
|
|
||||||
|
Header* newHeader(char *str){ |
||||||
|
Header *header = malloc(sizeof(Header)); |
||||||
|
memset(header, 0, sizeof(Header)); |
||||||
|
|
||||||
|
int position = -1; |
||||||
|
|
||||||
|
|
||||||
|
for ( unsigned int i = 0; i < strlen(str); i++ ){ |
||||||
|
if ( str[i] == ':' ){ |
||||||
|
position = i; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if ( position == -1 ){ |
||||||
|
printf("Header without colon. Not sure what to do\n"); |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
// We want to allocate 1 more than the length so we can have a \0 at the end
|
||||||
|
header->name = malloc( sizeof(char) * ( position + 1 ) ); |
||||||
|
memset(header->name, '\0', position+1); |
||||||
|
strncpy( header->name, str, position ); |
||||||
|
|
||||||
|
for ( unsigned int i = position+1; i < strlen(str); i++ ){ |
||||||
|
if ( str[i] == '\t' || str[i] == ' ' ) continue; |
||||||
|
position = i; |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
//Anything left is the value
|
||||||
|
header->value = malloc( sizeof(char) * ( strlen(str) - position ) ); |
||||||
|
memset(header->value, '\0', ( strlen(str) - position ) ); |
||||||
|
strcpy( header->value, str + position ); |
||||||
|
|
||||||
|
return header; |
||||||
|
} |
||||||
|
|
||||||
|
void addHeader(HeaderList *headers, char *str){ |
||||||
|
HeaderList *newListItem = malloc(sizeof(HeaderList)); |
||||||
|
|
||||||
|
newListItem->header = newHeader(str); |
||||||
|
newListItem->next = NULL; |
||||||
|
|
||||||
|
HeaderList *last = headers; |
||||||
|
|
||||||
|
while ( last->next != NULL ) last = last->next; |
||||||
|
|
||||||
|
last->next = newListItem; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
// Will return the first header in a header list with the name matching name
|
||||||
|
// It matches name case insensitively as header names are case insensitive
|
||||||
|
|
||||||
|
Header* getHeader(HeaderList *headers, char *name){ |
||||||
|
HeaderList *curr = headers; |
||||||
|
while ( curr != NULL ){ |
||||||
|
// Header names are case insensitive
|
||||||
|
if ( strcasecmp( curr->header->name, name) == 0 ){ |
||||||
|
return curr->header; |
||||||
|
} |
||||||
|
curr = curr->next; |
||||||
|
} |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
unsigned int countHeaders(HeaderList *headers){ |
||||||
|
unsigned int count = 0; |
||||||
|
while (headers != NULL){ |
||||||
|
count++; |
||||||
|
headers = headers->next; |
||||||
|
} |
||||||
|
return count; |
||||||
|
} |
||||||
|
|
||||||
|
unsigned int headerListCharLength(HeaderList *headers){ |
||||||
|
unsigned int length = 0; |
||||||
|
while (headers != NULL){ |
||||||
|
// 4 = colon + space + \r + \n
|
||||||
|
length += strlen(headers->header->name) + strlen(headers->header->value) + 4; |
||||||
|
headers = headers->next; |
||||||
|
} |
||||||
|
return length; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
char* headersToString(HeaderList *headers){ |
||||||
|
int len = headerListCharLength(headers) + 1; //null pointer
|
||||||
|
HeaderList *curr = headers; |
||||||
|
char *retStr = malloc( len * sizeof(char) ); |
||||||
|
memset(retStr, '\0', len * sizeof(char) ); |
||||||
|
while ( curr != NULL ){ |
||||||
|
strcat( retStr, curr->header->name ); |
||||||
|
strcat( retStr, ": " ); |
||||||
|
strcat( retStr, curr->header->value ); |
||||||
|
strcat( retStr, "\r\n" ); |
||||||
|
curr = curr->next; |
||||||
|
} |
||||||
|
return retStr; |
||||||
|
} |
@ -0,0 +1,46 @@ |
|||||||
|
#ifndef REQUESTRESPONSE |
||||||
|
#define REQUESTRESPONSE |
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h> |
||||||
|
#include <stdio.h> |
||||||
|
#include <string.h> |
||||||
|
|
||||||
|
//This file contains definitions that are shared between requests and responses such as header
|
||||||
|
/*
|
||||||
|
* A struct reperesenting an http header |
||||||
|
*/ |
||||||
|
typedef struct { |
||||||
|
char *name; |
||||||
|
// The spec doesn't specify a max size for headers, but nginx doesn't accept headers bigger than 4096 so that's probably ok for us
|
||||||
|
char *value; |
||||||
|
} Header; |
||||||
|
|
||||||
|
/*
|
||||||
|
* A linked list wrapper around the headers |
||||||
|
*/ |
||||||
|
typedef struct HeaderList HeaderList; |
||||||
|
struct HeaderList { |
||||||
|
Header *header; |
||||||
|
HeaderList *next; |
||||||
|
}; |
||||||
|
|
||||||
|
//Creates a new header struct from a string like "Content-Length: 123"
|
||||||
|
Header* newHeader(char *str); |
||||||
|
|
||||||
|
//Adds a header to the end of a header list
|
||||||
|
void addHeader(HeaderList *headers, char *str); |
||||||
|
|
||||||
|
Header* getHeader(HeaderList *headers, char *name); |
||||||
|
|
||||||
|
unsigned int countHeaders(HeaderList *headers); |
||||||
|
|
||||||
|
|
||||||
|
unsigned int headerListCharLength(HeaderList *headers); |
||||||
|
|
||||||
|
char* headersToString(HeaderList *headers); |
||||||
|
|
||||||
|
#endif /* ifndef REQUESTRESPONSE |
||||||
|
|
||||||
|
//THis file contains definitions that are shared between requests and responses such as header
|
||||||
|
*/ |
@ -0,0 +1,38 @@ |
|||||||
|
#include "response.h" |
||||||
|
|
||||||
|
Response* newResponse(){ |
||||||
|
Response *response = malloc( sizeof( Response ) ); |
||||||
|
memset(response, 0, sizeof(Response)); |
||||||
|
response->headers = malloc( sizeof( HeaderList ) ); |
||||||
|
response->headers->header = newHeader("Content-Length: 0"); |
||||||
|
response->headers->next = NULL; |
||||||
|
addHeader(response->headers, "Content-Type: text/plain"); |
||||||
|
response->statusCode = 200; |
||||||
|
response->statusMessage = "OK"; |
||||||
|
response->version = 1.1; |
||||||
|
return response; |
||||||
|
} |
||||||
|
|
||||||
|
char* responseToString( Response *rsp ){ |
||||||
|
// HTTP/x.x xxx OK \r\n
|
||||||
|
int fullLength = 13 + strlen(rsp->statusMessage) + 2 + |
||||||
|
// Headers \r\n\r\n
|
||||||
|
headerListCharLength(rsp->headers) + 4 + strlen(rsp->body); |
||||||
|
char retString[fullLength]; |
||||||
|
|
||||||
|
sprintf(retString, "HTTP/%.1f %3d %s\r\n%s\r\n%s", rsp->version, rsp->statusCode, |
||||||
|
rsp->statusMessage,headersToString(rsp->headers),rsp->body); |
||||||
|
return strdup(retString); |
||||||
|
} |
||||||
|
|
||||||
|
void responseSetBody(Response *rsp, char *string, bool updateContentLength){ |
||||||
|
rsp->body = string; |
||||||
|
|
||||||
|
|
||||||
|
if ( updateContentLength ){ |
||||||
|
Header *contentLengthHeader = getHeader(rsp->headers, "content-length"); |
||||||
|
char *value = malloc(sizeof(char) * 20); |
||||||
|
sprintf(value, "%lu", strlen(string) ); |
||||||
|
contentLengthHeader->value = strdup(value); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,34 @@ |
|||||||
|
#ifndef RESPONSE_H |
||||||
|
#define RESPONSE_H |
||||||
|
|
||||||
|
#include <netinet/in.h> |
||||||
|
#include <stdio.h> |
||||||
|
#include <stdlib.h> |
||||||
|
#include <string.h> |
||||||
|
#include <stdbool.h> |
||||||
|
|
||||||
|
#include "readline.h" |
||||||
|
#include "requestresponse.h" |
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A struct reperesenting an http request |
||||||
|
*/ |
||||||
|
typedef struct { |
||||||
|
// Common versions are: 0.9, 1.0, 1.1, 2.0
|
||||||
|
float version; |
||||||
|
int statusCode; |
||||||
|
char *statusMessage; |
||||||
|
HeaderList *headers; |
||||||
|
char *body; |
||||||
|
unsigned int headerLength; |
||||||
|
} Response; |
||||||
|
|
||||||
|
Response* newResponse(); |
||||||
|
char *responseToString(Response *rsp); |
||||||
|
void responseSetBody(Response *rsp, char *string, bool updateContentLength); |
||||||
|
//void* responseAddHeader(Response *req, char line[]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* ifndef REQUEST_H */ |
@ -0,0 +1,186 @@ |
|||||||
|
#ifndef REQUESTRESPONSE_TEST |
||||||
|
#define REQUESTRESPONSE_TEST |
||||||
|
|
||||||
|
#include "munit/munit.h" |
||||||
|
#include "../src/requestresponse.c" |
||||||
|
|
||||||
|
typedef struct { |
||||||
|
char *fullLine; |
||||||
|
char *name; |
||||||
|
char *value; |
||||||
|
} HeaderTestCase; |
||||||
|
|
||||||
|
static HeaderTestCase testCases[] = { |
||||||
|
{ "Content-Encoding: gzip", "Content-Encoding", "gzip" }, |
||||||
|
{ "Accept-Ranges: bytes", "Accept-Ranges", "bytes" }, |
||||||
|
{ "Age: 186432", "Age", "186432" }, |
||||||
|
{ "Cache-Control: max-age=604800", "Cache-Control", "max-age=604800" }, |
||||||
|
{ "Content-Type: text/html; charset=UTF-8", "Content-Type", "text/html; charset=UTF-8" }, |
||||||
|
{ "Date: Thu, 06 Jan 2022 18:52:13 GMT", "Date", "Thu, 06 Jan 2022 18:52:13 GMT" }, |
||||||
|
{ "Etag: \"3147526947+ident\"", "Etag", "\"3147526947+ident\"" }, |
||||||
|
{ "Expires: Thu, 13 Jan 2022 18:52:13 GMT", "Expires", "Thu, 13 Jan 2022 18:52:13 GMT" }, |
||||||
|
{ "Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT", "Last-Modified", "Thu, 17 Oct 2019 07:18:26 GMT" }, |
||||||
|
{ "Server: ECS (nyb/1D13)", "Server", "ECS (nyb/1D13)" }, |
||||||
|
{ "X-Cache: HIT", "X-Cache", "HIT" }, |
||||||
|
{ "Content-Length: 648", "Content-Length", "648" } |
||||||
|
}; |
||||||
|
|
||||||
|
MunitResult testHeadersName(const MunitParameter params[], |
||||||
|
void* user_data_or_fixture){ |
||||||
|
for ( int i = 0; i < sizeof(testCases) / sizeof(HeaderTestCase); i++ ){ |
||||||
|
Header *test = newHeader(testCases[i].fullLine); |
||||||
|
munit_assert_string_equal( testCases[i].name, test->name ); |
||||||
|
} |
||||||
|
return MUNIT_OK; |
||||||
|
} |
||||||
|
|
||||||
|
MunitResult testHeadersValue(const MunitParameter params[], |
||||||
|
void* user_data_or_fixture){ |
||||||
|
for ( int i = 0; i < sizeof(testCases) / sizeof(HeaderTestCase); i++ ){ |
||||||
|
Header *test = newHeader(testCases[i].fullLine); |
||||||
|
munit_assert_string_equal( testCases[i].value, test->value ); |
||||||
|
} |
||||||
|
return MUNIT_OK; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
MunitResult testHeadersListCount(const MunitParameter params[], |
||||||
|
void* user_data_or_fixture){ |
||||||
|
HeaderList *list = malloc( sizeof( HeaderList ) ); |
||||||
|
list->header = newHeader("Content-Length: 0"); |
||||||
|
list->next = malloc( sizeof( HeaderList ) ); |
||||||
|
list->next->header = newHeader("Test-header: 5"); |
||||||
|
list->next->next = NULL; |
||||||
|
munit_assert_int( 2, ==, countHeaders(list) ); |
||||||
|
list->next->next = malloc( sizeof( HeaderList ) ); |
||||||
|
list->next->next->header = newHeader("Test-header: 5"); |
||||||
|
list->next->next->next = NULL; |
||||||
|
munit_assert_int( 3, ==, countHeaders(list) ); |
||||||
|
return MUNIT_OK; |
||||||
|
} |
||||||
|
|
||||||
|
MunitResult testHeadersListAdd(const MunitParameter params[], |
||||||
|
void* user_data_or_fixture){ |
||||||
|
HeaderList *list = malloc( sizeof( HeaderList ) ); |
||||||
|
list->header = newHeader("Content-Length: 0"); |
||||||
|
addHeader( list, "Test-header: 5" ); |
||||||
|
munit_assert_int( 2, ==, countHeaders(list) ); |
||||||
|
addHeader( list, "Another-Test-header: 50" ); |
||||||
|
munit_assert_int( 3, ==, countHeaders(list) ); |
||||||
|
return MUNIT_OK; |
||||||
|
} |
||||||
|
|
||||||
|
MunitResult testHeadersListCharLength(const MunitParameter params[], |
||||||
|
void* user_data_or_fixture){ |
||||||
|
HeaderList *list = malloc( sizeof( HeaderList ) ); |
||||||
|
list->header = newHeader("Content-Length: 0"); |
||||||
|
munit_assert_int( headerListCharLength( list ) , ==, 19 ); |
||||||
|
addHeader( list, "Test-header: 5" ); |
||||||
|
munit_assert_int( headerListCharLength( list ) , ==, 35 ); |
||||||
|
addHeader( list, "Another-Test-header: 50" ); |
||||||
|
munit_assert_int( headerListCharLength( list ) , ==, 60 ); |
||||||
|
return MUNIT_OK; |
||||||
|
} |
||||||
|
|
||||||
|
MunitResult testHeadersToString(const MunitParameter params[], |
||||||
|
void* user_data_or_fixture){ |
||||||
|
HeaderList *list = malloc( sizeof( HeaderList ) ); |
||||||
|
list->header = newHeader("Content-Length: 0"); |
||||||
|
addHeader( list, "Test-header: 5" ); |
||||||
|
munit_assert_string_equal( headersToString(list), "Content-Length: 0\r\nTest-header: 5\r\n" ); |
||||||
|
return MUNIT_OK; |
||||||
|
} |
||||||
|
|
||||||
|
MunitResult testGetHeader(const MunitParameter params[], |
||||||
|
void* user_data_or_fixture){ |
||||||
|
HeaderList *list = malloc( sizeof( HeaderList ) ); |
||||||
|
list->header = newHeader("Content-Length: 0"); |
||||||
|
addHeader( list, "Test-header: 5" ); |
||||||
|
addHeader( list, "Another-Test-header: 50" ); |
||||||
|
Header *chosen = getHeader( list, "content-length" ); |
||||||
|
munit_assert_string_equal( chosen->value, "0" ); |
||||||
|
chosen = getHeader( list, "ConTENt-LenGth" ); |
||||||
|
munit_assert_string_equal( chosen->value, "0" ); |
||||||
|
chosen = getHeader( list, "test-header" ); |
||||||
|
munit_assert_string_equal( chosen->value, "5" ); |
||||||
|
chosen = getHeader( list, "another-test-header" ); |
||||||
|
munit_assert_string_equal( chosen->value, "50" ); |
||||||
|
chosen = getHeader( list, "Does-not-exist" ); |
||||||
|
munit_assert_null( chosen ); |
||||||
|
return MUNIT_OK; |
||||||
|
} |
||||||
|
|
||||||
|
static MunitTest requestresponse_tests[] = { |
||||||
|
{ |
||||||
|
"/headers/name", /* name */ |
||||||
|
testHeadersName, /* test */ |
||||||
|
NULL, /* setup */ |
||||||
|
NULL, /* tear_down */ |
||||||
|
MUNIT_TEST_OPTION_NONE, /* options */ |
||||||
|
NULL /* parameters */ |
||||||
|
}, { |
||||||
|
"/headers/value", /* name */ |
||||||
|
testHeadersValue, /* test */ |
||||||
|
NULL, /* setup */ |
||||||
|
NULL, /* tear_down */ |
||||||
|
MUNIT_TEST_OPTION_NONE, /* options */ |
||||||
|
NULL /* parameters */ |
||||||
|
}, { |
||||||
|
"/headerslist/count", /* name */ |
||||||
|
testHeadersListCount, /* test */ |
||||||
|
NULL, /* setup */ |
||||||
|
NULL, /* tear_down */ |
||||||
|
MUNIT_TEST_OPTION_NONE, /* options */ |
||||||
|
NULL /* parameters */ |
||||||
|
}, { |
||||||
|
"/headerslist/add", /* name */ |
||||||
|
testHeadersListAdd, /* test */ |
||||||
|
NULL, /* setup */ |
||||||
|
NULL, /* tear_down */ |
||||||
|
MUNIT_TEST_OPTION_NONE, /* options */ |
||||||
|
NULL /* parameters */ |
||||||
|
}, { |
||||||
|
"/headerslist/charLength", /* name */ |
||||||
|
testHeadersListCharLength, /* test */ |
||||||
|
NULL, /* setup */ |
||||||
|
NULL, /* tear_down */ |
||||||
|
MUNIT_TEST_OPTION_NONE, /* options */ |
||||||
|
NULL /* parameters */ |
||||||
|
}, { |
||||||
|
"/headerslist/toString", /* name */ |
||||||
|
testHeadersToString, /* test */ |
||||||
|
NULL, /* setup */ |
||||||
|
NULL, /* tear_down */ |
||||||
|
MUNIT_TEST_OPTION_NONE, /* options */ |
||||||
|
NULL /* parameters */ |
||||||
|
}, { |
||||||
|
"/headerslist/getHeader", /* name */ |
||||||
|
testGetHeader, /* test */ |
||||||
|
NULL, /* setup */ |
||||||
|
NULL, /* tear_down */ |
||||||
|
MUNIT_TEST_OPTION_NONE, /* options */ |
||||||
|
NULL /* parameters */ |
||||||
|
}, |
||||||
|
/* Mark the end of the array with an entry where the test
|
||||||
|
* function is NULL */ |
||||||
|
{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL } |
||||||
|
}; |
||||||
|
|
||||||
|
MunitSuite requestresponse_test_suite = { |
||||||
|
"/requestresponse", /* name */ |
||||||
|
requestresponse_tests, /* tests */ |
||||||
|
NULL, /* suites */ |
||||||
|
1, /* iterations */ |
||||||
|
MUNIT_SUITE_OPTION_NONE /* options */ |
||||||
|
}; |
||||||
|
|
||||||
|
#ifndef MAINTEST |
||||||
|
#define MAINTEST |
||||||
|
|
||||||
|
int main (int argc, char* argv[]) { |
||||||
|
return munit_suite_main(&requestresponse_test_suite, NULL, argc, argv); |
||||||
|
} |
||||||
|
|
||||||
|
#endif /* ifndef MAINTEST */ |
||||||
|
|
||||||
|
#endif /* ifndef REQUESTRESPONSE_TEST */ |
@ -0,0 +1,109 @@ |
|||||||
|
#ifndef RESPONSE_TEST |
||||||
|
#define RESPONSE_TEST value |
||||||
|
|
||||||
|
#include "munit/munit.h" |
||||||
|
#ifndef REQUESTRESPONSE_C |
||||||
|
#define REQUESTRESPONSE_C value |
||||||
|
#include "requestresponse.test.c" |
||||||
|
#endif /* ifndef REQUESTRESPONSE_C */ |
||||||
|
#include "../src/response.c" |
||||||
|
|
||||||
|
|
||||||
|
MunitResult testResponseNewStatus(const MunitParameter params[], |
||||||
|
void* user_data_or_fixture){ |
||||||
|
Response *rsp = newResponse(); |
||||||
|
munit_assert_int( rsp->statusCode, ==, 200 ); |
||||||
|
return MUNIT_OK; |
||||||
|
} |
||||||
|
|
||||||
|
MunitResult testResponseNewStatusMessage(const MunitParameter params[], |
||||||
|
void* user_data_or_fixture){ |
||||||
|
Response *rsp = newResponse(); |
||||||
|
munit_assert_string_equal( rsp->statusMessage, "OK" ); |
||||||
|
return MUNIT_OK; |
||||||
|
} |
||||||
|
|
||||||
|
MunitResult testResponseNewVersion(const MunitParameter params[], |
||||||
|
void* user_data_or_fixture){ |
||||||
|
Response *rsp = newResponse(); |
||||||
|
munit_assert_float( rsp->version, ==, 1.1 ); |
||||||
|
return MUNIT_OK; |
||||||
|
} |
||||||
|
|
||||||
|
MunitResult testResponseSetBody(const MunitParameter params[], |
||||||
|
void* user_data_or_fixture){ |
||||||
|
Response *rsp = newResponse(); |
||||||
|
responseSetBody( rsp, "Testing", 1 ); |
||||||
|
munit_assert_string_equal( rsp->body, "Testing" ); |
||||||
|
munit_assert_string_equal( getHeader( rsp->headers, "content-length" )->value, "7" ); |
||||||
|
return MUNIT_OK; |
||||||
|
} |
||||||
|
|
||||||
|
MunitResult testResponseToString(const MunitParameter params[], |
||||||
|
void* user_data_or_fixture){ |
||||||
|
Response *rsp = newResponse(); |
||||||
|
responseSetBody( rsp, "Testing", 1 ); |
||||||
|
munit_assert_string_equal( responseToString( rsp ), "HTTP/1.1 200 OK\r\nContent-Length: 7\r\nContent-Type: text/plain\r\n\r\nTesting" ); |
||||||
|
return MUNIT_OK; |
||||||
|
} |
||||||
|
|
||||||
|
static MunitTest response_tests[] = { |
||||||
|
{ |
||||||
|
"/new/status", /* name */ |
||||||
|
testResponseNewStatus, /* test */ |
||||||
|
NULL, /* setup */ |
||||||
|
NULL, /* tear_down */ |
||||||
|
MUNIT_TEST_OPTION_NONE, /* options */ |
||||||
|
NULL /* parameters */ |
||||||
|
}, { |
||||||
|
"/new/statusMessage", /* name */ |
||||||
|
testResponseNewStatusMessage, /* test */ |
||||||
|
NULL, /* setup */ |
||||||
|
NULL, /* tear_down */ |
||||||
|
MUNIT_TEST_OPTION_NONE, /* options */ |
||||||
|
NULL /* parameters */ |
||||||
|
}, { |
||||||
|
"/new/version", /* name */ |
||||||
|
testResponseNewVersion, /* test */ |
||||||
|
NULL, /* setup */ |
||||||
|
NULL, /* tear_down */ |
||||||
|
MUNIT_TEST_OPTION_NONE, /* options */ |
||||||
|
NULL /* parameters */ |
||||||
|
}, { |
||||||
|
"/set/body", /* name */ |
||||||
|
testResponseSetBody, /* test */ |
||||||
|
NULL, /* setup */ |
||||||
|
NULL, /* tear_down */ |
||||||
|
MUNIT_TEST_OPTION_NONE, /* options */ |
||||||
|
NULL /* parameters */ |
||||||
|
}, { |
||||||
|
"/to/string", /* name */ |
||||||
|
testResponseToString, /* test */ |
||||||
|
NULL, /* setup */ |
||||||
|
NULL, /* tear_down */ |
||||||
|
MUNIT_TEST_OPTION_NONE, /* options */ |
||||||
|
NULL /* parameters */ |
||||||
|
}, |
||||||
|
/* Mark the end of the array with an entry where the test
|
||||||
|
* function is NULL */ |
||||||
|
{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL } |
||||||
|
}; |
||||||
|
|
||||||
|
MunitSuite response_test_suite = { |
||||||
|
"/response", /* name */ |
||||||
|
response_tests, /* tests */ |
||||||
|
NULL, /* suites */ |
||||||
|
1, /* iterations */ |
||||||
|
MUNIT_SUITE_OPTION_NONE /* options */ |
||||||
|
}; |
||||||
|
|
||||||
|
#ifndef MAINTEST |
||||||
|
#define MAINTEST |
||||||
|
|
||||||
|
int main (int argc, char* argv[]) { |
||||||
|
return munit_suite_main(&response_test_suite, NULL, argc, argv); |
||||||
|
} |
||||||
|
|
||||||
|
#endif /* ifndef MAINTEST */ |
||||||
|
|
||||||
|
#endif /* ifndef RESPONSE_TEST */ |
Loading…
Reference in new issue