Skip to content

Commit c359bf3

Browse files
committed
Initial implementation
1 parent 23e8edb commit c359bf3

File tree

2 files changed

+146
-30
lines changed

2 files changed

+146
-30
lines changed

src/unity.c

Lines changed: 80 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,24 @@ const char UNITY_PROGMEM UnityStrErrShorthand[] = "Unity Shorth
6161
const char UNITY_PROGMEM UnityStrErrFloat[] = "Unity Floating Point Disabled";
6262
const char UNITY_PROGMEM UnityStrErrDouble[] = "Unity Double Precision Disabled";
6363
const char UNITY_PROGMEM UnityStrErr64[] = "Unity 64-bit Support Disabled";
64+
const char UNITY_PROGMEM UnityStrErrDetailStack[] = "Unity Detail Stack Support Disabled";
6465
static const char UNITY_PROGMEM UnityStrBreaker[] = "-----------------------";
6566
static const char UNITY_PROGMEM UnityStrResultsTests[] = " Tests ";
6667
static const char UNITY_PROGMEM UnityStrResultsFailures[] = " Failures ";
6768
static const char UNITY_PROGMEM UnityStrResultsIgnored[] = " Ignored ";
6869
#ifndef UNITY_EXCLUDE_DETAILS
70+
#ifdef UNITY_DETAIL_STACK_SIZE
71+
static const char* UNITY_PROGMEM UnityStrDetailLabels[] = UNITY_DETAIL_LABEL_NAMES;
72+
static const UNITY_COUNTER_TYPE UNITY_PROGMEM UnityStrDetailLabelsCount = sizeof(UnityStrDetailLabels) / sizeof(const char*);
73+
static const char UNITY_PROGMEM UnityStrErrDetailStackEmpty[] = " Detail Stack Empty";
74+
static const char UNITY_PROGMEM UnityStrErrDetailStackFull[] = " Detail Stack Full";
75+
static const char UNITY_PROGMEM UnityStrErrDetailStackLabel[] = " Detail Label Outside Of UNITY_DETAIL_LABEL_NAMES: ";
76+
static const char UNITY_PROGMEM UnityStrErrDetailStackPop[] = " Detail Pop With Unexpected Arguments";
77+
#else
6978
static const char UNITY_PROGMEM UnityStrDetail1Name[] = UNITY_DETAIL1_NAME " ";
7079
static const char UNITY_PROGMEM UnityStrDetail2Name[] = " " UNITY_DETAIL2_NAME " ";
7180
#endif
81+
#endif
7282
/*-----------------------------------------------
7383
* Pretty Printers & Test Result Output Handlers
7484
*-----------------------------------------------*/
@@ -574,6 +584,28 @@ static void UnityAddMsgIfSpecified(const char* msg)
574584
UNITY_PRINT_TEST_CONTEXT();
575585
#endif
576586
#ifndef UNITY_EXCLUDE_DETAILS
587+
#ifdef UNITY_DETAIL_STACK_SIZE
588+
{
589+
UNITY_COUNTER_TYPE c;
590+
for (c = 0; (c < Unity.CurrentDetailStackSize) && (c < UNITY_DETAIL_STACK_SIZE); c++) {
591+
const char* label;
592+
if ((Unity.CurrentDetailStackLabels[c] == UNITY_DETAIL_NONE) || (Unity.CurrentDetailStackLabels[c] > UnityStrDetailLabelsCount)) {
593+
break;
594+
}
595+
label = UnityStrDetailLabels[Unity.CurrentDetailStackLabels[c]];
596+
UnityPrint(UnityStrSpacer);
597+
if ((label[0] == '#') && (label[1] != 0)) {
598+
UnityPrint(label + 2);
599+
UNITY_OUTPUT_CHAR(' ');
600+
UnityPrintNumberByStyle(Unity.CurrentDetailStackValues[c], label[1]);
601+
} else if (Unity.CurrentDetailStackValues[c] != 0){
602+
UnityPrint(label);
603+
UNITY_OUTPUT_CHAR(' ');
604+
UnityPrint((const char*)Unity.CurrentDetailStackValues[c]);
605+
}
606+
}
607+
}
608+
#else
577609
if (Unity.CurrentDetail1)
578610
{
579611
UnityPrint(UnityStrSpacer);
@@ -585,6 +617,7 @@ static void UnityAddMsgIfSpecified(const char* msg)
585617
UnityPrint(Unity.CurrentDetail2);
586618
}
587619
}
620+
#endif
588621
#endif
589622
if (msg)
590623
{
@@ -2127,32 +2160,7 @@ void UnityFail(const char* msg, const UNITY_LINE_TYPE line)
21272160

21282161
UnityTestResultsBegin(Unity.TestFile, line);
21292162
UnityPrint(UnityStrFail);
2130-
if (msg != NULL)
2131-
{
2132-
UNITY_OUTPUT_CHAR(':');
2133-
2134-
#ifdef UNITY_PRINT_TEST_CONTEXT
2135-
UNITY_PRINT_TEST_CONTEXT();
2136-
#endif
2137-
#ifndef UNITY_EXCLUDE_DETAILS
2138-
if (Unity.CurrentDetail1)
2139-
{
2140-
UnityPrint(UnityStrDetail1Name);
2141-
UnityPrint(Unity.CurrentDetail1);
2142-
if (Unity.CurrentDetail2)
2143-
{
2144-
UnityPrint(UnityStrDetail2Name);
2145-
UnityPrint(Unity.CurrentDetail2);
2146-
}
2147-
UnityPrint(UnityStrSpacer);
2148-
}
2149-
#endif
2150-
if (msg[0] != ' ')
2151-
{
2152-
UNITY_OUTPUT_CHAR(' ');
2153-
}
2154-
UnityPrint(msg);
2155-
}
2163+
UnityAddMsgIfSpecified(msg);
21562164

21572165
UNITY_FAIL_AND_BAIL;
21582166
}
@@ -2195,7 +2203,13 @@ void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int
21952203
Unity.CurrentTestName = FuncName;
21962204
Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)FuncLineNum;
21972205
Unity.NumberOfTests++;
2206+
#ifndef UNITY_EXCLUDE_DETAILS
2207+
#ifdef UNITY_DETAIL_STACK_SIZE
2208+
Unity.CurrentDetailStackSize = 0;
2209+
#else
21982210
UNITY_CLR_DETAILS();
2211+
#endif
2212+
#endif
21992213
UNITY_EXEC_TIME_START();
22002214
if (TEST_PROTECT())
22012215
{
@@ -2263,6 +2277,46 @@ int UnityEnd(void)
22632277
return (int)(Unity.TestFailures);
22642278
}
22652279

