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 34typedef int (*BinaryOperator)(int a, int b); 35 36typedef struct OperatorFunction { 37 const char* operator; 38 BinaryOperator function; 39} OperatorFunction; 40 41extern int add(int a, int b); 42extern int subtract(int a, int b); 43extern int multiply(int a, int b); 44extern int divide(int a, int b); 45extern 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); 49extern 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); 55extern 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. */ 59int 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. */ 74int 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. 87int 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. 95void 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. 101void 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. 107void 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. 113void 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. 119void 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. */ 125void 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. */ 131void 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. */ 141void 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. */ 148void 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. */ 161void 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. 173void 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. */ 188void 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. */ 202void 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. */ 218void 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. 234void 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. */ 246void 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. */ 269void 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. */ 292void 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. */ 315void 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. 338void 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. 375void 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. 385void 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 399int 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