1
0
mirror of https://github.com/ThrowTheSwitch/Unity.git synced 2026-01-23 08:25:58 +01:00

Merge pull request #775 from ml-physec/more-details

Detail-Stack API
This commit is contained in:
Mark VanderVoord
2025-07-09 15:23:44 -04:00
committed by GitHub
10 changed files with 433 additions and 30 deletions

View File

@@ -0,0 +1,63 @@
# =========================================================================
# Unity - A Test Framework for C
# ThrowTheSwitch.org
# Copyright (c) 2007-24 Mike Karlesky, Mark VanderVoord, & Greg Williams
# SPDX-License-Identifier: MIT
# =========================================================================
#We try to detect the OS we are running on, and adjust commands as needed
ifeq ($(OS),Windows_NT)
ifeq ($(shell uname -s),) # not in a bash-like shell
CLEANUP = del /F /Q
MKDIR = mkdir
else # in a bash-like shell, like msys
CLEANUP = rm -f
MKDIR = mkdir -p
endif
TARGET_EXTENSION=.exe
else
CLEANUP = rm -f
MKDIR = mkdir -p
TARGET_EXTENSION=.out
endif
C_COMPILER=gcc
ifeq ($(shell uname -s), Darwin)
C_COMPILER=clang
endif
UNITY_ROOT=../..
CFLAGS=-std=c89
CFLAGS += -Wall
CFLAGS += -Wextra
CFLAGS += -Wpointer-arith
CFLAGS += -Wcast-align
CFLAGS += -Wwrite-strings
CFLAGS += -Wswitch-default
CFLAGS += -Wunreachable-code
CFLAGS += -Winit-self
CFLAGS += -Wmissing-field-initializers
CFLAGS += -Wno-unknown-pragmas
CFLAGS += -Wstrict-prototypes
CFLAGS += -Wundef
CFLAGS += -Wold-style-definition
#CFLAGS += -Wno-misleading-indentation
TARGET_BASE1=test1
TARGET1 = $(TARGET_BASE1)$(TARGET_EXTENSION)
SRC_FILES1=$(UNITY_ROOT)/src/unity.c src/ProductionCode.c test/TestProductionCode.c test/test_runners/TestProductionCode_Runner.c
INC_DIRS=-Isrc -I$(UNITY_ROOT)/src
SYMBOLS=-include"test/unity_detail_config.h" -DUNIT_TESTING
all: clean default
default: $(SRC_FILES1)
$(C_COMPILER) $(CFLAGS) $(INC_DIRS) $(SYMBOLS) $(SRC_FILES1) -o $(TARGET1)
- ./$(TARGET1)
clean:
$(CLEANUP) $(TARGET1) $(TARGET2)
ci: CFLAGS += -Werror
ci: default

View File

