unity.c 16.7 KB
Newer Older
G
greg-williams 已提交
1 2
#include "unity.h"
#include <stdio.h>
M
mvandervoord 已提交
3
#include <string.h>
G
greg-williams 已提交
4

5
struct _Unity Unity = { 0 };
G
greg-williams 已提交
6

7
void UnityPrint(const char* string)
G
greg-williams 已提交
8
{
9
    unsigned char* pch = (unsigned char*)string;
G
greg-williams 已提交
10 11 12 13 14

    if (pch != NULL)
    {
        while (*pch)
        {
15
            UNITY_OUTPUT_CHAR(*pch);
G
greg-williams 已提交
16 17 18 19 20
            pch++;
        }
    }
}

21
void UnityPrintNumberByStyle(const long number, const UNITY_DISPLAY_STYLE_T style)
G
greg-williams 已提交
22 23 24
{
    switch (style)
    {
M
mvandervoord 已提交
25 26 27 28 29
    case UNITY_DISPLAY_STYLE_HEX8:    UnityPrintNumberHex((unsigned long)number, 2);           break;
    case UNITY_DISPLAY_STYLE_HEX16:   UnityPrintNumberHex((unsigned long)number, 4);           break;
    case UNITY_DISPLAY_STYLE_HEX32:   UnityPrintNumberHex((unsigned long)number, 8);           break;
    case UNITY_DISPLAY_STYLE_UINT:    UnityPrintNumberUnsigned((unsigned long)number);         break;
    default:                          UnityPrintNumber(number);                                break;
G
greg-williams 已提交
30 31 32 33
    }
}

/// basically do an itoa using as little ram as possible
34
void UnityPrintNumber(const long number_to_print)
G
greg-williams 已提交
35
{
M
mvandervoord 已提交
36 37
    long divisor = 1;
    long next_divisor;
38
    long number = number_to_print;
G
greg-williams 已提交
39 40 41

    if (number < 0)
    {
42
        UNITY_OUTPUT_CHAR('-');
G
greg-williams 已提交
43 44 45 46
        number = -number;
    }

    // figure out initial divisor
M
mvandervoord 已提交
47
    while (number / divisor > 9)
G
greg-williams 已提交
48
    {
M
mvandervoord 已提交
49 50 51 52 53
        next_divisor = divisor * 10;
        if (next_divisor > divisor)
            divisor = next_divisor;
        else
            break;
G
greg-williams 已提交
54 55
    }

M
mvandervoord 已提交
56
    // now mod and print, then divide divisor
G
greg-williams 已提交
57 58
    do
    {
59
        UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10)));
M
mvandervoord 已提交
60
        divisor /= 10;
G
greg-williams 已提交
61
    }
M
mvandervoord 已提交
62
    while (divisor > 0);
G
greg-williams 已提交
63 64 65
}

/// basically do an itoa using as little ram as possible
66
void UnityPrintNumberUnsigned(const unsigned long number)
G
greg-williams 已提交
67
{
M
mvandervoord 已提交
68 69
    unsigned long divisor = 1;
    unsigned long next_divisor;
G
greg-williams 已提交
70 71

    // figure out initial divisor
M
mvandervoord 已提交
72
    while (number / divisor > 9)
G
greg-williams 已提交
73
    {
M
mvandervoord 已提交
74 75 76 77 78
        next_divisor = divisor * 10;
        if (next_divisor > divisor)
            divisor = next_divisor;
        else
            break;
G
greg-williams 已提交
79 80
    }

M
mvandervoord 已提交
81
    // now mod and print, then divide divisor
G
greg-williams 已提交
82 83
    do
    {
84
        UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10)));
M
mvandervoord 已提交
85
        divisor /= 10;
G
greg-williams 已提交
86
    }
M
mvandervoord 已提交
87
    while (divisor > 0);
G
greg-williams 已提交
88 89
}

