#include #include #include #include #include #include #include #include /* for write */ #define DEBUG #include "parser.h" static int verify_string( const char *str, const char *str_value, int line, const char *test_name ) { int str_len = strlen( str ); int str_value_length = strlen( str_value ); if( str_len != str_value_length || strcmp( str, str_value ) ){ printf( "Strings are not equal\n\"%s\":%d\n!=\n\"%s\":%d\nat %s:%d\n", str, str_len, str_value, str_value_length, test_name, line ); return 1; } return 0; } static int verify_match_string( const char *expr, const char *str_value, int line, const char *test_name ) { int status; regex_t reg_expr; regcomp( ®_expr, expr, REG_EXTENDED|REG_NOSUB ); status = regexec( ®_expr, str_value, (size_t) 0, NULL, 0 ); regfree( ®_expr ); if( status != 0 ){ printf( "No matching %s expression found in '%s' at %s:%d ", expr, str_value, test_name, line ); return 1; } return 0; } static int verify_no_match_string( const char *expr, const char *str_value, int line, const char *test_name ) { int status; regex_t reg_expr; regcomp( ®_expr, expr, REG_EXTENDED|REG_NOSUB ); status = regexec( ®_expr, str_value, (size_t) 0, NULL, 0 ); regfree( ®_expr ); if( status == 0 ){ printf( "Found matching %s expression found in '%s' at %s:%d ", expr, str_value, test_name, line ); return 1; } return 0; } static int verify_true( int expr, int line, const char *test_name ) { if( !expr ){ printf( "Expression is not true at %s:%d\n", test_name, line ); return 1; } return 0; } static int start_tag_count = 0; static int end_tag_count = 0; static void start_tag_handler( const void *data, const char *name_start, size_t name_length, ESIAttribute *attributes, void *user_data ) { ESIAttribute *attr = attributes; char *name = esi_strndup( name_start, name_length ); // printf( "Start Tag: %s\n", name ); ++start_tag_count; while( attr ){ // printf( "\tAttr: %s:%s\n", attr->name, attr->value ); attr = attr->next; } free( name ); } static void end_tag_handler( const void *data, const char *name_start, size_t name_length, void *user_data ) { char *name = esi_strndup( name_start, name_length ); // printf( "End Tag: %s\n", name ); ++end_tag_count; free( name ); } static void output_handler( const void *data, size_t size, void *user_data ) { write( (int)user_data, data, size ); } static void feed_data( ESIParser *parser, const char *data ) { // printf( "feeding: %s\n", data ); esi_parser_execute( parser, data, strlen(data) ); } #define TEST_INIT \ int fd; \ struct stat st; \ char *output = NULL; \ size_t output_size; \ int status = 0;\ start_tag_count = 0; \ end_tag_count = 0; \ printf( "%s: ", __FUNCTION__ ); \ esi_parser_init( parser ); \ \ esi_parser_start_tag_handler( parser, start_tag_handler ); \ esi_parser_end_tag_handler( parser, end_tag_handler ); \ \ unlink( "output.html" ); \ fd = open( "output.html", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); \ parser->user_data = (void*)fd; \ esi_parser_output_handler( parser, output_handler ); #define TEST_PREPARE_ASSERTIONS \ esi_parser_finish( parser ); \ \ close( fd ); \ \ fd = open( "output.html", O_RDONLY ); \ fstat( fd, &st ); \ output_size = st.st_size; \ output = (char*)malloc(sizeof(char)*(output_size+1)); \ read( fd, output, output_size ); \ output[output_size] = '\0'; \ close( fd ); #define TEST_FINISH\ free( output ); \ if( status ){ \ printf( "FAILED\n" ); \ }else{ \ printf( "PASSED\n" ); \ } #define ASSERT_EQUAL( s1, s2 )\ status |= verify_string( s1, s2, __LINE__, __FUNCTION__ ) #define ASSERT_MATCH( regex, str )\ status |= verify_match_string( regex, str, __LINE__, __FUNCTION__ ) #define ASSERT_NO_MATCH( regex, str )\ status |= verify_no_match_string( regex, str, __LINE__, __FUNCTION__ ) #define ASSERT_TRUE( expr )\ status |= verify_true( expr, __LINE__, __FUNCTION__ ) static void test_simple_parser_input( ESIParser *parser ) { TEST_INIT feed_data( parser, "

some input

some more input\nsome inputsome more input" ); TEST_PREPARE_ASSERTIONS ASSERT_EQUAL( "

some input

some more input\nsome inputsome more input", output ); ASSERT_TRUE( start_tag_count == 2 ); ASSERT_TRUE( end_tag_count == 2 ); TEST_FINISH } static void test_chunked_input( ESIParser *parser ) { TEST_INIT feed_data( parser, "some input<" ); feed_data( parser, "e" ); feed_data( parser, "s" ); feed_data( parser, "i" ); feed_data( parser, ":" ); feed_data( parser, "i" ); feed_data( parser, "n" ); feed_data( parser, "lin" ); feed_data( parser, "e" ); feed_data( parser, " " ); feed_data( parser, "s" ); feed_data( parser, "rc" ); feed_data( parser, "=" ); feed_data( parser, "'hel" ); feed_data( parser, "lo'" ); feed_data( parser, "/" ); feed_data( parser, ">some more input\nsome input" ); feed_data( parser, "some more input" ); TEST_PREPARE_ASSERTIONS ASSERT_EQUAL( "some inputsome more input\nsome inputsome more input", output ); ASSERT_TRUE( start_tag_count == 2 ); ASSERT_TRUE( end_tag_count == 2 ); TEST_FINISH } #define ESI_SAMPLE "../../../test/unit/esi-sample.html" static void test_sample_input( ESIParser *parser ) { int size = 0; FILE *input = NULL; char buffer[16]; /* intentially using a small buffer size */ TEST_INIT input = fopen( ESI_SAMPLE, "r" ); if( !input ){ printf( "Failed to open %s\n", ESI_SAMPLE ); return; } while( (size = fread( buffer, sizeof(char), 15, input )) > 0 ){ esi_parser_execute( parser, buffer, size ); } fclose( input ); TEST_PREPARE_ASSERTIONS ASSERT_MATCH("
", output ); ASSERT_MATCH("
some content
", output); ASSERT_MATCH("Support for em tags since they have an initial start sequence similar to and <esi: start/end sequence", output ); ASSERT_NO_MATCH("some more input" ); feed_data( parser, "some inputsome more input\nsome inputsome more input" ); feed_data( parser, "some inputsome more input\nsome inputsome more input" ); feed_data( parser, "

some input

some more input\nsome inputsome more input" ); feed_data( parser, "" ); TEST_PREPARE_ASSERTIONS ASSERT_EQUAL("some more inputsome inputsome more input\nsome inputsome more inputsome inputsome more input\nsome inputsome more input

some input

some more input\nsome inputsome more input", output ); ASSERT_TRUE( start_tag_count == 7 ); ASSERT_TRUE( end_tag_count == 7 ); TEST_FINISH } int main( int argc, char **argv ) { ESIParser *parser = esi_parser_new(); test_simple_parser_input( parser ); test_chunked_input( parser ); test_sample_input( parser ); test_line_by_line( parser ); esi_parser_free( parser ); return 0; }