@@ -0,0 +1,38 @@
Example 5
=========
Demonstrate Details Stack usage to implement something similar to a stacktrace.
This allows locating the error source much faster in branching/iterating code.
Build and run with Make
---
Just run `make`.
Output
---
Below the output is annotated with source of the elements.
```
test/TestProductionCode.c:36:test_BitExtractor:FAIL: Expected 0 Was 1. During call BitExtractor. During call BitExtractor_down. Bit Position 6. Bit Mask 0x02. Unexpected bit value
```
| String | Source |
|-----------------------------|---------------------------------------------------------------------------|
| `test/TestProductionCode.c` | `Unity.TestFile` |
| `36` | `UNITY_TEST_ASSERT_EQUAL_INT` line |
| `test_BitExtractor` | `RUN_TEST` name |
| `FAIL` | `UnityStrFail` |
| `Expected 1 Was 0` | `UnityAssertEqualNumber` |
| `During call` | Detail 0, Label |
| `BitExtractor` | Detail 0, Value |
| `During call` | Detail 0, Label |
| `BitExtractor` | Detail 0, Value |
| `During call` | Detail 1, Label |
| `BitExtractor_down` | Detail 1, Value |
| `Bit Position` | Detail 2, Label (literal starts with #\x18, so value is printed as INT32) |
| `6` | Detail 2 Value |
| `Bit Mask` | Detail 2, Label (literal starts with #\x41, so value is printed as HEX8) |
| `0x02` | Detail 2 Value |
| `Unexpected bit value` | `UNITY_TEST_ASSERT_EQUAL_INT` message |
While this example is a bit contrived, the source of the error can be clearly located to be within the `test_BitExtractor->BitExtractor->BitExtractor_down`

View File

@@ -0,0 +1,56 @@
/* =========================================================================
Unity - A Test Framework for C
ThrowTheSwitch.org
Copyright (c) 2007-25 Mike Karlesky, Mark VanderVoord, & Greg Williams
SPDX-License-Identifier: MIT
========================================================================= */
#include "ProductionCode.h"
#include <stdint.h>
#ifdef UNIT_TESTING
#include "unity.h"
#else
/* No-Op when not testing */
#define UNITY_DETAIL_PUSH
#define UNITY_DETAIL_POP
#endif
static void BitExtractor_up(uint8_t input, callback_t cb)
{
int32_t pos;
UNITY_DETAIL_PUSH(UNITY_DETAIL_CALL, __FUNCTION__);
for(pos=0; pos<8; pos++) {
UNITY_DETAIL_PUSH(UNITY_DETAIL_BIT_POS, pos);
UNITY_DETAIL_PUSH(UNITY_DETAIL_BIT_MASK, 1<<pos);
cb(pos, !!(input & (1<<pos)));
UNITY_DETAIL_POP(UNITY_DETAIL_BIT_MASK, 1<<pos);
UNITY_DETAIL_POP(UNITY_DETAIL_BIT_POS, pos);
}
UNITY_DETAIL_POP(UNITY_DETAIL_CALL, __FUNCTION__);
}
static void BitExtractor_down(uint8_t input, callback_t cb)
{
int32_t pos;
UNITY_DETAIL_PUSH(UNITY_DETAIL_CALL, __FUNCTION__);
for(pos=0; pos<8; pos++) {
UNITY_DETAIL_PUSH(UNITY_DETAIL_BIT_POS, pos);
UNITY_DETAIL_PUSH(UNITY_DETAIL_BIT_MASK, 0x80>>pos);
cb(pos, !!(input & (0x80>>pos)));
UNITY_DETAIL_POP(UNITY_DETAIL_BIT_MASK, 0x80>>pos);
UNITY_DETAIL_POP(UNITY_DETAIL_BIT_POS, pos);
}
UNITY_DETAIL_POP(UNITY_DETAIL_CALL, __FUNCTION__);
}
void BitExtractor(bit_direction_t dir, uint8_t input, callback_t cb)
{
UNITY_DETAIL_PUSH(UNITY_DETAIL_CALL, __FUNCTION__);
if(dir == BIT_DIRECTION_UP) {
BitExtractor_up(input, cb);
} else {
BitExtractor_down(input, cb);
}
UNITY_DETAIL_POP(UNITY_DETAIL_CALL, __FUNCTION__);
}

View File

@@ -0,0 +1,16 @@
/* =========================================================================
Unity - A Test Framework for C
ThrowTheSwitch.org
Copyright (c) 2007-25 Mike Karlesky, Mark VanderVoord, & Greg Williams
SPDX-License-Identifier: MIT
========================================================================= */
#include <stdint.h>
typedef void callback_t(int position, int bit_value);
typedef enum {
BIT_DIRECTION_UP,
BIT_DIRECTION_DOWN,
} bit_direction_t;
void BitExtractor(bit_direction_t dir, uint8_t input, callback_t cb);

View File

@@ -0,0 +1,3 @@
[wrap-git]
url = https://github.com/ThrowTheSwitch/Unity.git
revision = head

View File

@@ -0,0 +1,45 @@
/* =========================================================================
Unity - A Test Framework for C
ThrowTheSwitch.org
Copyright (c) 2007-25 Mike Karlesky, Mark VanderVoord, & Greg Williams
SPDX-License-Identifier: MIT
========================================================================= */
#include "ProductionCode.h"
#include "unity.h"
const int* current_expected_bits = NULL;
UNITY_LINE_TYPE current_vector_line = 0;
typedef struct {
UNITY_LINE_TYPE line;
uint8_t value;
bit_direction_t dir;
int expected_bits[8];
} test_vector_t;
void setUp(void)
{
}
void tearDown(void)
{
}
static void be_bit_tester(int position, int value) {
UNITY_TEST_ASSERT_EQUAL_INT(current_expected_bits[position], value, current_vector_line, "Unexpected bit value");
}
void test_BitExtractor(void)
{
const test_vector_t test_vectors[] = {
{__LINE__, 7, BIT_DIRECTION_UP, {1,1,1,0,0,0,0,0}},
{__LINE__, 7, BIT_DIRECTION_DOWN, {0,0,0,0,0,1,0,1}},
{0}
};
const test_vector_t* tv;
for (tv = test_vectors; tv->line; tv++) {
current_vector_line = tv->line;
current_expected_bits = tv->expected_bits;
BitExtractor(tv->dir, tv->value, be_bit_tester);
}
}

View File

@@ -0,0 +1,48 @@
/* AUTOGENERATED FILE. DO NOT EDIT. */
/*=======Test Runner Used To Run Each Test Below=====*/
#define RUN_TEST(TestFunc, TestLineNum) \
{ \
Unity.CurrentTestName = #TestFunc; \
Unity.CurrentTestLineNumber = TestLineNum; \
Unity.NumberOfTests++; \
if (TEST_PROTECT()) \
{ \
setUp(); \
TestFunc(); \
} \
if (TEST_PROTECT()) \
{ \
tearDown(); \
} \
UnityConcludeTest(); \
}
/*=======Automagically Detected Files To Include=====*/
#include "unity.h"
#include <setjmp.h>
#include <stdio.h>
#include "ProductionCode.h"
/*=======External Functions This Runner Calls=====*/
extern void setUp(void);
extern void tearDown(void);
extern void test_BitExtractor(void);
/*=======Test Reset Option=====*/
void resetTest(void);
void resetTest(void)
{
tearDown();
setUp();
}
/*=======MAIN=====*/
int main(void)
{
UnityBegin("test/TestProductionCode.c");
RUN_TEST(test_BitExtractor, 32);
return UNITY_END();
}

View File

@@ -0,0 +1,18 @@
#define UNITY_DETAIL_STACK_SIZE 5
#define LABEL_AS_INT32 "#\x18" /*UNITY_DISPLAY_STYLE_INT32 = 0x18 */
#define LABEL_AS_HEX8 "#\x41" /* UNITY_DISPLAY_STYLE_HEX8 = 0x41 */
#define UNITY_DETAIL_LABEL_NAMES { 0, \
UNITY_DETAIL1_NAME, \
UNITY_DETAIL2_NAME, \
"During call", \
LABEL_AS_INT32 "Bit Position", \
LABEL_AS_HEX8 "Bit Mask", \
}
typedef enum {
UNITY_DETAIL_NONE = 0,
UNITY_DETAIL_D1 = 1,
UNITY_DETAIL_D2 = 2,
UNITY_DETAIL_CALL,
UNITY_DETAIL_BIT_POS,
UNITY_DETAIL_BIT_MASK,
} UNITY_DETAIL_LABEL_T;

View File

@@ -61,14 +61,24 @@ const char UNITY_PROGMEM UnityStrErrShorthand[] = "Unity Shorth
const char UNITY_PROGMEM UnityStrErrFloat[] = "Unity Floating Point Disabled"; const char UNITY_PROGMEM UnityStrErrFloat[] = "Unity Floating Point Disabled";
const char UNITY_PROGMEM UnityStrErrDouble[] = "Unity Double Precision Disabled"; const char UNITY_PROGMEM UnityStrErrDouble[] = "Unity Double Precision Disabled";
const char UNITY_PROGMEM UnityStrErr64[] = "Unity 64-bit Support Disabled"; const char UNITY_PROGMEM UnityStrErr64[] = "Unity 64-bit Support Disabled";
const char UNITY_PROGMEM UnityStrErrDetailStack[] = "Unity Detail Stack Support Disabled";
static const char UNITY_PROGMEM UnityStrBreaker[] = "-----------------------"; static const char UNITY_PROGMEM UnityStrBreaker[] = "-----------------------";
static const char UNITY_PROGMEM UnityStrResultsTests[] = " Tests "; static const char UNITY_PROGMEM UnityStrResultsTests[] = " Tests ";
static const char UNITY_PROGMEM UnityStrResultsFailures[] = " Failures "; static const char UNITY_PROGMEM UnityStrResultsFailures[] = " Failures ";
static const char UNITY_PROGMEM UnityStrResultsIgnored[] = " Ignored "; static const char UNITY_PROGMEM UnityStrResultsIgnored[] = " Ignored ";
#ifndef UNITY_EXCLUDE_DETAILS #ifndef UNITY_EXCLUDE_DETAILS
#ifdef UNITY_DETAIL_STACK_SIZE
static const char* UNITY_PROGMEM UnityStrDetailLabels[] = UNITY_DETAIL_LABEL_NAMES;
static const UNITY_COUNTER_TYPE UNITY_PROGMEM UnityStrDetailLabelsCount = sizeof(UnityStrDetailLabels) / sizeof(const char*);
static const char UNITY_PROGMEM UnityStrErrDetailStackEmpty[] = " Detail Stack Empty";
static const char UNITY_PROGMEM UnityStrErrDetailStackFull[] = " Detail Stack Full";
static const char UNITY_PROGMEM UnityStrErrDetailStackLabel[] = " Detail Label Outside Of UNITY_DETAIL_LABEL_NAMES: ";
static const char UNITY_PROGMEM UnityStrErrDetailStackPop[] = " Detail Pop With Unexpected Arguments";
#else
static const char UNITY_PROGMEM UnityStrDetail1Name[] = UNITY_DETAIL1_NAME " "; static const char UNITY_PROGMEM UnityStrDetail1Name[] = UNITY_DETAIL1_NAME " ";
static const char UNITY_PROGMEM UnityStrDetail2Name[] = " " UNITY_DETAIL2_NAME " "; static const char UNITY_PROGMEM UnityStrDetail2Name[] = " " UNITY_DETAIL2_NAME " ";
#endif #endif
#endif
/*----------------------------------------------- /*-----------------------------------------------
* Pretty Printers & Test Result Output Handlers * Pretty Printers & Test Result Output Handlers
*-----------------------------------------------*/ *-----------------------------------------------*/
@@ -574,6 +584,28 @@ static void UnityAddMsgIfSpecified(const char* msg)
UNITY_PRINT_TEST_CONTEXT(); UNITY_PRINT_TEST_CONTEXT();
#endif #endif
#ifndef UNITY_EXCLUDE_DETAILS #ifndef UNITY_EXCLUDE_DETAILS
#ifdef UNITY_DETAIL_STACK_SIZE
{
UNITY_COUNTER_TYPE c;
for (c = 0; (c < Unity.CurrentDetailStackSize) && (c < UNITY_DETAIL_STACK_SIZE); c++) {
const char* label;
if ((Unity.CurrentDetailStackLabels[c] == UNITY_DETAIL_NONE) || (Unity.CurrentDetailStackLabels[c] > UnityStrDetailLabelsCount)) {
break;
}
label = UnityStrDetailLabels[Unity.CurrentDetailStackLabels[c]];
UnityPrint(UnityStrSpacer);
if ((label[0] == '#') && (label[1] != 0)) {
UnityPrint(label + 2);
UNITY_OUTPUT_CHAR(' ');
UnityPrintNumberByStyle(Unity.CurrentDetailStackValues[c], label[1]);
} else if (Unity.CurrentDetailStackValues[c] != 0){
UnityPrint(label);
UNITY_OUTPUT_CHAR(' ');
UnityPrint((const char*)Unity.CurrentDetailStackValues[c]);
}
}
}
#else
if (Unity.CurrentDetail1) if (Unity.CurrentDetail1)
{ {
UnityPrint(UnityStrSpacer); UnityPrint(UnityStrSpacer);
@@ -585,6 +617,7 @@ static void UnityAddMsgIfSpecified(const char* msg)
UnityPrint(Unity.CurrentDetail2); UnityPrint(Unity.CurrentDetail2);
} }
} }
#endif
#endif #endif
if (msg) if (msg)
{ {
@@ -2127,32 +2160,7 @@ void UnityFail(const char* msg, const UNITY_LINE_TYPE line)
UnityTestResultsBegin(Unity.TestFile, line); UnityTestResultsBegin(Unity.TestFile, line);
UnityPrint(UnityStrFail); UnityPrint(UnityStrFail);
if (msg != NULL) UnityAddMsgIfSpecified(msg);
{
UNITY_OUTPUT_CHAR(':');
#ifdef UNITY_PRINT_TEST_CONTEXT
UNITY_PRINT_TEST_CONTEXT();
#endif
#ifndef UNITY_EXCLUDE_DETAILS
if (Unity.CurrentDetail1)
{
UnityPrint(UnityStrDetail1Name);
UnityPrint(Unity.CurrentDetail1);
if (Unity.CurrentDetail2)
{
UnityPrint(UnityStrDetail2Name);
UnityPrint(Unity.CurrentDetail2);
}
UnityPrint(UnityStrSpacer);
}
#endif
if (msg[0] != ' ')
{
UNITY_OUTPUT_CHAR(' ');
}
UnityPrint(msg);
}
UNITY_FAIL_AND_BAIL; UNITY_FAIL_AND_BAIL;
} }
@@ -2195,7 +2203,13 @@ void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int
Unity.CurrentTestName = FuncName; Unity.CurrentTestName = FuncName;
Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)FuncLineNum; Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)FuncLineNum;
Unity.NumberOfTests++; Unity.NumberOfTests++;
#ifndef UNITY_EXCLUDE_DETAILS
#ifdef UNITY_DETAIL_STACK_SIZE
Unity.CurrentDetailStackSize = 0;
#else
UNITY_CLR_DETAILS(); UNITY_CLR_DETAILS();
#endif
#endif
UNITY_EXEC_TIME_START(); UNITY_EXEC_TIME_START();
if (TEST_PROTECT()) if (TEST_PROTECT())
{ {
@@ -2263,6 +2277,46 @@ int UnityEnd(void)
return (int)(Unity.TestFailures); return (int)(Unity.TestFailures);
} }
/*-----------------------------------------------
* Details Stack
*-----------------------------------------------*/
#ifndef UNITY_EXCLUDE_DETAILS
#ifdef UNITY_DETAIL_STACK_SIZE
void UnityPushDetail(UNITY_DETAIL_LABEL_TYPE label, UNITY_DETAIL_VALUE_TYPE value, const UNITY_LINE_TYPE line) {
if (Unity.CurrentDetailStackSize >= UNITY_DETAIL_STACK_SIZE) {
UnityTestResultsFailBegin(line);
UnityPrint(UnityStrErrDetailStackFull);
UnityAddMsgIfSpecified(NULL);
UNITY_FAIL_AND_BAIL;
}
if (label >= UnityStrDetailLabelsCount) {
UnityTestResultsFailBegin(line);
UnityPrint(UnityStrErrDetailStackLabel);
UnityPrintNumberUnsigned(label);
UnityAddMsgIfSpecified(NULL);
UNITY_FAIL_AND_BAIL;
}
Unity.CurrentDetailStackLabels[Unity.CurrentDetailStackSize] = label;
Unity.CurrentDetailStackValues[Unity.CurrentDetailStackSize++] = value;
}
void UnityPopDetail(UNITY_DETAIL_LABEL_TYPE label, UNITY_DETAIL_VALUE_TYPE value, const UNITY_LINE_TYPE line) {
if (Unity.CurrentDetailStackSize == 0) {
UnityTestResultsFailBegin(line);
UnityPrint(UnityStrErrDetailStackEmpty);
UnityAddMsgIfSpecified(NULL);
UNITY_FAIL_AND_BAIL;
}
if ((Unity.CurrentDetailStackLabels[Unity.CurrentDetailStackSize-1] != label) || (Unity.CurrentDetailStackValues[Unity.CurrentDetailStackSize-1] != value)) {
UnityTestResultsFailBegin(line);
UnityPrint(UnityStrErrDetailStackPop);
UnityAddMsgIfSpecified(NULL);
UNITY_FAIL_AND_BAIL;
}
Unity.CurrentDetailStackSize--;
}
#endif
#endif
/*----------------------------------------------- /*-----------------------------------------------
* Command Line Argument Support * Command Line Argument Support
*-----------------------------------------------*/ *-----------------------------------------------*/

