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