0001 #include <assert.h>
0002 #include <cgreen/breadcrumb.h>
0003 #include <cgreen/mocks.h>
0004 #include <cgreen/parameters.h>
0005 #include <inttypes.h>
0006
0007 #include <stdarg.h>
0008 #include <stdio.h>
0009 #include <stdlib.h>
0010 #include <string.h>
0011
0012 #ifdef __cplusplus
0013 namespace cgreen {
0014 #endif
0015
0016 typedef struct RecordedExpectation_ {
0017 const char *function;
0018 const char *test_file;
0019 int test_line;
0020 int time_to_live;
0021 CgreenVector *constraints;
0022 } RecordedExpectation;
0023
0024 const int UNLIMITED_TIME_TO_LIVE = 0x0f314159;
0025 static CgreenMockMode cgreen_mocks_are_ = strict_mocks;
0026 static CgreenVector *learned_mock_calls = NULL;
0027 static CgreenVector *successfully_mocked_calls = NULL;
0028 static CgreenVector *global_expectation_queue = NULL;
0029
0030 static CgreenVector *create_vector_of_actuals(va_list actuals, int count);
0031 static CgreenVector *create_equal_value_constraints_for(CgreenVector *parameter_names, CgreenVector *actual_values);
0032 static CgreenVector *create_constraints_vector(void);
0033 static RecordedExpectation *create_recorded_expectation(const char *function, const char *test_file, int test_line, CgreenVector *constraints);
0034 static CgreenVector *constraints_vector_from_va_list(va_list constraints);
0035 static void destroy_expectation(RecordedExpectation *expectation);
0036 static void ensure_expectation_queue_exists(void);
0037 static void ensure_learned_mock_calls_list_exists(void);
0038 static void ensure_successfully_mocked_calls_list_exists(void);
0039 void remove_expectation_for(const char *function);
0040 void trigger_unfulfilled_expectations(CgreenVector *expectation_queue, TestReporter *reporter);
0041 RecordedExpectation *find_expectation(const char *function);
0042 void apply_any_read_only_parameter_constraints(RecordedExpectation *expectation, const char *parameter, intptr_t actual, TestReporter* test_reporter);
0043 void apply_any_content_setting_parameter_constraints(RecordedExpectation *expectation, const char *parameter, intptr_t actual, TestReporter* test_reporter);
0044 intptr_t stored_result_or_default_for(CgreenVector* constraints);
0045 int number_of_parameter_constraints_in(const CgreenVector* constraints);
0046 static int number_of_parameters_in(const char *parameter_list);
0047 bool is_always_call(RecordedExpectation* expectation);
0048 bool have_always_expectation_for(const char* function);
0049
0050 bool is_never_call(RecordedExpectation* expectation);
0051 bool have_never_call_expectation_for(const char* function);
0052
0053 void report_violated_never_call(TestReporter*, RecordedExpectation*);
0054 void report_unexpected_call(TestReporter*, RecordedExpectation*);
0055 void report_mock_parameter_name_not_found(TestReporter *test_reporter, RecordedExpectation *expectation, const char *parameter);
0056 void destroy_expectation_if_time_to_die(RecordedExpectation *expectation);
0057
0058 void cgreen_mocks_are(CgreenMockMode mock_mode) {
0059 cgreen_mocks_are_ = mock_mode;
0060 }
0061
0062 static int number_of_parameters_in(const char *parameter_list) {
0063 int count = 1;
0064 const char *current = parameter_list;
0065
0066 if (strlen(parameter_list) == 0) return 0;
0067
0068 while (*current != '\0') {
0069 if (*current == ',') count++;
0070 current++;
0071 }
0072
0073 return count;
0074 }
0075
0076 int number_of_parameter_constraints_in(const CgreenVector* constraints) {
0077 int i, parameters = 0;
0078
0079 for (i = 0; i < cgreen_vector_size(constraints); i++) {
0080 Constraint *constraint = (Constraint *)cgreen_vector_get(constraints, i);
0081
0082 if (is_comparing(constraint)) {
0083 parameters++;
0084 }
0085 }
0086
0087 return parameters;
0088 }
0089
0090 void learn_mock_call_for(const char *function, const char *mock_file, int mock_line, CgreenVector *parameter_names, CgreenVector *actual_values) {
0091 CgreenVector *constraints = create_equal_value_constraints_for(parameter_names, actual_values);
0092
0093 RecordedExpectation *expectation = create_recorded_expectation(function, mock_file, mock_line, constraints);
0094 ensure_learned_mock_calls_list_exists();
0095 cgreen_vector_add(learned_mock_calls, (void*)expectation);
0096 }
0097
0098 void handle_missing_expectation_for(const char *function, const char *mock_file, int mock_line, CgreenVector *parameter_names, CgreenVector *actual_values, TestReporter *test_reporter) {
0099 RecordedExpectation *expectation;
0100 CgreenVector *no_constraints;
0101
0102 switch (cgreen_mocks_are_) {
0103 case loose_mocks:
0104 break;
0105
0106 case learning_mocks:
0107 learn_mock_call_for(function, mock_file, mock_line, parameter_names, actual_values);
0108 break;
0109
0110 case strict_mocks:
0111 no_constraints = create_constraints_vector();
0112 expectation = create_recorded_expectation(function, mock_file, mock_line, no_constraints);
0113 report_unexpected_call(test_reporter, expectation);
0114
0115 destroy_expectation(expectation);
0116 break;
0117 }
0118 }
0119
0120 intptr_t mock_(TestReporter* test_reporter, const char *function, const char *mock_file, int mock_line, const char *parameters, ...) {
0121 va_list actuals;
0122 CgreenVector *actual_values;
0123 CgreenVector *parameter_names;
0124 int failures_before_read_only_constraints_executed;
0125 int failures_after_read_only_constraints_executed;
0126 int i;
0127 intptr_t stored_result;
0128 RecordedExpectation *expectation = find_expectation(function);
0129
0130 va_start(actuals, parameters);
0131 actual_values = create_vector_of_actuals(actuals, number_of_parameters_in(parameters));
0132 va_end(actuals);
0133 parameter_names = create_vector_of_names(parameters);
0134
0135 if (expectation == NULL) {
0136 handle_missing_expectation_for(function, mock_file, mock_line, parameter_names, actual_values, test_reporter);
0137 destroy_cgreen_vector(actual_values);
0138 destroy_cgreen_vector(parameter_names);
0139 return 0;
0140 }
0141
0142 if (is_never_call(expectation)) {
0143 report_violated_never_call(test_reporter, expectation);
0144 destroy_cgreen_vector(actual_values);
0145 destroy_cgreen_vector(parameter_names);
0146 return 0;
0147 }
0148
0149 ensure_successfully_mocked_calls_list_exists();
0150 cgreen_vector_add(successfully_mocked_calls, (void*)function);
0151
0152 stored_result = stored_result_or_default_for(expectation->constraints);
0153
0154 for (i = 0; i < cgreen_vector_size(expectation->constraints); i++) {
0155 Constraint *constraint = (Constraint *)cgreen_vector_get(expectation->constraints, i);
0156
0157 if (!is_parameter(constraint)) continue;
0158
0159 if (!constraint_is_for_parameter_in(constraint, parameters)) {
0160
0161
0162
0163 report_mock_parameter_name_not_found(test_reporter, expectation, constraint->parameter_name);
0164 destroy_expectation_if_time_to_die(expectation);
0165 destroy_cgreen_vector(actual_values);
0166 destroy_cgreen_vector(parameter_names);
0167
0168 return stored_result;
0169 }
0170 }
0171
0172
0173
0174
0175 failures_before_read_only_constraints_executed = test_reporter->failures;
0176
0177 for (i = 0; i < cgreen_vector_size(parameter_names); i++) {
0178 const char* parameter_name = (const char*)cgreen_vector_get(parameter_names, i);
0179 uintptr_t actual = (uintptr_t)cgreen_vector_get(actual_values, i);
0180 apply_any_read_only_parameter_constraints(expectation, parameter_name, actual, test_reporter);
0181 }
0182
0183 failures_after_read_only_constraints_executed = test_reporter->failures;
0184
0185
0186
0187
0188 if (failures_before_read_only_constraints_executed == failures_after_read_only_constraints_executed) {
0189 for (i = 0; i < cgreen_vector_size(parameter_names); i++) {
0190 const char* parameter_name = (const char*)cgreen_vector_get(parameter_names, i);
0191 uintptr_t actual = (uintptr_t)cgreen_vector_get(actual_values, i);
0192 apply_any_content_setting_parameter_constraints(expectation, parameter_name, actual, test_reporter);
0193 }
0194 }
0195
0196 destroy_cgreen_vector(parameter_names);
0197 destroy_cgreen_vector(actual_values);
0198
0199 destroy_expectation_if_time_to_die(expectation);
0200
0201 return stored_result;
0202 }
0203
0204
0205 static CgreenVector *create_vector_of_actuals(va_list actuals, int count) {
0206 int i;
0207 CgreenVector *actual_values = create_cgreen_vector(NULL);
0208 for (i = 0; i < count; i++) {
0209 uintptr_t actual = va_arg(actuals, uintptr_t);
0210 cgreen_vector_add(actual_values, (void*)actual);
0211 }
0212 return actual_values;
0213 }
0214
0215
0216 static CgreenVector *create_equal_value_constraints_for(CgreenVector *parameter_names, CgreenVector *actual_values) {
0217 int i;
0218 CgreenVector *constraints = create_constraints_vector();
0219 for (i = 0; i < cgreen_vector_size(parameter_names); i++) {
0220 const char* parameter_name = (const char*)cgreen_vector_get(parameter_names, i);
0221 uintptr_t actual = (uintptr_t)cgreen_vector_get(actual_values, i);
0222 Constraint *constraint = create_equal_to_value_constraint((intptr_t)actual, parameter_name);
0223 cgreen_vector_add(constraints, constraint);
0224 }
0225 return constraints;
0226 }
0227
0228
0229 Constraint *when_(const char *parameter, Constraint* constraint) {
0230 constraint->parameter_name = parameter;
0231 return constraint;
0232 }
0233
0234 void destroy_expectation_if_time_to_die(RecordedExpectation *expectation) {
0235
0236 if (is_always_call(expectation)) {
0237 return;
0238 }
0239
0240
0241 expectation->time_to_live--;
0242
0243 if (expectation->time_to_live <= 0) {
0244 remove_expectation_for(expectation->function);
0245 destroy_expectation(expectation);
0246 }
0247 }
0248
0249 void expect_(TestReporter* test_reporter, const char *function, const char *test_file, int test_line, ...) {
0250 va_list constraints;
0251 RecordedExpectation *expectation;
0252 CgreenVector *constraints_vector;
0253
0254 if (have_always_expectation_for(function)) {
0255 test_reporter->assert_true(
0256 test_reporter,
0257 test_file,
0258 test_line,
0259 false,
0260 "Mocked function [%s] already has an expectation that it will always be called a certain way; "
0261 "any expectations declared after an always expectation are invalid", function);
0262 va_start(constraints, test_line);
0263 destroy_constraints(constraints);
0264 va_end(constraints);
0265
0266 return;
0267 }
0268
0269 if (have_never_call_expectation_for(function)) {
0270 test_reporter->assert_true(
0271 test_reporter,
0272 test_file,
0273 test_line,
0274 false,
0275 "Mocked function [%s] already has an expectation that it will never be called; "
0276 "any expectations declared after a never call expectation are invalid", function);
0277 va_start(constraints, test_line);
0278 destroy_constraints(constraints);
0279 va_end(constraints);
0280
0281 return;
0282 }
0283
0284
0285 va_start(constraints, test_line);
0286 constraints_vector = constraints_vector_from_va_list(constraints);
0287 expectation = create_recorded_expectation(function, test_file, test_line, constraints_vector);
0288 va_end(constraints);
0289 expectation->time_to_live = 1;
0290 cgreen_vector_add(global_expectation_queue, expectation);
0291 }
0292
0293 void always_expect_(TestReporter* test_reporter, const char *function, const char *test_file, int test_line, ...) {
0294 va_list constraints;
0295 RecordedExpectation *expectation;
0296 CgreenVector *constraints_vector;
0297
0298 if (have_always_expectation_for(function)) {
0299 test_reporter->assert_true(
0300 test_reporter,
0301 test_file,
0302 test_line,
0303 false,
0304 "Mocked function [%s] already has an expectation and will always be called a certain way; "
0305 "any expectations declared after an always expectation are discarded", function);
0306 va_start(constraints, test_line);
0307 destroy_constraints(constraints);
0308 va_end(constraints);
0309
0310 return;
0311 }
0312
0313 if (have_never_call_expectation_for(function)) {
0314 test_reporter->assert_true(
0315 test_reporter,
0316 test_file,
0317 test_line,
0318 false,
0319 "Mocked function [%s] already has an expectation that it will never be called; "
0320 "any expectations declared after a never call expectation are discarded", function);
0321 va_start(constraints, test_line);
0322 destroy_constraints(constraints);
0323 va_end(constraints);
0324
0325 return;
0326 }
0327
0328 va_start(constraints, test_line);
0329 constraints_vector = constraints_vector_from_va_list(constraints);
0330 expectation = create_recorded_expectation(function, test_file, test_line, constraints_vector);
0331 va_end(constraints);
0332 expectation->time_to_live = UNLIMITED_TIME_TO_LIVE;
0333 cgreen_vector_add(global_expectation_queue, expectation);
0334 }
0335
0336 void never_expect_(TestReporter* test_reporter, const char *function, const char *test_file, int test_line, ...) {
0337 va_list constraints;
0338 RecordedExpectation *expectation;
0339 CgreenVector *constraints_vector;
0340
0341 if (have_always_expectation_for(function)) {
0342 test_reporter->assert_true(
0343 test_reporter,
0344 test_file,
0345 test_line,
0346 false,
0347 "Mocked function [%s] already has an expectation and will always be called a certain way; "
0348 "declaring an expectation after an always expectation is not allowed", function);
0349 va_start(constraints, test_line);
0350 destroy_constraints(constraints);
0351 va_end(constraints);
0352
0353 return;
0354 }
0355
0356 if (have_never_call_expectation_for(function)) {
0357 test_reporter->assert_true(
0358 test_reporter,
0359 test_file,
0360 test_line,
0361 false,
0362 "Mocked function [%s] already has an expectation that it will never be called; "
0363 "declaring an expectation for a function after a never call expectation is not allowed", function);
0364 va_start(constraints, test_line);
0365 destroy_constraints(constraints);
0366 va_end(constraints);
0367
0368 return;
0369 }
0370
0371 va_start(constraints, test_line);
0372 constraints_vector = constraints_vector_from_va_list(constraints);
0373 expectation = create_recorded_expectation(function, test_file, test_line, constraints_vector);
0374 expectation->time_to_live = -UNLIMITED_TIME_TO_LIVE;
0375 cgreen_vector_add(global_expectation_queue, expectation);
0376 }
0377
0378
0379 void report_violated_never_call(TestReporter *test_reporter, RecordedExpectation* expectation) {
0380 test_reporter->assert_true(
0381 test_reporter,
0382 expectation->test_file,
0383 expectation->test_line,
0384 false,
0385 "Mocked function [%s] has an expectation that it will never be called, but it was",
0386 expectation->function);
0387 }
0388
0389
0390 static bool successfully_mocked_call(const char *function_name) {
0391 int i;
0392
0393 for (i = 0; i < cgreen_vector_size(successfully_mocked_calls); i++) {
0394 const char *successfully_mocked_function_name = (const char *)cgreen_vector_get(successfully_mocked_calls, i);
0395 if (strcmp(successfully_mocked_function_name, function_name) == 0) {
0396 return true;
0397 }
0398 }
0399
0400 return false;
0401 }
0402
0403
0404 void report_unexpected_call(TestReporter *test_reporter, RecordedExpectation* expectation) {
0405 const char *message;
0406 if (successfully_mocked_call(expectation->function)) {
0407 message = "Mocked function [%s] was called too many times";
0408 } else {
0409 message = "Mocked function [%s] did not have an expectation that it would be called";
0410 }
0411
0412 test_reporter->assert_true(
0413 test_reporter,
0414 expectation->test_file,
0415 expectation->test_line,
0416 false,
0417 message,
0418 expectation->function);
0419 }
0420
0421 void clear_mocks(void) {
0422 if (global_expectation_queue != NULL) {
0423 destroy_cgreen_vector(global_expectation_queue);
0424 global_expectation_queue = NULL;
0425 }
0426
0427 if (learned_mock_calls != NULL) {
0428 int i;
0429 for (i = 0; i < cgreen_vector_size(learned_mock_calls); i++) {
0430 RecordedExpectation *expectation = (RecordedExpectation*)cgreen_vector_get(learned_mock_calls, i);
0431 destroy_expectation(expectation);
0432 }
0433
0434 destroy_cgreen_vector(learned_mock_calls);
0435 learned_mock_calls = NULL;
0436 }
0437 }
0438
0439 void print_learned_mocks(void) {
0440 int e, c;
0441 CgreenBreadcrumb *breadcrumb = get_test_reporter()->breadcrumb;
0442 printf("%s: learned mocks:\n",
0443 get_current_from_breadcrumb(breadcrumb));
0444
0445 if (cgreen_vector_size(learned_mock_calls) == 0) {
0446 printf("\t<none>\n");
0447 return;
0448 }
0449
0450 for (e = 0; e < cgreen_vector_size(learned_mock_calls); e++) {
0451 RecordedExpectation *expectation = (RecordedExpectation*)cgreen_vector_get(learned_mock_calls, e);
0452 const char *function_name = expectation->function;
0453 printf("\texpect(%s", function_name);
0454 for (c = 0; c < cgreen_vector_size(expectation->constraints); c++) {
0455 Constraint *constraint = (Constraint *)cgreen_vector_get(expectation->constraints, c);
0456 printf(", when(%s, is_equal_to(%" PRIdPTR "))", constraint->expected_value_name, constraint->expected_value);
0457 }
0458 printf(");\n");
0459 }
0460 }
0461
0462 void tally_mocks(TestReporter *reporter) {
0463 if (cgreen_mocks_are_ == learning_mocks) {
0464 print_learned_mocks();
0465 }
0466
0467 trigger_unfulfilled_expectations(global_expectation_queue, reporter);
0468 clear_mocks();
0469 }
0470
0471
0472 static CgreenVector *create_constraints_vector(void) {
0473 return create_cgreen_vector((GenericDestructor)&destroy_constraint);
0474 }
0475
0476
0477 static CgreenVector *constraints_vector_from_va_list(va_list constraints) {
0478 CgreenVector *vector = create_constraints_vector();
0479 Constraint *constraint;
0480 while ((constraint = va_arg(constraints, Constraint *)) != (Constraint *)0) {
0481 cgreen_vector_add(vector, constraint);
0482 }
0483 return vector;
0484 }
0485
0486
0487 static RecordedExpectation *create_recorded_expectation(const char *function, const char *test_file, int test_line, CgreenVector *constraints) {
0488 RecordedExpectation *expectation;
0489
0490 ensure_expectation_queue_exists();
0491 expectation = (RecordedExpectation *)malloc(sizeof(RecordedExpectation));
0492 expectation->function = function;
0493 expectation->test_file = test_file;
0494 expectation->test_line = test_line;
0495 expectation->constraints = constraints;
0496
0497 return expectation;
0498 }
0499
0500 static void destroy_expectation(RecordedExpectation *expectation) {
0501 destroy_cgreen_vector(expectation->constraints);
0502 expectation->constraints = NULL;
0503 expectation->function = NULL;
0504 expectation->test_file = NULL;
0505 expectation->test_line = 0;
0506 expectation->time_to_live = 0;
0507
0508 free(expectation);
0509 }
0510
0511 static void ensure_successfully_mocked_calls_list_exists(void) {
0512 if (successfully_mocked_calls == NULL) {
0513
0514 successfully_mocked_calls = create_cgreen_vector(NULL);
0515 }
0516 }
0517
0518 static void ensure_learned_mock_calls_list_exists(void) {
0519 if (learned_mock_calls == NULL) {
0520
0521 learned_mock_calls = create_cgreen_vector(NULL);
0522 }
0523 }
0524
0525 static void ensure_expectation_queue_exists(void) {
0526 if (global_expectation_queue == NULL) {
0527 global_expectation_queue = create_cgreen_vector((GenericDestructor)&destroy_expectation);
0528 }
0529 }
0530
0531 void remove_expectation_for(const char *function) {
0532 int i;
0533 for (i = 0; i < cgreen_vector_size(global_expectation_queue); i++) {
0534 RecordedExpectation *expectation = (RecordedExpectation *)cgreen_vector_get(global_expectation_queue, i);
0535
0536 if (NULL == expectation) {
0537 printf("*** CGREEN: NULL expectation found -- maybe a previous incorrect removal?");
0538 continue;
0539 }
0540
0541 if (strcmp(expectation->function, function) == 0) {
0542 cgreen_vector_remove(global_expectation_queue, i);
0543 return;
0544 }
0545 }
0546 }
0547
0548 void trigger_unfulfilled_expectations(CgreenVector *expectation_queue, TestReporter *reporter) {
0549 int i;
0550 for (i = 0; i < cgreen_vector_size(expectation_queue); i++) {
0551 RecordedExpectation *expectation = (RecordedExpectation *)cgreen_vector_get(expectation_queue, i);
0552
0553 if (NULL == expectation) {
0554 fprintf(stderr, "*** NULL unfulfilled cgreen expectation found -- maybe a previous incorrect removal?");
0555 continue;
0556 }
0557
0558 if (is_always_call(expectation) || is_never_call(expectation)) {
0559 continue;
0560 }
0561
0562 (*reporter->assert_true)(
0563 reporter,
0564 expectation->test_file,
0565 expectation->test_line,
0566 0,
0567 "Expected call was not made to mocked function [%s]", expectation->function);
0568 }
0569 }
0570
0571 RecordedExpectation *find_expectation(const char *function) {
0572 int i;
0573 for (i = 0; i < cgreen_vector_size(global_expectation_queue); i++) {
0574 RecordedExpectation *expectation =
0575 (RecordedExpectation *)cgreen_vector_get(global_expectation_queue, i);
0576
0577 if (strcmp(expectation->function, function) == 0) {
0578 return expectation;
0579 }
0580 }
0581 return NULL;
0582 }
0583
0584 void report_mock_parameter_name_not_found(TestReporter *test_reporter, RecordedExpectation *expectation, const char *constraint_parameter_name) {
0585
0586 test_reporter->assert_true(
0587 test_reporter,
0588 expectation->test_file,
0589 expectation->test_line,
0590 false,
0591 "Mocked function [%s] did not define a parameter named [%s]. Did you misspell it in the expectation or forget it in the mock's argument list?",
0592 expectation->function,
0593 constraint_parameter_name);
0594 }
0595
0596 void apply_any_read_only_parameter_constraints(RecordedExpectation *expectation, const char *parameter, intptr_t actual, TestReporter* test_reporter) {
0597 int i;
0598
0599 for (i = 0; i < cgreen_vector_size(expectation->constraints); i++) {
0600 Constraint *constraint = (Constraint *)cgreen_vector_get(expectation->constraints, i);
0601
0602 if (constraint_is_not_for_parameter(constraint, parameter)) {
0603 continue;
0604 }
0605
0606 if (constraint->type == CONTENT_SETTER) {
0607 continue;
0608 }
0609
0610 constraint->execute(
0611 constraint,
0612 expectation->function,
0613 actual,
0614 expectation->test_file,
0615 expectation->test_line,
0616 test_reporter);
0617 }
0618 }
0619
0620 void apply_any_content_setting_parameter_constraints(RecordedExpectation *expectation, const char *parameter, intptr_t actual, TestReporter* test_reporter) {
0621 int i;
0622 for (i = 0; i < cgreen_vector_size(expectation->constraints); i++) {
0623 Constraint *constraint = (Constraint *)cgreen_vector_get(expectation->constraints, i);
0624
0625 if (constraint_is_not_for_parameter(constraint, parameter)) {
0626 continue;
0627 }
0628
0629 if (constraint->type != CONTENT_SETTER) {
0630 continue;
0631 }
0632
0633 constraint->execute(
0634 constraint,
0635 expectation->function,
0636 actual,
0637 expectation->test_file,
0638 expectation->test_line,
0639 test_reporter);
0640 }
0641 }
0642
0643 intptr_t stored_result_or_default_for(CgreenVector* constraints) {
0644 int i;
0645 for (i = 0; i < cgreen_vector_size(constraints); i++) {
0646 Constraint *constraint = (Constraint *)cgreen_vector_get(constraints, i);
0647
0648 if (constraint->type == RETURN_VALUE) {
0649 return constraint->expected_value;
0650 }
0651 }
0652
0653 return 0;
0654 }
0655
0656 bool is_always_call(RecordedExpectation* expectation) {
0657 return expectation->time_to_live == UNLIMITED_TIME_TO_LIVE;
0658 }
0659
0660 bool have_always_expectation_for(const char* function) {
0661 int i;
0662 for (i = 0; i < cgreen_vector_size(global_expectation_queue); i++) {
0663 RecordedExpectation *expectation =
0664 (RecordedExpectation *)cgreen_vector_get(global_expectation_queue, i);
0665 if (strcmp(expectation->function, function) == 0) {
0666 if (is_always_call(expectation)) {
0667 return true;
0668 }
0669 }
0670 }
0671
0672 return false;
0673 }
0674
0675 bool is_never_call(RecordedExpectation* expectation) {
0676 return expectation->time_to_live == -UNLIMITED_TIME_TO_LIVE;
0677 }
0678
0679 bool have_never_call_expectation_for(const char* function) {
0680 int i;
0681 for (i = 0; i < cgreen_vector_size(global_expectation_queue); i++) {
0682 RecordedExpectation *expectation =
0683 (RecordedExpectation *)cgreen_vector_get(global_expectation_queue, i);
0684 if (strcmp(expectation->function, function) == 0) {
0685 if (is_never_call(expectation)) {
0686 return true;
0687 }
0688 }
0689 }
0690
0691 return false;
0692 }
0693
0694 #ifdef __cplusplus
0695 }
0696 #endif
0697
0698