• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

thetic / mutiny / 24575604752

17 Apr 2026 04:26PM UTC coverage: 98.713% (+0.08%) from 98.629%
24575604752

Pull #59

github

web-flow
Merge 3d55a5f86 into e0583988c
Pull Request #59: Dissolve internal unit tests; restore coverage via public interface

3 of 3 new or added lines in 2 files covered. (100.0%)

4 existing lines in 4 files now uncovered.

5062 of 5128 relevant lines covered (98.71%)

3554.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

99.39
/src/mock/mock.cpp
1
#include "mutiny/mock.hpp"
2

3
#include "mutiny/mock/ActualCallTrace.hpp"
4
#include "mutiny/mock/CheckedActualCall.hpp"
5
#include "mutiny/mock/CheckedExpectedCall.hpp"
6
#include "mutiny/mock/ExpectedCall.hpp"
7
#include "mutiny/mock/ExpectedCallsList.hpp"
8
#include "mutiny/mock/Failure.hpp"
9
#include "mutiny/mock/IgnoredActualCall.hpp"
10
#include "mutiny/mock/IgnoredExpectedCall.hpp"
11
#include "mutiny/mock/NamedValueComparatorsAndCopiersRepository.hpp"
12
#include "mutiny/mock/NamedValueList.hpp"
13

14
#include "mutiny/test/Shell.hpp"
15

16
#define MOCK_SUPPORT_SCOPE_PREFIX "!!!$$$MockingSupportScope$$$!!!"
17

