2 * Copyright 2008 Google Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
23 /* Compatibility with the Windows standard C library. */
24 #define vsnprintf _vsnprintf
27 #define array_length(x) (sizeof(x) / sizeof((x)[0]))
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. */
34 typedef int (*BinaryOperator)(int a, int b);
36 typedef struct OperatorFunction {
38 BinaryOperator function;
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[]);
57 int example_test_fprintf(FILE* const file, const char *format, ...) PRINTF_ATTRIBUTE(2, 3);
58 int example_test_printf(const char *format, ...) PRINTF_ATTRIBUTE(1, 2);
60 char temporary_buffer[256];
62 /* A mock fprintf function that checks the value of strings printed to the
63 * standard error stream. */
64 int example_test_fprintf(FILE* const file, const char *format, ...) {
67 assert_true(file == stderr);
68 va_start(args, format);
69 return_value = vsnprintf(temporary_buffer, sizeof(temporary_buffer),
71 check_expected(temporary_buffer);
76 /* A mock printf function that checks the value of strings printed to the
77 * standard output stream. */
78 int example_test_printf(const char *format, ...) {
81 va_start(args, format);
82 return_value = vsnprintf(temporary_buffer, sizeof(temporary_buffer),
84 check_expected(temporary_buffer);
89 /* A mock binary operator function. */
90 static int binary_operator(int a, int b) {
97 /* Ensure add() adds two integers correctly. */
98 static void test_add(void **state) {
99 (void) state; /* unused */
101 assert_int_equal(add(3, 3), 6);
102 assert_int_equal(add(3, -3), 0);
105 /* Ensure subtract() subtracts two integers correctly. */
106 static void test_subtract(void **state) {
107 (void) state; /* unused */
109 assert_int_equal(subtract(3, 3), 0);
110 assert_int_equal(subtract(3, -3), 6);
113 /* Ensure multiple() mulitplies two integers correctly. */
114 static void test_multiply(void **state) {
115 (void) state; /* unused */
117 assert_int_equal(multiply(3, 3), 9);
118 assert_int_equal(multiply(3, 0), 0);
121 /* Ensure divide() divides one integer by another correctly. */
122 static void test_divide(void **state) {
123 (void) state; /* unused */
125 assert_int_equal(divide(10, 2), 5);
126 assert_int_equal(divide(2, 10), 0);
129 /* Ensure divide() asserts when trying to divide by zero. */
130 static void test_divide_by_zero(void **state) {
131 (void) state; /* unused */
133 expect_assert_failure(divide(100, 0));
136 /* Ensure find_operator_function_by_string() asserts when a NULL pointer is
137 * specified as the table to search. */
138 static void test_find_operator_function_by_string_null_functions(void **state) {
139 (void) state; /* unused */
141 expect_assert_failure(find_operator_function_by_string(1, NULL, "test"));
144 /* Ensure find_operator_function_by_string() asserts when a NULL pointer is
145 * specified as the string to search for. */
146 static void test_find_operator_function_by_string_null_string(void **state) {
147 const OperatorFunction operator_functions[] = {
148 {"+", binary_operator},
151 (void) state; /* unused */
153 expect_assert_failure(find_operator_function_by_string(
154 array_length(operator_functions), operator_functions, NULL));
157 /* Ensure find_operator_function_by_string() returns NULL when a NULL pointer
158 * is specified as the table to search when the table size is 0. */
159 static void test_find_operator_function_by_string_valid_null_functions(void **state) {
160 (void) state; /* unused */
162 assert_int_equal(find_operator_function_by_string(0, NULL, "test"), NULL);
165 /* Ensure find_operator_function_by_string() returns NULL when searching for
166 * an operator string that isn't in the specified table. */
167 static void test_find_operator_function_by_string_not_found(void **state) {
168 const OperatorFunction operator_functions[] = {
169 {"+", binary_operator},
170 {"-", binary_operator},
171 {"/", binary_operator},
174 (void) state; /* unused */
176 assert_int_equal(find_operator_function_by_string(
177 array_length(operator_functions), operator_functions, "test"),
181 /* Ensure find_operator_function_by_string() returns the correct function when
182 * searching for an operator string that is in the specified table. */
183 static void test_find_operator_function_by_string_found(void **state) {
184 const OperatorFunction operator_functions[] = {
185 {"+", (BinaryOperator)0x12345678},
186 {"-", (BinaryOperator)0xDEADBEEF},
187 {"/", (BinaryOperator)0xABADCAFE},
190 (void) state; /* unused */
192 assert_int_equal(find_operator_function_by_string(
193 array_length(operator_functions), operator_functions, "-"),
197 /* Ensure perform_operation() asserts when a NULL arguments array is specified. */
198 static void test_perform_operation_null_args(void **state) {
199 const OperatorFunction operator_functions[] = {
200 {"+", binary_operator},
202 int number_of_intermediate_values;
203 int *intermediate_values;
206 (void) state; /* unused */
208 expect_assert_failure(perform_operation(
209 1, NULL, array_length(operator_functions), operator_functions,
210 &number_of_intermediate_values, &intermediate_values,
214 /* Ensure perform_operation() asserts when a NULL operator_functions array is
216 static void test_perform_operation_null_operator_functions(void **state) {
217 const char *args[] = {
218 "1", "+", "2", "*", "4"
220 int number_of_intermediate_values;
221 int *intermediate_values;
224 (void) state; /* unused */
226 expect_assert_failure(perform_operation(
227 array_length(args), (char **) args, 1, NULL, &number_of_intermediate_values,
228 &intermediate_values, &error_occurred));
231 /* Ensure perform_operation() asserts when a NULL pointer is specified for
232 * number_of_intermediate_values. */
233 static void test_perform_operation_null_number_of_intermediate_values(void **state) {
234 const OperatorFunction operator_functions[] = {
235 {"+", binary_operator},
237 const char *args[] = {
238 "1", "+", "2", "*", "4"
240 int *intermediate_values;
243 (void) state; /* unused */
245 expect_assert_failure(perform_operation(
246 array_length(args), (char **) args, 1, operator_functions, NULL,
247 &intermediate_values, &error_occurred));
250 /* Ensure perform_operation() asserts when a NULL pointer is specified for
251 * intermediate_values. */
252 static void test_perform_operation_null_intermediate_values(void **state) {
253 const OperatorFunction operator_functions[] = {
254 {"+", binary_operator},
256 const char *args[] = {
257 "1", "+", "2", "*", "4"
259 int number_of_intermediate_values;
262 (void) state; /* unused */
264 expect_assert_failure(perform_operation(
265 array_length(args), (char **) args, array_length(operator_functions),
266 operator_functions, &number_of_intermediate_values, NULL,
270 /* Ensure perform_operation() returns 0 when no arguments are specified. */
271 static void test_perform_operation_no_arguments(void **state) {
272 int number_of_intermediate_values;
273 int *intermediate_values;
276 (void) state; /* unused */
278 assert_int_equal(perform_operation(
279 0, NULL, 0, NULL, &number_of_intermediate_values, &intermediate_values,
280 &error_occurred), 0);
281 assert_int_equal(error_occurred, 0);
284 /* Ensure perform_operation() returns an error if the first argument isn't
285 * an integer string. */
286 static void test_perform_operation_first_arg_not_integer(void **state) {
287 const OperatorFunction operator_functions[] = {
288 {"+", binary_operator},
290 const char *args[] = {
291 "test", "+", "2", "*", "4"
293 int number_of_intermediate_values;
294 int *intermediate_values;
297 (void) state; /* unused */
299 expect_string(example_test_fprintf, temporary_buffer,
300 "Unable to parse integer from argument test\n");
302 assert_int_equal(perform_operation(
303 array_length(args), (char **) args, array_length(operator_functions),
304 operator_functions, &number_of_intermediate_values,
305 &intermediate_values, &error_occurred), 0);
306 assert_int_equal(error_occurred, 1);
309 /* Ensure perform_operation() returns an error when parsing an unknown
311 static void test_perform_operation_unknown_operator(void **state) {
312 const OperatorFunction operator_functions[] = {
313 {"+", binary_operator},
315 const char *args[] = {
316 "1", "*", "2", "*", "4"
318 int number_of_intermediate_values;
319 int *intermediate_values;
322 (void) state; /* unused */
324 expect_string(example_test_fprintf, temporary_buffer,
325 "Unknown operator *, argument 1\n");
327 assert_int_equal(perform_operation(
328 array_length(args), (char **) args, array_length(operator_functions),
329 operator_functions, &number_of_intermediate_values,
330 &intermediate_values, &error_occurred), 0);
331 assert_int_equal(error_occurred, 1);
334 /* Ensure perform_operation() returns an error when nothing follows an
336 static void test_perform_operation_missing_argument(void **state) {
337 const OperatorFunction operator_functions[] = {
338 {"+", binary_operator},
340 const char *args[] = {
343 int number_of_intermediate_values;
344 int *intermediate_values;
347 (void) state; /* unused */
349 expect_string(example_test_fprintf, temporary_buffer,
350 "Binary operator + missing argument\n");
352 assert_int_equal(perform_operation(
353 array_length(args), (char **) args, array_length(operator_functions),
354 operator_functions, &number_of_intermediate_values,
355 &intermediate_values, &error_occurred), 0);
356 assert_int_equal(error_occurred, 1);
359 /* Ensure perform_operation() returns an error when an integer doesn't follow
361 static void test_perform_operation_no_integer_after_operator(void **state) {
362 const OperatorFunction operator_functions[] = {
363 {"+", binary_operator},
365 const char *args[] = {
368 int number_of_intermediate_values;
369 int *intermediate_values;
372 (void) state; /* unused */
374 expect_string(example_test_fprintf, temporary_buffer,
375 "Unable to parse integer test of argument 2\n");
377 assert_int_equal(perform_operation(
378 array_length(args), (char **) args, array_length(operator_functions),
379 operator_functions, &number_of_intermediate_values,
380 &intermediate_values, &error_occurred), 0);
381 assert_int_equal(error_occurred, 1);
385 /* Ensure perform_operation() succeeds given valid input parameters. */
386 static void test_perform_operation(void **state) {
387 const OperatorFunction operator_functions[] = {
388 {"+", binary_operator},
389 {"*", binary_operator},
391 const char *args[] = {
392 "1", "+", "3", "*", "10",
394 int number_of_intermediate_values;
395 int *intermediate_values;
398 (void) state; /* unused */
400 /* Setup return values of mock operator functions. */
402 expect_value(binary_operator, a, 1);
403 expect_value(binary_operator, b, 3);
404 will_return(binary_operator, 4);
406 /* Multiplication. */
407 expect_value(binary_operator, a, 4);
408 expect_value(binary_operator, b, 10);
409 will_return(binary_operator, 40);
411 assert_int_equal(perform_operation(
412 array_length(args), (char **) args, array_length(operator_functions),
413 operator_functions, &number_of_intermediate_values,
414 &intermediate_values, &error_occurred), 40);
415 assert_int_equal(error_occurred, 0);
417 assert_true(intermediate_values);
418 assert_int_equal(intermediate_values[0], 4);
419 assert_int_equal(intermediate_values[1], 40);
420 test_free(intermediate_values);
424 /* Ensure main() in example.c succeeds given no arguments. */
425 static void test_example_main_no_args(void **state) {
426 const char *args[] = {
430 (void) state; /* unused */
432 assert_int_equal(example_main(array_length(args), (char **) args), 0);
437 /* Ensure main() in example.c succeeds given valid input arguments. */
438 static void test_example_main(void **state) {
439 const char *args[] = {
440 "example", "1", "+", "3", "*", "10",
443 (void) state; /* unused */
445 expect_string(example_test_printf, temporary_buffer, "1\n");
446 expect_string(example_test_printf, temporary_buffer, " + 3 = 4\n");
447 expect_string(example_test_printf, temporary_buffer, " * 10 = 40\n");
448 expect_string(example_test_printf, temporary_buffer, "= 40\n");
450 assert_int_equal(example_main(array_length(args), (char **) args), 0);
457 unit_test(test_subtract),
458 unit_test(test_multiply),
459 unit_test(test_divide),
460 unit_test(test_divide_by_zero),
461 unit_test(test_find_operator_function_by_string_null_functions),
462 unit_test(test_find_operator_function_by_string_null_string),
463 unit_test(test_find_operator_function_by_string_valid_null_functions),
464 unit_test(test_find_operator_function_by_string_not_found),
465 unit_test(test_find_operator_function_by_string_found),
466 unit_test(test_perform_operation_null_args),
467 unit_test(test_perform_operation_null_operator_functions),
468 unit_test(test_perform_operation_null_number_of_intermediate_values),
469 unit_test(test_perform_operation_null_intermediate_values),
470 unit_test(test_perform_operation_no_arguments),
471 unit_test(test_perform_operation_first_arg_not_integer),
472 unit_test(test_perform_operation_unknown_operator),
473 unit_test(test_perform_operation_missing_argument),
474 unit_test(test_perform_operation_no_integer_after_operator),
475 unit_test(test_perform_operation),
476 unit_test(test_example_main_no_args),
477 unit_test(test_example_main),
479 return run_tests(tests);