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

thetic / mutiny / 24436629772

15 Apr 2026 04:36AM UTC coverage: 98.749% (-0.2%) from 98.953%
24436629772

Pull #54

github

web-flow
Merge f10eeaff1 into cc6c1f755
Pull Request #54: Handle fixed-width types in mocking

137 of 137 new or added lines in 12 files covered. (100.0%)

5 existing lines in 2 files now uncovered.

5051 of 5115 relevant lines covered (98.75%)

4002.39 hits per line

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

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

3
#include "mutiny/mock/NamedValueComparatorsAndCopiersRepository.hpp"
4

5
#include "mutiny/test/Shell.hpp"
6

7
namespace mu {
8
namespace tiny {
9
namespace mock {
10

11
NamedValueComparatorsAndCopiersRepository* NamedValue::default_repository_ =
12
    nullptr;
13
const double NamedValue::default_double_tolerance = 0.005;
14

15
void NamedValue::set_default_comparators_and_copiers_repository(
2,303✔
16
    NamedValueComparatorsAndCopiersRepository* repository
17
)
18
{
19
  default_repository_ = repository;
2,303✔
20
}
2,303✔
21

22
NamedValueComparatorsAndCopiersRepository* NamedValue::
58✔
23
    get_default_comparators_and_copiers_repository()
24
{
25
  return default_repository_;
58✔
26
}
27

28
NamedValue::NamedValue(const String& name)
1,596✔
29
  : name_(name)
1,596✔
30
  , type_("int")
1,596✔
31

32
{
33
  value_.int_value = 0;
1,596✔
34
}
1,596✔
35

36
NamedValue::NamedValue(NamedValue&& other) noexcept
1,072✔
37
  : name_(static_cast<String&&>(other.name_))
1,072✔
38
  , type_(static_cast<String&&>(other.type_))
1,072✔
39
  , is_const_object_(other.is_const_object_)
1,072✔
40
  , value_(other.value_)
1,072✔
41
  , size_(other.size_)
1,072✔
42
  , comparator_(other.comparator_)
1,072✔
43
  , copier_(other.copier_)
1,072✔
44
{
45
}
1,072✔
46

47
void NamedValue::set_value(bool value)
30✔
48
{
49
  type_ = "bool";
30✔
50
  value_.bool_value = value;
30✔
51
}
30✔
52

53
void NamedValue::set_value(unsigned int value)
61✔
54
{
55
  type_ = "unsigned int";
61✔
56
  value_.unsigned_int_value = value;
61✔
57
}
61✔
58

59
void NamedValue::set_value(int value)
233✔
60
{
61
  type_ = "int";
233✔
62
  value_.int_value = value;
233✔
63
}
233✔
64

65
void NamedValue::set_value(long int value)
41✔
66
{
67
  type_ = "long int";
41✔
68
  value_.long_int_value = value;
41✔
69
}
41✔
70

71
void NamedValue::set_value(unsigned long int value)
41✔
72
{
73
  type_ = "unsigned long int";
41✔
74
  value_.unsigned_long_int_value = value;
41✔
75
}
41✔
76

77
void NamedValue::set_value(long long value)
35✔
78
{
79
  type_ = "long long int";
35✔
80
  value_.long_long_int_value = value;
35✔
81
}
35✔
82

83
void NamedValue::set_value(unsigned long long value)
34✔
84
{
85
  type_ = "unsigned long long int";
34✔
86
  value_.unsigned_long_long_int_value = value;
34✔
87
}
34✔
88

89
void NamedValue::set_value(double value)
43✔
90
{
91
  set_value(value, default_double_tolerance);
43✔
92
}
43✔
93

94
void NamedValue::set_value(double value, double tolerance)
52✔
95
{
96
  type_ = "double";
52✔
97
  value_.double_value.value = value;
52✔
98
  value_.double_value.tolerance = tolerance;
52✔
99
}
52✔
100

101
void NamedValue::set_value(void* value)
49✔
102
{
103
  type_ = "void*";
49✔
104
  value_.pointer_value = value;
49✔
105
}
49✔
106

107
void NamedValue::set_value(const void* value)
59✔
108
{
109
  type_ = "const void*";
59✔
110
  value_.const_pointer_value = value;
59✔
111
}
59✔
112

113
void NamedValue::set_value(NamedValue::FunctionPointerValue value)
23✔
114
{
115
  type_ = "void (*)()";
23✔
116
  value_.function_pointer_value = value;
23✔
117
}
23✔
118

119
void NamedValue::set_value(const char* value)
43✔
120
{
121
  type_ = "const char*";
43✔
122
  value_.string_value = value;
43✔
123
}
43✔
124

125
void NamedValue::set_memory_buffer(const unsigned char* value, size_t size)
21✔
126
{
127
  type_ = "const unsigned char*";
21✔
128
  value_.memory_buffer_value = value;
21✔
129
  size_ = size;
21✔
130
}
21✔
131

132
void NamedValue::set_const_object_pointer(
101✔
133
    const String& type,
134
    const void* object_ptr
135
)
136
{
137
  type_ = type;
101✔
138
  is_const_object_ = true;
101✔
139
  value_.const_object_pointer_value = object_ptr;
101✔
140
  if (default_repository_) {
101✔
141
    comparator_ = default_repository_->get_comparator_for_type(type);
88✔
142
    copier_ = default_repository_->get_copier_for_type(type);
88✔
143
  }
144
}
101✔
145

146
void NamedValue::set_object_pointer(const String& type, void* object_ptr)
49✔
147
{
148
  type_ = type;
49✔
149
  is_const_object_ = false;
49✔
150
  value_.object_pointer_value = object_ptr;
49✔
151
  if (default_repository_) {
49✔
152
    comparator_ = default_repository_->get_comparator_for_type(type);
49✔
153
    copier_ = default_repository_->get_copier_for_type(type);
49✔
154
  }
155
}
49✔
156

157
void NamedValue::set_size(size_t size)
37✔
158
{
159
  size_ = size;
37✔
160
}
37✔
161

UNCOV
162
void NamedValue::set_name(const char* name)
×
163
{
UNCOV
164
  name_ = name;
×
UNCOV
165
}
×
166

167
String NamedValue::get_name() const
2,899✔
168
{
169
  return name_;
2,899✔
170
}
171

172
String NamedValue::get_type() const
1,107✔
173
{
174
  return type_;
1,107✔
175
}
176

177
template<>
178
bool NamedValue::get_value<bool>() const
25✔
179
{
180
  STRCMP_EQUAL("bool", type_.c_str());
25✔
181
  return value_.bool_value;
25✔
182
}
183

184
template<>
185
int NamedValue::get_value<int>() const
53✔
186
{
187
  STRCMP_EQUAL("int", type_.c_str());
53✔
188
  return value_.int_value;
53✔
189
}
190

191
template<>
192
unsigned int NamedValue::get_value<unsigned int>() const
30✔
193
{
194
  if (type_ == "int" && value_.int_value >= 0)
30✔
195
    return static_cast<unsigned int>(value_.int_value);
1✔
196
  STRCMP_EQUAL("unsigned int", type_.c_str());
29✔
197
  return value_.unsigned_int_value;
29✔
198
}
199

200
template<>
201
long int NamedValue::get_value<long int>() const
31✔
202
{
203
  if (type_ == "int")
31✔
204
    return value_.int_value;
1✔
205
  else if (type_ == "unsigned int")
30✔
206
    return static_cast<long int>(value_.unsigned_int_value);
1✔
207
  STRCMP_EQUAL("long int", type_.c_str());
29✔
208
  return value_.long_int_value;
29✔
209
}
210

211
template<>
212
unsigned long int NamedValue::get_value<unsigned long int>() const
31✔
213
{
214
  if (type_ == "unsigned int")
31✔
215
    return value_.unsigned_int_value;
1✔
216
  else if (type_ == "int" && value_.int_value >= 0)
30✔
217
    return static_cast<unsigned long int>(value_.int_value);
1✔
218
  else if (type_ == "long int" && value_.long_int_value >= 0)
29✔
219
    return static_cast<unsigned long int>(value_.long_int_value);
1✔
220
  STRCMP_EQUAL("unsigned long int", type_.c_str());
28✔
221
  return value_.unsigned_long_int_value;
28✔
222
}
223

224
template<>
225
long long NamedValue::get_value<long long>() const
29✔
226
{
227
  if (type_ == "int")
29✔
228
    return value_.int_value;
1✔
229
  else if (type_ == "unsigned int")
28✔
230
    return static_cast<long long int>(value_.unsigned_int_value);
1✔
231
  else if (type_ == "long int")
27✔
232
    return value_.long_int_value;
1✔
233
  else if (type_ == "unsigned long int")
26✔
234
    return static_cast<long long int>(value_.unsigned_long_int_value);
1✔
235
  STRCMP_EQUAL("long long int", type_.c_str());
25✔
236
  return value_.long_long_int_value;
25✔
237
}
238

239
template<>
240
unsigned long long NamedValue::get_value<unsigned long long>() const
30✔
241
{
242
  if (type_ == "unsigned int")
30✔
243
    return value_.unsigned_int_value;
1✔
244
  else if (type_ == "int" && value_.int_value >= 0)
29✔
245
    return static_cast<unsigned long long int>(value_.int_value);
1✔
246
  else if (type_ == "long int" && value_.long_int_value >= 0)
28✔
247
    return static_cast<unsigned long long int>(value_.long_int_value);
1✔
248
  else if (type_ == "unsigned long int")
27✔
249
    return value_.unsigned_long_int_value;
1✔
250
  else if (type_ == "long long int" && value_.long_long_int_value >= 0)
26✔
251
    return static_cast<unsigned long long int>(value_.long_long_int_value);
1✔
252
  STRCMP_EQUAL("unsigned long long int", type_.c_str());
25✔
253
  return value_.unsigned_long_long_int_value;
25✔
254
}
255

256
template<>
257
double NamedValue::get_value<double>() const
19✔
258
{
259
  STRCMP_EQUAL("double", type_.c_str());
19✔
260
  return value_.double_value.value;
19✔
261
}
262

263
double NamedValue::get_double_tolerance() const
3✔
264
{
265
  STRCMP_EQUAL("double", type_.c_str());
3✔
266
  return value_.double_value.tolerance;
3✔
267
}
268

269
template<>
270
const char* NamedValue::get_value<const char*>() const
17✔
271
{
272
  STRCMP_EQUAL("const char*", type_.c_str());
17✔
273
  return value_.string_value;
17✔
274
}
275

276
template<>
277
void* NamedValue::get_value<void*>() const
17✔
278
{
279
  STRCMP_EQUAL("void*", type_.c_str());
17✔
280
  return value_.pointer_value;
17✔
281
}
282

283
template<>
284
const void* NamedValue::get_value<const void*>() const
38✔
285
{
286
  STRCMP_EQUAL("const void*", type_.c_str());
38✔
287
  return value_.const_pointer_value;
38✔
288
}
289

290
template<>
291
NamedValue::FunctionPointerValue NamedValue::get_value<
16✔
292
    NamedValue::FunctionPointerValue>() const
293
{
294
  STRCMP_EQUAL("void (*)()", type_.c_str());
16✔
295
  return value_.function_pointer_value;
16✔
296
}
297

298
const unsigned char* NamedValue::get_memory_buffer() const
3✔
299
{
300
  STRCMP_EQUAL("const unsigned char*", type_.c_str());
3✔
301
  return value_.memory_buffer_value;
3✔
302
}
303

304
const void* NamedValue::get_const_object_pointer() const
21✔
305
{
306
  return value_.const_object_pointer_value;
21✔
307
}
308

309
void* NamedValue::get_object_pointer() const
478✔
310
{
311
  return value_.object_pointer_value;
478✔
312
}
313

314
bool NamedValue::is_const_object() const
5✔
315
{
316
  return is_const_object_;
5✔
317
}
318

319
size_t NamedValue::get_size() const
24✔
320
{
321
  return size_;
24✔
322
}
323

324
NamedValueComparator* NamedValue::get_comparator() const
19✔
325
{
326
  return comparator_;
19✔
327
}
328

329
NamedValueCopier* NamedValue::get_copier() const
44✔
330
{
331
  return copier_;
44✔
332
}
333

334
bool NamedValue::equals(const NamedValue& p) const
199✔
335
{
336
  if ((type_ == "long int") && (p.type_ == "int"))
199✔
337
    return value_.long_int_value == p.value_.int_value;
1✔
338
  else if ((type_ == "int") && (p.type_ == "long int"))
198✔
339
    return value_.int_value == p.value_.long_int_value;
1✔
340
  else if ((type_ == "unsigned int") && (p.type_ == "int"))
197✔
341
    return (p.value_.int_value >= 0) &&
2✔
342
           (value_.unsigned_int_value ==
1✔
343
            static_cast<unsigned int>(p.value_.int_value));
2✔
344
  else if ((type_ == "int") && (p.type_ == "unsigned int"))
196✔
345
    return (value_.int_value >= 0) &&
2✔
346
           (static_cast<unsigned int>(value_.int_value) ==
1✔
347
            p.value_.unsigned_int_value);
2✔
348
  else if ((type_ == "unsigned long int") && (p.type_ == "int"))
195✔
349
    return (p.value_.int_value >= 0) &&
2✔
350
           (value_.unsigned_long_int_value ==
1✔
351
            static_cast<unsigned long>(p.value_.int_value));
2✔
352
  else if ((type_ == "int") && (p.type_ == "unsigned long int"))
194✔
353
    return (value_.int_value >= 0) &&
2✔
354
           (static_cast<unsigned long>(value_.int_value) ==
1✔
355
            p.value_.unsigned_long_int_value);
2✔
356
  else if ((type_ == "unsigned int") && (p.type_ == "long int"))
193✔
357
    return (p.value_.long_int_value >= 0) &&
2✔
358
           (value_.unsigned_int_value ==
1✔
359
            static_cast<unsigned long>(p.value_.long_int_value));
2✔
360
  else if ((type_ == "long int") && (p.type_ == "unsigned int"))
192✔
361
    return (value_.long_int_value >= 0) &&
2✔
362
           (static_cast<unsigned long>(value_.long_int_value) ==
1✔
363
            p.value_.unsigned_int_value);
2✔
364
  else if ((type_ == "unsigned int") && (p.type_ == "unsigned long int"))
191✔
365
    return value_.unsigned_int_value == p.value_.unsigned_long_int_value;
1✔
366
  else if ((type_ == "unsigned long int") && (p.type_ == "unsigned int"))
190✔
367
    return value_.unsigned_long_int_value == p.value_.unsigned_int_value;
1✔
368
  else if ((type_ == "long int") && (p.type_ == "unsigned long int"))
189✔
369
    return (value_.long_int_value >= 0) &&
3✔
370
           (static_cast<unsigned long>(value_.long_int_value) ==
1✔
371
            p.value_.unsigned_long_int_value);
3✔
372
  else if ((type_ == "unsigned long int") && (p.type_ == "long int"))
187✔
373
    return (p.value_.long_int_value >= 0) &&
3✔
374
           (value_.unsigned_long_int_value ==
1✔
375
            static_cast<unsigned long>(p.value_.long_int_value));
3✔
376
  else if ((type_ == "long long int") && (p.type_ == "int"))
185✔
377
    return value_.long_long_int_value == p.value_.int_value;
1✔
378
  else if ((type_ == "int") && (p.type_ == "long long int"))
184✔
379
    return value_.int_value == p.value_.long_long_int_value;
1✔
380
  else if ((type_ == "long long int") && (p.type_ == "long int"))
183✔
381
    return value_.long_long_int_value == p.value_.long_int_value;
1✔
382
  else if ((type_ == "long int") && (p.type_ == "long long int"))
182✔
383
    return value_.long_int_value == p.value_.long_long_int_value;
1✔
384
  else if ((type_ == "long long int") && (p.type_ == "unsigned int"))
181✔
385
    return (value_.long_long_int_value >= 0) &&
2✔
386
           (static_cast<unsigned long long>(value_.long_long_int_value) ==
1✔
387
            p.value_.unsigned_int_value);
2✔
388
  else if ((type_ == "unsigned int") && (p.type_ == "long long int"))
180✔
389
    return (p.value_.long_long_int_value >= 0) &&
2✔
390
           (value_.unsigned_int_value ==
1✔
391
            static_cast<unsigned long long>(p.value_.long_long_int_value));
2✔
392
  else if ((type_ == "long long int") && (p.type_ == "unsigned long int"))
179✔
393
    return (value_.long_long_int_value >= 0) &&
2✔
394
           (static_cast<unsigned long long>(value_.long_long_int_value) ==
1✔
395
            p.value_.unsigned_long_int_value);
2✔
396
  else if ((type_ == "unsigned long int") && (p.type_ == "long long int"))
178✔
397
    return (p.value_.long_long_int_value >= 0) &&
2✔
398
           (value_.unsigned_long_int_value ==
1✔
399
            static_cast<unsigned long long>(p.value_.long_long_int_value));
2✔
400
  else if ((type_ == "long long int") && (p.type_ == "unsigned long long int"))
177✔
401
    return (value_.long_long_int_value >= 0) &&
2✔
402
           (static_cast<unsigned long long>(value_.long_long_int_value) ==
1✔
403
            p.value_.unsigned_long_long_int_value);
2✔
404
  else if ((type_ == "unsigned long long int") && (p.type_ == "long long int"))
176✔
405
    return (p.value_.long_long_int_value >= 0) &&
2✔
406
           (value_.unsigned_long_long_int_value ==
1✔
407
            static_cast<unsigned long long>(p.value_.long_long_int_value));
2✔
408
  else if ((type_ == "unsigned long long int") && (p.type_ == "int"))
175✔
409
    return (p.value_.int_value >= 0) &&
2✔
410
           (value_.unsigned_long_long_int_value ==
1✔
411
            static_cast<unsigned long long>(p.value_.int_value));
2✔
412
  else if ((type_ == "int") && (p.type_ == "unsigned long long int"))
174✔
413
    return (value_.int_value >= 0) &&
2✔
414
           (static_cast<unsigned long long>(value_.int_value) ==
1✔
415
            p.value_.unsigned_long_long_int_value);
2✔
416
  else if ((type_ == "unsigned long long int") && (p.type_ == "unsigned int"))
173✔
417
    return value_.unsigned_long_long_int_value == p.value_.unsigned_int_value;
1✔
418
  else if ((type_ == "unsigned int") && (p.type_ == "unsigned long long int"))
172✔
419
    return value_.unsigned_int_value == p.value_.unsigned_long_long_int_value;
1✔
420
  else if ((type_ == "unsigned long long int") && (p.type_ == "long int"))
171✔
421
    return (p.value_.long_int_value >= 0) &&
2✔
422
           (value_.unsigned_long_long_int_value ==
1✔
423
            static_cast<unsigned long long>(p.value_.long_int_value));
2✔
424
  else if ((type_ == "long int") && (p.type_ == "unsigned long long int"))
170✔
425
    return (value_.long_int_value >= 0) &&
2✔
426
           (static_cast<unsigned long long>(value_.long_int_value) ==
1✔
427
            p.value_.unsigned_long_long_int_value);
2✔
428
  else if (
169✔
429
      (type_ == "unsigned long long int") && (p.type_ == "unsigned long int")
169✔
430
  )
431
    return value_.unsigned_long_long_int_value ==
1✔
432
           p.value_.unsigned_long_int_value;
1✔
433
  else if (
168✔
434
      (type_ == "unsigned long int") && (p.type_ == "unsigned long long int")
168✔
435
  )
436
    return value_.unsigned_long_int_value ==
1✔
437
           p.value_.unsigned_long_long_int_value;
1✔
438

439
  if (type_ != p.type_)
167✔
440
    return false;
2✔
441

442
  if (type_ == "bool")
165✔
443
    return value_.bool_value == p.value_.bool_value;
6✔
444
  else if (type_ == "int")
159✔
445
    return value_.int_value == p.value_.int_value;
77✔
446
  else if (type_ == "unsigned int")
82✔
447
    return value_.unsigned_int_value == p.value_.unsigned_int_value;
10✔
448
  else if (type_ == "long int")
72✔
449
    return value_.long_int_value == p.value_.long_int_value;
2✔
450
  else if (type_ == "unsigned long int")
70✔
451
    return value_.unsigned_long_int_value == p.value_.unsigned_long_int_value;
3✔
452
  else if (type_ == "long long int")
67✔
453
    return value_.long_long_int_value == p.value_.long_long_int_value;
3✔
454
  else if (type_ == "unsigned long long int")
64✔
455
    return value_.unsigned_long_long_int_value ==
3✔
456
           p.value_.unsigned_long_long_int_value;
3✔
457
  else if (type_ == "const char*")
61✔
458
    return String(value_.string_value) == String(p.value_.string_value);
7✔
459
  else if (type_ == "void*")
54✔
460
    return value_.pointer_value == p.value_.pointer_value;
4✔
461
  else if (type_ == "const void*")
50✔
462
    return value_.const_pointer_value == p.value_.const_pointer_value;
3✔
463
  else if (type_ == "void (*)()")
47✔
464
    return value_.function_pointer_value == p.value_.function_pointer_value;
4✔
465
  else if (type_ == "double")
43✔
466
    return (test::approx_equal(
36✔
467
        value_.double_value.value,
18✔
468
        p.value_.double_value.value,
18✔
469
        value_.double_value.tolerance
18✔
470
    ));
18✔
471
  else if (type_ == "const unsigned char*") {
25✔
472
    if (size_ != p.size_) {
6✔
473
      return false;
1✔
474
    }
475
    return memcmp(
10✔
476
               value_.memory_buffer_value, p.value_.memory_buffer_value, size_
5✔
477
           ) == 0;
5✔
478
  }
479

480
  if (comparator_)
19✔
481
    return comparator_->is_equal(
32✔
482
        value_.const_object_pointer_value, p.value_.const_object_pointer_value
16✔
483
    );
16✔
484

485
  return false;
3✔
486
}
487

488
bool NamedValue::compatible_for_copying(const NamedValue& p) const
51✔
489
{
490
  if (type_ == p.type_)
51✔
491
    return true;
24✔
492

493
  if ((type_ == "const void*") && (p.type_ == "void*"))
27✔
494
    return true;
25✔
495

496
  return false;
2✔
497
}
498

499
String NamedValue::to_string() const
119✔
500
{
501
  if (type_ == "bool")
119✔
502
    return string_from(value_.bool_value);
2✔
503
  else if (type_ == "int")
117✔
504
    return string_from(value_.int_value) + " " +
76✔
505
           brackets_formatted_hex_string_from(value_.int_value);
114✔
506
  else if (type_ == "unsigned int")
79✔
507
    return string_from(value_.unsigned_int_value) + " " +
22✔
508
           brackets_formatted_hex_string_from(value_.unsigned_int_value);
33✔
509
  else if (type_ == "long int")
68✔
510
    return string_from(value_.long_int_value) + " " +
10✔
511
           brackets_formatted_hex_string_from(value_.long_int_value);
15✔
512
  else if (type_ == "unsigned long int")
63✔
513
    return string_from(value_.unsigned_long_int_value) + " " +
10✔
514
           brackets_formatted_hex_string_from(value_.unsigned_long_int_value);
15✔
515
  else if (type_ == "long long int")
58✔
516
    return string_from(value_.long_long_int_value) + " " +
4✔
517
           brackets_formatted_hex_string_from(value_.long_long_int_value);
6✔
518
  else if (type_ == "unsigned long long int")
56✔
519
    return string_from(value_.unsigned_long_long_int_value) + " " +
4✔
520
           brackets_formatted_hex_string_from(
2✔
521
               value_.unsigned_long_long_int_value
2✔
522
           );
2✔
523
  else if (type_ == "const char*")
54✔
524
    return value_.string_value;
19✔
525
  else if (type_ == "void*")
35✔
526
    return string_from(value_.pointer_value);
2✔
527
  else if (type_ == "void (*)()")
33✔
528
    return string_from(value_.function_pointer_value);
2✔
529
  else if (type_ == "const void*")
31✔
530
    return string_from(value_.const_pointer_value);
2✔
531
  else if (type_ == "double")
29✔
532
    return string_from(value_.double_value.value);
8✔
533
  else if (type_ == "const unsigned char*")
21✔
534
    return string_from_binary_with_size_or_null(
535
        value_.memory_buffer_value, size_
13✔
536
    );
13✔
537

538
  if (comparator_)
8✔
539
    return comparator_->value_to_string(value_.const_object_pointer_value);
5✔
540

541
  return string_from_format(
542
      "No comparator found for type: \"%s\"", type_.c_str()
543
  );
3✔
544
}
545

546
} // namespace mock
547
} // namespace tiny
548
} // 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