18
namespace mu {
19
namespace tiny {
20
namespace mock {
21

22
class Support::Impl
23
{
24
  friend class Support;
25

26
  FailureReporter default_reporter_;
27
  FailureReporter* active_reporter_{ nullptr };
28
  FailureReporter* standard_reporter_;
29
  ExpectedCallsList expectations_;
30
  CheckedActualCall* last_actual_function_call_{ nullptr };
31
  NamedValueComparatorsAndCopiersRepository comparators_and_copiers_repository_;
32
  NamedValueList data_;
33

34
  Impl()
46✔
35
    : standard_reporter_(&default_reporter_)
46✔
36

37
  {
38
  }
46✔
39
};
40

41
Support& mock(
2,162✔
42
    const String& mock_name,
43
    FailureReporter* failure_reporter_for_this_call
44
)
45
{
46
  static Support global_mock;
2,162✔
47
  Support& mock_support = (mock_name != "")
2,162✔
48
                              ? *global_mock.get_mock_support_scope(mock_name)
89✔
49
                              : global_mock;
2,251✔
50
  mock_support.set_active_reporter(failure_reporter_for_this_call);
2,162✔
51
  mock_support.set_default_comparators_and_copiers_repository();
2,162✔
52
  return mock_support;
2,162✔
53
}
54

55
Support::Support(const String& mock_name)
46✔
56
  : impl_(new Impl())
46✔
57
  , mock_name_(mock_name)
92✔
58
{
59
}
46✔
60

61
Support::~Support()
128✔
62
{
63
  delete impl_;
46✔
64
}
82✔
65

66
void Support::crash_on_failure(bool should_crash)
5✔
67
{
68
  impl_->active_reporter_->crash_on_failure(should_crash);
5✔
69
}
5✔
70

71
void Support::set_mock_failure_standard_reporter(FailureReporter* reporter)
213✔
72
{
73
  impl_->standard_reporter_ =
213✔
74
      (reporter != nullptr) ? reporter : &impl_->default_reporter_;
213✔
75

76
  if (impl_->last_actual_function_call_)
213✔
77
    impl_->last_actual_function_call_->set_mock_failure_reporter(
30✔
78
        impl_->standard_reporter_
30✔
79
    );
80

81
  for (NamedValueListNode* p = impl_->data_.begin(); p; p = p->next())
218✔
82
    if (get_mock_support(p))
5✔
83
      get_mock_support(p)->set_mock_failure_standard_reporter(
5✔
84
          impl_->standard_reporter_
5✔
85
      );
86
}
213✔
87

88
void Support::set_active_reporter(FailureReporter* reporter)
2,162✔
89
{
90
  impl_->active_reporter_ = (reporter) ? reporter : impl_->standard_reporter_;
2,162✔
91
}
2,162✔
92

93
void Support::set_default_comparators_and_copiers_repository()
2,162✔
94
{
95
  NamedValue::set_default_comparators_and_copiers_repository(
2,162✔
96
      &impl_->comparators_and_copiers_repository_
2,162✔
97
  );
98
}
2,162✔
99

100
void Support::install_comparator(
14✔
101
    const String& type_name,
102
    NamedValueComparator& comparator
103
)
104
{
105
  impl_->comparators_and_copiers_repository_.install_comparator(
14✔
106
      type_name, comparator
107
  );
108

109
  for (NamedValueListNode* p = impl_->data_.begin(); p; p = p->next())
15✔
110
    if (get_mock_support(p))
1✔
111
      get_mock_support(p)->install_comparator(type_name, comparator);
1✔
112
}
14✔
113

114
void Support::install_copier(const String& type_name, NamedValueCopier& copier)
19✔
115
{
116
  impl_->comparators_and_copiers_repository_.install_copier(type_name, copier);
19✔
117

118
  for (NamedValueListNode* p = impl_->data_.begin(); p; p = p->next())
20✔
119
    if (get_mock_support(p))
1✔
120
      get_mock_support(p)->install_copier(type_name, copier);
1✔
121
}
19✔
122

123
void Support::install_comparators_and_copiers(
40✔
124
    const NamedValueComparatorsAndCopiersRepository& repository
125
)
126
{
127
  impl_->comparators_and_copiers_repository_.install_comparators_and_copiers(
40✔
128
      repository
129
  );
130

131
  for (NamedValueListNode* p = impl_->data_.begin(); p; p = p->next())
41✔
132
    if (get_mock_support(p))
1✔
133
      get_mock_support(p)->install_comparators_and_copiers(repository);
1✔
134
}
40✔
135

136
void Support::remove_all_comparators_and_copiers()
69✔
137
{
138
  impl_->comparators_and_copiers_repository_.clear();
69✔
139
  for (NamedValueListNode* p = impl_->data_.begin(); p; p = p->next())
75✔
140
    if (get_mock_support(p))
6✔
141
      get_mock_support(p)->remove_all_comparators_and_copiers();
6✔
142
}
69✔
143

144
void Support::clear()
430✔
145
{
146
  delete impl_->last_actual_function_call_;
430✔
147
  impl_->last_actual_function_call_ = nullptr;
430✔
148

149
  tracing_ = false;
430✔
150
  ActualCallTrace::clear_instance();
430✔
151

152
  impl_->expectations_.delete_all_expectations_and_clear_list();
430✔
153
  ignore_other_calls_ = false;
430✔
154
  enabled_ = true;
430✔
155
  actual_call_order_ = 0;
430✔
156
  expected_call_order_ = 0;
430✔
157
  strict_ordering_ = false;
430✔
158

159
  for (NamedValueListNode* p = impl_->data_.begin(); p; p = p->next()) {
511✔
160
    Support* support = get_mock_support(p);
81✔
161
    if (support) {
81✔
162
      support->clear();
36✔
163
      delete support;
36✔
164
    }
165
  }
166
  impl_->data_.clear();
430✔
167
}
430✔
168

169
void Support::strict_order()
19✔
170
{
171
  strict_ordering_ = true;
19✔
172
}
19✔
173

174
String Support::append_scope_to_name(const String& function_name)
800✔
175
{
176
  if (mock_name_.empty())
800✔
177
    return function_name;
743✔
178
  return mock_name_ + "::" + function_name;
57✔
179
}
180

181
ExpectedCall& Support::expect_one_call(const String& function_name)
382✔
182
{
183
  return expect_n_calls(1, function_name);
382✔
184
}
185

186
void Support::expect_no_call(const String& function_name)
2✔
187
{
188
  expect_n_calls(0, function_name);
2✔
189
}
2✔
190

191
ExpectedCall& Support::expect_n_calls(
391✔
192
    unsigned int amount,
193
    const String& function_name
194
)
195
{
196
  if (!enabled_)
391✔
197
    return IgnoredExpectedCall::instance();
6✔
198

199
  count_check();
385✔
200

201
  auto* call = new CheckedExpectedCall(amount);
385✔
202
  call->with_name(append_scope_to_name(function_name));
385✔
203
  if (strict_ordering_) {
385✔
204
    call->with_call_order(
27✔
205
        expected_call_order_ + 1, expected_call_order_ + amount
27✔
206
    );
207
    expected_call_order_ += amount;
27✔
208
  }
209
  impl_->expectations_.add_expected_call(call);
385✔
210
  return *call;
385✔
211
}
212

213
CheckedActualCall* Support::create_actual_call()
391✔
214
{
215
  impl_->last_actual_function_call_ = new CheckedActualCall(
×
216
      ++actual_call_order_, impl_->active_reporter_, impl_->expectations_
391✔
217
  );
391✔
218
  return impl_->last_actual_function_call_;
391✔
219
}
220

221
bool Support::call_is_ignored(const String& function_name)
402✔
222
{
223
  return ignore_other_calls_ &&
418✔
224
         !impl_->expectations_.has_expectation_with_name(function_name);
418✔
225
}
226

227
ActualCall& Support::actual_call(const char* function_name)
415✔
228
{
229
  String scope_function_name = append_scope_to_name(function_name);
415✔
230

231
  if (impl_->last_actual_function_call_) {
415✔
232
    impl_->last_actual_function_call_->check_expectations();
98✔
233
    delete impl_->last_actual_function_call_;
98✔
234
    impl_->last_actual_function_call_ = nullptr;
98✔
235
  }
236

237
  if (!enabled_)
415✔
238
    return IgnoredActualCall::instance();
2✔
239
  if (tracing_)
413✔
240
    return ActualCallTrace::instance().with_name(scope_function_name);
11✔
241

242
  if (call_is_ignored(scope_function_name)) {
402✔
243
    return IgnoredActualCall::instance();
11✔
244
  }
245

246
  CheckedActualCall* call = create_actual_call();
391✔
247
  call->set_name_and_check(static_cast<String&&>(scope_function_name));
396✔
248
  return *call;
381✔
249
}
410✔
250

251
void Support::ignore_other_calls()
14✔
252
{
253
  ignore_other_calls_ = true;
14✔
254

255
  for (NamedValueListNode* p = impl_->data_.begin(); p; p = p->next())
16✔
256
    if (get_mock_support(p))
2✔
257
      get_mock_support(p)->ignore_other_calls();
2✔
258
}
14✔
259

260
void Support::disable()
9✔
261
{
262
  enabled_ = false;
9✔
263

264
  for (NamedValueListNode* p = impl_->data_.begin(); p; p = p->next())
10✔
265
    if (get_mock_support(p))
1✔
266
      get_mock_support(p)->disable();
1✔
267
}
9✔
268

269
void Support::enable()
6✔
270
{
271
  enabled_ = true;
6✔
272

273
  for (NamedValueListNode* p = impl_->data_.begin(); p; p = p->next())
8✔
274
    if (get_mock_support(p))
2✔
275
      get_mock_support(p)->enable();
2✔
276
}
6✔
277

278
void Support::tracing(bool enabled)
47✔
279
{
280
  tracing_ = enabled;
47✔
281

282
  for (NamedValueListNode* p = impl_->data_.begin(); p; p = p->next())
48✔
283
    if (get_mock_support(p))
1✔
284
      get_mock_support(p)->tracing(enabled);
1✔
285
}
47✔
286

287
const char* Support::get_trace_output()
10✔
288
{
289
  return ActualCallTrace::instance().get_trace_output();
10✔
290
}
291

292
bool Support::expected_calls_left()
371✔
293
{
294
  check_expectations_of_last_actual_call();
371✔
295
  int calls_left = impl_->expectations_.has_unfulfilled_expectations();
371✔
296

297
  for (NamedValueListNode* p = impl_->data_.begin(); p; p = p->next())
414✔
298
    if (get_mock_support(p))
43✔
299
      calls_left += get_mock_support(p)->expected_calls_left();
23✔
300

301
  return calls_left != 0;
371✔
302
}
303

304
bool Support::was_last_actual_call_fulfilled()
396✔
305
{
306
  if (impl_->last_actual_function_call_ &&
696✔
307
      !impl_->last_actual_function_call_->is_fulfilled())
300✔
308
    return false;
36✔
309

310
  for (NamedValueListNode* p = impl_->data_.begin(); p; p = p->next())
402✔
311
    if (get_mock_support(p) &&
70✔
312
        !get_mock_support(p)->was_last_actual_call_fulfilled())
25✔
313
      return false;
3✔
314

315
  return true;
357✔
316
}
317

318
void Support::fail_test_with_expected_calls_not_fulfilled()
11✔
319
{
320
  ExpectedCallsList expectations_list;
11✔
321
  expectations_list.add_expectations(impl_->expectations_);
11✔
322

323
  for (NamedValueListNode* p = impl_->data_.begin(); p; p = p->next())
13✔
324
    if (get_mock_support(p))
2✔
325
      expectations_list.add_expectations(
2✔
326
          get_mock_support(p)->impl_->expectations_
2✔
327
      );
328

329
  ExpectedCallsDidntHappenFailure failure(
330
      impl_->active_reporter_->get_test_to_fail(), expectations_list
11✔
331
  );
11✔
332
  fail_test(failure);
11✔
333
}
11✔
334

335
void Support::fail_test_with_out_of_order_calls()
4✔
336
{
337
  ExpectedCallsList expectations_list;
4✔
338
  expectations_list.add_expectations(impl_->expectations_);
4✔
339

340
  for (NamedValueListNode* p = impl_->data_.begin(); p; p = p->next())
9✔
341
    if (get_mock_support(p))
5✔
342
      expectations_list.add_expectations(
5✔
343
          get_mock_support(p)->impl_->expectations_
5✔
344
      );
345

346
  CallOrderFailure failure(
347
      impl_->active_reporter_->get_test_to_fail(), expectations_list
4✔
348
  );
4✔
349
  fail_test(failure);
4✔
350
}
4✔
351

352
void Support::fail_test(Failure& failure)
15✔
353
{
354
  clear();
15✔
355
  impl_->active_reporter_->fail_test(static_cast<Failure&&>(failure));
15✔
356
}
15✔
357

358
void Support::count_check()
385✔
359
{
360
  test::Shell::get_current()->count_check();
385✔
361
}
385✔
362

363
void Support::check_expectations_of_last_actual_call()
742✔
364
{
365
  if (impl_->last_actual_function_call_)
742✔
366
    impl_->last_actual_function_call_->check_expectations();
549✔
367

368
  for (NamedValueListNode* p = impl_->data_.begin(); p; p = p->next())
830✔
369
    if (get_mock_support(p) &&
136✔
370
        get_mock_support(p)->impl_->last_actual_function_call_)
48✔
371
      get_mock_support(p)
29✔
372
          ->impl_->last_actual_function_call_->check_expectations();
29✔
373
}
742✔
374

375
bool Support::has_calls_out_of_order()
394✔
376
{
377
  if (impl_->expectations_.has_calls_out_of_order()) {
394✔
378
    return true;
4✔
379
  }
380
  for (NamedValueListNode* p = impl_->data_.begin(); p; p = p->next())
430✔
381
    if (get_mock_support(p) && get_mock_support(p)->has_calls_out_of_order()) {
43✔
382
      return true;
3✔
383
    }
384
  return false;
387✔
385
}
386

387
void Support::check_expectations()
371✔
388
{
389
  check_expectations_of_last_actual_call();
371✔
390

391
  if (was_last_actual_call_fulfilled() && expected_calls_left())
371✔
392
    fail_test_with_expected_calls_not_fulfilled();
11✔
393

394
  if (has_calls_out_of_order())
371✔
395
    fail_test_with_out_of_order_calls();
4✔
396
}
371✔
397

398
bool Support::has_data(const String& name)
95✔
399
{
400
  return impl_->data_.get_value_by_name(name) != nullptr;
95✔
401
}
402

403
NamedValue* Support::retrieve_data_from_store(const String& name)
86✔
404
{
405
  NamedValue* new_data = impl_->data_.get_value_by_name(name);
86✔
406
  if (new_data == nullptr) {
86✔
407
    new_data = new NamedValue(name);
81✔
408
    impl_->data_.add(new_data);
81✔
409
  }
410
  return new_data;
86✔
411
}
412

413
void Support::set_data(const String& name, bool value)
3✔
414
{
415
  NamedValue* new_data = retrieve_data_from_store(name);
3✔
416
  new_data->set_value(value);
3✔
417
}
3✔
418

419
void Support::set_data(const String& name, unsigned int value)
3✔
420
{
421
  NamedValue* new_data = retrieve_data_from_store(name);
3✔
422
  new_data->set_value(value);
3✔
423
}
3✔
424

425
void Support::set_data(const String& name, int value)
9✔
426
{
427
  NamedValue* new_data = retrieve_data_from_store(name);
9✔
428
  new_data->set_value(value);
9✔
429
}
9✔
430

431
void Support::set_data(const String& name, long int value)
3✔
432
{
433
  NamedValue* new_data = retrieve_data_from_store(name);
3✔
434
  new_data->set_value(value);
3✔
435
}
3✔
436

437
void Support::set_data(const String& name, unsigned long int value)
2✔
438
{
439
  NamedValue* new_data = retrieve_data_from_store(name);
2✔
440
  new_data->set_value(value);
2✔
441
}
2✔
442

443
void Support::set_data(const String& name, const char* value)
4✔
444
{
445
  NamedValue* new_data = retrieve_data_from_store(name);
4✔
446
  new_data->set_value(value);
4✔
447
}
4✔
448

449
void Support::set_data(const String& name, double value)
4✔
450
{
451
  NamedValue* new_data = retrieve_data_from_store(name);
4✔
452
  new_data->set_value(value);
4✔
453
}
4✔
454

455
void Support::set_data(const String& name, void* value)
4✔
456
{
457
  NamedValue* new_data = retrieve_data_from_store(name);
4✔
458
  new_data->set_value(value);
4✔
459
}
4✔
460

461
void Support::set_data(const String& name, const void* value)
4✔
462
{
463
  NamedValue* new_data = retrieve_data_from_store(name);
4✔
464
  new_data->set_value(value);
4✔
465
}
4✔
466

467
void Support::set_data(const String& name, long long value)
2✔
468
{
469
  NamedValue* new_data = retrieve_data_from_store(name);
2✔
470
  new_data->set_value(value);
2✔
471
}
2✔
472

473
void Support::set_data(const String& name, unsigned long long value)
2✔
474
{
475
  NamedValue* new_data = retrieve_data_from_store(name);
2✔
476
  new_data->set_value(value);
2✔
477
}
2✔
478

479
void Support::set_data(const String& name, FunctionPointerValue value)
4✔
480
{
481
  NamedValue* new_data = retrieve_data_from_store(name);
4✔
482
  new_data->set_value(value);
4✔
483
}
4✔
484

485
void Support::set_data_object(
40✔
486
    const String& name,
487
    const String& type,
488
    void* value
489
)
490
{
491
  NamedValue* new_data = retrieve_data_from_store(name);
40✔
492
  new_data->set_object_pointer(type, value);
40✔
493
}
40✔
494

495
void Support::set_data_const_object(
2✔
496
    const String& name,
497
    const String& type,
498
    const void* value
499
)
500
{
501
  NamedValue* new_data = retrieve_data_from_store(name);
2✔
502
  new_data->set_const_object_pointer(type, value);
2✔
503
}
2✔
504

505
NamedValue Support::get_data(const String& name)
160✔
506
{
507
  NamedValue* value = impl_->data_.get_value_by_name(name);
160✔
508
  if (value == nullptr)
160✔
509
    return NamedValue("");
2✔
510
  return *value;
158✔
511
}
512

513
Support* Support::clone(const String& mock_name)
36✔
514
{
515
  auto* new_mock = new Support(mock_name);
36✔
516
  new_mock->set_mock_failure_standard_reporter(impl_->standard_reporter_);
36✔
517
  if (ignore_other_calls_)
36✔
518
    new_mock->ignore_other_calls();
2✔
519

520
  if (!enabled_)
36✔
521
    new_mock->disable();
1✔
522

523
  if (strict_ordering_)
36✔
524
    new_mock->strict_order();
5✔
525

526
  new_mock->tracing(tracing_);
36✔
527
  new_mock->install_comparators_and_copiers(
36✔
528
      impl_->comparators_and_copiers_repository_
36✔
529
  );
530
  return new_mock;
36✔
531
}
532

533
Support* Support::get_mock_support_scope(const String& name)
92✔
534
{
535
  String mocking_support_name = MOCK_SUPPORT_SCOPE_PREFIX;
92✔
536
  mocking_support_name += name;
92✔
537

538
  if (has_data(mocking_support_name)) {
92✔
539
    STRCMP_EQUAL("Support", get_data(mocking_support_name).get_type().c_str());
56✔
540
    return static_cast<Support*>(
541
        get_data(mocking_support_name).get_object_pointer()
112✔
542
    );
56✔
543
  }
544

545
  Support* new_mock = clone(name);
36✔
546

547
  set_data_object(mocking_support_name, "Support", new_mock);
36✔
548
  return new_mock;
36✔
549
}
92✔
550

551
Support* Support::get_mock_support(NamedValueListNode* node)
502✔
552
{
553
  if (node->get_type() == "Support" &&
1,361✔
554
      string_contains(node->get_name(), MOCK_SUPPORT_SCOPE_PREFIX))
859✔
555
    return static_cast<Support*>(node->item()->get_object_pointer());
357✔
556
  return nullptr;
145✔
557
}
558

559
NamedValue Support::return_value()
61✔
560
{
561
  if (impl_->last_actual_function_call_)
61✔
562
    return impl_->last_actual_function_call_->return_value();
61✔
UNCOV
563
  return NamedValue("");
×
564
}
565

566
bool Support::has_return_value()
95✔
567
{
568
  if (impl_->last_actual_function_call_)
95✔
569
    return impl_->last_actual_function_call_->has_return_value();
80✔
570
  return false;
15✔
571
}
572

573
} // namespace mock
574
} // namespace tiny
575
} // namespace mu
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc