135375f98Sopenharmony_ci/* Copyright (c) 2010 James Grenning and Contributed to Unity Project
235375f98Sopenharmony_ci * ==========================================
335375f98Sopenharmony_ci *  Unity Project - A Test Framework for C
435375f98Sopenharmony_ci *  Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
535375f98Sopenharmony_ci *  [Released under MIT License. Please refer to license.txt for details]
635375f98Sopenharmony_ci * ========================================== */
735375f98Sopenharmony_ci
835375f98Sopenharmony_ci#include "unity_fixture.h"
935375f98Sopenharmony_ci#include "unity_internals.h"
1035375f98Sopenharmony_ci#include <string.h>
1135375f98Sopenharmony_ci
1235375f98Sopenharmony_cistruct UNITY_FIXTURE_T UnityFixture;
1335375f98Sopenharmony_ci
1435375f98Sopenharmony_ci/* If you decide to use the function pointer approach.
1535375f98Sopenharmony_ci * Build with -D UNITY_OUTPUT_CHAR=outputChar and include <stdio.h>
1635375f98Sopenharmony_ci * int (*outputChar)(int) = putchar; */
1735375f98Sopenharmony_ci
1835375f98Sopenharmony_civoid setUp(void)    { /*does nothing*/ }
1935375f98Sopenharmony_civoid tearDown(void) { /*does nothing*/ }
2035375f98Sopenharmony_ci
2135375f98Sopenharmony_cistatic void announceTestRun(unsigned int runNumber)
2235375f98Sopenharmony_ci{
2335375f98Sopenharmony_ci    UnityPrint("Unity test run ");
2435375f98Sopenharmony_ci    UnityPrintNumberUnsigned(runNumber+1);
2535375f98Sopenharmony_ci    UnityPrint(" of ");
2635375f98Sopenharmony_ci    UnityPrintNumberUnsigned(UnityFixture.RepeatCount);
2735375f98Sopenharmony_ci    UNITY_PRINT_EOL();
2835375f98Sopenharmony_ci}
2935375f98Sopenharmony_ci
3035375f98Sopenharmony_ciint UnityMain(int argc, const char* argv[], void (*runAllTests)(void))
3135375f98Sopenharmony_ci{
3235375f98Sopenharmony_ci    int result = UnityGetCommandLineOptions(argc, argv);
3335375f98Sopenharmony_ci    unsigned int r;
3435375f98Sopenharmony_ci    if (result != 0)
3535375f98Sopenharmony_ci        return result;
3635375f98Sopenharmony_ci
3735375f98Sopenharmony_ci    for (r = 0; r < UnityFixture.RepeatCount; r++)
3835375f98Sopenharmony_ci    {
3935375f98Sopenharmony_ci        UnityBegin(argv[0]);
4035375f98Sopenharmony_ci        announceTestRun(r);
4135375f98Sopenharmony_ci        runAllTests();
4235375f98Sopenharmony_ci        if (!UnityFixture.Verbose) UNITY_PRINT_EOL();
4335375f98Sopenharmony_ci        UnityEnd();
4435375f98Sopenharmony_ci    }
4535375f98Sopenharmony_ci
4635375f98Sopenharmony_ci    return (int)Unity.TestFailures;
4735375f98Sopenharmony_ci}
4835375f98Sopenharmony_ci
4935375f98Sopenharmony_cistatic int selected(const char* filter, const char* name)
5035375f98Sopenharmony_ci{
5135375f98Sopenharmony_ci    if (filter == 0)
5235375f98Sopenharmony_ci        return 1;
5335375f98Sopenharmony_ci    return strstr(name, filter) ? 1 : 0;
5435375f98Sopenharmony_ci}
5535375f98Sopenharmony_ci
5635375f98Sopenharmony_cistatic int testSelected(const char* test)
5735375f98Sopenharmony_ci{
5835375f98Sopenharmony_ci    return selected(UnityFixture.NameFilter, test);
5935375f98Sopenharmony_ci}
6035375f98Sopenharmony_ci
6135375f98Sopenharmony_cistatic int groupSelected(const char* group)
6235375f98Sopenharmony_ci{
6335375f98Sopenharmony_ci    return selected(UnityFixture.GroupFilter, group);
6435375f98Sopenharmony_ci}
6535375f98Sopenharmony_ci
6635375f98Sopenharmony_civoid UnityTestRunner(unityfunction* setup,
6735375f98Sopenharmony_ci                     unityfunction* testBody,
6835375f98Sopenharmony_ci                     unityfunction* teardown,
6935375f98Sopenharmony_ci                     const char* printableName,
7035375f98Sopenharmony_ci                     const char* group,
7135375f98Sopenharmony_ci                     const char* name,
7235375f98Sopenharmony_ci                     const char* file,
7335375f98Sopenharmony_ci                     unsigned int line)
7435375f98Sopenharmony_ci{
7535375f98Sopenharmony_ci    if (testSelected(name) && groupSelected(group))
7635375f98Sopenharmony_ci    {
7735375f98Sopenharmony_ci        Unity.TestFile = file;
7835375f98Sopenharmony_ci        Unity.CurrentTestName = printableName;
7935375f98Sopenharmony_ci        Unity.CurrentTestLineNumber = line;
8035375f98Sopenharmony_ci        if (UnityFixture.Verbose)
8135375f98Sopenharmony_ci        {
8235375f98Sopenharmony_ci            UnityPrint(printableName);
8335375f98Sopenharmony_ci        #ifndef UNITY_REPEAT_TEST_NAME
8435375f98Sopenharmony_ci            Unity.CurrentTestName = NULL;
8535375f98Sopenharmony_ci        #endif
8635375f98Sopenharmony_ci        }
8735375f98Sopenharmony_ci        else if (UnityFixture.Silent)
8835375f98Sopenharmony_ci        {
8935375f98Sopenharmony_ci            /* Do Nothing */
9035375f98Sopenharmony_ci        }
9135375f98Sopenharmony_ci        else
9235375f98Sopenharmony_ci        {
9335375f98Sopenharmony_ci            UNITY_OUTPUT_CHAR('.');
9435375f98Sopenharmony_ci        }
9535375f98Sopenharmony_ci
9635375f98Sopenharmony_ci        Unity.NumberOfTests++;
9735375f98Sopenharmony_ci        UnityPointer_Init();
9835375f98Sopenharmony_ci
9935375f98Sopenharmony_ci        UNITY_EXEC_TIME_START();
10035375f98Sopenharmony_ci
10135375f98Sopenharmony_ci        if (TEST_PROTECT())
10235375f98Sopenharmony_ci        {
10335375f98Sopenharmony_ci            setup();
10435375f98Sopenharmony_ci            testBody();
10535375f98Sopenharmony_ci        }
10635375f98Sopenharmony_ci        if (TEST_PROTECT())
10735375f98Sopenharmony_ci        {
10835375f98Sopenharmony_ci            teardown();
10935375f98Sopenharmony_ci        }
11035375f98Sopenharmony_ci        if (TEST_PROTECT())
11135375f98Sopenharmony_ci        {
11235375f98Sopenharmony_ci            UnityPointer_UndoAllSets();
11335375f98Sopenharmony_ci        }
11435375f98Sopenharmony_ci        UnityConcludeFixtureTest();
11535375f98Sopenharmony_ci    }
11635375f98Sopenharmony_ci}
11735375f98Sopenharmony_ci
11835375f98Sopenharmony_civoid UnityIgnoreTest(const char* printableName, const char* group, const char* name)
11935375f98Sopenharmony_ci{
12035375f98Sopenharmony_ci    if (testSelected(name) && groupSelected(group))
12135375f98Sopenharmony_ci    {
12235375f98Sopenharmony_ci        Unity.NumberOfTests++;
12335375f98Sopenharmony_ci        Unity.TestIgnores++;
12435375f98Sopenharmony_ci        if (UnityFixture.Verbose)
12535375f98Sopenharmony_ci        {
12635375f98Sopenharmony_ci            UnityPrint(printableName);
12735375f98Sopenharmony_ci            UNITY_PRINT_EOL();
12835375f98Sopenharmony_ci        }
12935375f98Sopenharmony_ci        else if (UnityFixture.Silent)
13035375f98Sopenharmony_ci        {
13135375f98Sopenharmony_ci            /* Do Nothing */
13235375f98Sopenharmony_ci        }
13335375f98Sopenharmony_ci        else
13435375f98Sopenharmony_ci        {
13535375f98Sopenharmony_ci            UNITY_OUTPUT_CHAR('!');
13635375f98Sopenharmony_ci        }
13735375f98Sopenharmony_ci    }
13835375f98Sopenharmony_ci}
13935375f98Sopenharmony_ci
14035375f98Sopenharmony_ci/*-------------------------------------------------------- */
14135375f98Sopenharmony_ci/*Automatic pointer restoration functions */
14235375f98Sopenharmony_cistruct PointerPair
14335375f98Sopenharmony_ci{
14435375f98Sopenharmony_ci    void** pointer;
14535375f98Sopenharmony_ci    void* old_value;
14635375f98Sopenharmony_ci};
14735375f98Sopenharmony_ci
14835375f98Sopenharmony_cistatic struct PointerPair pointer_store[UNITY_MAX_POINTERS];
14935375f98Sopenharmony_cistatic int pointer_index = 0;
15035375f98Sopenharmony_ci
15135375f98Sopenharmony_civoid UnityPointer_Init(void)
15235375f98Sopenharmony_ci{
15335375f98Sopenharmony_ci    pointer_index = 0;
15435375f98Sopenharmony_ci}
15535375f98Sopenharmony_ci
15635375f98Sopenharmony_civoid UnityPointer_Set(void** pointer, void* newValue, UNITY_LINE_TYPE line)
15735375f98Sopenharmony_ci{
15835375f98Sopenharmony_ci    if (pointer_index >= UNITY_MAX_POINTERS)
15935375f98Sopenharmony_ci    {
16035375f98Sopenharmony_ci        UNITY_TEST_FAIL(line, "Too many pointers set");
16135375f98Sopenharmony_ci    }
16235375f98Sopenharmony_ci    else
16335375f98Sopenharmony_ci    {
16435375f98Sopenharmony_ci        pointer_store[pointer_index].pointer = pointer;
16535375f98Sopenharmony_ci        pointer_store[pointer_index].old_value = *pointer;
16635375f98Sopenharmony_ci        *pointer = newValue;
16735375f98Sopenharmony_ci        pointer_index++;
16835375f98Sopenharmony_ci    }
16935375f98Sopenharmony_ci}
17035375f98Sopenharmony_ci
17135375f98Sopenharmony_civoid UnityPointer_UndoAllSets(void)
17235375f98Sopenharmony_ci{
17335375f98Sopenharmony_ci    while (pointer_index > 0)
17435375f98Sopenharmony_ci    {
17535375f98Sopenharmony_ci        pointer_index--;
17635375f98Sopenharmony_ci        *(pointer_store[pointer_index].pointer) =
17735375f98Sopenharmony_ci            pointer_store[pointer_index].old_value;
17835375f98Sopenharmony_ci    }
17935375f98Sopenharmony_ci}
18035375f98Sopenharmony_ci
18135375f98Sopenharmony_ciint UnityGetCommandLineOptions(int argc, const char* argv[])
18235375f98Sopenharmony_ci{
18335375f98Sopenharmony_ci    int i;
18435375f98Sopenharmony_ci    UnityFixture.Verbose = 0;
18535375f98Sopenharmony_ci    UnityFixture.Silent = 0;
18635375f98Sopenharmony_ci    UnityFixture.GroupFilter = 0;
18735375f98Sopenharmony_ci    UnityFixture.NameFilter = 0;
18835375f98Sopenharmony_ci    UnityFixture.RepeatCount = 1;
18935375f98Sopenharmony_ci
19035375f98Sopenharmony_ci    if (argc == 1)
19135375f98Sopenharmony_ci        return 0;
19235375f98Sopenharmony_ci
19335375f98Sopenharmony_ci    for (i = 1; i < argc; )
19435375f98Sopenharmony_ci    {
19535375f98Sopenharmony_ci        if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0)
19635375f98Sopenharmony_ci        {
19735375f98Sopenharmony_ci            /* Usage */
19835375f98Sopenharmony_ci            UnityPrint("Runs a series of unit tests.");
19935375f98Sopenharmony_ci            UNITY_PRINT_EOL();
20035375f98Sopenharmony_ci            UNITY_PRINT_EOL();
20135375f98Sopenharmony_ci            UnityPrint("When no flag is specified, all tests are run.");
20235375f98Sopenharmony_ci            UNITY_PRINT_EOL();
20335375f98Sopenharmony_ci            UNITY_PRINT_EOL();
20435375f98Sopenharmony_ci            UnityPrint("Optional flags:");
20535375f98Sopenharmony_ci            UNITY_PRINT_EOL();
20635375f98Sopenharmony_ci            UnityPrint("  -v          Verbose output: show all tests executed even if they pass");
20735375f98Sopenharmony_ci            UNITY_PRINT_EOL();
20835375f98Sopenharmony_ci            UnityPrint("  -s          Silent mode: minimal output showing only test failures");
20935375f98Sopenharmony_ci            UNITY_PRINT_EOL();
21035375f98Sopenharmony_ci            UnityPrint("  -g NAME     Only run tests in groups that contain the string NAME");
21135375f98Sopenharmony_ci            UNITY_PRINT_EOL();
21235375f98Sopenharmony_ci            UnityPrint("  -n NAME     Only run tests whose name contains the string NAME");
21335375f98Sopenharmony_ci            UNITY_PRINT_EOL();
21435375f98Sopenharmony_ci            UnityPrint("  -r NUMBER   Repeatedly run all tests NUMBER times");
21535375f98Sopenharmony_ci            UNITY_PRINT_EOL();
21635375f98Sopenharmony_ci            UnityPrint("  -h, --help  Display this help message");
21735375f98Sopenharmony_ci            UNITY_PRINT_EOL();
21835375f98Sopenharmony_ci            UNITY_PRINT_EOL();
21935375f98Sopenharmony_ci#ifdef UNITY_CUSTOM_HELP_MSG
22035375f98Sopenharmony_ci            /* User-defined help message, e.g. to point to project-specific documentation */
22135375f98Sopenharmony_ci            UnityPrint(UNITY_CUSTOM_HELP_MSG);
22235375f98Sopenharmony_ci            UNITY_PRINT_EOL();
22335375f98Sopenharmony_ci#else
22435375f98Sopenharmony_ci            /* Default help suffix if a custom one is not defined */
22535375f98Sopenharmony_ci            UnityPrint("More information about Unity: https://www.throwtheswitch.org/unity");
22635375f98Sopenharmony_ci            UNITY_PRINT_EOL();
22735375f98Sopenharmony_ci#endif
22835375f98Sopenharmony_ci            return 1;  /* Exit without running the tests */
22935375f98Sopenharmony_ci        }
23035375f98Sopenharmony_ci        else if (strcmp(argv[i], "-v") == 0)
23135375f98Sopenharmony_ci        {
23235375f98Sopenharmony_ci            UnityFixture.Verbose = 1;
23335375f98Sopenharmony_ci            i++;
23435375f98Sopenharmony_ci        }
23535375f98Sopenharmony_ci        else if (strcmp(argv[i], "-s") == 0)
23635375f98Sopenharmony_ci        {
23735375f98Sopenharmony_ci            UnityFixture.Silent = 1;
23835375f98Sopenharmony_ci            i++;
23935375f98Sopenharmony_ci        }
24035375f98Sopenharmony_ci        else if (strcmp(argv[i], "-g") == 0)
24135375f98Sopenharmony_ci        {
24235375f98Sopenharmony_ci            i++;
24335375f98Sopenharmony_ci            if (i >= argc)
24435375f98Sopenharmony_ci                return 1;
24535375f98Sopenharmony_ci            UnityFixture.GroupFilter = argv[i];
24635375f98Sopenharmony_ci            i++;
24735375f98Sopenharmony_ci        }
24835375f98Sopenharmony_ci        else if (strcmp(argv[i], "-n") == 0)
24935375f98Sopenharmony_ci        {
25035375f98Sopenharmony_ci            i++;
25135375f98Sopenharmony_ci            if (i >= argc)
25235375f98Sopenharmony_ci                return 1;
25335375f98Sopenharmony_ci            UnityFixture.NameFilter = argv[i];
25435375f98Sopenharmony_ci            i++;
25535375f98Sopenharmony_ci        }
25635375f98Sopenharmony_ci        else if (strcmp(argv[i], "-r") == 0)
25735375f98Sopenharmony_ci        {
25835375f98Sopenharmony_ci            UnityFixture.RepeatCount = 2;
25935375f98Sopenharmony_ci            i++;
26035375f98Sopenharmony_ci            if (i < argc)
26135375f98Sopenharmony_ci            {
26235375f98Sopenharmony_ci                if (*(argv[i]) >= '0' && *(argv[i]) <= '9')
26335375f98Sopenharmony_ci                {
26435375f98Sopenharmony_ci                    unsigned int digit = 0;
26535375f98Sopenharmony_ci                    UnityFixture.RepeatCount = 0;
26635375f98Sopenharmony_ci                    while (argv[i][digit] >= '0' && argv[i][digit] <= '9')
26735375f98Sopenharmony_ci                    {
26835375f98Sopenharmony_ci                        UnityFixture.RepeatCount *= 10;
26935375f98Sopenharmony_ci                        UnityFixture.RepeatCount += (unsigned int)argv[i][digit++] - '0';
27035375f98Sopenharmony_ci                    }
27135375f98Sopenharmony_ci                    i++;
27235375f98Sopenharmony_ci                }
27335375f98Sopenharmony_ci            }
27435375f98Sopenharmony_ci        }
27535375f98Sopenharmony_ci        else
27635375f98Sopenharmony_ci        {
27735375f98Sopenharmony_ci            /* ignore unknown parameter */
27835375f98Sopenharmony_ci            i++;
27935375f98Sopenharmony_ci        }
28035375f98Sopenharmony_ci    }
28135375f98Sopenharmony_ci    return 0;
28235375f98Sopenharmony_ci}
28335375f98Sopenharmony_ci
28435375f98Sopenharmony_civoid UnityConcludeFixtureTest(void)
28535375f98Sopenharmony_ci{
28635375f98Sopenharmony_ci    if (Unity.CurrentTestIgnored)
28735375f98Sopenharmony_ci    {
28835375f98Sopenharmony_ci        Unity.TestIgnores++;
28935375f98Sopenharmony_ci        UNITY_PRINT_EOL();
29035375f98Sopenharmony_ci    }
29135375f98Sopenharmony_ci    else if (!Unity.CurrentTestFailed)
29235375f98Sopenharmony_ci    {
29335375f98Sopenharmony_ci        if (UnityFixture.Verbose)
29435375f98Sopenharmony_ci        {
29535375f98Sopenharmony_ci            UnityPrint(" ");
29635375f98Sopenharmony_ci            UnityPrint(UnityStrPass);
29735375f98Sopenharmony_ci            UNITY_EXEC_TIME_STOP();
29835375f98Sopenharmony_ci            UNITY_PRINT_EXEC_TIME();
29935375f98Sopenharmony_ci            UNITY_PRINT_EOL();
30035375f98Sopenharmony_ci        }
30135375f98Sopenharmony_ci    }
30235375f98Sopenharmony_ci    else /* Unity.CurrentTestFailed */
30335375f98Sopenharmony_ci    {
30435375f98Sopenharmony_ci        Unity.TestFailures++;
30535375f98Sopenharmony_ci        UNITY_PRINT_EOL();
30635375f98Sopenharmony_ci    }
30735375f98Sopenharmony_ci
30835375f98Sopenharmony_ci    Unity.CurrentTestFailed = 0;
30935375f98Sopenharmony_ci    Unity.CurrentTestIgnored = 0;
31035375f98Sopenharmony_ci}
311