diff options
author | Heather Lee Wilson <hwilson@google.com> | 2013-12-28 15:12:39 -0800 |
---|---|---|
committer | Heather Lee Wilson <hwilson@google.com> | 2013-12-28 15:18:58 -0800 |
commit | bdd62c531bbdea115a3a7e71bba91c19dd319cc4 (patch) | |
tree | ca6dbdc52599a865901d0ab1121563ae1ca5f47a /cmockery_0_1_2/src/example | |
parent | 78931d3e5b88cec04dac31c95ca67ff6378bed76 (diff) | |
download | cmockery-android-cts-5.1_r1.tar.gz |
Uploading cmockery 0.1.2 to external/cmockeryandroid-wear-5.0.0_r1android-cts-5.1_r9android-cts-5.1_r8android-cts-5.1_r7android-cts-5.1_r6android-cts-5.1_r5android-cts-5.1_r4android-cts-5.1_r3android-cts-5.1_r28android-cts-5.1_r27android-cts-5.1_r26android-cts-5.1_r25android-cts-5.1_r24android-cts-5.1_r23android-cts-5.1_r22android-cts-5.1_r21android-cts-5.1_r20android-cts-5.1_r2android-cts-5.1_r19android-cts-5.1_r18android-cts-5.1_r17android-cts-5.1_r16android-cts-5.1_r15android-cts-5.1_r14android-cts-5.1_r13android-cts-5.1_r10android-cts-5.1_r1android-cts-5.0_r9android-cts-5.0_r8android-cts-5.0_r7android-cts-5.0_r6android-cts-5.0_r5android-cts-5.0_r4android-cts-5.0_r3android-5.1.1_r9android-5.1.1_r8android-5.1.1_r7android-5.1.1_r6android-5.1.1_r5android-5.1.1_r4android-5.1.1_r38android-5.1.1_r37android-5.1.1_r36android-5.1.1_r35android-5.1.1_r34android-5.1.1_r33android-5.1.1_r30android-5.1.1_r3android-5.1.1_r29android-5.1.1_r28android-5.1.1_r26android-5.1.1_r25android-5.1.1_r24android-5.1.1_r23android-5.1.1_r22android-5.1.1_r20android-5.1.1_r2android-5.1.1_r19android-5.1.1_r18android-5.1.1_r17android-5.1.1_r16android-5.1.1_r15android-5.1.1_r14android-5.1.1_r13android-5.1.1_r12android-5.1.1_r10android-5.1.1_r1android-5.1.0_r5android-5.1.0_r4android-5.1.0_r3android-5.1.0_r1android-5.0.2_r3android-5.0.2_r1android-5.0.1_r1android-5.0.0_r7android-5.0.0_r6android-5.0.0_r5.1android-5.0.0_r5android-5.0.0_r4android-5.0.0_r3android-5.0.0_r2android-5.0.0_r1lollipop-wear-releaselollipop-releaselollipop-mr1-wfc-releaselollipop-mr1-releaselollipop-mr1-fi-releaselollipop-mr1-devlollipop-mr1-cts-releaselollipop-devlollipop-cts-release
A lightweight library to simplify and generalize the process of writing unit
tests for C applications.
Change-Id: I460a9b6740f10593e35ae988df753a43491c6456
Diffstat (limited to 'cmockery_0_1_2/src/example')
-rw-r--r-- | cmockery_0_1_2/src/example/allocate_module.c | 44 | ||||
-rw-r--r-- | cmockery_0_1_2/src/example/allocate_module_test.c | 47 | ||||
-rw-r--r-- | cmockery_0_1_2/src/example/assert_macro.c | 37 | ||||
-rw-r--r-- | cmockery_0_1_2/src/example/assert_macro_test.c | 44 | ||||
-rw-r--r-- | cmockery_0_1_2/src/example/calculator.c | 266 | ||||
-rw-r--r-- | cmockery_0_1_2/src/example/calculator_test.c | 425 | ||||
-rw-r--r-- | cmockery_0_1_2/src/example/customer_database.c | 44 | ||||
-rw-r--r-- | cmockery_0_1_2/src/example/customer_database_test.c | 69 | ||||
-rw-r--r-- | cmockery_0_1_2/src/example/database.h | 37 | ||||
-rw-r--r-- | cmockery_0_1_2/src/example/key_value.c | 54 | ||||
-rw-r--r-- | cmockery_0_1_2/src/example/key_value_test.c | 80 | ||||
-rw-r--r-- | cmockery_0_1_2/src/example/product_database.c | 22 | ||||
-rw-r--r-- | cmockery_0_1_2/src/example/product_database_test.c | 66 | ||||
-rw-r--r-- | cmockery_0_1_2/src/example/run_tests.c | 30 |
14 files changed, 1265 insertions, 0 deletions
diff --git a/cmockery_0_1_2/src/example/allocate_module.c b/cmockery_0_1_2/src/example/allocate_module.c new file mode 100644 index 0000000..dda7260 --- /dev/null +++ b/cmockery_0_1_2/src/example/allocate_module.c @@ -0,0 +1,44 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stdlib.h> + +#if UNIT_TESTING +extern void* _test_malloc(const size_t size, const char* file, const int line); +extern void* _test_calloc(const size_t number_of_elements, const size_t size, + const char* file, const int line); +extern void _test_free(void* const ptr, const char* file, const int line); + +#define malloc(size) _test_malloc(size, __FILE__, __LINE__) +#define calloc(num, size) _test_calloc(num, size, __FILE__, __LINE__) +#define free(ptr) _test_free(ptr, __FILE__, __LINE__) +#endif // UNIT_TESTING + +void leak_memory() { + int * const temporary = (int*)malloc(sizeof(int)); + *temporary = 0; +} + +void buffer_overflow() { + char * const memory = (char*)malloc(sizeof(int)); + memory[sizeof(int)] = '!'; + free(memory); +} + +void buffer_underflow() { + char * const memory = (char*)malloc(sizeof(int)); + memory[-1] = '!'; + free(memory); +} diff --git a/cmockery_0_1_2/src/example/allocate_module_test.c b/cmockery_0_1_2/src/example/allocate_module_test.c new file mode 100644 index 0000000..f7d6079 --- /dev/null +++ b/cmockery_0_1_2/src/example/allocate_module_test.c @@ -0,0 +1,47 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stdarg.h> +#include <stddef.h> +#include <setjmp.h> +#include <cmockery.h> + +extern void leak_memory(); +extern void buffer_overflow(); +extern void buffer_underflow(); + +// Test case that fails as leak_memory() leaks a dynamically allocated block. +void leak_memory_test(void **state) { + leak_memory(); +} + +// Test case that fails as buffer_overflow() corrupts an allocated block. +void buffer_overflow_test(void **state) { + buffer_overflow(); +} + +// Test case that fails as buffer_underflow() corrupts an allocated block. +void buffer_underflow_test(void **state) { + buffer_underflow(); +} + +int main(int argc, char* argv[]) { + const UnitTest tests[] = { + unit_test(leak_memory_test), + unit_test(buffer_overflow_test), + unit_test(buffer_underflow_test), + }; + return run_tests(tests); +} diff --git a/cmockery_0_1_2/src/example/assert_macro.c b/cmockery_0_1_2/src/example/assert_macro.c new file mode 100644 index 0000000..aadcac3 --- /dev/null +++ b/cmockery_0_1_2/src/example/assert_macro.c @@ -0,0 +1,37 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <string.h> + +static const char* status_code_strings[] = { + "Address not found", + "Connection dropped", + "Connection timed out", +}; + +const char* get_status_code_string(const unsigned int status_code) { + return status_code_strings[status_code]; +}; + +unsigned int string_to_status_code(const char* const status_code_string) { + unsigned int i; + for (i = 0; i < sizeof(status_code_string) / sizeof(status_code_string[0]); + i++) { + if (strcmp(status_code_strings[i], status_code_string) == 0) { + return i; + } + } + return ~0U; +} diff --git a/cmockery_0_1_2/src/example/assert_macro_test.c b/cmockery_0_1_2/src/example/assert_macro_test.c new file mode 100644 index 0000000..0df8f96 --- /dev/null +++ b/cmockery_0_1_2/src/example/assert_macro_test.c @@ -0,0 +1,44 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stdarg.h> +#include <stddef.h> +#include <setjmp.h> +#include <cmockery.h> + +extern const char* get_status_code_string(const unsigned int status_code); +extern unsigned int string_to_status_code( + const char* const status_code_string); + +/* This test will fail since the string returned by get_status_code_string(0) + * doesn't match "Connection timed out". */ +void get_status_code_string_test(void **state) { + assert_string_equal(get_status_code_string(0), "Address not found"); + assert_string_equal(get_status_code_string(1), "Connection timed out"); +} + +// This test will fail since the status code of "Connection timed out" isn't 1 +void string_to_status_code_test(void **state) { + assert_int_equal(string_to_status_code("Address not found"), 0); + assert_int_equal(string_to_status_code("Connection timed out"), 1); +} + +int main(int argc, char *argv[]) { + const UnitTest tests[] = { + unit_test(get_status_code_string_test), + unit_test(string_to_status_code_test), + }; + return run_tests(tests); +} diff --git a/cmockery_0_1_2/src/example/calculator.c b/cmockery_0_1_2/src/example/calculator.c new file mode 100644 index 0000000..da3775b --- /dev/null +++ b/cmockery_0_1_2/src/example/calculator.c @@ -0,0 +1,266 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// A calculator example used to demonstrate the cmockery testing library. + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +// If this is being built for a unit test. +#if UNIT_TESTING + +/* Redirect printf to a function in the test application so it's possible to + * test the standard output. */ +#ifdef printf +#undef printf +#endif // printf +#define printf example_test_printf + +extern void print_message(const char *format, ...); + +/* Redirect fprintf to a function in the test application so it's possible to + * test error messages. */ +#ifdef fprintf +#undef fprintf +#endif // fprintf +#define fprintf example_test_fprintf + +extern int example_test_fprintf(FILE * const file, const char *format, ...); + +// Redirect assert to mock_assert() so assertions can be caught by cmockery. +#ifdef assert +#undef assert +#endif // assert +#define assert(expression) \ + mock_assert((int)(expression), #expression, __FILE__, __LINE__) +void mock_assert(const int result, const char* expression, const char *file, + const int line); + +/* Redirect calloc and free to test_calloc() and test_free() so cmockery can + * check for memory leaks. */ +#ifdef calloc +#undef calloc +#endif // calloc +#define calloc(num, size) _test_calloc(num, size, __FILE__, __LINE__) +#ifdef free +#undef free +#endif // free +#define free(ptr) _test_free(ptr, __FILE__, __LINE__) +void* _test_calloc(const size_t number_of_elements, const size_t size, + const char* file, const int line); +void _test_free(void* const ptr, const char* file, const int line); + +/* main is defined in the unit test so redefine name of the the main function + * here. */ +#define main example_main + +/* All functions in this object need to be exposed to the test application, + * so redefine static to nothing. */ +#define static + +#endif // UNIT_TESTING + + +// A binary arithmetic integer operation (add, subtract etc.) +typedef int (*BinaryOperator)(int a, int b); + +// Structure which maps operator strings to functions. +typedef struct OperatorFunction { + const char* operator; + BinaryOperator function; +} OperatorFunction; + + +static int add(int a, int b); +static int subtract(int a, int b); +static int multiply(int a, int b); +static int divide(int a, int b); + +// Associate operator strings to functions. +static OperatorFunction operator_function_map[] = { + {"+", add}, + {"-", subtract}, + {"*", multiply}, + {"/", divide}, +}; + +static int add(int a, int b) { + return a + b; +} + +static int subtract(int a, int b) { + return a - b; +} + +static int multiply(int a, int b) { + return a * b; +} + +static int divide(int a, int b) { + assert(b); // Check for divde by zero. + return a / b; +} + +/* Searches the specified array of operator_functions for the function + * associated with the specified operator_string. This function returns the + * function associated with operator_string if successful, NULL otherwise. + */ +static BinaryOperator find_operator_function_by_string( + const size_t number_of_operator_functions, + const OperatorFunction * const operator_functions, + const char* const operator_string) { + size_t i; + assert(!number_of_operator_functions || operator_functions); + assert(operator_string); + + for (i = 0; i < number_of_operator_functions; i++) { + const OperatorFunction *const operator_function = + &operator_functions[i]; + if (strcmp(operator_function->operator, operator_string) == 0) { + return operator_function->function; + } + } + return NULL; +} + +/* Perform a series of binary arithmetic integer operations with no operator + * precedence. + * + * The input expression is specified by arguments which is an array of + * containing number_of_arguments strings. Operators invoked by the expression + * are specified by the array operator_functions containing + * number_of_operator_functions, OperatorFunction structures. The value of + * each binary operation is stored in a pointer returned to intermediate_values + * which is allocated by malloc(). + * + * If successful, this function returns the integer result of the operations. + * If an error occurs while performing the operation error_occurred is set to + * 1, the operation is aborted and 0 is returned. + */ +static int perform_operation( + int number_of_arguments, char *arguments[], + const size_t number_of_operator_functions, + const OperatorFunction * const operator_functions, + int * const number_of_intermediate_values, + int ** const intermediate_values, int * const error_occurred) { + char *end_of_integer; + int value; + unsigned int i; + assert(!number_of_arguments || arguments); + assert(!number_of_operator_functions || operator_functions); + assert(error_occurred); + assert(number_of_intermediate_values); + assert(intermediate_values); + + *error_occurred = 0; + *number_of_intermediate_values = 0; + *intermediate_values = NULL; + if (!number_of_arguments) + return 0; + + // Parse the first value. + value = (int)strtol(arguments[0], &end_of_integer, 10); + if (end_of_integer == arguments[0]) { + // If an error occurred while parsing the integer. + fprintf(stderr, "Unable to parse integer from argument %s\n", + arguments[0]); + *error_occurred = 1; + return 0; + } + + // Allocate an array for the output values. + *intermediate_values = calloc(((number_of_arguments - 1) / 2), + sizeof(**intermediate_values)); + + i = 1; + while (i < number_of_arguments) { + int other_value; + const char* const operator_string = arguments[i]; + const BinaryOperator function = find_operator_function_by_string( + number_of_operator_functions, operator_functions, operator_string); + int * const intermediate_value = + &((*intermediate_values)[*number_of_intermediate_values]); + (*number_of_intermediate_values) ++; + + if (!function) { + fprintf(stderr, "Unknown operator %s, argument %d\n", + operator_string, i); + *error_occurred = 1; + break; + } + i ++; + + if (i == number_of_arguments) { + fprintf(stderr, "Binary operator %s missing argument\n", + operator_string); + *error_occurred = 1; + break; + } + + other_value = (int)strtol(arguments[i], &end_of_integer, 10); + if (end_of_integer == arguments[i]) { + // If an error occurred while parsing the integer. + fprintf(stderr, "Unable to parse integer %s of argument %d\n", + arguments[i], i); + *error_occurred = 1; + break; + } + i ++; + + // Perform the operation and store the intermediate value. + *intermediate_value = function(value, other_value); + value = *intermediate_value; + } + if (*error_occurred) { + free(*intermediate_values); + *intermediate_values = NULL; + *number_of_intermediate_values = 0; + return 0; + } + return value; +} + +int main(int argc, char *argv[]) { + int return_value; + int number_of_intermediate_values; + int *intermediate_values; + // Peform the operation. + const int result = perform_operation( + argc - 1, &argv[1], + sizeof(operator_function_map) / sizeof(operator_function_map[0]), + operator_function_map, &number_of_intermediate_values, + &intermediate_values, &return_value); + + // If no errors occurred display the result. + if (!return_value && argc > 1) { + unsigned int i; + unsigned int intermediate_value_index = 0; + printf("%s\n", argv[1]); + for (i = 2; i < argc; i += 2) { + assert(intermediate_value_index < number_of_intermediate_values); + printf(" %s %s = %d\n", argv[i], argv[i + 1], + intermediate_values[intermediate_value_index++]); + } + printf("= %d\n", result); + } + if (intermediate_values) { + free(intermediate_values); + } + + return return_value; +} diff --git a/cmockery_0_1_2/src/example/calculator_test.c b/cmockery_0_1_2/src/example/calculator_test.c new file mode 100644 index 0000000..6feaf41 --- /dev/null +++ b/cmockery_0_1_2/src/example/calculator_test.c @@ -0,0 +1,425 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stdarg.h> +#include <stddef.h> +#include <setjmp.h> +#include "cmockery.h" +#include <stdio.h> + +#ifdef _WIN32 +// Compatibility with the Windows standard C library. +#define vsnprintf _vsnprintf +#endif // _WIN32 + +#define array_length(x) (sizeof(x) / sizeof((x)[0])) + +/* To simplify this code, these functions and data structures could have been + * separated out from the application example.c into a header shared with + * test application. However, this example illustrates how it's possible to + * test existing code with little modification. */ + +typedef int (*BinaryOperator)(int a, int b); + +typedef struct OperatorFunction { + const char* operator; + BinaryOperator function; +} OperatorFunction; + +extern int add(int a, int b); +extern int subtract(int a, int b); +extern int multiply(int a, int b); +extern int divide(int a, int b); +extern BinaryOperator find_operator_function_by_string( + const size_t number_of_operator_functions, + const OperatorFunction * const operator_functions, + const char* const operator_string); +extern int perform_operation( + int number_of_arguments, char *arguments[], + const size_t number_of_operator_functions, + const OperatorFunction * const operator_functions, + int * const number_of_intermediate_values, + int ** const intermediate_values, int * const error_occurred); +extern int example_main(int argc, char *argv[]); + +/* A mock fprintf function that checks the value of strings printed to the + * standard error stream. */ +int example_test_fprintf(FILE* const file, const char *format, ...) { + int return_value; + va_list args; + char temporary_buffer[256]; + assert_true(file == stderr); + va_start(args, format); + return_value = vsnprintf(temporary_buffer, sizeof(temporary_buffer), + format, args); + check_expected(temporary_buffer); + va_end(args); + return return_value; +} + +/* A mock printf function that checks the value of strings printed to the + * standard output stream. */ +int example_test_printf(const char *format, ...) { + int return_value; + va_list args; + char temporary_buffer[256]; + va_start(args, format); + return_value = vsnprintf(temporary_buffer, sizeof(temporary_buffer), + format, args); + check_expected(temporary_buffer); + va_end(args); + return return_value; +} + +// A mock binary operator function. +int binary_operator(int a, int b) { + check_expected(a); + check_expected(b); + return (int)mock(); +} + + +// Ensure add() adds two integers correctly. +void test_add(void **state) { + assert_int_equal(add(3, 3), 6); + assert_int_equal(add(3, -3), 0); +} + +// Ensure subtract() subtracts two integers correctly. +void test_subtract(void **state) { + assert_int_equal(subtract(3, 3), 0); + assert_int_equal(subtract(3, -3), 6); +} + +// Ensure multiple() mulitplies two integers correctly. +void test_multiply(void **state) { + assert_int_equal(multiply(3, 3), 9); + assert_int_equal(multiply(3, 0), 0); +} + +// Ensure divide() divides one integer by another correctly. +void test_divide(void **state) { + assert_int_equal(divide(10, 2), 5); + assert_int_equal(divide(2, 10), 0); +} + +// Ensure divide() asserts when trying to divide by zero. +void test_divide_by_zero(void **state) { + expect_assert_failure(divide(100, 0)); +} + +/* Ensure find_operator_function_by_string() asserts when a NULL pointer is + * specified as the table to search. */ +void test_find_operator_function_by_string_null_functions(void **state) { + expect_assert_failure(find_operator_function_by_string(1, NULL, "test")); +} + +/* Ensure find_operator_function_by_string() asserts when a NULL pointer is + * specified as the string to search for. */ +void test_find_operator_function_by_string_null_string(void **state) { + const OperatorFunction operator_functions[] = { + {"+", binary_operator}, + }; + expect_assert_failure(find_operator_function_by_string( + array_length(operator_functions), operator_functions, NULL)); +} + +/* Ensure find_operator_function_by_string() returns NULL when a NULL pointer + * is specified as the table to search when the table size is 0. */ +void test_find_operator_function_by_string_valid_null_functions(void **state) { + assert_int_equal((int)find_operator_function_by_string(0, NULL, "test"), + (int)NULL); +} + +/* Ensure find_operator_function_by_string() returns NULL when searching for + * an operator string that isn't in the specified table. */ +void test_find_operator_function_by_string_not_found(void **state) { + const OperatorFunction operator_functions[] = { + {"+", binary_operator}, + {"-", binary_operator}, + {"/", binary_operator}, + }; + assert_int_equal((int)find_operator_function_by_string( + array_length(operator_functions), operator_functions, "test"), + (int)NULL); +} + +/* Ensure find_operator_function_by_string() returns the correct function when + * searching for an operator string that is in the specified table. */ +void test_find_operator_function_by_string_found(void **state) { + const OperatorFunction operator_functions[] = { + {"+", (BinaryOperator)0x12345678}, + {"-", (BinaryOperator)0xDEADBEEF}, + {"/", (BinaryOperator)0xABADCAFE}, + }; + assert_int_equal((int)find_operator_function_by_string( + array_length(operator_functions), operator_functions, "-"), + 0xDEADBEEF); +} + +// Ensure perform_operation() asserts when a NULL arguments array is specified. +void test_perform_operation_null_args(void **state) { + const OperatorFunction operator_functions[] = { + {"+", binary_operator}, + }; + int number_of_intermediate_values; + int *intermediate_values; + int error_occurred; + expect_assert_failure(perform_operation( + 1, NULL, array_length(operator_functions), operator_functions, + &number_of_intermediate_values, &intermediate_values, + &error_occurred)); +} + +/* Ensure perform_operation() asserts when a NULL operator_functions array is + * specified. */ +void test_perform_operation_null_operator_functions(void **state) { + char *args[] = { + "1", "+", "2", "*", "4" + }; + int number_of_intermediate_values; + int *intermediate_values; + int error_occurred; + expect_assert_failure(perform_operation( + array_length(args), args, 1, NULL, &number_of_intermediate_values, + &intermediate_values, &error_occurred)); +} + +/* Ensure perform_operation() asserts when a NULL pointer is specified for + * number_of_intermediate_values. */ +void test_perform_operation_null_number_of_intermediate_values(void **state) { + const OperatorFunction operator_functions[] = { + {"+", binary_operator}, + }; + char *args[] = { + "1", "+", "2", "*", "4" + }; + int *intermediate_values; + int error_occurred; + expect_assert_failure(perform_operation( + array_length(args), args, 1, operator_functions, NULL, + &intermediate_values, &error_occurred)); +} + +/* Ensure perform_operation() asserts when a NULL pointer is specified for + * intermediate_values. */ +void test_perform_operation_null_intermediate_values(void **state) { + const OperatorFunction operator_functions[] = { + {"+", binary_operator}, + }; + char *args[] = { + "1", "+", "2", "*", "4" + }; + int number_of_intermediate_values; + int error_occurred; + expect_assert_failure(perform_operation( + array_length(args), args, array_length(operator_functions), + operator_functions, &number_of_intermediate_values, NULL, + &error_occurred)); +} + +// Ensure perform_operation() returns 0 when no arguments are specified. +void test_perform_operation_no_arguments(void **state) { + int number_of_intermediate_values; + int *intermediate_values; + int error_occurred; + assert_int_equal(perform_operation( + 0, NULL, 0, NULL, &number_of_intermediate_values, &intermediate_values, + &error_occurred), 0); + assert_int_equal(error_occurred, 0); +} + +/* Ensure perform_operation() returns an error if the first argument isn't + * an integer string. */ +void test_perform_operation_first_arg_not_integer(void **state) { + const OperatorFunction operator_functions[] = { + {"+", binary_operator}, + }; + char *args[] = { + "test", "+", "2", "*", "4" + }; + int number_of_intermediate_values; + int *intermediate_values; + int error_occurred; + + expect_string(example_test_fprintf, temporary_buffer, + "Unable to parse integer from argument test\n"); + + assert_int_equal(perform_operation( + array_length(args), args, array_length(operator_functions), + operator_functions, &number_of_intermediate_values, + &intermediate_values, &error_occurred), 0); + assert_int_equal(error_occurred, 1); +} + +/* Ensure perform_operation() returns an error when parsing an unknown + * operator. */ +void test_perform_operation_unknown_operator(void **state) { + const OperatorFunction operator_functions[] = { + {"+", binary_operator}, + }; + char *args[] = { + "1", "*", "2", "*", "4" + }; + int number_of_intermediate_values; + int *intermediate_values; + int error_occurred; + + expect_string(example_test_fprintf, temporary_buffer, + "Unknown operator *, argument 1\n"); + + assert_int_equal(perform_operation( + array_length(args), args, array_length(operator_functions), + operator_functions, &number_of_intermediate_values, + &intermediate_values, &error_occurred), 0); + assert_int_equal(error_occurred, 1); +} + +/* Ensure perform_operation() returns an error when nothing follows an + * operator. */ +void test_perform_operation_missing_argument(void **state) { + const OperatorFunction operator_functions[] = { + {"+", binary_operator}, + }; + char *args[] = { + "1", "+", + }; + int number_of_intermediate_values; + int *intermediate_values; + int error_occurred; + + expect_string(example_test_fprintf, temporary_buffer, + "Binary operator + missing argument\n"); + + assert_int_equal(perform_operation( + array_length(args), args, array_length(operator_functions), + operator_functions, &number_of_intermediate_values, + &intermediate_values, &error_occurred), 0); + assert_int_equal(error_occurred, 1); +} + +/* Ensure perform_operation() returns an error when an integer doesn't follow + * an operator. */ +void test_perform_operation_no_integer_after_operator(void **state) { + const OperatorFunction operator_functions[] = { + {"+", binary_operator}, + }; + char *args[] = { + "1", "+", "test", + }; + int number_of_intermediate_values; + int *intermediate_values; + int error_occurred; + + expect_string(example_test_fprintf, temporary_buffer, + "Unable to parse integer test of argument 2\n"); + + assert_int_equal(perform_operation( + array_length(args), args, array_length(operator_functions), + operator_functions, &number_of_intermediate_values, + &intermediate_values, &error_occurred), 0); + assert_int_equal(error_occurred, 1); +} + + +// Ensure perform_operation() succeeds given valid input parameters. +void test_perform_operation(void **state) { + const OperatorFunction operator_functions[] = { + {"+", binary_operator}, + {"*", binary_operator}, + }; + char *args[] = { + "1", "+", "3", "*", "10", + }; + int number_of_intermediate_values; + int *intermediate_values; + int error_occurred; + + // Setup return values of mock operator functions. + // Addition. + expect_value(binary_operator, a, 1); + expect_value(binary_operator, b, 3); + will_return(binary_operator, 4); + + // Multiplication. + expect_value(binary_operator, a, 4); + expect_value(binary_operator, b, 10); + will_return(binary_operator, 40); + + assert_int_equal(perform_operation( + array_length(args), args, array_length(operator_functions), + operator_functions, &number_of_intermediate_values, + &intermediate_values, &error_occurred), 40); + assert_int_equal(error_occurred, 0); + + assert_true(intermediate_values); + assert_int_equal(intermediate_values[0], 4); + assert_int_equal(intermediate_values[1], 40); + test_free(intermediate_values); +} + + +// Ensure main() in example.c succeeds given no arguments. +void test_example_main_no_args(void **state) { + char *args[] = { + "example", + }; + assert_int_equal(example_main(array_length(args), args), 0); +} + + + +// Ensure main() in example.c succeeds given valid input arguments. +void test_example_main(void **state) { + char *args[] = { + "example", "1", "+", "3", "*", "10", + }; + + expect_string(example_test_printf, temporary_buffer, "1\n"); + expect_string(example_test_printf, temporary_buffer, " + 3 = 4\n"); + expect_string(example_test_printf, temporary_buffer, " * 10 = 40\n"); + expect_string(example_test_printf, temporary_buffer, "= 40\n"); + + assert_int_equal(example_main(array_length(args), args), 0); +} + + +int main(int argc, char* argv[]) { + UnitTest tests[] = { + unit_test(test_add), + unit_test(test_subtract), + unit_test(test_multiply), + unit_test(test_divide), + unit_test(test_divide_by_zero), + unit_test(test_find_operator_function_by_string_null_functions), + unit_test(test_find_operator_function_by_string_null_string), + unit_test(test_find_operator_function_by_string_valid_null_functions), + unit_test(test_find_operator_function_by_string_not_found), + unit_test(test_find_operator_function_by_string_found), + unit_test(test_perform_operation_null_args), + unit_test(test_perform_operation_null_operator_functions), + unit_test(test_perform_operation_null_number_of_intermediate_values), + unit_test(test_perform_operation_null_intermediate_values), + unit_test(test_perform_operation_no_arguments), + unit_test(test_perform_operation_first_arg_not_integer), + unit_test(test_perform_operation_unknown_operator), + unit_test(test_perform_operation_missing_argument), + unit_test(test_perform_operation_no_integer_after_operator), + unit_test(test_perform_operation), + unit_test(test_example_main_no_args), + unit_test(test_example_main), + }; + return run_tests(tests); +} diff --git a/cmockery_0_1_2/src/example/customer_database.c b/cmockery_0_1_2/src/example/customer_database.c new file mode 100644 index 0000000..1cfce7e --- /dev/null +++ b/cmockery_0_1_2/src/example/customer_database.c @@ -0,0 +1,44 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stddef.h> +#include <stdio.h> +#include <database.h> +#ifdef _WIN32 +#define snprintf _snprintf +#endif // _WIN32 + +// Connect to the database containing customer information. +DatabaseConnection* connect_to_customer_database() { + return connect_to_database("customers.abcd.org", 321); +} + +/* Find the ID of a customer by his/her name returning a value > 0 if + * successful, 0 otherwise. */ +unsigned int get_customer_id_by_name( + DatabaseConnection * const connection, + const char * const customer_name) { + char query_string[256]; + int number_of_results; + void **results; + snprintf(query_string, sizeof(query_string), + "SELECT ID FROM CUSTOMERS WHERE NAME = %s", customer_name); + number_of_results = connection->query_database(connection, query_string, + &results); + if (number_of_results != 1) { + return -1; + } + return (unsigned int)results[0]; +} diff --git a/cmockery_0_1_2/src/example/customer_database_test.c b/cmockery_0_1_2/src/example/customer_database_test.c new file mode 100644 index 0000000..b059007 --- /dev/null +++ b/cmockery_0_1_2/src/example/customer_database_test.c @@ -0,0 +1,69 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stdarg.h> +#include <stddef.h> +#include <setjmp.h> +#include <cmockery.h> +#include <database.h> + +extern DatabaseConnection* connect_to_customer_database(); +extern unsigned int get_customer_id_by_name( + DatabaseConnection * const connection, const char * const customer_name); + +// Mock query database function. +unsigned int mock_query_database( + DatabaseConnection* const connection, const char * const query_string, + void *** const results) { + *results = (void**)mock(); + return (unsigned int)mock(); +} + +// Mock of the connect to database function. +DatabaseConnection* connect_to_database(const char * const database_url, + const unsigned int port) { + return (DatabaseConnection*)mock(); +} + +void test_connect_to_customer_database(void **state) { + will_return(connect_to_database, 0x0DA7ABA53); + assert_int_equal((int)connect_to_customer_database(), 0x0DA7ABA53); +} + +/* This test fails as the mock function connect_to_database() will have no + * value to return. */ +void fail_connect_to_customer_database(void **state) { + assert_true(connect_to_customer_database() == + (DatabaseConnection*)0x0DA7ABA53); +} + +void test_get_customer_id_by_name(void **state) { + DatabaseConnection connection = { + "somedatabase.somewhere.com", 12345678, mock_query_database + }; + // Return a single customer ID when mock_query_database() is called. + int customer_ids = 543; + will_return(mock_query_database, &customer_ids); + will_return(mock_query_database, 1); + assert_int_equal(get_customer_id_by_name(&connection, "john doe"), 543); +} + +int main(int argc, char* argv[]) { + const UnitTest tests[] = { + unit_test(test_connect_to_customer_database), + unit_test(test_get_customer_id_by_name), + }; + return run_tests(tests); +} diff --git a/cmockery_0_1_2/src/example/database.h b/cmockery_0_1_2/src/example/database.h new file mode 100644 index 0000000..f6f6a43 --- /dev/null +++ b/cmockery_0_1_2/src/example/database.h @@ -0,0 +1,37 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +typedef struct DatabaseConnection DatabaseConnection; + +/* Function that takes an SQL query string and sets results to an array of + * pointers with the result of the query. The value returned specifies the + * number of items in the returned array of results. The returned array of + * results are statically allocated and should not be deallocated using free() + */ +typedef unsigned int (*QueryDatabase)( + DatabaseConnection* const connection, const char * const query_string, + void *** const results); + +// Connection to a database. +struct DatabaseConnection { + const char *url; + unsigned int port; + QueryDatabase query_database; +}; + +// Connect to a database. +DatabaseConnection* connect_to_database(const char * const url, + const unsigned int port); + diff --git a/cmockery_0_1_2/src/example/key_value.c b/cmockery_0_1_2/src/example/key_value.c new file mode 100644 index 0000000..00e1bc4 --- /dev/null +++ b/cmockery_0_1_2/src/example/key_value.c @@ -0,0 +1,54 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +typedef struct KeyValue { + unsigned int key; + const char* value; +} KeyValue; + +static KeyValue *key_values = NULL; +static unsigned int number_of_key_values = 0; + +void set_key_values(KeyValue * const new_key_values, + const unsigned int new_number_of_key_values) { + key_values = new_key_values; + number_of_key_values = new_number_of_key_values; +} + +// Compare two key members of KeyValue structures. +int key_value_compare_keys(const void *a, const void *b) { + return (int)((KeyValue*)a)->key - (int)((KeyValue*)b)->key; +} + +// Search an array of key value pairs for the item with the specified value. +KeyValue* find_item_by_value(const char * const value) { + unsigned int i; + for (i = 0; i < number_of_key_values; i++) { + if (strcmp(key_values[i].value, value) == 0) { + return &key_values[i]; + } + } + return NULL; +} + +// Sort an array of key value pairs by key. +void sort_items_by_key() { + qsort(key_values, number_of_key_values, sizeof(*key_values), + key_value_compare_keys); +} diff --git a/cmockery_0_1_2/src/example/key_value_test.c b/cmockery_0_1_2/src/example/key_value_test.c new file mode 100644 index 0000000..4f58e57 --- /dev/null +++ b/cmockery_0_1_2/src/example/key_value_test.c @@ -0,0 +1,80 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stdarg.h> +#include <stddef.h> +#include <setjmp.h> +#include <string.h> +#include <cmockery.h> + +/* This is duplicated here from the module setup_teardown.c to reduce the + * number of files used in this test. */ +typedef struct KeyValue { + unsigned int key; + const char* value; +} KeyValue; + +void set_key_values(KeyValue * const new_key_values, + const unsigned int new_number_of_key_values); +extern KeyValue* find_item_by_value(const char * const value); +extern void sort_items_by_key(); + +static KeyValue key_values[] = { + { 10, "this" }, + { 52, "test" }, + { 20, "a" }, + { 13, "is" }, +}; + +void create_key_values(void **state) { + KeyValue * const items = (KeyValue*)test_malloc(sizeof(key_values)); + memcpy(items, key_values, sizeof(key_values)); + *state = (void*)items; + set_key_values(items, sizeof(key_values) / sizeof(key_values[0])); +} + +void destroy_key_values(void **state) { + test_free(*state); + set_key_values(NULL, 0); +} + +void test_find_item_by_value(void **state) { + unsigned int i; + for (i = 0; i < sizeof(key_values) / sizeof(key_values[0]); i++) { + KeyValue * const found = find_item_by_value(key_values[i].value); + assert_true(found); + assert_int_equal(found->key, key_values[i].key); + assert_string_equal(found->value, key_values[i].value); + } +} + +void test_sort_items_by_key(void **state) { + unsigned int i; + KeyValue * const kv = *state; + sort_items_by_key(); + for (i = 1; i < sizeof(key_values) / sizeof(key_values[0]); i++) { + assert_true(kv[i - 1].key < kv[i].key); + } +} + +int main(int argc, char* argv[]) { + const UnitTest tests[] = { + unit_test_setup_teardown(test_find_item_by_value, create_key_values, + destroy_key_values), + unit_test_setup_teardown(test_sort_items_by_key, create_key_values, + destroy_key_values), + }; + return run_tests(tests); +} diff --git a/cmockery_0_1_2/src/example/product_database.c b/cmockery_0_1_2/src/example/product_database.c new file mode 100644 index 0000000..6c6ecf2 --- /dev/null +++ b/cmockery_0_1_2/src/example/product_database.c @@ -0,0 +1,22 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <database.h> + +// Connect to the database containing customer information. +DatabaseConnection* connect_to_product_database() { + return connect_to_database("products.abcd.org", 322); +} + diff --git a/cmockery_0_1_2/src/example/product_database_test.c b/cmockery_0_1_2/src/example/product_database_test.c new file mode 100644 index 0000000..d3c5109 --- /dev/null +++ b/cmockery_0_1_2/src/example/product_database_test.c @@ -0,0 +1,66 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stdarg.h> +#include <stddef.h> +#include <setjmp.h> +#include <cmockery.h> +#include <database.h> + +extern DatabaseConnection* connect_to_product_database(); + +/* Mock connect to database function. + * NOTE: This mock function is very general could be shared between tests + * that use the imaginary database.h module. */ +DatabaseConnection* connect_to_database(const char * const url, + const unsigned int port) { + check_expected(url); + check_expected(port); + return (DatabaseConnection*)mock(); +} + +void test_connect_to_product_database(void **state) { + expect_string(connect_to_database, url, "products.abcd.org"); + expect_value(connect_to_database, port, 322); + will_return(connect_to_database, 0xDA7ABA53); + assert_int_equal((int)connect_to_product_database(), 0xDA7ABA53); +} + +/* This test will fail since the expected URL is different to the URL that is + * passed to connect_to_database() by connect_to_product_database(). */ +void test_connect_to_product_database_bad_url(void **state) { + expect_string(connect_to_database, url, "products.abcd.com"); + expect_value(connect_to_database, port, 322); + will_return(connect_to_database, 0xDA7ABA53); + assert_int_equal((int)connect_to_product_database(), 0xDA7ABA53); +} + +/* This test will fail since the mock connect_to_database() will attempt to + * retrieve a value for the parameter port which isn't specified by this + * test function. */ +void test_connect_to_product_database_missing_parameter(void **state) { + expect_string(connect_to_database, url, "products.abcd.org"); + will_return(connect_to_database, 0xDA7ABA53); + assert_int_equal((int)connect_to_product_database(), 0xDA7ABA53); +} + +int main(int argc, char* argv[]) { + const UnitTest tests[] = { + unit_test(test_connect_to_product_database), + unit_test(test_connect_to_product_database_bad_url), + unit_test(test_connect_to_product_database_missing_parameter), + }; + return run_tests(tests); +} diff --git a/cmockery_0_1_2/src/example/run_tests.c b/cmockery_0_1_2/src/example/run_tests.c new file mode 100644 index 0000000..f6d7620 --- /dev/null +++ b/cmockery_0_1_2/src/example/run_tests.c @@ -0,0 +1,30 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stdarg.h> +#include <stddef.h> +#include <setjmp.h> +#include <cmockery.h> + +// A test case that does nothing and succeeds. +void null_test_success(void **state) { +} + +int main(int argc, char* argv[]) { + const UnitTest tests[] = { + unit_test(null_test_success), + }; + return run_tests(tests); +} |