View File

@@ -517,13 +517,30 @@ typedef enum
UNITY_ARRAY_UNKNOWN UNITY_ARRAY_UNKNOWN
} UNITY_FLAGS_T; } UNITY_FLAGS_T;
#ifndef UNITY_EXCLUDE_DETAILS
#ifdef UNITY_DETAIL_STACK_SIZE
#ifndef UNITY_DETAIL_LABEL_TYPE
#define UNITY_DETAIL_LABEL_TYPE uint8_t
#endif
#ifndef UNITY_DETAIL_VALUE_TYPE
#define UNITY_DETAIL_VALUE_TYPE UNITY_PTR_TO_INT
#endif
#endif
#endif
struct UNITY_STORAGE_T struct UNITY_STORAGE_T
{ {
const char* TestFile; const char* TestFile;
const char* CurrentTestName; const char* CurrentTestName;
#ifndef UNITY_EXCLUDE_DETAILS #ifndef UNITY_EXCLUDE_DETAILS
#ifdef UNITY_DETAIL_STACK_SIZE
UNITY_DETAIL_LABEL_TYPE CurrentDetailStackLabels[UNITY_DETAIL_STACK_SIZE];
UNITY_DETAIL_VALUE_TYPE CurrentDetailStackValues[UNITY_DETAIL_STACK_SIZE];
UNITY_COUNTER_TYPE CurrentDetailStackSize;
#else
const char* CurrentDetail1; const char* CurrentDetail1;
const char* CurrentDetail2; const char* CurrentDetail2;
#endif
#endif #endif
UNITY_LINE_TYPE CurrentTestLineNumber; UNITY_LINE_TYPE CurrentTestLineNumber;
UNITY_COUNTER_TYPE NumberOfTests; UNITY_COUNTER_TYPE NumberOfTests;
@@ -566,10 +583,6 @@ void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int
#define UNITY_SET_DETAIL(d1) #define UNITY_SET_DETAIL(d1)
#define UNITY_SET_DETAILS(d1,d2) #define UNITY_SET_DETAILS(d1,d2)
#else #else
#define UNITY_CLR_DETAILS() do { Unity.CurrentDetail1 = 0; Unity.CurrentDetail2 = 0; } while (0)
#define UNITY_SET_DETAIL(d1) do { Unity.CurrentDetail1 = (d1); Unity.CurrentDetail2 = 0; } while (0)
#define UNITY_SET_DETAILS(d1,d2) do { Unity.CurrentDetail1 = (d1); Unity.CurrentDetail2 = (d2); } while (0)
#ifndef UNITY_DETAIL1_NAME #ifndef UNITY_DETAIL1_NAME
#define UNITY_DETAIL1_NAME "Function" #define UNITY_DETAIL1_NAME "Function"
#endif #endif
@@ -577,6 +590,47 @@ void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int
#ifndef UNITY_DETAIL2_NAME #ifndef UNITY_DETAIL2_NAME
#define UNITY_DETAIL2_NAME "Argument" #define UNITY_DETAIL2_NAME "Argument"
#endif #endif
#ifdef UNITY_DETAIL_STACK_SIZE
/* stack based implementation */
#ifndef UNITY_DETAIL_LABEL_NAMES
/* Note: If the label name string starts with '#', the second byte is interpreted as UNITY_DISPLAY_STYLE_T,
* and the detail value will be printed as number (e.g. "#\x24Line" to output "Line <UINT32 value>").
* Otherwise, the detail value must be a pointer to a string that is valid until it is pop'ed.
*/
#define UNITY_DETAIL_LABEL_NAMES {0, UNITY_DETAIL1_NAME, UNITY_DETAIL2_NAME}
typedef enum
{
UNITY_DETAIL_NONE = 0,
UNITY_DETAIL_D1 = 1,
UNITY_DETAIL_D2 = 2
} UNITY_DETAIL_LABEL_T;
#endif
void UnityPushDetail(UNITY_DETAIL_LABEL_TYPE label, UNITY_DETAIL_VALUE_TYPE value, const UNITY_LINE_TYPE line);
void UnityPopDetail(UNITY_DETAIL_LABEL_TYPE label, UNITY_DETAIL_VALUE_TYPE value, const UNITY_LINE_TYPE line);
#define UNITY_CLR_DETAILS() do { \
if(Unity.CurrentDetailStackSize && \
Unity.CurrentDetailStackLabels[Unity.CurrentDetailStackSize - 1] == UNITY_DETAIL_D2) { \
Unity.CurrentDetailStackLabels[--Unity.CurrentDetailStackSize] = UNITY_DETAIL_NONE;} \
if(Unity.CurrentDetailStackSize && \
Unity.CurrentDetailStackLabels[Unity.CurrentDetailStackSize - 1] == UNITY_DETAIL_D1) { \
Unity.CurrentDetailStackLabels[--Unity.CurrentDetailStackSize] = UNITY_DETAIL_NONE;} \
} while (0)
#define UNITY_SET_DETAIL(d1) do { UNITY_CLR_DETAILS(); \
UnityPushDetail(UNITY_DETAIL_D1, (UNITY_DETAIL_VALUE_TYPE)(d1), __LINE__); \
} while (0)
#define UNITY_SET_DETAILS(d1,d2) do { UNITY_CLR_DETAILS(); \
UnityPushDetail(UNITY_DETAIL_D1, (UNITY_DETAIL_VALUE_TYPE)(d1), __LINE__); \
UnityPushDetail(UNITY_DETAIL_D2, (UNITY_DETAIL_VALUE_TYPE)(d2), __LINE__); \
} while (0)
#else
/* just two hardcoded slots */
#define UNITY_CLR_DETAILS() do { Unity.CurrentDetail1 = 0; Unity.CurrentDetail2 = 0; } while (0)
#define UNITY_SET_DETAIL(d1) do { Unity.CurrentDetail1 = (d1); Unity.CurrentDetail2 = 0; } while (0)
#define UNITY_SET_DETAILS(d1,d2) do { Unity.CurrentDetail1 = (d1); Unity.CurrentDetail2 = (d2); } while (0)
#endif
#endif #endif
#ifdef UNITY_PRINT_TEST_CONTEXT #ifdef UNITY_PRINT_TEST_CONTEXT
@@ -1184,5 +1238,13 @@ int UnityTestMatches(void);
#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) #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)
#endif #endif
#if !defined(UNITY_EXCLUDE_DETAILS) && defined(UNITY_DETAIL_STACK_SIZE)
#define UNITY_DETAIL_PUSH(label, value) UnityPushDetail((UNITY_DETAIL_LABEL_TYPE)(label), (UNITY_DETAIL_VALUE_TYPE)(value), __LINE__)
#define UNITY_DETAIL_POP(label, value) UnityPopDetail((UNITY_DETAIL_LABEL_TYPE)(label), (UNITY_DETAIL_VALUE_TYPE)(value), __LINE__)
#else
#define UNITY_DETAIL_PUSH(label, value) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDetailStack)
#define UNITY_DETAIL_POP(label, value) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDetailStack)
#endif
/* End of UNITY_INTERNALS_H */ /* End of UNITY_INTERNALS_H */
#endif #endif