Home | History | Annotate | Download | only in example
      1 /*
      2  * Copyright 2008 Google Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 #include <stdarg.h>
     17 #include <stddef.h>
     18 #include <setjmp.h>
     19 #include "cmockery.h"
     20 #include <stdio.h>
     21 
     22 #ifdef _WIN32
     23 // Compatibility with the Windows standard C library.
     24 #define vsnprintf _vsnprintf
     25 #endif // _WIN32
     26 
     27 #define array_length(x) (sizeof(x) / sizeof((x)[0]))
     28 
     29 /* To simplify this code, these functions and data structures could have been
     30  * separated out from the application example.c into a header shared with
     31  * test application.  However, this example illustrates how it's possible to
     32  * test existing code with little modification. */
     33 
     34 typedef int (*BinaryOperator)(int a, int b);
     35 
     36 typedef struct OperatorFunction {
     37 	const char* operator;
     38 	BinaryOperator function;
     39 } OperatorFunction;
     40 
     41 extern int add(int a, int b);
     42 extern int subtract(int a, int b);
     43 extern int multiply(int a, int b);
     44 extern int divide(int a, int b);
     45 extern BinaryOperator find_operator_function_by_string(
     46         const size_t number_of_operator_functions,
     47         const OperatorFunction * const operator_functions,
     48         const char* const operator_string);
     49 extern int perform_operation(
     50         int number_of_arguments, char *arguments[],
     51         const size_t number_of_operator_functions,
     52         const OperatorFunction * const operator_functions,
     53         int * const number_of_intermediate_values,
     54         int ** const intermediate_values, int * const error_occurred);
     55 extern int example_main(int argc, char *argv[]);
     56 
     57 /* A mock fprintf function that checks the value of strings printed to the
     58  * standard error stream. */
     59 int example_test_fprintf(FILE* const file, const char *format, ...) {
     60 	int return_value;
     61 	va_list args;
     62 	char temporary_buffer[256];
     63 	assert_true(file == stderr);
     64 	va_start(args, format);
     65 	return_value = vsnprintf(temporary_buffer, sizeof(temporary_buffer),
     66 	                         format, args);
     67 	check_expected(temporary_buffer);
     68 	va_end(args);
     69 	return return_value;
     70 }
     71 
     72 /* A mock printf function that checks the value of strings printed to the
     73  * standard output stream. */
     74 int example_test_printf(const char *format, ...) {
     75 	int return_value;
     76 	va_list args;
     77 	char temporary_buffer[256];
     78 	va_start(args, format);
     79 	return_value = vsnprintf(temporary_buffer, sizeof(temporary_buffer),
     80 	                         format, args);
     81 	check_expected(temporary_buffer);
     82 	va_end(args);
     83 	return return_value;
     84 }
     85 
     86 // A mock binary operator function.
     87 int binary_operator(int a, int b) {
     88 	check_expected(a);
     89 	check_expected(b);
     90 	return (int)mock();
     91 }
     92 
     93 
     94 // Ensure add() adds two integers correctly.
     95 void test_add(void **state) {
     96 	assert_int_equal(add(3, 3), 6);
     97 	assert_int_equal(add(3, -3), 0);
     98 }
     99 
    100 // Ensure subtract() subtracts two integers correctly.
    101 void test_subtract(void **state) {
    102 	assert_int_equal(subtract(3, 3), 0);
    103 	assert_int_equal(subtract(3, -3), 6);
    104 }
    105 
    106 // Ensure multiple() mulitplies two integers correctly.
    107 void test_multiply(void **state) {
    108 	assert_int_equal(multiply(3, 3), 9);
    109 	assert_int_equal(multiply(3, 0), 0);
    110 }
    111 
    112 // Ensure divide() divides one integer by another correctly.
    113 void test_divide(void **state) {
    114 	assert_int_equal(divide(10, 2), 5);
    115 	assert_int_equal(divide(2, 10), 0);
    116 }
    117 
    118 // Ensure divide() asserts when trying to divide by zero.
    119 void test_divide_by_zero(void **state) {
    120 	expect_assert_failure(divide(100, 0));
    121 }
    122 
    123 /* Ensure find_operator_function_by_string() asserts when a NULL pointer is
    124  * specified as the table to search. */
    125 void test_find_operator_function_by_string_null_functions(void **state) {
    126 	expect_assert_failure(find_operator_function_by_string(1, NULL, "test"));
    127 }
    128 
    129 /* Ensure find_operator_function_by_string() asserts when a NULL pointer is
    130  * specified as the string to search for. */
    131 void test_find_operator_function_by_string_null_string(void **state) {
    132 	const OperatorFunction operator_functions[] = {
    133 		{"+", binary_operator},
    134 	};
    135 	expect_assert_failure(find_operator_function_by_string(
    136 	    array_length(operator_functions), operator_functions, NULL));
    137 }
    138 
    139 /* Ensure find_operator_function_by_string() returns NULL when a NULL pointer
    140  * is specified as the table to search when the table size is 0. */
    141 void test_find_operator_function_by_string_valid_null_functions(void **state) {
    142   assert_int_equal((int)find_operator_function_by_string(0, NULL, "test"),
    143 	                     (int)NULL);
    144 }
    145 
    146 /* Ensure find_operator_function_by_string() returns NULL when searching for
    147  * an operator string that isn't in the specified table. */
    148 void test_find_operator_function_by_string_not_found(void **state) {
    149 	const OperatorFunction operator_functions[] = {
    150 		{"+", binary_operator},
    151 		{"-", binary_operator},
    152 		{"/", binary_operator},
    153 	};
    154 	assert_int_equal((int)find_operator_function_by_string(
    155 	        array_length(operator_functions), operator_functions, "test"),
    156 	    (int)NULL);
    157 }
    158 
    159 /* Ensure find_operator_function_by_string() returns the correct function when
    160  * searching for an operator string that is in the specified table. */
    161 void test_find_operator_function_by_string_found(void **state) {
    162 	const OperatorFunction operator_functions[] = {
    163 		{"+", (BinaryOperator)0x12345678},
    164 		{"-", (BinaryOperator)0xDEADBEEF},
    165 		{"/", (BinaryOperator)0xABADCAFE},
    166 	};
    167 	assert_int_equal((int)find_operator_function_by_string(
    168 	        array_length(operator_functions), operator_functions, "-"),
    169 	    0xDEADBEEF);
    170 }
    171 
    172 // Ensure perform_operation() asserts when a NULL arguments array is specified.
    173 void test_perform_operation_null_args(void **state) {
    174 	const OperatorFunction operator_functions[] = {
    175 		{"+", binary_operator},
    176 	};
    177 	int number_of_intermediate_values;
    178 	int *intermediate_values;
    179 	int error_occurred;
    180 	expect_assert_failure(perform_operation(
    181 	    1, NULL, array_length(operator_functions), operator_functions,
    182 	    &number_of_intermediate_values, &intermediate_values,
    183 	    &error_occurred));
    184 }
    185 
    186 /* Ensure perform_operation() asserts when a NULL operator_functions array is
    187  * specified. */
    188 void test_perform_operation_null_operator_functions(void **state) {
    189 	char *args[] = {
    190 		"1", "+", "2", "*", "4"
    191 	};
    192 	int number_of_intermediate_values;
    193 	int *intermediate_values;
    194 	int error_occurred;
    195 	expect_assert_failure(perform_operation(
    196 	    array_length(args), args, 1, NULL, &number_of_intermediate_values,
    197 	    &intermediate_values, &error_occurred));
    198 }
    199 
    200 /* Ensure perform_operation() asserts when a NULL pointer is specified for
    201  * number_of_intermediate_values. */
    202 void test_perform_operation_null_number_of_intermediate_values(void **state) {
    203 	const OperatorFunction operator_functions[] = {
    204 		{"+", binary_operator},
    205 	};
    206 	char *args[] = {
    207 		"1", "+", "2", "*", "4"
    208 	};
    209 	int *intermediate_values;
    210 	int error_occurred;
    211 	expect_assert_failure(perform_operation(
    212 	    array_length(args), args, 1, operator_functions, NULL,
    213 	    &intermediate_values, &error_occurred));
    214 }
    215 
    216 /* Ensure perform_operation() asserts when a NULL pointer is specified for
    217  * intermediate_values. */
    218 void test_perform_operation_null_intermediate_values(void **state) {
    219 	const OperatorFunction operator_functions[] = {
    220 		{"+", binary_operator},
    221 	};
    222 	char *args[] = {
    223 		"1", "+", "2", "*", "4"
    224 	};
    225 	int number_of_intermediate_values;
    226 	int error_occurred;
    227 	expect_assert_failure(perform_operation(
    228 	    array_length(args), args, array_length(operator_functions),
    229 	    operator_functions, &number_of_intermediate_values, NULL,
    230 	    &error_occurred));
    231 }
    232 
    233 // Ensure perform_operation() returns 0 when no arguments are specified.
    234 void test_perform_operation_no_arguments(void **state) {
    235 	int number_of_intermediate_values;
    236 	int *intermediate_values;
    237 	int error_occurred;
    238 	assert_int_equal(perform_operation(
    239 	    0, NULL, 0, NULL, &number_of_intermediate_values, &intermediate_values,
    240 	    &error_occurred), 0);
    241 	assert_int_equal(error_occurred, 0);
    242 }
    243 
    244 /* Ensure perform_operation() returns an error if the first argument isn't
    245  * an integer string. */
    246 void test_perform_operation_first_arg_not_integer(void **state) {
    247 	const OperatorFunction operator_functions[] = {
    248 		{"+", binary_operator},
    249 	};
    250 	char *args[] = {
    251 		"test", "+", "2", "*", "4"
    252 	};
    253 	int number_of_intermediate_values;
    254 	int *intermediate_values;
    255 	int error_occurred;
    256 
    257 	expect_string(example_test_fprintf, temporary_buffer,
    258 	              "Unable to parse integer from argument test\n");
    259 
    260 	assert_int_equal(perform_operation(
    261 	    array_length(args), args, array_length(operator_functions),
    262 	    operator_functions, &number_of_intermediate_values,
    263 	    &intermediate_values, &error_occurred), 0);
    264 	assert_int_equal(error_occurred, 1);
    265 }
    266 
    267 /* Ensure perform_operation() returns an error when parsing an unknown
    268  * operator. */
    269 void test_perform_operation_unknown_operator(void **state) {
    270 	const OperatorFunction operator_functions[] = {
    271 		{"+", binary_operator},
    272 	};
    273 	char *args[] = {
    274 		"1", "*", "2", "*", "4"
    275 	};
    276 	int number_of_intermediate_values;
    277 	int *intermediate_values;
    278 	int error_occurred;
    279 
    280 	expect_string(example_test_fprintf, temporary_buffer,
    281 	              "Unknown operator *, argument 1\n");
    282 
    283 	assert_int_equal(perform_operation(
    284 	    array_length(args), args, array_length(operator_functions),
    285 	    operator_functions, &number_of_intermediate_values,
    286 	    &intermediate_values, &error_occurred), 0);
    287 	assert_int_equal(error_occurred, 1);
    288 }
    289 
    290 /* Ensure perform_operation() returns an error when nothing follows an
    291  * operator. */
    292 void test_perform_operation_missing_argument(void **state) {
    293 	const OperatorFunction operator_functions[] = {
    294 		{"+", binary_operator},
    295 	};
    296 	char *args[] = {
    297 		"1", "+",
    298 	};
    299 	int number_of_intermediate_values;
    300 	int *intermediate_values;
    301 	int error_occurred;
    302 
    303 	expect_string(example_test_fprintf, temporary_buffer,
    304 	              "Binary operator + missing argument\n");
    305 
    306 	assert_int_equal(perform_operation(
    307 	    array_length(args), args, array_length(operator_functions),
    308 	    operator_functions, &number_of_intermediate_values,
    309 	    &intermediate_values, &error_occurred), 0);
    310 	assert_int_equal(error_occurred, 1);
    311 }
    312 
    313 /* Ensure perform_operation() returns an error when an integer doesn't follow
    314  * an operator. */
    315 void test_perform_operation_no_integer_after_operator(void **state) {
    316 	const OperatorFunction operator_functions[] = {
    317 		{"+", binary_operator},
    318 	};
    319 	char *args[] = {
    320 		"1", "+", "test",
    321 	};
    322 	int number_of_intermediate_values;
    323 	int *intermediate_values;
    324 	int error_occurred;
    325 
    326 	expect_string(example_test_fprintf, temporary_buffer,
    327 	              "Unable to parse integer test of argument 2\n");
    328 
    329 	assert_int_equal(perform_operation(
    330 	    array_length(args), args, array_length(operator_functions),
    331 	    operator_functions, &number_of_intermediate_values,
    332 	    &intermediate_values, &error_occurred), 0);
    333 	assert_int_equal(error_occurred, 1);
    334 }
    335 
    336 
    337 // Ensure perform_operation() succeeds given valid input parameters.
    338 void test_perform_operation(void **state) {
    339 	const OperatorFunction operator_functions[] = {
    340 		{"+", binary_operator},
    341 		{"*", binary_operator},
    342 	};
    343 	char *args[] = {
    344 		"1", "+", "3", "*", "10",
    345 	};
    346 	int number_of_intermediate_values;
    347 	int *intermediate_values;
    348 	int error_occurred;
    349 
    350 	// Setup return values of mock operator functions.
    351 	// Addition.
    352 	expect_value(binary_operator, a, 1);
    353 	expect_value(binary_operator, b, 3);
    354 	will_return(binary_operator, 4);
    355 
    356 	// Multiplication.
    357 	expect_value(binary_operator, a, 4);
    358 	expect_value(binary_operator, b, 10);
    359 	will_return(binary_operator, 40);
    360 
    361 	assert_int_equal(perform_operation(
    362 	    array_length(args), args, array_length(operator_functions),
    363 	    operator_functions, &number_of_intermediate_values,
    364 	    &intermediate_values, &error_occurred), 40);
    365 	assert_int_equal(error_occurred, 0);
    366 
    367 	assert_true(intermediate_values);
    368 	assert_int_equal(intermediate_values[0], 4);
    369 	assert_int_equal(intermediate_values[1], 40);
    370 	test_free(intermediate_values);
    371 }
    372 
    373 
    374 // Ensure main() in example.c succeeds given no arguments.
    375 void test_example_main_no_args(void **state) {
    376 	char *args[] = {
    377 		"example",
    378 	};
    379 	assert_int_equal(example_main(array_length(args), args), 0);
    380 }
    381 
    382 
    383 
    384 // Ensure main() in example.c succeeds given valid input arguments.
    385 void test_example_main(void **state) {
    386 	char *args[] = {
    387 		"example", "1", "+", "3", "*", "10",
    388 	};
    389 
    390 	expect_string(example_test_printf, temporary_buffer, "1\n");
    391 	expect_string(example_test_printf, temporary_buffer, "  + 3 = 4\n");
    392 	expect_string(example_test_printf, temporary_buffer, "  * 10 = 40\n");
    393 	expect_string(example_test_printf, temporary_buffer, "= 40\n");
    394 
    395 	assert_int_equal(example_main(array_length(args), args), 0);
    396 }
    397 
    398 
    399 int main(int argc, char* argv[]) {
    400 	UnitTest tests[] = {
    401 		unit_test(test_add),
    402 		unit_test(test_subtract),
    403 		unit_test(test_multiply),
    404 		unit_test(test_divide),
    405 		unit_test(test_divide_by_zero),
    406 		unit_test(test_find_operator_function_by_string_null_functions),
    407 		unit_test(test_find_operator_function_by_string_null_string),
    408 		unit_test(test_find_operator_function_by_string_valid_null_functions),
    409 		unit_test(test_find_operator_function_by_string_not_found),
    410 		unit_test(test_find_operator_function_by_string_found),
    411 		unit_test(test_perform_operation_null_args),
    412 		unit_test(test_perform_operation_null_operator_functions),
    413 		unit_test(test_perform_operation_null_number_of_intermediate_values),
    414 		unit_test(test_perform_operation_null_intermediate_values),
    415 		unit_test(test_perform_operation_no_arguments),
    416 		unit_test(test_perform_operation_first_arg_not_integer),
    417 		unit_test(test_perform_operation_unknown_operator),
    418 		unit_test(test_perform_operation_missing_argument),
    419 		unit_test(test_perform_operation_no_integer_after_operator),
    420 		unit_test(test_perform_operation),
    421 		unit_test(test_example_main_no_args),
    422 		unit_test(test_example_main),
    423 	};
    424 	return run_tests(tests);
    425 }
    426