2280+
/*-----------------------------------------------
2281+
* Details Stack
2282+
*-----------------------------------------------*/
2283+
#ifndef UNITY_EXCLUDE_DETAILS
2284+
#ifdef UNITY_DETAIL_STACK_SIZE
2285+
void UnityPushDetail(UNITY_DETAIL_LABEL_TYPE label, UNITY_DETAIL_VALUE_TYPE value, const UNITY_LINE_TYPE line) {
2286+
if (Unity.CurrentDetailStackSize >= UNITY_DETAIL_STACK_SIZE) {
2287+
UnityTestResultsFailBegin(line);
2288+
UnityPrint(UnityStrErrDetailStackFull);
2289+
UnityAddMsgIfSpecified(NULL);
2290+
UNITY_FAIL_AND_BAIL;
2291+
}
2292+
if (label >= UnityStrDetailLabelsCount) {
2293+
UnityTestResultsFailBegin(line);
2294+
UnityPrint(UnityStrErrDetailStackLabel);
2295+
UnityPrintNumberUnsigned(label);
2296+
UnityAddMsgIfSpecified(NULL);
2297+
UNITY_FAIL_AND_BAIL;
2298+
}
2299+
Unity.CurrentDetailStackLabels[Unity.CurrentDetailStackSize] = label;
2300+
Unity.CurrentDetailStackValues[Unity.CurrentDetailStackSize++] = value;
2301+
}
2302+
void UnityPopDetail(UNITY_DETAIL_LABEL_TYPE label, UNITY_DETAIL_VALUE_TYPE value, const UNITY_LINE_TYPE line) {
2303+
if (Unity.CurrentDetailStackSize == 0) {
2304+
UnityTestResultsFailBegin(line);
2305+
UnityPrint(UnityStrErrDetailStackEmpty);
2306+
UnityAddMsgIfSpecified(NULL);
2307+
UNITY_FAIL_AND_BAIL;
2308+
}
2309+
if ((Unity.CurrentDetailStackLabels[Unity.CurrentDetailStackSize-1] != label) || (Unity.CurrentDetailStackValues[Unity.CurrentDetailStackSize-1] != value)) {
2310+
UnityTestResultsFailBegin(line);
2311+
UnityPrint(UnityStrErrDetailStackPop);
2312+
UnityAddMsgIfSpecified(NULL);
2313+
UNITY_FAIL_AND_BAIL;
2314+
}
2315+
Unity.CurrentDetailStackSize--;
2316+
}
2317+
#endif
2318+
#endif
2319+
22662320
/*-----------------------------------------------
22672321
* Command Line Argument Support
22682322
*-----------------------------------------------*/