90
void UnityPrintNumberHex(const unsigned long number, const char nibbles_to_print)
G
greg-williams 已提交
91 92
{
    unsigned long nibble;
93
	char nibbles = nibbles_to_print;
G
greg-williams 已提交
94 95 96 97 98 99 100
    UnityPrint("0x");

    while (nibbles > 0)
    {
        nibble = (number >> (--nibbles << 2)) & 0x0000000F;
        if (nibble <= 9)
        {
101
            UNITY_OUTPUT_CHAR((char)('0' + nibble));
G
greg-williams 已提交
102 103 104
        }
        else
        {
105
            UNITY_OUTPUT_CHAR((char)('A' - 10 + nibble));
G
greg-williams 已提交
106 107 108 109
        }
    }
}

110
void UnityPrintMask(const unsigned long mask, const unsigned long number)
G
greg-williams 已提交
111
{
M
mvandervoord 已提交
112
    unsigned long bit = 0x80000000;
M
mvandervoord 已提交
113
    long i;
G
greg-williams 已提交
114 115 116 117 118 119 120

    for (i = 0; i < 32; i++)
    {
        if (bit & mask)
        {
            if (bit & number)
            {
121
                UNITY_OUTPUT_CHAR('1');
G
greg-williams 已提交
122 123 124
            }
            else
            {
125
                UNITY_OUTPUT_CHAR('0');
G
greg-williams 已提交
126 127 128 129
            }
        }
        else
        {
130
            UNITY_OUTPUT_CHAR('X');
G
greg-williams 已提交
131
        }
M
mvandervoord 已提交
132
        bit = bit >> 1;
G
greg-williams 已提交
133 134 135
    }
}

136
void UnityTestResultsBegin(const char* file, const long line)
G
greg-williams 已提交
137
{
138
    UnityPrint(file);
139
    UNITY_OUTPUT_CHAR(':');
G
greg-williams 已提交
140
    UnityPrintNumber(line);
141
    UNITY_OUTPUT_CHAR(':');
G
greg-williams 已提交
142
    UnityPrint(Unity.CurrentTestName);
143
    UNITY_OUTPUT_CHAR(':');
G
greg-williams 已提交
144 145
}

146 147 148 149 150 151
void UnityTestResultsFailBegin(const long line)
{
    UnityTestResultsBegin(Unity.AssertContainerFile, line);
    UnityPrint("FAIL:");
}

G
greg-williams 已提交
152 153 154 155 156 157 158 159
void UnityConcludeTest()
{
    if (Unity.CurrentTestIgnored)
    {
        Unity.TestIgnores++;
    }
    else if (!Unity.CurrentTestFailed)
    {
160 161
        UnityTestResultsBegin(Unity.TestFile, Unity.CurrentTestLineNumber);
        UnityPrint("PASS\n");
G
greg-williams 已提交
162 163 164 165 166 167 168 169 170 171
    }
    else
    {
        Unity.TestFailures++;
    }

    Unity.CurrentTestFailed = 0;
    Unity.CurrentTestIgnored = 0;
}

M
mvandervoord 已提交
172 173 174
void UnityAssertBits(const long mask,
                     const long expected,
                     const long actual,
175
                     const char* msg,
176
                     const unsigned short lineNumber)
G
greg-williams 已提交
177 178 179 180 181
{
    if ((mask & expected) != (mask & actual))
    {
        Unity.CurrentTestFailed = 1;

182
        UnityTestResultsFailBegin(lineNumber);
G
greg-williams 已提交
183 184 185 186
        UnityPrint("Expected ");
        UnityPrintMask(mask, expected);
        UnityPrint(" was ");
        UnityPrintMask(mask, actual);
187
        UNITY_OUTPUT_CHAR('.');
G
greg-williams 已提交
188 189
        if (msg)
        {
190
            UNITY_OUTPUT_CHAR(' ');
G
greg-williams 已提交
191 192
            UnityPrint(msg);
        }
193
        UNITY_OUTPUT_CHAR('\n');
G
greg-williams 已提交
194 195 196
    }
}

