mirror of
https://github.com/status-im/react-native.git
synced 2025-01-27 01:40:08 +00:00
Fix RCTAssert logic
This commit is contained in:
parent
1d452f3e4d
commit
3cef3010e6
@ -14,13 +14,13 @@
|
||||
/**
|
||||
* The default error domain to be used for React errors.
|
||||
*/
|
||||
extern NSString *const RCTErrorDomain;
|
||||
RCT_EXTERN NSString *const RCTErrorDomain;
|
||||
|
||||
/**
|
||||
* A block signature to be used for custom assertion handling.
|
||||
*/
|
||||
typedef void (^RCTAssertFunction)(
|
||||
BOOL condition,
|
||||
NSString *condition,
|
||||
NSString *fileName,
|
||||
NSNumber *lineNumber,
|
||||
NSString *function,
|
||||
@ -30,12 +30,18 @@ typedef void (^RCTAssertFunction)(
|
||||
/**
|
||||
* This is the main assert macro that you should use.
|
||||
*/
|
||||
#define RCTAssert(condition, ...) do { BOOL pass = ((condition) != 0); \
|
||||
if (RCT_NSASSERT && !pass) { [[NSAssertionHandler currentHandler] handleFailureInFunction:@(__func__) \
|
||||
file:@(__FILE__) lineNumber:__LINE__ description:__VA_ARGS__]; } \
|
||||
_RCTAssertFormat(pass, __FILE__, __LINE__, __func__, __VA_ARGS__); \
|
||||
#define RCTAssert(condition, ...) do { \
|
||||
if ((condition) == 0) { \
|
||||
_RCTAssertFormat(#condition, __FILE__, __LINE__, __func__, __VA_ARGS__); \
|
||||
if (RCT_NSASSERT) { \
|
||||
[[NSAssertionHandler currentHandler] handleFailureInFunction:@(__func__) \
|
||||
file:@(__FILE__) lineNumber:__LINE__ description:__VA_ARGS__]; \
|
||||
} \
|
||||
} \
|
||||
} while (false)
|
||||
RCT_EXTERN void _RCTAssertFormat(BOOL, const char *, int, const char *, NSString *, ...) NS_FORMAT_FUNCTION(5,6);
|
||||
RCT_EXTERN void _RCTAssertFormat(
|
||||
const char *, const char *, int, const char *, NSString *, ...
|
||||
) NS_FORMAT_FUNCTION(5,6);
|
||||
|
||||
/**
|
||||
* Convenience macro for asserting that a parameter is non-nil/non-zero.
|
||||
@ -64,6 +70,13 @@ RCT_EXTERN RCTAssertFunction RCTGetAssertFunction(void);
|
||||
*/
|
||||
RCT_EXTERN void RCTAddAssertFunction(RCTAssertFunction assertFunction);
|
||||
|
||||
/**
|
||||
* This method temporarily overrides the assert function while performing the
|
||||
* specified block. This is useful for testing purposes (to detect if a given
|
||||
* function asserts something) or to suppress or override assertions temporarily.
|
||||
*/
|
||||
RCT_EXTERN void RCTPerformBlockWithAssertFunction(void (^block)(void), RCTAssertFunction assertFunction);
|
||||
|
||||
/**
|
||||
* Get the current thread's name (or the current queue, if in debug mode)
|
||||
*/
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
NSString *const RCTErrorDomain = @"RCTErrorDomain";
|
||||
|
||||
static NSString *const RCTAssertFunctionStack = @"RCTAssertFunctionStack";
|
||||
|
||||
RCTAssertFunction RCTCurrentAssertFunction = nil;
|
||||
|
||||
NSException *_RCTNotImplementedException(SEL, Class);
|
||||
@ -22,26 +24,6 @@ NSException *_RCTNotImplementedException(SEL cmd, Class cls)
|
||||
reason:msg userInfo:nil];
|
||||
}
|
||||
|
||||
void _RCTAssertFormat(
|
||||
BOOL condition,
|
||||
const char *fileName,
|
||||
int lineNumber,
|
||||
const char *function,
|
||||
NSString *format, ...)
|
||||
{
|
||||
if (RCTCurrentAssertFunction) {
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
NSString *message = [[NSString alloc] initWithFormat:format arguments:args];
|
||||
va_end(args);
|
||||
|
||||
RCTCurrentAssertFunction(
|
||||
condition, @(fileName), @(lineNumber), @(function), message
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void RCTSetAssertFunction(RCTAssertFunction assertFunction)
|
||||
{
|
||||
RCTCurrentAssertFunction = assertFunction;
|
||||
@ -56,7 +38,7 @@ void RCTAddAssertFunction(RCTAssertFunction assertFunction)
|
||||
{
|
||||
RCTAssertFunction existing = RCTCurrentAssertFunction;
|
||||
if (existing) {
|
||||
RCTCurrentAssertFunction = ^(BOOL condition,
|
||||
RCTCurrentAssertFunction = ^(NSString *condition,
|
||||
NSString *fileName,
|
||||
NSNumber *lineNumber,
|
||||
NSString *function,
|
||||
@ -70,6 +52,34 @@ void RCTAddAssertFunction(RCTAssertFunction assertFunction)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the topmost stacked assert function for the current thread, which
|
||||
* may not be the same as the current value of RCTCurrentAssertFunction.
|
||||
*/
|
||||
static RCTAssertFunction RCTGetLocalAssertFunction()
|
||||
{
|
||||
NSMutableDictionary *threadDictionary = [NSThread currentThread].threadDictionary;
|
||||
NSArray *functionStack = threadDictionary[RCTAssertFunctionStack];
|
||||
RCTAssertFunction assertFunction = [functionStack lastObject];
|
||||
if (assertFunction) {
|
||||
return assertFunction;
|
||||
}
|
||||
return RCTCurrentAssertFunction;
|
||||
}
|
||||
|
||||
void RCTPerformBlockWithAssertFunction(void (^block)(void), RCTAssertFunction assertFunction)
|
||||
{
|
||||
NSMutableDictionary *threadDictionary = [NSThread currentThread].threadDictionary;
|
||||
NSMutableArray *functionStack = threadDictionary[RCTAssertFunctionStack];
|
||||
if (!functionStack) {
|
||||
functionStack = [[NSMutableArray alloc] init];
|
||||
threadDictionary[RCTAssertFunctionStack] = functionStack;
|
||||
}
|
||||
[functionStack addObject:assertFunction];
|
||||
block();
|
||||
[functionStack removeLastObject];
|
||||
}
|
||||
|
||||
NSString *RCTCurrentThreadName(void)
|
||||
{
|
||||
NSThread *thread = [NSThread currentThread];
|
||||
@ -84,3 +94,22 @@ NSString *RCTCurrentThreadName(void)
|
||||
}
|
||||
return threadName;
|
||||
}
|
||||
|
||||
void _RCTAssertFormat(
|
||||
const char *condition,
|
||||
const char *fileName,
|
||||
int lineNumber,
|
||||
const char *function,
|
||||
NSString *format, ...)
|
||||
{
|
||||
RCTAssertFunction assertFunction = RCTGetLocalAssertFunction();
|
||||
if (assertFunction) {
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
NSString *message = [[NSString alloc] initWithFormat:format arguments:args];
|
||||
va_end(args);
|
||||
|
||||
assertFunction(@(condition), @(fileName), @(lineNumber), @(function), message);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user