src/unity_internals.h

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -512,13 +512,30 @@ typedef enum
512512
UNITY_ARRAY_UNKNOWN
513513
} UNITY_FLAGS_T;
514514

515+
#ifndef UNITY_EXCLUDE_DETAILS
516+
#ifdef UNITY_DETAIL_STACK_SIZE
517+
#ifndef UNITY_DETAIL_LABEL_TYPE
518+
#define UNITY_DETAIL_LABEL_TYPE uint8_t
519+
#endif
520+
#ifndef UNITY_DETAIL_VALUE_TYPE
521+
#define UNITY_DETAIL_VALUE_TYPE UNITY_PTR_TO_INT
522+
#endif
523+
#endif
524+
#endif
525+
515526
struct UNITY_STORAGE_T
516527
{
517528
const char* TestFile;
518529
const char* CurrentTestName;
519530
#ifndef UNITY_EXCLUDE_DETAILS
531+
#ifdef UNITY_DETAIL_STACK_SIZE
532+
UNITY_DETAIL_LABEL_TYPE CurrentDetailStackLabels[UNITY_DETAIL_STACK_SIZE];
533+
UNITY_DETAIL_VALUE_TYPE CurrentDetailStackValues[UNITY_DETAIL_STACK_SIZE];
534+
UNITY_COUNTER_TYPE CurrentDetailStackSize;
535+
#else
520536
const char* CurrentDetail1;
521537
const char* CurrentDetail2;
538+
#endif
522539
#endif
523540
UNITY_LINE_TYPE CurrentTestLineNumber;
524541
UNITY_COUNTER_TYPE NumberOfTests;
@@ -561,17 +578,54 @@ void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int
561578
#define UNITY_SET_DETAIL(d1)
562579
#define UNITY_SET_DETAILS(d1,d2)
563580
#else
564-
#define UNITY_CLR_DETAILS() do { Unity.CurrentDetail1 = 0; Unity.CurrentDetail2 = 0; } while (0)
565-
#define UNITY_SET_DETAIL(d1) do { Unity.CurrentDetail1 = (d1); Unity.CurrentDetail2 = 0; } while (0)
566-
#define UNITY_SET_DETAILS(d1,d2) do { Unity.CurrentDetail1 = (d1); Unity.CurrentDetail2 = (d2); } while (0)
567-
568581
#ifndef UNITY_DETAIL1_NAME
569582
#define UNITY_DETAIL1_NAME "Function"
570583
#endif
571584

572585
#ifndef UNITY_DETAIL2_NAME
573586
#define UNITY_DETAIL2_NAME "Argument"
574587
#endif
588+
589+
#ifdef UNITY_DETAIL_STACK_SIZE
590+
/* stack based implementation */
591+
#ifndef UNITY_DETAIL_LABEL_NAMES
592+
/* Note: If the label name string starts with '#', the second byte is interpreted as UNITY_DISPLAY_STYLE_T,
593+
* and the detail value will be printed as number (e.g. "#\x24Line" to output "Line <UINT32 value>").
594+
* Otherwise, the detail value must be a pointer to a string that is valid until it is pop'ed.
595+
*/
596+
#define UNITY_DETAIL_LABEL_NAMES {0, UNITY_DETAIL1_NAME, UNITY_DETAIL2_NAME}
597+
typedef enum
598+
{
599+
UNITY_DETAIL_NONE = 0,
600+
UNITY_DETAIL_D1 = 1,
601+
UNITY_DETAIL_D2 = 2
602+
} UNITY_DETAIL_LABEL_T;
603+
#endif
604+
void UnityPushDetail(UNITY_DETAIL_LABEL_TYPE label, UNITY_DETAIL_VALUE_TYPE value, const UNITY_LINE_TYPE line);
605+
void UnityPopDetail(UNITY_DETAIL_LABEL_TYPE label, UNITY_DETAIL_VALUE_TYPE value, const UNITY_LINE_TYPE line);
606+
607+
#define UNITY_CLR_DETAILS() do { \
608+
if(Unity.CurrentDetailStackSize && \
609+
Unity.CurrentDetailStackLabels[Unity.CurrentDetailStackSize - 1] == UNITY_DETAIL_D2) { \
610+
Unity.CurrentDetailStackLabels[--Unity.CurrentDetailStackSize] = UNITY_DETAIL_NONE;} \
611+
if(Unity.CurrentDetailStackSize && \
612+
Unity.CurrentDetailStackLabels[Unity.CurrentDetailStackSize - 1] == UNITY_DETAIL_D1) { \
613+
Unity.CurrentDetailStackLabels[--Unity.CurrentDetailStackSize] = UNITY_DETAIL_NONE;} \
614+
} while (0)
615+
#define UNITY_SET_DETAIL(d1) do { UNITY_CLR_DETAILS(); \
616+
UnityPushDetail(UNITY_DETAIL_D1, (UNITY_DETAIL_VALUE_TYPE)(d1), __LINE__); \
617+
} while (0)
618+
#define UNITY_SET_DETAILS(d1,d2) do { UNITY_CLR_DETAILS(); \
619+
UnityPushDetail(UNITY_DETAIL_D1, (UNITY_DETAIL_VALUE_TYPE)(d1), __LINE__); \
620+
UnityPushDetail(UNITY_DETAIL_D2, (UNITY_DETAIL_VALUE_TYPE)(d2), __LINE__); \
621+
} while (0)
622+
623+
#else
624+
/* just two hardcoded slots */
625+
#define UNITY_CLR_DETAILS() do { Unity.CurrentDetail1 = 0; Unity.CurrentDetail2 = 0; } while (0)
626+
#define UNITY_SET_DETAIL(d1) do { Unity.CurrentDetail1 = (d1); Unity.CurrentDetail2 = 0; } while (0)
627+
#define UNITY_SET_DETAILS(d1,d2) do { Unity.CurrentDetail1 = (d1); Unity.CurrentDetail2 = (d2); } while (0)
628+
#endif
575629
#endif
576630

577631
#ifdef UNITY_PRINT_TEST_CONTEXT
@@ -1179,5 +1233,13 @@ int UnityTestMatches(void);
11791233
#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_DET)
11801234
#endif
11811235

1236+
#if !defined(UNITY_EXCLUDE_DETAILS) && defined(UNITY_DETAIL_STACK_SIZE)
1237+
#define UNITY_DETAIL_PUSH(label, value) UnityPushDetail((UNITY_DETAIL_LABEL_TYPE)(label), (UNITY_DETAIL_VALUE_TYPE)(value), __LINE__)
1238+
#define UNITY_DETAIL_POP(label, value) UnityPopDetail((UNITY_DETAIL_LABEL_TYPE)(label), (UNITY_DETAIL_VALUE_TYPE)(value), __LINE__)
1239+
#else
1240+
#define UNITY_DETAIL_PUSH(label, value) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDetailStack)
1241+
#define UNITY_DETAIL_POP(label, value) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDetailStack)
1242+
#endif
1243+
11821244
/* End of UNITY_INTERNALS_H */
11831245
#endif

0 commit comments

Comments
 (0)