197
void UnityAssertEqualNumber(const long expected,
M
mvandervoord 已提交
198
                         const long actual,
199
                         const char* msg,
200 201
                         const unsigned short lineNumber,
                         const UNITY_DISPLAY_STYLE_T style)
G
greg-williams 已提交
202 203 204 205 206
{
    if (expected != actual)
    {
        Unity.CurrentTestFailed = 1;

207
        UnityTestResultsFailBegin(lineNumber);
G
greg-williams 已提交
208 209 210 211
        UnityPrint("Expected ");
        UnityPrintNumberByStyle(expected, style);
        UnityPrint(" was ");
        UnityPrintNumberByStyle(actual, style);
212
        UNITY_OUTPUT_CHAR('.');
G
greg-williams 已提交
213 214
        if (msg)
        {
215
            UNITY_OUTPUT_CHAR(' ');
G
greg-williams 已提交
216 217
            UnityPrint(msg);
        }
218
        UNITY_OUTPUT_CHAR('\n');
G
greg-williams 已提交
219 220 221
    }
}

222 223 224 225 226 227 228 229 230 231
void UnityAssertEqualNumberUnsigned(const unsigned long expected,
                         const unsigned long actual,
                         const char* msg,
                         const unsigned short lineNumber,
                         const UNITY_DISPLAY_STYLE_T style)
{
    if (expected != actual)
    {
        Unity.CurrentTestFailed = 1;

232
        UnityTestResultsFailBegin(lineNumber);
233 234 235 236
        UnityPrint("Expected ");
        UnityPrintNumberByStyle(expected, style);
        UnityPrint(" was ");
        UnityPrintNumberByStyle(actual, style);
237
        UNITY_OUTPUT_CHAR('.');
238 239
        if (msg)
        {
240
            UNITY_OUTPUT_CHAR(' ');
241 242
            UnityPrint(msg);
        }
243
        UNITY_OUTPUT_CHAR('\n');
244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261
    }
}

void UnityAssertEqualIntArray(const int* expected,
                              const int* actual,
                              const unsigned long num_elements,
                              const char* msg,
                              const unsigned short lineNumber,
                              const UNITY_DISPLAY_STYLE_T style)
{
    unsigned long elements = num_elements;
    const int* ptr_expected = expected;
    const int* ptr_actual = actual;

    if (elements == 0)
    {
        Unity.CurrentTestFailed = 1;

262
        UnityTestResultsFailBegin(lineNumber);
263 264 265
        UnityPrint("You asked me to compare 0 elements of an array, which was pointless.");
        if (msg)
        {
266
            UNITY_OUTPUT_CHAR(' ');
267 268
            UnityPrint(msg);
        }
269
        UNITY_OUTPUT_CHAR('\n');
270 271 272 273 274 275 276 277 278
        return;
    }

    while (elements--)
    {
        if (*ptr_expected++ != *ptr_actual++)
        {
            Unity.CurrentTestFailed = 1;

279
            UnityTestResultsFailBegin(lineNumber);
280 281 282 283 284 285
            UnityPrint("Element ");
            UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
            UnityPrint(" Expected ");
            UnityPrintNumberByStyle(*--ptr_expected, style);
            UnityPrint(" was ");
            UnityPrintNumberByStyle(*--ptr_actual, style);
286
            UNITY_OUTPUT_CHAR('.');
287 288
            if (msg)
            {
289
                UNITY_OUTPUT_CHAR(' ');
290 291
                UnityPrint(msg);
            }
292
            UNITY_OUTPUT_CHAR('\n');
293 294 295 296 297 298 299
            return;
        }
    }
}

void UnityAssertEqualUnsignedIntArray(const unsigned int* expected,
                              const unsigned int* actual,
M
mvandervoord 已提交
300 301 302 303 304 305
                              const unsigned long num_elements,
                              const char* msg,
                              const unsigned short lineNumber,
                              const UNITY_DISPLAY_STYLE_T style)
{
    unsigned long elements = num_elements;
306 307
    const unsigned int* ptr_expected = expected;
    const unsigned int* ptr_actual = actual;
M
mvandervoord 已提交
308 309 310 311 312

    if (elements == 0)
    {
        Unity.CurrentTestFailed = 1;

313
        UnityTestResultsFailBegin(lineNumber);
314
        UnityPrint("You asked me to compare nothing, which was pointless.");
M
mvandervoord 已提交
315 316
        if (msg)
        {
317
            UNITY_OUTPUT_CHAR(' ');
M
mvandervoord 已提交
318 319
            UnityPrint(msg);
        }
320
        UNITY_OUTPUT_CHAR('\n');
M
mvandervoord 已提交
321 322 323 324 325 326 327 328 329
        return;
    }

    while (elements--)
    {
        if (*ptr_expected++ != *ptr_actual++)
        {
            Unity.CurrentTestFailed = 1;

330
            UnityTestResultsFailBegin(lineNumber);
M
mvandervoord 已提交
331 332 333 334 335 336
            UnityPrint("Element ");
            UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
            UnityPrint(" Expected ");
            UnityPrintNumberByStyle(*--ptr_expected, style);
            UnityPrint(" was ");
            UnityPrintNumberByStyle(*--ptr_actual, style);
337
            UNITY_OUTPUT_CHAR('.');
M
mvandervoord 已提交
338 339
            if (msg)
            {
340
                UNITY_OUTPUT_CHAR(' ');
M
mvandervoord 已提交
341 342
                UnityPrint(msg);
            }
343
            UNITY_OUTPUT_CHAR('\n');
M
mvandervoord 已提交
344 345 346 347 348
            return;
        }
    }
}

349
#ifndef UNITY_EXCLUDE_FLOAT
350 351 352
void UnityAssertFloatsWithin(const _UF delta,
                             const _UF expected,
                             const _UF actual,
353
                             const char* msg,
354
                             const unsigned short lineNumber)
G
greg-williams 已提交
355
{
356 357
    _UF diff = actual - expected;
    _UF pos_delta = delta;
358
    
G
greg-williams 已提交
359 360
    if (diff < 0)
    {
361
        diff = 0.0f - diff;
G
greg-williams 已提交
362
    }
363 364 365 366 367 368
    if (pos_delta < 0)
    {
        pos_delta = 0.0f - pos_delta;
    }
    
    if (pos_delta < diff)
G
greg-williams 已提交
369 370
    {
        Unity.CurrentTestFailed = 1;
371
        UnityTestResultsFailBegin(lineNumber);
G
greg-williams 已提交
372 373 374
        UnityPrint("Floats not within delta.");
        if (msg)
        {
375
            UNITY_OUTPUT_CHAR(' ');
G
greg-williams 已提交
376 377
            UnityPrint(msg);
        }
378
        UNITY_OUTPUT_CHAR('\n');
G
greg-williams 已提交
379 380
    }
}
381
#endif
G
greg-williams 已提交
382

383
void UnityAssertNumbersWithin(const long delta,
M
mvandervoord 已提交
384 385
                           const long expected,
                           const long actual,
386
                           const char* msg,
387
                           const unsigned short lineNumber)
G
greg-williams 已提交
388
{
389
    int diff = actual - expected;
G
greg-williams 已提交
390 391 392 393 394 395 396 397 398

    if (diff < 0)
    {
        diff = -diff;
    }

    if (delta < diff)
    {
        Unity.CurrentTestFailed = 1;
399
        UnityTestResultsFailBegin(lineNumber);
400 401 402
        UnityPrint("Values not within delta.");
        if (msg)
        {
403
            UNITY_OUTPUT_CHAR(' ');
404 405
            UnityPrint(msg);
        }
406
        UNITY_OUTPUT_CHAR('\n');
407 408 409 410 411 412 413 414 415 416 417 418 419 420
    }
}

void UnityAssertNumbersUnsignedWithin(const unsigned long delta,
                           const unsigned long expected,
                           const unsigned long actual,
                           const char* msg,
                           const unsigned short lineNumber)
{
    unsigned int diff = actual - expected;

    if (delta < diff)
    {
        Unity.CurrentTestFailed = 1;
421
        UnityTestResultsFailBegin(lineNumber);
422
        UnityPrint("Values not within delta.");
G
greg-williams 已提交
423 424
        if (msg)
        {
425
            UNITY_OUTPUT_CHAR(' ');
G
greg-williams 已提交
426 427
            UnityPrint(msg);
        }
428
        UNITY_OUTPUT_CHAR('\n');
G
greg-williams 已提交
429 430 431
    }
}

432 433 434
void UnityAssertEqualString(const char* expected,
                            const char* actual,
                            const char* msg,
435
                            const unsigned short lineNumber)
G
greg-williams 已提交
436
{
M
mvandervoord 已提交
437
    unsigned long i;
G
greg-williams 已提交
438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459

    // if both pointers not null compare the strings
    if (expected && actual)
    {
        for (i = 0; expected[i] || actual[i]; i++)
        {
            if (expected[i] != actual[i])
            {
                Unity.CurrentTestFailed = 1;
            }
        }
    }
    else
    { // handle case of one pointers being null (if both null, test should pass)
        if (expected != actual)
        {
            Unity.CurrentTestFailed = 1;
        }
    }

    if (Unity.CurrentTestFailed)
    {
460
        UnityTestResultsFailBegin(lineNumber);
G
greg-williams 已提交
461 462 463 464
        UnityPrint("Expected '");
        UnityPrint(expected);
        UnityPrint("' was '");
        UnityPrint(actual);
465 466
        UNITY_OUTPUT_CHAR('\'');
        UNITY_OUTPUT_CHAR('.');
G
greg-williams 已提交
467
        if (msg)
468
        {
469
            UNITY_OUTPUT_CHAR(' ');
470 471
            UnityPrint(msg);
        }
472
        UNITY_OUTPUT_CHAR('\n');
473 474 475 476
    }
}


M
mvandervoord 已提交
477 478 479
void UnityAssertEqualMemory(const void* expected,
                            const void* actual,
                            unsigned long length,
480
                            const char* msg,
481
                            const unsigned short lineNumber)
482 483
{
    if (length == 0)
484 485 486
    {
        Unity.CurrentTestFailed = 1;

487
        UnityTestResultsFailBegin(lineNumber);
488 489 490
        UnityPrint("You asked me to compare nothing, which was pointless.");
        if (msg)
        {
491
            UNITY_OUTPUT_CHAR(' ');
492 493
            UnityPrint(msg);
        }
494
        UNITY_OUTPUT_CHAR('\n');
495
        return;
496
    }
497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515

    // if both pointers not null compare the memory
    if (expected && actual)
    {
        if (memcmp(expected, actual, length) != 0)
        {
            Unity.CurrentTestFailed = 1;
        }
    }
    else
    { // handle case of one pointers being null (if both null, test should pass)
        if (expected != actual)
        {
            Unity.CurrentTestFailed = 1;
        }
    }

    if (Unity.CurrentTestFailed)
    {
516
        UnityTestResultsFailBegin(lineNumber);
517
        UnityPrint("Memory Mismatch.");
518
        if (msg)
G
greg-williams 已提交
519
        {
520
            UNITY_OUTPUT_CHAR(' ');
G
greg-williams 已提交
521 522
            UnityPrint(msg);
        }
523
        UNITY_OUTPUT_CHAR('\n');
G
greg-williams 已提交
524 525 526
    }
}

527 528 529 530 531 532 533
void UnityAssertEqualMemoryArray(const void* expected,
                                 const void* actual,
                                 unsigned long length,
                                 unsigned long num_elements,
                                 const char* msg,
                                 const unsigned short lineNumber)
{
534 535
	  unsigned char* expected_ptr = (unsigned char*)expected;
	  unsigned char* actual_ptr = (unsigned char*)actual;	
536 537 538 539 540
    unsigned long elements = num_elements;
    if ((elements == 0) || (length == 0))
    {
        Unity.CurrentTestFailed = 1;

541
        UnityTestResultsFailBegin(lineNumber);
542 543 544
        UnityPrint("You asked me to compare nothing, which was pointless.");
        if (msg)
        {
545
            UNITY_OUTPUT_CHAR(' ');
546 547
            UnityPrint(msg);
        }
548
        UNITY_OUTPUT_CHAR('\n');
549 550 551 552
        return;
    }
    
    // if both pointers not null compare the memory
553
    if (expected_ptr && actual_ptr)
554 555 556
    {
        while (elements--)
        {
557
            if (memcmp((const void*)expected_ptr, (const void*)actual_ptr, length) != 0)
558 559 560 561
            {
                Unity.CurrentTestFailed = 1;
                break;
            }
562 563
            expected_ptr += length;
            actual_ptr += length;
564 565 566 567
        }
    }
    else
    { // handle case of one pointers being null (if both null, test should pass) 
568
        if (expected_ptr != actual_ptr)
569 570 571 572 573 574 575
        {
            Unity.CurrentTestFailed = 1;
        }
    }

    if (Unity.CurrentTestFailed)
    {
576
        UnityTestResultsFailBegin(lineNumber);
577 578 579 580 581
        UnityPrint("Element ");
        UnityPrintNumberByStyle((num_elements - elements - 1), UNITY_DISPLAY_STYLE_UINT);
        UnityPrint(" Memory Mismatch.");
        if (msg)
        {
582
            UNITY_OUTPUT_CHAR(' ');
583 584
            UnityPrint(msg);
        }
585
        UNITY_OUTPUT_CHAR('\n');
586 587 588
    }
}

M
mvandervoord 已提交
589
void UnityFail(const char* message, const long line)
G
greg-williams 已提交
590 591
{
    Unity.CurrentTestFailed = 1;
592 593 594 595 596 597 598
    UnityTestResultsBegin(Unity.AssertContainerFile, line);
    UnityPrint("FAIL");
    if (message != NULL)
    {
      UNITY_OUTPUT_CHAR(':');
      UnityPrint(message);
    }
599
    UNITY_OUTPUT_CHAR('\n');
G
greg-williams 已提交
600 601
}

M
mvandervoord 已提交
602
void UnityIgnore(const char* message, const long line)
G
greg-williams 已提交
603 604
{
    Unity.CurrentTestIgnored = 1;
605 606 607 608 609 610 611 612
    UnityTestResultsBegin(Unity.AssertContainerFile, line);
    UnityPrint("IGNORE");
    if (message != NULL)
    {
      UNITY_OUTPUT_CHAR(':');
      UnityPrint(message);
    }
    UNITY_OUTPUT_CHAR('\n');
G
greg-williams 已提交
613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636
}

void UnityBegin()
{
    Unity.NumberOfTests = 0;
}

void UnityEnd(void)
{
    UnityPrintNumber(Unity.NumberOfTests);
    UnityPrint(" Tests ");
    UnityPrintNumber(Unity.TestFailures);
    UnityPrint(" Failures ");
    UnityPrintNumber(Unity.TestIgnores);
    UnityPrint(" Ignored\n");
    if (Unity.TestFailures == 0U)
    {
        UnityPrint("OK\n");
    }
    else
    {
        UnityPrint("FAIL\n");
    }
}