From 0daa4fe2f37ae2410aa8b3d847ad061aeda8e64f Mon Sep 17 00:00:00 2001 From: Arthur Vivian Date: Thu, 24 Jun 2021 13:31:48 +0100 Subject: [PATCH] Add NSError errors in place of NSException --- Source/Renderer/Rive.mm | 3 +- Source/Renderer/RiveArtboard.mm | 36 +++--- Source/Renderer/RiveFile.mm | 63 ++++++----- Source/Renderer/RiveStateMachine.mm | 23 ++-- Source/Renderer/RiveStateMachineInstance.mm | 32 +++--- Source/Renderer/include/Rive.h | 18 ++- Source/Renderer/include/RiveArtboard.h | 12 +- Source/Renderer/include/RiveFile.h | 16 +-- Source/Renderer/include/RiveStateMachine.h | 4 +- .../include/RiveStateMachineInstance.h | 6 +- Source/Views/RiveView.swift | 93 ++++++++-------- Tests/RiveAnimationConfigurationsTest.mm | 51 +++++---- Tests/RiveAnimationLoadTest.mm | 97 +++++++++------- Tests/RiveArtboardLoadTest.mm | 72 ++++++------ Tests/RiveDelegatesTest.swift | 79 +++++++------ Tests/RiveFileLoadTest.mm | 36 +++--- Tests/RiveRuntimeTests.mm | 91 +++++++++------ Tests/RiveStateMachineConfigurationTest.mm | 81 +++++++------- Tests/RiveStateMachineLoadTest.mm | 104 ++++++++++-------- Tests/StateMachineInstanceTest.mm | 71 ++++++------ Tests/util.h | 2 +- Tests/util.mm | 4 +- 22 files changed, 557 insertions(+), 437 deletions(-) diff --git a/Source/Renderer/Rive.mm b/Source/Renderer/Rive.mm index c79927b1..72da51d1 100644 --- a/Source/Renderer/Rive.mm +++ b/Source/Renderer/Rive.mm @@ -10,8 +10,7 @@ #import "RivePrivateHeaders.h" #import "RiveRenderer.hpp" -@implementation RiveException -@end +NSString *const RiveErrorDomain = @"rive.app.ios.runtime"; /* * RiveRenderer diff --git a/Source/Renderer/RiveArtboard.mm b/Source/Renderer/RiveArtboard.mm index d9f16e9e..5e2ebcc0 100644 --- a/Source/Renderer/RiveArtboard.mm +++ b/Source/Renderer/RiveArtboard.mm @@ -28,10 +28,11 @@ - (NSInteger)animationCount { } // Returns the first animation in the artboard, or null if it has none -- (RiveLinearAnimation *)firstAnimation { +- (RiveLinearAnimation *)firstAnimation:(NSError**) error { rive::LinearAnimation *animation = _artboard->firstAnimation(); if (animation == nullptr) { - @throw [[RiveException alloc] initWithName:@"NoAnimations" reason:@"No Animations found." userInfo:nil]; + *error = [NSError errorWithDomain:RiveErrorDomain code:RiveNoAnimations userInfo:@{NSLocalizedDescriptionKey: @"No Animations found.", @"name": @"NoAnimations"}]; + return nil; } else { return [[RiveLinearAnimation alloc] initWithAnimation:animation]; @@ -39,27 +40,28 @@ - (RiveLinearAnimation *)firstAnimation { } -- (RiveLinearAnimation *)animationFromIndex:(NSInteger)index { +- (RiveLinearAnimation *)animationFromIndex:(NSInteger)index error:(NSError**) error { if (index < 0 || index >= [self animationCount]) { - @throw [[RiveException alloc] initWithName:@"NoAnimationFound" reason:[NSString stringWithFormat: @"No Animation found at index %ld.", (long)index] userInfo:nil]; + *error = [NSError errorWithDomain:RiveErrorDomain code:RiveNoAnimationFound userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat: @"No Animation found at index %ld.", (long)index], @"name": @"NoAnimationFound"}]; + return nil; } return [[RiveLinearAnimation alloc] initWithAnimation: _artboard->animation(index)]; } -- (RiveLinearAnimation *)animationFromName:(NSString *)name { +- (RiveLinearAnimation *)animationFromName:(NSString *)name error:(NSError**) error { std::string stdName = std::string([name UTF8String]); rive::LinearAnimation *animation = _artboard->animation(stdName); if (animation == nullptr) { - @throw [[RiveException alloc] initWithName:@"NoAnimationFound" reason:[NSString stringWithFormat: @"No Animation found with name %@.", name] userInfo:nil]; + *error = [NSError errorWithDomain:RiveErrorDomain code:RiveNoAnimationFound userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat: @"No Animation found with name %@.", name], @"name": @"NoAnimationFound"}]; + return nil; } return [[RiveLinearAnimation alloc] initWithAnimation: animation]; } - (NSArray *)animationNames{ NSMutableArray *animationNames = [NSMutableArray array]; - for (NSUInteger i=0; i<[self animationCount]; i++){ - [animationNames addObject:[[self animationFromIndex: i] name]]; + [animationNames addObject:[[self animationFromIndex:i error:nil] name]]; } return animationNames; } @@ -69,10 +71,11 @@ - (NSInteger)stateMachineCount { return _artboard->stateMachineCount(); } -- (RiveStateMachine *)firstStateMachine { +- (RiveStateMachine *)firstStateMachine:(NSError**)error { rive::StateMachine *stateMachine = _artboard->firstStateMachine(); if (stateMachine == nullptr) { - @throw [[RiveException alloc] initWithName:@"NoStateMachines" reason:@"No State Machines found." userInfo:nil]; + *error = [NSError errorWithDomain:RiveErrorDomain code:RiveNoStateMachines userInfo:@{NSLocalizedDescriptionKey: @"No State Machines found.", @"name": @"NoStateMachines"}]; + return nil; } else { return [[RiveStateMachine alloc] initWithStateMachine:stateMachine]; @@ -80,28 +83,29 @@ - (RiveStateMachine *)firstStateMachine { } // Returns a state machine at the given index, or null if the index is invalid -- (RiveStateMachine *)stateMachineFromIndex:(NSInteger)index { +- (RiveStateMachine *)stateMachineFromIndex:(NSInteger)index error:(NSError**)error { if (index < 0 || index >= [self stateMachineCount]) { - @throw [[RiveException alloc] initWithName:@"NoStateMachineFound" reason:[NSString stringWithFormat: @"No State Machine found at index %ld.", (long)index] userInfo:nil]; + *error = [NSError errorWithDomain:RiveErrorDomain code:RiveNoStateMachineFound userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat: @"No State Machine found at index %ld.", (long)index], @"name": @"NoStateMachineFound"}]; + return nil; } return [[RiveStateMachine alloc] initWithStateMachine: _artboard->stateMachine(index)]; } // Returns a state machine with the given name, or null if none exists -- (RiveStateMachine *)stateMachineFromName:(NSString *)name { +- (RiveStateMachine *)stateMachineFromName:(NSString *)name error:(NSError**)error { std::string stdName = std::string([name UTF8String]); rive::StateMachine *machine = _artboard->stateMachine(stdName); if (machine == nullptr) { - @throw [[RiveException alloc] initWithName:@"NoStateMachineFound" reason:[NSString stringWithFormat: @"No State Machine found with name %@.", name] userInfo:nil]; + *error = [NSError errorWithDomain:RiveErrorDomain code:RiveNoStateMachineFound userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat: @"No State Machine found with name %@.", name], @"name": @"NoStateMachineFound"}]; + return nil; } return [[RiveStateMachine alloc] initWithStateMachine: machine]; } - (NSArray *)stateMachineNames{ NSMutableArray *stateMachineNames = [NSMutableArray array]; - for (NSUInteger i=0; i<[self stateMachineCount]; i++){ - [stateMachineNames addObject:[[self stateMachineFromIndex: i] name]]; + [stateMachineNames addObject:[[self stateMachineFromIndex:i error:nil] name]]; } return stateMachineNames; } diff --git a/Source/Renderer/RiveFile.mm b/Source/Renderer/RiveFile.mm index 0249f374..b171a0a3 100644 --- a/Source/Renderer/RiveFile.mm +++ b/Source/Renderer/RiveFile.mm @@ -31,7 +31,7 @@ @implementation RiveFile { + (uint)majorVersion { return UInt8(rive::File::majorVersion); } + (uint)minorVersion { return UInt8(rive::File::minorVersion); } -- (nullable instancetype)initWithByteArray:(NSArray *)array { +- (nullable instancetype)initWithByteArray:(NSArray *)array error:(NSError**)error { if (self = [super init]) { UInt8* bytes; @try { @@ -41,7 +41,10 @@ - (nullable instancetype)initWithByteArray:(NSArray *)array { bytes[index] = number.unsignedIntValue; }]; rive::BinaryReader reader = [self getReader:bytes byteLength:array.count]; - [self import:reader]; + BOOL ok = [self import:reader error:error]; + if (!ok) { + return nil; + } self.isLoaded = true; } @finally { @@ -53,10 +56,13 @@ - (nullable instancetype)initWithByteArray:(NSArray *)array { return nil; } -- (nullable instancetype)initWithBytes:(UInt8 *)bytes byteLength:(UInt64)length { +- (nullable instancetype)initWithBytes:(UInt8 *)bytes byteLength:(UInt64)length error:(NSError**)error { if (self = [super init]) { rive::BinaryReader reader = [self getReader:bytes byteLength:length]; - [self import:reader]; + BOOL ok = [self import:reader error:error]; + if (!ok) { + return nil; + } self.isLoaded = true; return self; } @@ -66,20 +72,19 @@ - (nullable instancetype)initWithBytes:(UInt8 *)bytes byteLength:(UInt64)length /* * Creates a RiveFile from a binary resource */ -- (nullable instancetype)initWithResource:(NSString *)resourceName withExtension:(NSString *)extension { +- (nullable instancetype)initWithResource:(NSString *)resourceName withExtension:(NSString *)extension error:(NSError**)error { NSString *filepath = [[NSBundle mainBundle] pathForResource:resourceName ofType:extension]; NSURL *fileUrl = [NSURL fileURLWithPath:filepath]; NSData *fileData = [NSData dataWithContentsOfURL:fileUrl]; UInt8 *bytePtr = (UInt8 *)[fileData bytes]; - - return [self initWithBytes:bytePtr byteLength:fileData.length]; + return [self initWithBytes:bytePtr byteLength:fileData.length error:error]; } /* * Creates a RiveFile from a binary resource, and assumes the resource extension is '.riv' */ -- (nullable instancetype)initWithResource:(NSString *)resourceName { - return [self initWithResource:resourceName withExtension:@"riv"]; +- (nullable instancetype)initWithResource:(NSString *)resourceName error:(NSError**)error { + return [self initWithResource:resourceName withExtension:@"riv" error:error]; } /* @@ -100,12 +105,15 @@ - (nullable instancetype)initWithHttpUrl:(NSString *)url withDelegate:(idartboard(); if (artboard == nullptr) { - @throw [[RiveException alloc] initWithName:@"NoArtboardsFound" reason: @"No Artboards Found." userInfo:nil]; + *error = [NSError errorWithDomain:RiveErrorDomain code:RiveNoArtboardsFound userInfo:@{NSLocalizedDescriptionKey: @"No Artboards Found.", @"name": @"NoArtboardsFound"}]; + return nil; } else { return [[RiveArtboard alloc] initWithArtboard: artboard]; } - } - (NSInteger)artboardCount { return riveFile->artboardCount(); } -- (RiveArtboard *)artboardFromIndex:(NSInteger)index { +- (RiveArtboard *)artboardFromIndex:(NSInteger)index error:(NSError**)error { if (index >= [self artboardCount]) { - @throw [[RiveException alloc] initWithName:@"NoArtboardFound" reason:[NSString stringWithFormat: @"No Artboard Found at index %ld.", (long)index] userInfo:nil]; + *error = [NSError errorWithDomain:RiveErrorDomain code:RiveNoArtboardFound userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat: @"No Artboard Found at index %ld.", (long)index], @"name": @"NoArtboardFound"}]; + return nil; } return [[RiveArtboard alloc] initWithArtboard: reinterpret_cast(riveFile->artboard(index))]; } -- (RiveArtboard *)artboardFromName:(NSString *)name { +- (RiveArtboard *)artboardFromName:(NSString *)name error:(NSError**)error { std::string stdName = std::string([name UTF8String]); rive::Artboard *artboard = riveFile->artboard(stdName); if (artboard == nullptr) { - @throw [[RiveException alloc] initWithName:@"NoArtboardFound" reason:[NSString stringWithFormat: @"No Artboard Found with name %@.", name] userInfo:nil]; + *error = [NSError errorWithDomain:RiveErrorDomain code:RiveNoArtboardFound userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat: @"No Artboard Found with name %@.", name], @"name": @"NoArtboardFound"}]; + return nil; } else { return [[RiveArtboard alloc] initWithArtboard: artboard]; } @@ -176,8 +188,7 @@ - (NSArray *)artboardNames { NSMutableArray *artboardNames = [NSMutableArray array]; for (NSUInteger i=0; i<[self artboardCount]; i++) { - NSString* name = [[self artboardFromIndex: i] name]; - [artboardNames addObject:name]; + [artboardNames addObject:[[self artboardFromIndex: i error:nil] name]]; } return artboardNames; } diff --git a/Source/Renderer/RiveStateMachine.mm b/Source/Renderer/RiveStateMachine.mm index 04a54bbe..4760e51d 100644 --- a/Source/Renderer/RiveStateMachine.mm +++ b/Source/Renderer/RiveStateMachine.mm @@ -47,7 +47,7 @@ - (RiveStateMachineInstance *)instance { return [[RiveStateMachineInstance alloc] initWithStateMachine: stateMachine]; } -- (RiveStateMachineInput *)_convertInput:(const rive::StateMachineInput *)input{ +- (RiveStateMachineInput *)_convertInput:(const rive::StateMachineInput *)input error:(NSError**)error { if (input->is()){ return [[RiveStateMachineBoolInput alloc] initWithStateMachineInput: input]; } @@ -58,35 +58,36 @@ - (RiveStateMachineInput *)_convertInput:(const rive::StateMachineInput *)input{ return [[RiveStateMachineTriggerInput alloc] initWithStateMachineInput: input]; } else { - @throw [[RiveException alloc] initWithName:@"UnkownInput" reason: @"Unknown State Machine Input" userInfo:nil]; + *error = [NSError errorWithDomain:RiveErrorDomain code:RiveUnknownStateMachineInput userInfo:@{NSLocalizedDescriptionKey: @"Unknown State Machine Input", @"name": @"UnknownStateMachineInput"}]; + return nil; } } // Creates a new instance of this state machine -- (RiveStateMachineInput *)inputFromIndex:(NSInteger)index { +- (RiveStateMachineInput *)inputFromIndex:(NSInteger)index error:(NSError**)error { if (index >= [self inputCount]) { - @throw [[RiveException alloc] initWithName:@"NoStateMachineInputFound" reason:[NSString stringWithFormat: @"No Input found at index %ld.", (long)index] userInfo:nil]; + *error = [NSError errorWithDomain:RiveErrorDomain code:RiveNoStateMachineInputFound userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat: @"No Input found at index %ld.", (long)index], @"name": @"NoStateMachineInputFound"}]; + return nil; } - return [self _convertInput: stateMachine->input(index) ]; + return [self _convertInput: stateMachine->input(index) error:error]; } // Creates a new instance of this state machine -- (RiveStateMachineInput *)inputFromName:(NSString*)name { - +- (RiveStateMachineInput *)inputFromName:(NSString*)name error:(NSError**)error { std::string stdName = std::string([name UTF8String]); const rive::StateMachineInput *stateMachineInput = stateMachine->input(stdName); if (stateMachineInput == nullptr) { - @throw [[RiveException alloc] initWithName:@"NoStateMachineInputFound" reason:[NSString stringWithFormat: @"No State Machine Input found with name %@.", name] userInfo:nil]; + *error = [NSError errorWithDomain:RiveErrorDomain code:RiveNoStateMachineInputFound userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat: @"No State Machine Input found with name %@.", name], @"name": @"NoStateMachineInputFound"}]; + return nil; } else { - return [self _convertInput: stateMachineInput]; + return [self _convertInput: stateMachineInput error:error]; } } - (NSArray *)inputNames{ NSMutableArray *inputNames = [NSMutableArray array]; - for (NSUInteger i=0; i<[self inputCount]; i++){ - [inputNames addObject:[[self inputFromIndex: i] name]]; + [inputNames addObject:[[self inputFromIndex:i error:nil] name]]; } return inputNames; } diff --git a/Source/Renderer/RiveStateMachineInstance.mm b/Source/Renderer/RiveStateMachineInstance.mm index d5b61e97..d72cc8b5 100644 --- a/Source/Renderer/RiveStateMachineInstance.mm +++ b/Source/Renderer/RiveStateMachineInstance.mm @@ -112,7 +112,7 @@ - (NSInteger)inputCount{ return instance->inputCount(); } -- (RiveSMIInput *)_convertInput:(const rive::SMIInput *)input{ +- (RiveSMIInput *)_convertInput:(const rive::SMIInput *)input error:(NSError**)error { if (input->input()->is()){ return [[RiveSMIBool alloc] initWithSMIInput: input]; } @@ -123,37 +123,43 @@ - (RiveSMIInput *)_convertInput:(const rive::SMIInput *)input{ return [[RiveSMITrigger alloc] initWithSMIInput: input]; } else { - @throw [[RiveException alloc] initWithName:@"UnkownInput" reason: @"Unknown State Machine Input" userInfo:nil]; + *error = [NSError errorWithDomain:RiveErrorDomain code:RiveUnknownStateMachineInput userInfo:@{NSLocalizedDescriptionKey: @"Unknown State Machine Input", @"name": @"UnknownStateMachineInput"}]; + return nil; } } // Creates a new instance of this state machine -- (RiveSMIInput *)inputFromIndex:(NSInteger)index { +- (RiveSMIInput *)inputFromIndex:(NSInteger)index error:(NSError**)error { if (index >= [self inputCount]) { - @throw [[RiveException alloc] initWithName:@"NoStateMachineInputFound" reason:[NSString stringWithFormat: @"No Input found at index %ld.", (long)index] userInfo:nil]; + *error = [NSError errorWithDomain:RiveErrorDomain code:RiveNoStateMachineInputFound userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat: @"No Input found at index %ld.", (long)index], @"name": @"NoStateMachineInputFound"}]; + return nil; } - return [self _convertInput: instance->input(index) ]; + return [self _convertInput: instance->input(index) error:error]; } // Creates a new instance of this state machine -- (RiveSMIInput *)inputFromName:(NSString*)name { +- (RiveSMIInput *)inputFromName:(NSString*)name error:(NSError**)error { std::string stdName = std::string([name UTF8String]); RiveSMIInput* input = [RiveSMIInput alloc]; for (int i=0; i< [self inputCount]; i++) { - input = [self inputFromIndex: i]; + input = [self inputFromIndex: i error:error]; + if (input == nil) { + return nil; + } if ([[input name] isEqualToString: name]){ return input; } } - @throw [[RiveException alloc] initWithName:@"NoStateMachineInputFound" reason:[NSString stringWithFormat: @"No State Machine Input found with name %@.", name] userInfo:nil]; + *error = [NSError errorWithDomain:RiveErrorDomain code:RiveNoStateMachineInputFound userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat: @"No State Machine Input found with name %@.", name], @"name": @"NoStateMachineInputFound"}]; + return nil; } - (NSArray *)inputNames{ NSMutableArray *inputNames = [NSMutableArray array]; for (NSUInteger i=0; i<[self inputCount]; i++){ - [inputNames addObject:[[self inputFromIndex: i] name]]; + [inputNames addObject:[[self inputFromIndex: i error:nil] name]]; } return inputNames; } @@ -177,14 +183,14 @@ - (RiveLayerState *)_convertLayerState:(const rive::LayerState *)layerState{ } else { return [[RiveUnknownState alloc] initWithLayerState: layerState]; - // @throw [[RiveException alloc] initWithName:@"UnknownLayerState" reason: @"Unknown Layer State" userInfo:nil]; } } -- (RiveLayerState *)stateChangedFromIndex:(NSInteger)index{ +- (RiveLayerState *)stateChangedFromIndex:(NSInteger)index error:(NSError**)error { const rive::LayerState *layerState = instance->stateChangedByIndex(index); if (layerState == nullptr) { - @throw [[RiveException alloc] initWithName:@"NoStateChangeFound" reason:[NSString stringWithFormat: @"No State Changed found at index %ld.", (long)index] userInfo:nil]; + *error = [NSError errorWithDomain:RiveErrorDomain code:RiveNoStateChangeFound userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat: @"No State Changed found at index %ld.", (long)index], @"name": @"NoStateChangeFound"}]; + return nil; } else { return [self _convertLayerState: layerState]; } @@ -193,7 +199,7 @@ - (NSArray *)stateChanges{ NSMutableArray *inputNames = [NSMutableArray array]; for (NSUInteger i=0; i<[self stateChangedCount]; i++){ - [inputNames addObject:[[self stateChangedFromIndex: i] name]]; + [inputNames addObject:[[self stateChangedFromIndex: i error:nil] name]]; } return inputNames; } diff --git a/Source/Renderer/include/Rive.h b/Source/Renderer/include/Rive.h index 0a36735e..79cf5ed4 100644 --- a/Source/Renderer/include/Rive.h +++ b/Source/Renderer/include/Rive.h @@ -74,8 +74,22 @@ typedef NS_ENUM(NSInteger, Alignment) { alignmentBottomRight }; -@interface RiveException : NSException -@end +FOUNDATION_EXPORT NSString *const RiveErrorDomain; + +typedef NS_ENUM(NSInteger, RiveErrorCode) { + RiveNoArtboardsFound = 100, + RiveNoArtboardFound = 101, + RiveNoAnimations = 200, + RiveNoAnimationFound = 201, + RiveNoStateMachines = 300, + RiveNoStateMachineFound = 301, + RiveNoStateMachineInputFound = 400, + RiveUnknownStateMachineInput = 401, + RiveNoStateChangeFound = 402, + RiveUnsupportedVersion = 500, + RiveMalformedFile = 600, + RiveUnknownError = 700, +}; /* * RiveRenderer diff --git a/Source/Renderer/include/RiveArtboard.h b/Source/Renderer/include/RiveArtboard.h index 2cd2827b..37bc7c27 100644 --- a/Source/Renderer/include/RiveArtboard.h +++ b/Source/Renderer/include/RiveArtboard.h @@ -28,15 +28,15 @@ NS_ASSUME_NONNULL_BEGIN - (NSInteger)animationCount; - (NSArray *)animationNames; -- (RiveLinearAnimation *)firstAnimation; -- (RiveLinearAnimation *)animationFromIndex:(NSInteger)index; -- (RiveLinearAnimation *)animationFromName:(NSString *)name; +- (RiveLinearAnimation * __nullable)firstAnimation:(NSError **)error; +- (RiveLinearAnimation * __nullable)animationFromIndex:(NSInteger)index error:(NSError **)error; +- (RiveLinearAnimation * __nullable)animationFromName:(NSString *)name error:(NSError **)error; - (NSInteger)stateMachineCount; - (NSArray *)stateMachineNames; -- (RiveStateMachine *)firstStateMachine; -- (RiveStateMachine *)stateMachineFromIndex:(NSInteger)index; -- (RiveStateMachine *)stateMachineFromName:(NSString *)name; +- (RiveStateMachine * __nullable)firstStateMachine:(NSError **)error; +- (RiveStateMachine * __nullable)stateMachineFromIndex:(NSInteger)index error:(NSError **)error; +- (RiveStateMachine * __nullable)stateMachineFromName:(NSString *)name error:(NSError **)error; - (void)advanceBy:(double)elapsedSeconds; - (void)draw:(RiveRenderer *)renderer; diff --git a/Source/Renderer/include/RiveFile.h b/Source/Renderer/include/RiveFile.h index c8be8a1f..5c541fcd 100644 --- a/Source/Renderer/include/RiveFile.h +++ b/Source/Renderer/include/RiveFile.h @@ -31,23 +31,23 @@ NS_ASSUME_NONNULL_BEGIN // Delegate for calling when a file has finished loading @property id delegate; -- (nullable instancetype)initWithByteArray:(NSArray *)bytes; -- (nullable instancetype)initWithBytes:(UInt8 *)bytes byteLength:(UInt64)length; -- (nullable instancetype)initWithResource:(NSString *)resourceName withExtension:(NSString *)extension; -- (nullable instancetype)initWithResource:(NSString *)resourceName; +- (nullable instancetype)initWithByteArray:(NSArray *)bytes error:(NSError**)error; +- (nullable instancetype)initWithBytes:(UInt8 *)bytes byteLength:(UInt64)length error:(NSError**)error; +- (nullable instancetype)initWithResource:(NSString *)resourceName withExtension:(NSString *)extension error:(NSError**)error; +- (nullable instancetype)initWithResource:(NSString *)resourceName error:(NSError**)error; - (nullable instancetype)initWithHttpUrl:(NSString *)url withDelegate:(id)delegate; // Returns a reference to the default artboard -- (RiveArtboard *)artboard; +- (RiveArtboard * __nullable)artboard:(NSError**)error; // Returns the number of artboards in the file - (NSInteger)artboardCount; // Returns the artboard by its index -- (RiveArtboard *)artboardFromIndex:(NSInteger)index; +- (RiveArtboard * __nullable)artboardFromIndex:(NSInteger)index error:(NSError**)error; // Returns the artboard by its name -- (RiveArtboard *)artboardFromName:(NSString *)name; +- (RiveArtboard * __nullable)artboardFromName:(NSString *)name error:(NSError**)error; // Returns the names of all artboards in the file. - (NSArray *)artboardNames; @@ -58,7 +58,7 @@ NS_ASSUME_NONNULL_BEGIN * Delegate to inform when a rive file is loaded */ @protocol RiveFileDelegate -- (void)riveFileDidLoad:(RiveFile *)riveFile; +- (BOOL)riveFileDidLoad:(RiveFile *)riveFile error:(NSError**)error; @end NS_ASSUME_NONNULL_END diff --git a/Source/Renderer/include/RiveStateMachine.h b/Source/Renderer/include/RiveStateMachine.h index 13156457..ef6d54d7 100644 --- a/Source/Renderer/include/RiveStateMachine.h +++ b/Source/Renderer/include/RiveStateMachine.h @@ -26,8 +26,8 @@ NS_ASSUME_NONNULL_BEGIN - (NSInteger)inputCount; - (RiveStateMachineInstance *)instance; - (NSArray *)inputNames; -- (RiveStateMachineInput *)inputFromIndex:(NSInteger)index; -- (RiveStateMachineInput *)inputFromName:(NSString*)name; +- (RiveStateMachineInput * __nullable)inputFromIndex:(NSInteger)index error:(NSError**)error; +- (RiveStateMachineInput * __nullable)inputFromName:(NSString*)name error:(NSError**)error; @end NS_ASSUME_NONNULL_END diff --git a/Source/Renderer/include/RiveStateMachineInstance.h b/Source/Renderer/include/RiveStateMachineInstance.h index a2d22f66..72fff128 100644 --- a/Source/Renderer/include/RiveStateMachineInstance.h +++ b/Source/Renderer/include/RiveStateMachineInstance.h @@ -34,10 +34,10 @@ NS_ASSUME_NONNULL_BEGIN - (const RiveSMINumber *)getNumber:(NSString*)name; - (NSArray *)inputNames; - (NSInteger)inputCount; -- (RiveSMIInput *)inputFromIndex:(NSInteger)index; -- (RiveSMIInput *)inputFromName:(NSString*)name; +- (RiveSMIInput * __nullable)inputFromIndex:(NSInteger)index error:(NSError**)error; +- (RiveSMIInput * __nullable)inputFromName:(NSString*)name error:(NSError**)error; - (NSInteger)stateChangedCount; -- (RiveLayerState *)stateChangedFromIndex:(NSInteger)index; +- (RiveLayerState * __nullable)stateChangedFromIndex:(NSInteger)index error:(NSError**)error; - (NSArray *)stateChanges; @end diff --git a/Source/Views/RiveView.swift b/Source/Views/RiveView.swift index 982bd170..9e9094cb 100644 --- a/Source/Views/RiveView.swift +++ b/Source/Views/RiveView.swift @@ -184,7 +184,7 @@ public class RiveView: UIView { stopDelegate: StopDelegate? = nil, inputsDelegate: InputsDelegate? = nil, stateChangeDelegate: StateChangeDelegate? = nil - ) { + ) throws { super.init(frame: .zero) self.fit = fit self.alignment = alignment @@ -194,7 +194,7 @@ public class RiveView: UIView { self.stopDelegate = stopDelegate self.inputsDelegate = inputsDelegate self.stateChangeDelegate = stateChangeDelegate - self.configure(riveFile, andArtboard: artboard, andAnimation: animation, andStateMachine: stateMachine, andAutoPlay: autoplay) + try self.configure(riveFile, andArtboard: artboard, andAnimation: animation, andStateMachine: stateMachine, andAutoPlay: autoplay) } /// Minimalist constructor, call `.configure` to customize the `RiveView` later. @@ -209,8 +209,8 @@ public class RiveView: UIView { // Handle when a Rive file is asynchronously loaded extension RiveView: RiveFileDelegate { - public func riveFileDidLoad(_ riveFile: RiveFile) { - self.configure(riveFile); + public func riveFileDidLoad(_ riveFile: RiveFile) throws { + try self.configure(riveFile) } } @@ -256,7 +256,7 @@ extension RiveView { andAnimation animation: String?=nil, andStateMachine stateMachine: String?=nil, andAutoPlay autoPlay: Bool=true - ) { + ) throws { clear() // Always save the config options to preserve for reset @@ -289,9 +289,9 @@ extension RiveView { let rootArtboard: RiveArtboard? if let artboardName = configOptions?.artboard { - rootArtboard = riveFile.artboard(fromName:artboardName) + rootArtboard = try riveFile.artboard(fromName:artboardName) } else { - rootArtboard = riveFile.artboard() + rootArtboard = try riveFile.artboard() } guard let artboard = rootArtboard else { fatalError("No default artboard exists") @@ -307,11 +307,11 @@ extension RiveView { // Start the animation loop if autoPlay { if let animationName = configOptions?.animation { - play(animationName: animationName) + try play(animationName: animationName) } else if let stateMachineName = configOptions?.stateMachine { - play(animationName: stateMachineName, isStateMachine: true) + try play(animationName: stateMachineName, isStateMachine: true) } else { - play() + try play() } } else { advance(delta: 0) @@ -367,12 +367,12 @@ extension RiveView { /// Returns a list of valid state machine inputs for any instanced state machine /// - Returns a list of valid state machine inputs and their types - open func stateMachineInputs() -> [StateMachineInput] { + open func stateMachineInputs() throws -> [StateMachineInput] { var inputs: [StateMachineInput] = [] - stateMachines.forEach({ machine in + try stateMachines.forEach({ machine in let inputCount = machine.inputCount() - for i in 0...inputCount-1 { - let input = machine.input(from: i) + for i in 0.. [RiveStateMachineInstance]{ + ) throws -> [RiveStateMachineInstance]{ let stateMachineInstances = _stateMachines(animationName: animationName) if (stateMachineInstances.isEmpty){ guard let guardedArtboard=_artboard else { return [] } - let stateMachineInstance = guardedArtboard.stateMachine(fromName: animationName).instance() + let stateMachineInstance = try guardedArtboard.stateMachine(fromName: animationName).instance() return [stateMachineInstance] } return stateMachineInstances @@ -718,14 +718,14 @@ extension RiveView { private func _getOrCreateLinearAnimationInstances( animationName: String - ) -> [RiveLinearAnimationInstance]{ + ) throws -> [RiveLinearAnimationInstance] { let animationInstances = _animations(animationName: animationName) if (animationInstances.isEmpty){ guard let guardedArtboard=_artboard else { return [] } - let animationInstance = guardedArtboard.animation(fromName:animationName).instance() + let animationInstance = try guardedArtboard.animation(fromName:animationName).instance() return [animationInstance] } return animationInstances @@ -736,14 +736,14 @@ extension RiveView { loop: Loop = .loopAuto, direction: Direction = .directionAuto, isStateMachine: Bool = false - ){ + ) throws { if (isStateMachine) { - let stateMachineInstances = _getOrCreateStateMachines(animationName:animationName) - stateMachineInstances.forEach { stateMachineInstance in - _play(stateMachineInstance) + let stateMachineInstances = try _getOrCreateStateMachines(animationName:animationName) + try stateMachineInstances.forEach { stateMachineInstance in + try _play(stateMachineInstance) } } else { - let animationInstances = _getOrCreateLinearAnimationInstances(animationName: animationName) + let animationInstances = try _getOrCreateLinearAnimationInstances(animationName: animationName) animationInstances.forEach { animationInstance in _play( @@ -822,7 +822,7 @@ extension RiveView { } } - private func _play(_ stateMachineInstance: RiveStateMachineInstance) { + private func _play(_ stateMachineInstance: RiveStateMachineInstance) throws { if (!stateMachines.contains(stateMachineInstance)) { stateMachines.append( stateMachineInstance @@ -831,7 +831,8 @@ extension RiveView { playingStateMachines.insert(stateMachineInstance) eventQueue.add( { self.playDelegate?.play(stateMachineInstance.name(),isStateMachine:true) } ) - eventQueue.add( { self.inputsDelegate?.inputs(self.stateMachineInputs()) } ) + let inputs = try self.stateMachineInputs() + eventQueue.add( { self.inputsDelegate?.inputs(inputs) } ) } /// Pauses a playing state machine diff --git a/Tests/RiveAnimationConfigurationsTest.mm b/Tests/RiveAnimationConfigurationsTest.mm index bf7af1ee..25c460af 100644 --- a/Tests/RiveAnimationConfigurationsTest.mm +++ b/Tests/RiveAnimationConfigurationsTest.mm @@ -21,9 +21,10 @@ @implementation RiveAnimationConfigurationsTest * Test loop mode -> loop */ - (void)testLoop { - RiveFile* file = [Util loadTestFile:@"animationconfigurations"]; - RiveArtboard* artboard = [file artboard]; - RiveLinearAnimation* animation = [artboard animationFromName:@"loop"]; + RiveFile* file = [Util loadTestFile:@"animationconfigurations" error:nil]; + RiveArtboard* artboard = [file artboard:nil]; + + RiveLinearAnimation* animation = [artboard animationFromName:@"loop" error:nil]; XCTAssertEqual([animation loop], Loop::loopLoop); } @@ -32,10 +33,11 @@ - (void)testLoop { * Test loop mode -> pingpong */ - (void)testPingPong { - RiveFile* file = [Util loadTestFile:@"animationconfigurations"]; - RiveArtboard* artboard = [file artboard]; - RiveLinearAnimation* animation = [artboard animationFromName:@"pingpong"]; + RiveFile* file = [Util loadTestFile:@"animationconfigurations" error:nil]; + RiveArtboard* artboard = [file artboard:nil]; + RiveLinearAnimation* animation = [artboard animationFromName:@"pingpong" error:nil]; + XCTAssertEqual([animation loop], Loop::loopPingPong); } @@ -43,9 +45,10 @@ - (void)testPingPong { * Test loop mode -> oneShot */ - (void)testOneShot { - RiveFile* file = [Util loadTestFile:@"animationconfigurations"]; - RiveArtboard* artboard = [file artboard]; - RiveLinearAnimation* animation = [artboard animationFromName:@"oneshot"]; + RiveFile* file = [Util loadTestFile:@"animationconfigurations" error:nil]; + RiveArtboard* artboard = [file artboard:nil]; + + RiveLinearAnimation* animation = [artboard animationFromName:@"oneshot" error:nil]; XCTAssertEqual([animation loop], Loop::loopOneShot); } @@ -54,9 +57,10 @@ - (void)testOneShot { * Test duration -> 1sec/ 60fps */ - (void)testDuration1sec60fps { - RiveFile* file = [Util loadTestFile:@"animationconfigurations"]; - RiveArtboard* artboard = [file artboard]; - RiveLinearAnimation* animation = [artboard animationFromName:@"1sec60fps"]; + RiveFile* file = [Util loadTestFile:@"animationconfigurations" error:nil]; + RiveArtboard* artboard = [file artboard:nil]; + + RiveLinearAnimation* animation = [artboard animationFromName:@"1sec60fps" error:nil]; XCTAssertEqual([animation duration], 60); XCTAssertEqual([animation effectiveDuration], 60); @@ -69,9 +73,10 @@ - (void)testDuration1sec60fps { * Test duration -> 1sec/ 120fps */ - (void)testDuration1sec120fps { - RiveFile* file = [Util loadTestFile:@"animationconfigurations"]; - RiveArtboard* artboard = [file artboard]; - RiveLinearAnimation* animation = [artboard animationFromName:@"1sec120fps"]; + RiveFile* file = [Util loadTestFile:@"animationconfigurations" error:nil]; + RiveArtboard* artboard = [file artboard:nil]; + + RiveLinearAnimation* animation = [artboard animationFromName:@"1sec120fps" error:nil]; XCTAssertEqual([animation duration], 120); XCTAssertEqual([animation effectiveDuration], 120); @@ -84,9 +89,10 @@ - (void)testDuration1sec120fps { * Test duration -> 1sec/ 60fps f30->f50 */ - (void)testDuration1sec60fpsf30f50 { - RiveFile* file = [Util loadTestFile:@"animationconfigurations"]; - RiveArtboard* artboard = [file artboard]; - RiveLinearAnimation* animation = [artboard animationFromName:@"1sec60fps_f30f50"]; + RiveFile* file = [Util loadTestFile:@"animationconfigurations" error:nil]; + RiveArtboard* artboard = [file artboard:nil]; + + RiveLinearAnimation* animation = [artboard animationFromName:@"1sec60fps_f30f50" error:nil]; XCTAssertEqual([animation duration], 60); XCTAssertEqual([animation effectiveDuration], 20); @@ -99,9 +105,10 @@ - (void)testDuration1sec60fpsf30f50 { * Test duration -> 1sec/ 120fps f50->f80 */ - (void)testDuration1sec120fpsf50f80 { - RiveFile* file = [Util loadTestFile:@"animationconfigurations"]; - RiveArtboard* artboard = [file artboard]; - RiveLinearAnimation* animation = [artboard animationFromName:@"1sec120fps_f50f80"]; + RiveFile* file = [Util loadTestFile:@"animationconfigurations" error:nil]; + RiveArtboard* artboard = [file artboard:nil]; + + RiveLinearAnimation* animation = [artboard animationFromName:@"1sec120fps_f50f80" error:nil]; XCTAssertEqual([animation duration], 120); XCTAssertEqual([animation effectiveDuration], 30); @@ -110,6 +117,4 @@ - (void)testDuration1sec120fpsf50f80 { XCTAssertEqual([animation workEnd], 80); } - - @end diff --git a/Tests/RiveAnimationLoadTest.mm b/Tests/RiveAnimationLoadTest.mm index aefd47db..1c5ed231 100644 --- a/Tests/RiveAnimationLoadTest.mm +++ b/Tests/RiveAnimationLoadTest.mm @@ -22,12 +22,18 @@ @implementation RiveAnimationLoadTest * Test first Animation */ - (void)testAnimationFirstAnimation { - RiveFile* file = [Util loadTestFile:@"multipleartboards"]; - RiveArtboard* artboard = [file artboardFromName:@"artboard1"]; + NSError* error = nil; + RiveFile* file = [Util loadTestFile:@"multipleartboards" error:&error]; + RiveArtboard* artboard = [file artboardFromName:@"artboard1" error:&error]; + + RiveLinearAnimation* animation = [artboard firstAnimation:&error]; + XCTAssertNil(error); + + RiveLinearAnimation* animationByIndex = [artboard animationFromIndex:0 error:&error]; + XCTAssertNil(error); - RiveLinearAnimation* animation = [artboard firstAnimation]; - RiveLinearAnimation* animationByIndex = [artboard animationFromIndex:0]; - RiveLinearAnimation* animationByName = [artboard animationFromName:@"artboard1animation1"]; + RiveLinearAnimation* animationByName = [artboard animationFromName:@"artboard1animation1" error:&error]; + XCTAssertNil(error); XCTAssertTrue([animation.name isEqualToString:animationByIndex.name]); XCTAssertTrue([animation.name isEqualToString:animationByName.name]); @@ -40,19 +46,24 @@ - (void)testAnimationFirstAnimation { * Test second Animation */ - (void)testAnimationSecondAnimation { - RiveFile* file = [Util loadTestFile:@"multipleartboards"]; - RiveArtboard* artboard = [file artboardFromName:@"artboard2"]; + NSError* error = nil; + RiveFile* file = [Util loadTestFile:@"multipleartboards" error:&error]; + RiveArtboard* artboard = [file artboardFromName:@"artboard2" error:&error]; - RiveLinearAnimation* animation = [artboard firstAnimation]; - RiveLinearAnimation* animationByIndex = [artboard animationFromIndex:0]; - RiveLinearAnimation* animationByName = [artboard animationFromName:@"artboard2animation1"]; + RiveLinearAnimation* animation = [artboard firstAnimation:&error]; + XCTAssertNil(error); + RiveLinearAnimation* animationByIndex = [artboard animationFromIndex:0 error:&error]; + XCTAssertNil(error); + RiveLinearAnimation* animationByName = [artboard animationFromName:@"artboard2animation1" error:&error]; + XCTAssertNil(error); XCTAssertTrue([animation.name isEqualToString:animationByIndex.name]); XCTAssertTrue([animation.name isEqualToString:animationByName.name]); - - RiveLinearAnimation* animation2ByIndex = [artboard animationFromIndex:1]; - RiveLinearAnimation* animation2ByName = [artboard animationFromName:@"artboard2animation2"]; + RiveLinearAnimation* animation2ByIndex = [artboard animationFromIndex:1 error:&error]; + XCTAssertNil(error); + RiveLinearAnimation* animation2ByName = [artboard animationFromName:@"artboard2animation2" error:&error]; + XCTAssertNil(error); XCTAssertTrue([animation2ByIndex.name isEqualToString:animation2ByName.name]); @@ -65,8 +76,8 @@ - (void)testAnimationSecondAnimation { * Test no animations */ - (void)testArtboardHasNoAnimations { - RiveFile* file = [Util loadTestFile:@"noanimation"]; - RiveArtboard* artboard = [file artboard]; + RiveFile* file = [Util loadTestFile:@"noanimation" error:nil]; + RiveArtboard* artboard = [file artboard:nil]; XCTAssertEqual([artboard animationCount], 0); @@ -77,44 +88,52 @@ - (void)testArtboardHasNoAnimations { * Test access nothing */ - (void)testArtboardAnimationDoesntExist { - RiveFile* file = [Util loadTestFile:@"noanimation"]; - RiveArtboard* artboard = [file artboard]; - XCTAssertThrowsSpecificNamed( - [artboard firstAnimation], - RiveException, - @"NoAnimations" - ); + RiveFile* file = [Util loadTestFile:@"noanimation" error:nil]; + RiveArtboard* artboard = [file artboard:nil]; + + NSError* error = nil; + RiveLinearAnimation* animation = [artboard firstAnimation:&error]; + + XCTAssertNil(animation); + XCTAssertNotNil(error); + XCTAssertEqualObjects([error domain], @"rive.app.ios.runtime"); + XCTAssertEqualObjects([[error userInfo] valueForKey:@"name"], @"NoAnimations"); + XCTAssertEqual([error code], 200); } /* * Test access index doesnt exist */ - (void)testArtboardAnimationAtIndexDoesntExist { - RiveFile* file = [Util loadTestFile:@"noanimation"]; - RiveArtboard* artboard = [file artboard]; - - - XCTAssertThrowsSpecificNamed( - [artboard animationFromIndex:0], - RiveException, - @"NoAnimationFound" - ); + RiveFile* file = [Util loadTestFile:@"noanimation" error:nil]; + RiveArtboard* artboard = [file artboard:nil]; + + NSError* error = nil; + RiveLinearAnimation* animation = [artboard animationFromIndex:0 error:&error]; + XCTAssertNil(animation); + + XCTAssertNotNil(error); + XCTAssertEqualObjects([error domain], @"rive.app.ios.runtime"); + XCTAssertEqualObjects([[error userInfo] valueForKey:@"name"], @"NoAnimationFound"); + XCTAssertEqual([error code], 201); } /* * Test access name doesnt exist */ - (void)testArtboardAnimationWithNameDoesntExist { - RiveFile* file = [Util loadTestFile:@"noanimation"]; - RiveArtboard* artboard = [file artboard]; + RiveFile* file = [Util loadTestFile:@"noanimation" error:nil]; + RiveArtboard* artboard = [file artboard:nil]; - - XCTAssertThrowsSpecificNamed( - [artboard animationFromName:@"boo"], - RiveException, - @"NoAnimationFound" - ); + NSError* error = nil; + RiveLinearAnimation* animation = [artboard animationFromName:@"boo" error:&error]; + XCTAssertNil(animation); + + XCTAssertNotNil(error); + XCTAssertEqualObjects([error domain], @"rive.app.ios.runtime"); + XCTAssertEqualObjects([[error userInfo] valueForKey:@"name"], @"NoAnimationFound"); + XCTAssertEqual([error code], 201); } @end diff --git a/Tests/RiveArtboardLoadTest.mm b/Tests/RiveArtboardLoadTest.mm index 024fcab6..8549e2ce 100644 --- a/Tests/RiveArtboardLoadTest.mm +++ b/Tests/RiveArtboardLoadTest.mm @@ -20,13 +20,12 @@ @implementation RiveArtboardLoadTest * Test loading multiple artboards */ - (void)testLoadArtboard { - RiveFile* file = [Util loadTestFile:@"multipleartboards"]; + RiveFile* file = [Util loadTestFile:@"multipleartboards" error:nil]; XCTAssertEqual([file artboardCount], 2); - XCTAssertEqual([[file artboardFromIndex:1] name], [[file artboardFromName:@"artboard1"] name]); - XCTAssertEqual([[file artboardFromIndex:0] name], [[file artboardFromName:@"artboard2"] name]); - + XCTAssertEqual([[file artboardFromIndex:1 error:nil] name], [[file artboardFromName:@"artboard1" error:nil] name]); + XCTAssertEqual([[file artboardFromIndex:0 error:nil] name], [[file artboardFromName:@"artboard2" error:nil] name]); NSArray *target = [NSArray arrayWithObjects:@"artboard2", @"artboard1", nil]; XCTAssertTrue([[file artboardNames] isEqualToArray: target]); @@ -36,7 +35,7 @@ - (void)testLoadArtboard { * Test no animations */ - (void)testNoArtboard { - RiveFile* file = [Util loadTestFile:@"noartboard"]; + RiveFile* file = [Util loadTestFile:@"noartboard" error:nil]; XCTAssertEqual([file artboardCount], 0); XCTAssertTrue([[file artboardNames] isEqualToArray: [NSArray array]]); @@ -46,55 +45,64 @@ - (void)testNoArtboard { * Test access first */ - (void)testNoArtboardAccessFirst { - RiveFile* file = [Util loadTestFile:@"noartboard"]; + RiveFile* file = [Util loadTestFile:@"noartboard" error:nil]; + + NSError* error = nil; + RiveArtboard* artboard = [file artboard:&error]; - XCTAssertThrowsSpecificNamed( - [file artboard], - RiveException, - @"NoArtboardsFound" - ); + XCTAssertNil(artboard); + XCTAssertNotNil(error); + XCTAssertEqualObjects([error domain], @"rive.app.ios.runtime"); + XCTAssertEqual([error code], 100); + XCTAssertEqualObjects([[error userInfo] valueForKey:@"name"], @"NoArtboardsFound"); } /* * Test access index doesnt exist */ - (void)testNoArtboardAccessFromIndex { - RiveFile* file = [Util loadTestFile:@"noartboard"]; + RiveFile* file = [Util loadTestFile:@"noartboard" error:nil]; + + NSError* error = nil; + RiveArtboard* artboard = [file artboardFromIndex:0 error:&error]; - XCTAssertThrowsSpecificNamed( - [file artboardFromIndex:0], - RiveException, - @"NoArtboardFound" - ); + XCTAssertNil(artboard); + XCTAssertNotNil(error); + XCTAssertEqualObjects([error domain], @"rive.app.ios.runtime"); + XCTAssertEqual([error code], 101); + XCTAssertEqualObjects([[error userInfo] valueForKey:@"name"], @"NoArtboardFound"); } /* * Test access name doesnt exist */ - (void)testNoArtboardAccessFromName { - RiveFile* file = [Util loadTestFile:@"noartboard"]; + RiveFile* file = [Util loadTestFile:@"noartboard" error:nil]; - XCTAssertThrowsSpecificNamed( - [file artboardFromName:@"boo"], - RiveException, - @"NoArtboardFound" - ); + NSError* error = nil; + RiveArtboard* artboard = [file artboardFromName:@"boo" error:&error]; + + XCTAssertNil(artboard); + XCTAssertNotNil(error); + XCTAssertEqualObjects([error domain], @"rive.app.ios.runtime"); + XCTAssertEqual([error code], 101); + XCTAssertEqualObjects([[error userInfo] valueForKey:@"name"], @"NoArtboardFound"); } /* * Test access a bunch of artboards */ - (void)testLoadArtboardsForEachShape { - RiveFile* file = [Util loadTestFile:@"shapes"]; + RiveFile* file = [Util loadTestFile:@"shapes" error:nil]; - [file artboardFromName:@"rect"]; - [file artboardFromName:@"ellipse"]; - [file artboardFromName:@"triangle"]; - [file artboardFromName:@"polygon"]; - [file artboardFromName:@"star"]; - [file artboardFromName:@"pen"]; - [file artboardFromName:@"groups"]; - [file artboardFromName:@"bone"]; + [file artboardFromName:@"rect" error:nil]; + [file artboardFromName:@"ellipse" error:nil]; + [file artboardFromName:@"triangle" error:nil]; + [file artboardFromName:@"polygon" error:nil]; + [file artboardFromName:@"star" error:nil]; + [file artboardFromName:@"pen" error:nil]; + [file artboardFromName:@"groups" error:nil]; + [file artboardFromName:@"bone" error:nil]; } @end diff --git a/Tests/RiveDelegatesTest.swift b/Tests/RiveDelegatesTest.swift index 2c976e6c..5268da7b 100644 --- a/Tests/RiveDelegatesTest.swift +++ b/Tests/RiveDelegatesTest.swift @@ -21,11 +21,9 @@ func getBytes(resourceName: String, resourceExt: String=".riv") -> [UInt8] { return [UInt8](data) } -func getRiveFile(resourceName: String, resourceExt: String=".riv") -> RiveFile{ +func getRiveFile(resourceName: String, resourceExt: String=".riv") throws -> RiveFile { let byteArray = getBytes(resourceName: resourceName, resourceExt: resourceExt) - guard let riveFile = RiveFile(byteArray: byteArray) else { - fatalError("Failed to import Rive File.") - } + let riveFile = try RiveFile(byteArray: byteArray) return riveFile } @@ -82,47 +80,47 @@ class MrDelegate: LoopDelegate, PlayDelegate, PauseDelegate, StopDelegate, State } class DelegatesTest: XCTestCase { - func testPlay(){ + func testPlay() throws { let delegate = MrDelegate() - let view = RiveView.init( + let view = try RiveView.init( riveFile: getRiveFile(resourceName:"multiple_animations"), autoplay: false, playDelegate: delegate ) - view.play(animationName: "one") + try view.play(animationName: "one") view.advance(delta:0) XCTAssertEqual(delegate.linearAnimaitonPlays.count, 1) } - func testPlayTwice(){ + func testPlayTwice() throws { let delegate = MrDelegate() - let view = RiveView.init( + let view = try RiveView.init( riveFile: getRiveFile(resourceName:"multiple_animations"), autoplay: false, playDelegate: delegate ) - view.play(animationName: "one") - view.play(animationName: "one") + try view.play(animationName: "one") + try view.play(animationName: "one") view.advance(delta:0) XCTAssertEqual(delegate.linearAnimaitonPlays.count, 2) } - func testPause(){ + func testPause() throws { let delegate = MrDelegate() - let view = RiveView.init( + let view = try RiveView.init( riveFile: getRiveFile(resourceName:"multiple_animations"), autoplay: false, pauseDelegate: delegate ) - view.play(animationName: "one") + try view.play(animationName: "one") view.pause(animationName: "one") view.advance(delta:0) XCTAssertEqual(delegate.linearAnimaitonPauses.count, 1) } - func testPauseWhenNotPlaying(){ + func testPauseWhenNotPlaying() throws { let delegate = MrDelegate() - let view = RiveView.init( + let view = try RiveView.init( riveFile: getRiveFile(resourceName:"multiple_animations"), autoplay: false, pauseDelegate: delegate @@ -132,22 +130,22 @@ class DelegatesTest: XCTestCase { XCTAssertEqual(delegate.linearAnimaitonPauses.count, 0) } - func testStop(){ + func testStop() throws { let delegate = MrDelegate() - let view = RiveView.init( + let view = try RiveView.init( riveFile: getRiveFile(resourceName:"multiple_animations"), autoplay: false, stopDelegate: delegate ) - view.play(animationName: "one") + try view.play(animationName: "one") view.stop(animationName: "one") view.advance(delta:0) XCTAssertEqual(delegate.linearAnimaitonStops.count, 1) } - func testStopNotMounted(){ + func testStopNotMounted() throws { let delegate = MrDelegate() - let view = RiveView.init( + let view = try RiveView.init( riveFile: getRiveFile(resourceName:"multiple_animations"), autoplay: false, stopDelegate: delegate @@ -158,23 +156,23 @@ class DelegatesTest: XCTestCase { XCTAssertEqual(delegate.linearAnimaitonStops.count, 0) } - func testStopPaused(){ + func testStopPaused() throws { let delegate = MrDelegate() - let view = RiveView.init( + let view = try RiveView.init( riveFile: getRiveFile(resourceName:"multiple_animations"), autoplay: false, stopDelegate: delegate ) - view.play(animationName: "one") + try view.play(animationName: "one") view.pause(animationName: "one") view.stop(animationName: "one") view.advance(delta:0) XCTAssertEqual(delegate.linearAnimaitonStops.count, 1) } - func testLoopOneShot(){ + func testLoopOneShot() throws { let delegate = MrDelegate() - let view = RiveView.init( + let view = try RiveView.init( riveFile: getRiveFile(resourceName:"multiple_animations"), autoplay: false, loopDelegate: delegate, @@ -183,7 +181,7 @@ class DelegatesTest: XCTestCase { stopDelegate: delegate ) - view.play(animationName: "one", loop: .loopOneShot) + try view.play(animationName: "one", loop: .loopOneShot) view.advance(delta:Double(view.animations.first!.animation().effectiveDurationInSeconds()+0.1)) // rough. we need an extra advance to flush the stop. view.advance(delta:0.1) @@ -194,9 +192,9 @@ class DelegatesTest: XCTestCase { XCTAssertEqual(delegate.linearAnimaitonStops.count, 1) } - func testLoopLoop(){ + func testLoopLoop() throws { let delegate = MrDelegate() - let view = RiveView.init( + let view = try RiveView.init( riveFile: getRiveFile(resourceName:"multiple_animations"), autoplay: false, loopDelegate: delegate, @@ -205,7 +203,7 @@ class DelegatesTest: XCTestCase { stopDelegate: delegate ) - view.play(animationName: "one", loop: .loopLoop) + try view.play(animationName: "one", loop: .loopLoop) view.advance(delta:Double(view.animations.first!.animation().effectiveDurationInSeconds()+0.1)) XCTAssertEqual(delegate.loops.count, 1) @@ -214,9 +212,9 @@ class DelegatesTest: XCTestCase { XCTAssertEqual(delegate.linearAnimaitonStops.count, 0) } - func testLoopPingPong(){ + func testLoopPingPong() throws { let delegate = MrDelegate() - let view = RiveView.init( + let view = try RiveView.init( riveFile: getRiveFile(resourceName:"multiple_animations"), autoplay: false, loopDelegate: delegate, @@ -225,7 +223,7 @@ class DelegatesTest: XCTestCase { stopDelegate: delegate ) - view.play(animationName: "one", loop: .loopPingPong) + try view.play(animationName: "one", loop: .loopPingPong) view.advance(delta:Double(view.animations.first!.animation().effectiveDurationInSeconds()+0.1)) XCTAssertEqual(delegate.loops.count, 1) @@ -234,17 +232,16 @@ class DelegatesTest: XCTestCase { XCTAssertEqual(delegate.linearAnimaitonStops.count, 0) } - func testStateMachineLayerStates(){ + func testStateMachineLayerStates() throws { let delegate = MrDelegate() - let view = RiveView.init( + let view = try RiveView.init( riveFile: getRiveFile(resourceName:"what_a_state"), stateMachine: "State Machine 2", playDelegate: delegate, pauseDelegate: delegate, stateChangeDelegate: delegate - ) - + view.advance(delta:0.1) XCTAssertEqual(delegate.stateMachinePlays.count, 1) XCTAssertEqual(delegate.stateMachineStates.count, 1) @@ -259,9 +256,9 @@ class DelegatesTest: XCTestCase { XCTAssertEqual(delegate.stateMachinePauses.count, 1) } - func testStateMachineLayerStatesComplex(){ + func testStateMachineLayerStatesComplex() throws { let delegate = MrDelegate() - let view = RiveView.init( + let view = try RiveView.init( riveFile: getRiveFile(resourceName:"what_a_state"), stateMachine: "State Machine 1", stateChangeDelegate: delegate @@ -271,7 +268,7 @@ class DelegatesTest: XCTestCase { XCTAssertEqual(delegate.stateMachineStates.count, 0) // lets just start, expect 1 change. - view.fireState("State Machine 1", inputName: "right") + try view.fireState("State Machine 1", inputName: "right") // TODO: looks like we got a bit of a bug here. if we do not call this advance, // the first animation doesnt seem to get the delta applied. i think its all because of // how the @@ -300,7 +297,7 @@ class DelegatesTest: XCTestCase { XCTAssertEqual(0, delegate.stateMachineStates.count) // ok lets change thigns up again. - view.fireState("State Machine 1", inputName: "change") + try view.fireState("State Machine 1", inputName: "change") view.advance(delta:0.0) view.advance(delta:0.4) XCTAssertEqual(true, view.isPlaying) diff --git a/Tests/RiveFileLoadTest.mm b/Tests/RiveFileLoadTest.mm index 60f19cf9..0c419529 100644 --- a/Tests/RiveFileLoadTest.mm +++ b/Tests/RiveFileLoadTest.mm @@ -20,30 +20,37 @@ @implementation RiveFileLoadTest * Test loading junk, should complain. */ - (void)testLoadFile { - XCTAssertThrowsSpecificNamed( - [Util loadTestFile:@"junk"], - RiveException, - @"Malformed" - ); + NSError* error = nil; + RiveFile* file = [Util loadTestFile:@"junk" error:&error]; + + XCTAssertNil(file); + XCTAssertNotNil(error); + XCTAssertEqualObjects([error domain], @"rive.app.ios.runtime"); + XCTAssertEqualObjects([[error userInfo] valueForKey:@"name"], @"Malformed"); + XCTAssertEqual([error code], 600); } /* * Test loading format 6 file. this should complain */ - (void)testLoadFormat6 { - XCTAssertThrowsSpecificNamed( - [Util loadTestFile:@"sample6"], - RiveException, - @"UnsupportedVersion" - ); + NSError* error = nil; + RiveFile* file = [Util loadTestFile:@"sample6" error:&error]; + + XCTAssertNil(file); + XCTAssertNotNil(error); + XCTAssertEqualObjects([error domain], @"rive.app.ios.runtime"); + XCTAssertEqualObjects([[error userInfo] valueForKey:@"name"], @"UnsupportedVersion"); + XCTAssertEqual([error code], 500); } /* * Test loading format Flux file */ - (void)testLoadFlux { - RiveFile* file = [Util loadTestFile:@"flux_capacitor"]; - RiveArtboard* artboard = [file artboard]; + NSError* error = nil; + RiveFile* file = [Util loadTestFile:@"flux_capacitor" error:&error]; + RiveArtboard* artboard = [file artboard:&error]; XCTAssertEqual(artboard.animationCount, 1); } @@ -51,8 +58,9 @@ - (void)testLoadFlux { * Test loading format Buggy file */ - (void)testLoadBuggy { - RiveFile* file = [Util loadTestFile:@"off_road_car_blog"]; - RiveArtboard* artboard = [file artboard]; + NSError* error = nil; + RiveFile* file = [Util loadTestFile:@"off_road_car_blog" error:&error]; + RiveArtboard* artboard = [file artboard:&error]; XCTAssertEqual(artboard.animationCount, 5); } diff --git a/Tests/RiveRuntimeTests.mm b/Tests/RiveRuntimeTests.mm index 8559e297..0afb68c7 100644 --- a/Tests/RiveRuntimeTests.mm +++ b/Tests/RiveRuntimeTests.mm @@ -119,7 +119,7 @@ - (void)tearDown { */ - (void)testRiveFileCreation { // Valid Rive file, should not be null - RiveFile* file = [[RiveFile alloc] initWithBytes: pingPongRiveFileBytes byteLength: 156]; + RiveFile* file = [[RiveFile alloc] initWithBytes: pingPongRiveFileBytes byteLength: 156 error:nil]; XCTAssert(file != NULL); } @@ -128,8 +128,8 @@ - (void)testRiveFileCreation { * Tests retrieving the default artboard from Rive files */ - (void)testRetrieveDefaultArtboardFromRiveFile { - RiveFile* file = [[RiveFile alloc] initWithBytes: pingPongRiveFileBytes byteLength: 156]; - RiveArtboard* artboard = [file artboard]; + RiveFile* file = [[RiveFile alloc] initWithBytes: pingPongRiveFileBytes byteLength: 156 error:nil]; + RiveArtboard* artboard = [file artboard:nil]; XCTAssert(artboard != NULL); XCTAssert([[artboard name] isEqual: @"New Artboard"]); } @@ -138,7 +138,7 @@ - (void)testRetrieveDefaultArtboardFromRiveFile { * Tests retrieving artboard count from Rive files */ - (void)testRetrieveArtboardCountFromRiveFile { - RiveFile* file = [[RiveFile alloc] initWithBytes: pingPongRiveFileBytes byteLength: 156]; + RiveFile* file = [[RiveFile alloc] initWithBytes: pingPongRiveFileBytes byteLength: 156 error:nil]; NSInteger count = [file artboardCount]; XCTAssert(count == 1); } @@ -147,8 +147,8 @@ - (void)testRetrieveArtboardCountFromRiveFile { * Tests retrieving artboard by index */ - (void)testRetrieveArtboardByIndex { - RiveFile* file = [[RiveFile alloc] initWithBytes: pingPongRiveFileBytes byteLength: 156]; - RiveArtboard* artboard = [file artboardFromIndex: 0]; + RiveFile* file = [[RiveFile alloc] initWithBytes: pingPongRiveFileBytes byteLength: 156 error:nil]; + RiveArtboard* artboard = [file artboardFromIndex: 0 error:nil]; XCTAssert(artboard != NULL); XCTAssert([[artboard name] isEqual: @"New Artboard"]); } @@ -157,8 +157,8 @@ - (void)testRetrieveArtboardByIndex { * Tests retrieving artboard by name */ - (void)testRetrieveArtboardByName { - RiveFile* file = [[RiveFile alloc] initWithBytes: pingPongRiveFileBytes byteLength: 156]; - RiveArtboard* artboard = [file artboardFromName: @"New Artboard"]; + RiveFile* file = [[RiveFile alloc] initWithBytes: pingPongRiveFileBytes byteLength: 156 error:nil]; + RiveArtboard* artboard = [file artboardFromName: @"New Artboard" error:nil]; XCTAssert(artboard != NULL); XCTAssert([[artboard name] isEqual: @"New Artboard"]); } @@ -167,8 +167,8 @@ - (void)testRetrieveArtboardByName { * Tests retrieving animation count from artboards */ - (void)testRetrieveAnimationCountFromArtboard { - RiveFile* file = [[RiveFile alloc] initWithBytes: pingPongRiveFileBytes byteLength: 156]; - RiveArtboard* artboard = [file artboard]; + RiveFile* file = [[RiveFile alloc] initWithBytes: pingPongRiveFileBytes byteLength: 156 error:nil]; + RiveArtboard* artboard = [file artboard:nil]; NSInteger count = [artboard animationCount]; XCTAssert(count == 1); } @@ -177,13 +177,13 @@ - (void)testRetrieveAnimationCountFromArtboard { * Tests retrieving the first animation */ - (void)testRetrieveFirstAnimation { - RiveFile* file = [[RiveFile alloc] initWithBytes: pingPongRiveFileBytes byteLength: 156]; + RiveFile* file = [[RiveFile alloc] initWithBytes: pingPongRiveFileBytes byteLength: 156 error:nil]; XCTAssert(file != NULL); - RiveArtboard* artboard = [file artboard]; + RiveArtboard* artboard = [file artboard:nil]; XCTAssert(artboard != NULL); XCTAssert([artboard animationCount] == 1); - RiveLinearAnimation* animation = artboard.firstAnimation; + RiveLinearAnimation* animation = [artboard firstAnimation:nil]; XCTAssert(animation != NULL); XCTAssert([animation.name isEqual:@"Animation 1"]); } @@ -192,9 +192,11 @@ - (void)testRetrieveFirstAnimation { * Tests retrieving animation by index */ - (void)testRetrieveAnimationByIndex { - RiveFile* file = [[RiveFile alloc] initWithBytes: pingPongRiveFileBytes byteLength: 156]; - RiveArtboard* artboard = [file artboard]; - RiveLinearAnimation* animation = [artboard animationFromIndex: 0]; + RiveFile* file = [[RiveFile alloc] initWithBytes: pingPongRiveFileBytes byteLength: 156 error:nil]; + RiveArtboard* artboard = [file artboard:nil]; + NSError* error = nil; + + RiveLinearAnimation* animation = [artboard animationFromIndex: 0 error:nil]; XCTAssert(animation != NULL); XCTAssert([[animation name] isEqual: @"Animation 1"]); } @@ -203,9 +205,11 @@ - (void)testRetrieveAnimationByIndex { * Tests retrieving animations by name */ - (void)testRetrieveAnimationByName { - RiveFile* file = [[RiveFile alloc] initWithBytes: pingPongRiveFileBytes byteLength: 156]; - RiveArtboard* artboard = [file artboard]; - RiveLinearAnimation* animation = [artboard animationFromName: @"Animation 1"]; + RiveFile* file = [[RiveFile alloc] initWithBytes: pingPongRiveFileBytes byteLength: 156 error:nil]; + RiveArtboard* artboard = [file artboard:nil]; + NSError* error = nil; + + RiveLinearAnimation* animation = [artboard animationFromName: @"Animation 1" error:&error]; XCTAssert(animation != NULL); XCTAssert([animation.name isEqual: @"Animation 1"]); } @@ -214,13 +218,13 @@ - (void)testRetrieveAnimationByName { * Tests retrieving the first state machine */ - (void)testRetrieveFirstStateMachine { - RiveFile* file = [[RiveFile alloc] initWithBytes: stateMachineFileBytes byteLength: 916]; + RiveFile* file = [[RiveFile alloc] initWithBytes: stateMachineFileBytes byteLength: 916 error:nil]; XCTAssert(file != NULL); - RiveArtboard* artboard = [file artboard]; + RiveArtboard* artboard = [file artboard:nil]; XCTAssert(artboard != NULL); XCTAssert([artboard stateMachineCount] == 1); - RiveStateMachine* machine = artboard.firstStateMachine; + RiveStateMachine* machine = [artboard firstStateMachine:nil]; XCTAssert(machine != NULL); XCTAssert([machine.name isEqual:@"StateMachine"]); } @@ -229,39 +233,58 @@ - (void)testRetrieveFirstStateMachine { * Tests retrieving state machines by index */ - (void)testRetrieveStateMachineByIndex { - RiveFile* file = [[RiveFile alloc] initWithBytes: stateMachineFileBytes byteLength: 916]; + RiveFile* file = [[RiveFile alloc] initWithBytes: stateMachineFileBytes byteLength: 916 error:nil]; XCTAssert(file != NULL); - RiveArtboard* artboard = [file artboard]; + RiveArtboard* artboard = [file artboard:nil]; XCTAssert(artboard != NULL); XCTAssert([artboard stateMachineCount] == 1); - RiveStateMachine* machine = [artboard stateMachineFromIndex: 0]; + RiveStateMachine* machine = [artboard stateMachineFromIndex: 0 error:nil]; XCTAssert(machine != NULL); XCTAssert([machine.name isEqual: @"StateMachine"]); - XCTAssertThrows([artboard stateMachineFromIndex: 1]); - XCTAssertThrows([artboard stateMachineFromIndex: -1]); + + NSError* error = nil; + machine = [artboard stateMachineFromIndex: 1 error:&error]; + XCTAssertNil(machine); + XCTAssertEqualObjects([error domain], @"rive.app.ios.runtime"); + XCTAssertEqual([error code], 301); + XCTAssertEqualObjects([[error userInfo] valueForKey:@"name"], @"NoStateMachineFound"); + + error = nil; + machine = [artboard stateMachineFromIndex: -1 error:&error]; + XCTAssertNil(machine); + XCTAssertEqualObjects([error domain], @"rive.app.ios.runtime"); + XCTAssertEqual([error code], 301); + XCTAssertEqualObjects([[error userInfo] valueForKey:@"name"], @"NoStateMachineFound"); } /* * Tests retrieving state machines by name */ - (void)testRetrieveStateMachineByName { - RiveFile* file = [[RiveFile alloc] initWithBytes: stateMachineFileBytes byteLength: 916]; + RiveFile* file = [[RiveFile alloc] initWithBytes: stateMachineFileBytes byteLength: 916 error:nil]; XCTAssert(file != NULL); - RiveArtboard* artboard = [file artboard]; + RiveArtboard* artboard = [file artboard:nil]; XCTAssert(artboard != NULL); - RiveStateMachine* machine = [artboard stateMachineFromName: @"StateMachine"]; + RiveStateMachine* machine = [artboard stateMachineFromName: @"StateMachine" error:nil]; XCTAssert(machine != NULL); - XCTAssertThrows([artboard stateMachineFromName: @"Bad Name"]); + + NSError* error = nil; + machine = [artboard stateMachineFromName: @"Bad Name" error:&error]; + XCTAssertNil(machine); + XCTAssertEqualObjects([error domain], @"rive.app.ios.runtime"); + XCTAssertEqual([error code], 301); + XCTAssertEqualObjects([[error userInfo] valueForKey:@"name"], @"NoStateMachineFound"); } /* * Tests creating state machine instances */ - (void)testCreateStateMachineInstance { - RiveFile* file = [[RiveFile alloc] initWithBytes: stateMachineFileBytes byteLength: 916]; - RiveArtboard* artboard = [file artboard]; - RiveStateMachine* machine = artboard.firstStateMachine; + RiveFile* file = [[RiveFile alloc] initWithBytes: stateMachineFileBytes byteLength: 916 error:nil]; + RiveArtboard* artboard = [file artboard:nil]; + + RiveStateMachine* machine = [artboard firstStateMachine:nil]; XCTAssert(machine != NULL); RiveStateMachineInstance* instance = [[RiveStateMachineInstance alloc] init]; XCTAssert(instance != NULL); diff --git a/Tests/RiveStateMachineConfigurationTest.mm b/Tests/RiveStateMachineConfigurationTest.mm index c2aabf1a..0baddefe 100644 --- a/Tests/RiveStateMachineConfigurationTest.mm +++ b/Tests/RiveStateMachineConfigurationTest.mm @@ -20,8 +20,9 @@ @implementation RiveStateMachineConfigurationTest * Test nothing */ - (void)testNothing { - RiveFile* file = [Util loadTestFile:@"state_machine_configurations"]; - RiveStateMachine* stateMachine = [[file artboard] stateMachineFromName:@"nothing"]; + RiveFile* file = [Util loadTestFile:@"state_machine_configurations" error:nil]; + + RiveStateMachine* stateMachine = [[file artboard:nil] stateMachineFromName:@"nothing" error:nil]; XCTAssertEqual([stateMachine inputCount], 0); XCTAssertEqual([stateMachine layerCount], 0); @@ -31,8 +32,9 @@ - (void)testNothing { * Test oneLayer */ - (void)testOneLayer { - RiveFile* file = [Util loadTestFile:@"state_machine_configurations"]; - RiveStateMachine* stateMachine = [[file artboard] stateMachineFromName:@"one_layer"]; + RiveFile* file = [Util loadTestFile:@"state_machine_configurations" error:nil]; + + RiveStateMachine* stateMachine = [[file artboard:nil] stateMachineFromName:@"one_layer" error:nil]; XCTAssertEqual([stateMachine inputCount], 0); XCTAssertEqual([stateMachine layerCount], 1); @@ -42,8 +44,9 @@ - (void)testOneLayer { * Test two layers */ - (void)testTwoLayers { - RiveFile* file = [Util loadTestFile:@"state_machine_configurations"]; - RiveStateMachine* stateMachine = [[file artboard] stateMachineFromName:@"two_layers"]; + RiveFile* file = [Util loadTestFile:@"state_machine_configurations" error:nil]; + + RiveStateMachine* stateMachine = [[file artboard:nil] stateMachineFromName:@"two_layers" error:nil]; XCTAssertEqual([stateMachine inputCount], 0); XCTAssertEqual([stateMachine layerCount], 2); @@ -53,38 +56,40 @@ - (void)testTwoLayers { * Test number input */ - (void)testNumberInput { - RiveFile* file = [Util loadTestFile:@"state_machine_configurations"]; - RiveStateMachine* stateMachine = [[file artboard] stateMachineFromName:@"number_input"]; + RiveFile* file = [Util loadTestFile:@"state_machine_configurations" error:nil]; + + RiveStateMachine* stateMachine = [[file artboard:nil] stateMachineFromName:@"number_input" error:nil]; XCTAssertEqual([stateMachine inputCount], 1); XCTAssertEqual([stateMachine layerCount], 1); - RiveStateMachineInput* input = [stateMachine inputFromIndex:0]; + RiveStateMachineInput* input = [stateMachine inputFromIndex:0 error:nil]; XCTAssertEqual([input isBoolean], 0); XCTAssertEqual([input isTrigger], 0); XCTAssertEqual([input isNumber], 1); XCTAssertTrue([[input name] isEqualToString:@"Number 1"]); - XCTAssertTrue([[[stateMachine inputFromName: @"Number 1"] name] isEqualToString:@"Number 1"]); + XCTAssertTrue([[[stateMachine inputFromName: @"Number 1" error:nil] name] isEqualToString:@"Number 1"]); } /* * Test bool input */ - (void)testBooleanInput { - RiveFile* file = [Util loadTestFile:@"state_machine_configurations"]; - RiveStateMachine* stateMachine = [[file artboard] stateMachineFromName:@"boolean_input"]; + RiveFile* file = [Util loadTestFile:@"state_machine_configurations" error:nil]; + + RiveStateMachine* stateMachine = [[file artboard:nil] stateMachineFromName:@"boolean_input" error:nil]; XCTAssertEqual([stateMachine inputCount], 1); XCTAssertEqual([stateMachine layerCount], 1); - RiveStateMachineInput* input = [stateMachine inputFromIndex:0]; + RiveStateMachineInput* input = [stateMachine inputFromIndex:0 error:nil]; XCTAssertEqual([input isBoolean], 1); XCTAssertEqual([input isTrigger], 0); XCTAssertEqual([input isNumber], 0); XCTAssertTrue([[input name] isEqualToString:@"Boolean 1"]); - XCTAssertTrue([[[stateMachine inputFromName: @"Boolean 1"] name] isEqualToString:@"Boolean 1"]); + XCTAssertTrue([[[stateMachine inputFromName: @"Boolean 1" error:nil] name] isEqualToString:@"Boolean 1"]); } @@ -92,27 +97,29 @@ - (void)testBooleanInput { * Test trigger input */ - (void)testTriggerInput { - RiveFile* file = [Util loadTestFile:@"state_machine_configurations"]; - RiveStateMachine* stateMachine = [[file artboard] stateMachineFromName:@"trigger_input"]; + RiveFile* file = [Util loadTestFile:@"state_machine_configurations" error:nil]; + + RiveStateMachine* stateMachine = [[file artboard:nil] stateMachineFromName:@"trigger_input" error:nil]; XCTAssertEqual([stateMachine inputCount], 1); XCTAssertEqual([stateMachine layerCount], 1); - RiveStateMachineInput* input = [stateMachine inputFromIndex:0]; + RiveStateMachineInput* input = [stateMachine inputFromIndex:0 error:nil]; XCTAssertEqual([input isBoolean], 0); XCTAssertEqual([input isTrigger], 1); XCTAssertEqual([input isNumber], 0); XCTAssertTrue([[input name] isEqualToString:@"Trigger 1"]); - XCTAssertTrue([[[stateMachine inputFromName: @"Trigger 1"] name] isEqualToString:@"Trigger 1"]); + XCTAssertTrue([[[stateMachine inputFromName: @"Trigger 1" error:nil] name] isEqualToString:@"Trigger 1"]); } /* * Test mixed input */ - (void)testMixedInput { - RiveFile* file = [Util loadTestFile:@"state_machine_configurations"]; - RiveStateMachine* stateMachine = [[file artboard] stateMachineFromName:@"mixed"]; + RiveFile* file = [Util loadTestFile:@"state_machine_configurations" error:nil]; + + RiveStateMachine* stateMachine = [[file artboard:nil] stateMachineFromName:@"mixed" error:nil]; XCTAssertEqual([stateMachine inputCount], 6); XCTAssertEqual([stateMachine layerCount], 4); @@ -120,27 +127,27 @@ - (void)testMixedInput { XCTAssertTrue([[stateMachine inputNames] isEqualToArray: target]); - XCTAssertEqual([[stateMachine inputFromName:@"zero"] isNumber], true); - XCTAssertEqual([[stateMachine inputFromName:@"off"] isBoolean], true); - XCTAssertEqual([[stateMachine inputFromName:@"trigger"] isTrigger], true); - XCTAssertEqual([[stateMachine inputFromName:@"two_point_two"] isNumber], true); - XCTAssertEqual([[stateMachine inputFromName:@"on"] isBoolean], true); - XCTAssertEqual([[stateMachine inputFromName:@"three"] isNumber], true); + XCTAssertEqual([[stateMachine inputFromName:@"zero" error:nil] isNumber], true); + XCTAssertEqual([[stateMachine inputFromName:@"off" error:nil] isBoolean], true); + XCTAssertEqual([[stateMachine inputFromName:@"trigger" error:nil] isTrigger], true); + XCTAssertEqual([[stateMachine inputFromName:@"two_point_two" error:nil] isNumber], true); + XCTAssertEqual([[stateMachine inputFromName:@"on" error:nil] isBoolean], true); + XCTAssertEqual([[stateMachine inputFromName:@"three" error:nil] isNumber], true); - XCTAssertEqual([[stateMachine inputFromName:@"zero"] isKindOfClass:[RiveStateMachineNumberInput class]], true); - XCTAssertEqual([(RiveStateMachineNumberInput *)[stateMachine inputFromName:@"zero"] value], 0); - XCTAssertEqual([[stateMachine inputFromName:@"two_point_two"] isKindOfClass:[RiveStateMachineNumberInput class]], true); - XCTAssertEqual([(RiveStateMachineNumberInput *)[stateMachine inputFromName:@"two_point_two"] value], (float)2.2); - XCTAssertEqual([[stateMachine inputFromName:@"three"] isKindOfClass:[RiveStateMachineNumberInput class]], true); - XCTAssertEqual([(RiveStateMachineNumberInput *)[stateMachine inputFromName:@"three"] value], (float)3); + XCTAssertEqual([[stateMachine inputFromName:@"zero" error:nil] isKindOfClass:[RiveStateMachineNumberInput class]], true); + XCTAssertEqual([(RiveStateMachineNumberInput *)[stateMachine inputFromName:@"zero" error:nil] value], 0); + XCTAssertEqual([[stateMachine inputFromName:@"two_point_two" error:nil] isKindOfClass:[RiveStateMachineNumberInput class]], true); + XCTAssertEqual([(RiveStateMachineNumberInput *)[stateMachine inputFromName:@"two_point_two" error:nil] value], (float)2.2); + XCTAssertEqual([[stateMachine inputFromName:@"three" error:nil] isKindOfClass:[RiveStateMachineNumberInput class]], true); + XCTAssertEqual([(RiveStateMachineNumberInput *)[stateMachine inputFromName:@"three" error:nil] value], (float)3); - XCTAssertEqual([[stateMachine inputFromName:@"on"] isKindOfClass:[RiveStateMachineBoolInput class]], true); - XCTAssertEqual([(RiveStateMachineBoolInput *)[stateMachine inputFromName:@"on"] value], true); - XCTAssertEqual([[stateMachine inputFromName:@"off"] isKindOfClass:[RiveStateMachineBoolInput class]], true); - XCTAssertEqual([(RiveStateMachineBoolInput *)[stateMachine inputFromName:@"off"] value], false); + XCTAssertEqual([[stateMachine inputFromName:@"on" error:nil] isKindOfClass:[RiveStateMachineBoolInput class]], true); + XCTAssertEqual([(RiveStateMachineBoolInput *)[stateMachine inputFromName:@"on" error:nil] value], true); + XCTAssertEqual([[stateMachine inputFromName:@"off" error:nil] isKindOfClass:[RiveStateMachineBoolInput class]], true); + XCTAssertEqual([(RiveStateMachineBoolInput *)[stateMachine inputFromName:@"off" error:nil] value], false); - XCTAssertEqual([[stateMachine inputFromName:@"trigger"] isKindOfClass:[RiveStateMachineTriggerInput class]], true); + XCTAssertEqual([[stateMachine inputFromName:@"trigger" error:nil] isKindOfClass:[RiveStateMachineTriggerInput class]], true); } @end diff --git a/Tests/RiveStateMachineLoadTest.mm b/Tests/RiveStateMachineLoadTest.mm index 5ed88521..21c9a91e 100644 --- a/Tests/RiveStateMachineLoadTest.mm +++ b/Tests/RiveStateMachineLoadTest.mm @@ -21,12 +21,16 @@ @implementation RiveStateMachineLoadTest * Test first StateMachine */ - (void)testStateMachineFirstStateMachine { - RiveFile* file = [Util loadTestFile:@"multipleartboards"]; - RiveArtboard* artboard = [file artboardFromName:@"artboard1"]; + NSError* error = nil; + RiveFile* file = [Util loadTestFile:@"multipleartboards" error:&error]; + RiveArtboard* artboard = [file artboardFromName:@"artboard1" error:&error]; - RiveStateMachine* animation = [artboard firstStateMachine]; - RiveStateMachine* animationByIndex = [artboard stateMachineFromIndex:0]; - RiveStateMachine* animationByName = [artboard stateMachineFromName:@"artboard1stateMachine1"]; + RiveStateMachine* animation = [artboard firstStateMachine:&error]; + XCTAssertNil(error); + RiveStateMachine* animationByIndex = [artboard stateMachineFromIndex:0 error:&error]; + XCTAssertNil(error); + RiveStateMachine* animationByName = [artboard stateMachineFromName:@"artboard1stateMachine1" error:&error]; + XCTAssertNil(error); XCTAssertTrue([animation.name isEqualToString:animationByIndex.name]); XCTAssertTrue([animation.name isEqualToString:animationByName.name]); @@ -39,19 +43,24 @@ - (void)testStateMachineFirstStateMachine { * Test second StateMachine */ - (void)testStateMachineSecondStateMachine { - RiveFile* file = [Util loadTestFile:@"multipleartboards"]; - RiveArtboard* artboard = [file artboardFromName:@"artboard2"]; + NSError* error = nil; + RiveFile* file = [Util loadTestFile:@"multipleartboards" error:&error]; + RiveArtboard* artboard = [file artboardFromName:@"artboard2" error:&error]; - RiveStateMachine* animation = [artboard firstStateMachine]; - RiveStateMachine* animationByIndex = [artboard stateMachineFromIndex:0]; - RiveStateMachine* animationByName = [artboard stateMachineFromName:@"artboard2stateMachine1"]; + RiveStateMachine* animation = [artboard firstStateMachine:&error]; + XCTAssertNil(error); + RiveStateMachine* animationByIndex = [artboard stateMachineFromIndex:0 error:&error]; + XCTAssertNil(error); + RiveStateMachine* animationByName = [artboard stateMachineFromName:@"artboard2stateMachine1" error:&error]; + XCTAssertNil(error); XCTAssertTrue([animation.name isEqualToString:animationByIndex.name]); XCTAssertTrue([animation.name isEqualToString:animationByName.name]); - - RiveStateMachine* animation2ByIndex = [artboard stateMachineFromIndex:1]; - RiveStateMachine* animation2ByName = [artboard stateMachineFromName:@"artboard2stateMachine2"]; + RiveStateMachine* animation2ByIndex = [artboard stateMachineFromIndex:1 error:&error]; + XCTAssertNil(error); + RiveStateMachine* animation2ByName = [artboard stateMachineFromName:@"artboard2stateMachine2" error:&error]; + XCTAssertNil(error); XCTAssertTrue([animation2ByIndex.name isEqualToString:animation2ByName.name]); @@ -64,8 +73,8 @@ - (void)testStateMachineSecondStateMachine { * Test no state machines */ - (void)testArtboardHasNoStateMachine { - RiveFile* file = [Util loadTestFile:@"noanimation"]; - RiveArtboard* artboard = [file artboard]; + RiveFile* file = [Util loadTestFile:@"noanimation" error:nil]; + RiveArtboard* artboard = [file artboard:nil]; XCTAssertEqual([artboard animationCount], 0); @@ -73,47 +82,50 @@ - (void)testArtboardHasNoStateMachine { } /* - * Test access nothing - */ +* Test access nothing +*/ - (void)testArtboardStateMachineDoesntExist { - RiveFile* file = [Util loadTestFile:@"noanimation"]; - RiveArtboard* artboard = [file artboard]; + RiveFile* file = [Util loadTestFile:@"noanimation" error:nil]; + RiveArtboard* artboard = [file artboard:nil]; + + NSError* error = nil; + RiveStateMachine* stateMachine = [artboard firstStateMachine:&error]; - XCTAssertThrowsSpecificNamed( - [artboard firstStateMachine], - RiveException, - @"NoStateMachines" - ); + XCTAssertNil(stateMachine); + XCTAssertEqualObjects([error domain], @"rive.app.ios.runtime"); + XCTAssertEqualObjects([[error userInfo] valueForKey:@"name"], @"NoStateMachines"); + XCTAssertEqual([error code], 300); } /* - * Test access index doesnt exist - */ +* Test access index doesnt exist +*/ - (void)testArtboardStateMachineAtIndexDoesntExist { - RiveFile* file = [Util loadTestFile:@"noanimation"]; - RiveArtboard* artboard = [file artboard]; - - - XCTAssertThrowsSpecificNamed( - [artboard stateMachineFromIndex:0], - RiveException, - @"NoStateMachineFound" - ); + RiveFile* file = [Util loadTestFile:@"noanimation" error:nil]; + RiveArtboard* artboard = [file artboard:nil]; + + NSError* error = nil; + RiveStateMachine* stateMachine = [artboard stateMachineFromIndex:0 error:&error]; + + XCTAssertNil(stateMachine); + XCTAssertEqualObjects([error domain], @"rive.app.ios.runtime"); + XCTAssertEqualObjects([[error userInfo] valueForKey:@"name"], @"NoStateMachineFound"); + XCTAssertEqual([error code], 301); } /* - * Test access name doesnt exist - */ +* Test access name doesnt exist +*/ - (void)testArtboardStateMachineWithNameDoesntExist { - RiveFile* file = [Util loadTestFile:@"noanimation"]; - RiveArtboard* artboard = [file artboard]; - - - XCTAssertThrowsSpecificNamed( - [artboard stateMachineFromName:@"boo"], - RiveException, - @"NoStateMachineFound" - ); + RiveFile* file = [Util loadTestFile:@"noanimation" error:nil]; + RiveArtboard* artboard = [file artboard:nil]; + + NSError* error = nil; + RiveStateMachine* stateMachine = [artboard stateMachineFromName:@"boo" error:&error]; + XCTAssertNil(stateMachine); + XCTAssertEqualObjects([error domain], @"rive.app.ios.runtime"); + XCTAssertEqualObjects([[error userInfo] valueForKey:@"name"], @"NoStateMachineFound"); + XCTAssertEqual([error code], 301); } @end diff --git a/Tests/StateMachineInstanceTest.mm b/Tests/StateMachineInstanceTest.mm index 4abf3077..3cce7bc0 100644 --- a/Tests/StateMachineInstanceTest.mm +++ b/Tests/StateMachineInstanceTest.mm @@ -21,8 +21,9 @@ @implementation RiveStateMachineInstanceTest * Test nothing */ - (void)testNothing { - RiveFile* file = [Util loadTestFile:@"state_machine_configurations"]; - RiveStateMachineInstance* stateMachineInstance = [[[file artboard] stateMachineFromName:@"nothing"] instance]; + RiveFile* file = [Util loadTestFile:@"state_machine_configurations" error:nil]; + + RiveStateMachineInstance* stateMachineInstance = [[[file artboard:nil] stateMachineFromName:@"nothing" error:nil] instance]; XCTAssertEqual([stateMachineInstance inputCount], 0); } @@ -31,18 +32,19 @@ - (void)testNothing { * Test number input */ - (void)testNumberInput { - RiveFile* file = [Util loadTestFile:@"state_machine_configurations"]; - RiveStateMachineInstance* stateMachineInstance = [[[file artboard] stateMachineFromName:@"number_input"] instance]; + RiveFile* file = [Util loadTestFile:@"state_machine_configurations" error:nil]; + + RiveStateMachineInstance* stateMachineInstance = [[[file artboard:nil] stateMachineFromName:@"number_input" error:nil] instance]; XCTAssertEqual([stateMachineInstance inputCount], 1); - RiveSMIInput* input = [stateMachineInstance inputFromIndex:0]; + RiveSMIInput* input = [stateMachineInstance inputFromIndex:0 error:nil]; XCTAssertEqual([input isBoolean], 0); XCTAssertEqual([input isTrigger], 0); XCTAssertEqual([input isNumber], 1); XCTAssertTrue([[input name] isEqualToString:@"Number 1"]); - XCTAssertTrue([[[stateMachineInstance inputFromName: @"Number 1"] name] isEqualToString:@"Number 1"]); + XCTAssertTrue([[[stateMachineInstance inputFromName: @"Number 1" error:nil] name] isEqualToString:@"Number 1"]); [(RiveSMINumber*)input setValue: 15]; XCTAssertEqual([(RiveSMINumber*)input value], 15); @@ -52,18 +54,19 @@ - (void)testNumberInput { * Test bool input */ - (void)testBooleanInput { - RiveFile* file = [Util loadTestFile:@"state_machine_configurations"]; - RiveStateMachineInstance* stateMachineInstance = [[[file artboard] stateMachineFromName:@"boolean_input"] instance]; + RiveFile* file = [Util loadTestFile:@"state_machine_configurations" error:nil]; + + RiveStateMachineInstance* stateMachineInstance = [[[file artboard:nil] stateMachineFromName:@"boolean_input" error:nil] instance]; XCTAssertEqual([stateMachineInstance inputCount], 1); - RiveSMIInput* input = [stateMachineInstance inputFromIndex:0]; + RiveSMIInput* input = [stateMachineInstance inputFromIndex:0 error:nil]; XCTAssertEqual([input isBoolean], 1); XCTAssertEqual([input isTrigger], 0); XCTAssertEqual([input isNumber], 0); XCTAssertTrue([[input name] isEqualToString:@"Boolean 1"]); - XCTAssertTrue([[[stateMachineInstance inputFromName: @"Boolean 1"] name] isEqualToString:@"Boolean 1"]); + XCTAssertTrue([[[stateMachineInstance inputFromName: @"Boolean 1" error:nil] name] isEqualToString:@"Boolean 1"]); [(RiveSMIBool*)input setValue: false]; XCTAssertEqual([(RiveSMIBool*)input value], false); @@ -76,18 +79,19 @@ - (void)testBooleanInput { * Test trigger input */ - (void)testTriggerInput { - RiveFile* file = [Util loadTestFile:@"state_machine_configurations"]; - RiveStateMachineInstance* stateMachineInstance = [[[file artboard] stateMachineFromName:@"trigger_input"] instance]; + RiveFile* file = [Util loadTestFile:@"state_machine_configurations" error:nil]; + + RiveStateMachineInstance* stateMachineInstance = [[[file artboard:nil] stateMachineFromName:@"trigger_input" error:nil] instance]; XCTAssertEqual([stateMachineInstance inputCount], 1); - RiveSMIInput* input = [stateMachineInstance inputFromIndex:0]; + RiveSMIInput* input = [stateMachineInstance inputFromIndex:0 error:nil]; XCTAssertEqual([input isBoolean], 0); XCTAssertEqual([input isTrigger], 1); XCTAssertEqual([input isNumber], 0); XCTAssertTrue([[input name] isEqualToString:@"Trigger 1"]); - XCTAssertTrue([[[stateMachineInstance inputFromName: @"Trigger 1"] name] isEqualToString:@"Trigger 1"]); + XCTAssertTrue([[[stateMachineInstance inputFromName: @"Trigger 1" error:nil] name] isEqualToString:@"Trigger 1"]); [(RiveSMITrigger*)input fire]; } @@ -96,35 +100,36 @@ - (void)testTriggerInput { * Test mixed input */ - (void)testMixedInput { - RiveFile* file = [Util loadTestFile:@"state_machine_configurations"]; - RiveStateMachineInstance* stateMachineInstance = [[[file artboard] stateMachineFromName:@"mixed"] instance]; + RiveFile* file = [Util loadTestFile:@"state_machine_configurations" error:nil]; + + RiveStateMachineInstance* stateMachineInstance = [[[file artboard:nil] stateMachineFromName:@"mixed" error:nil] instance]; XCTAssertEqual([stateMachineInstance inputCount], 6); NSArray * target = [NSArray arrayWithObjects:@"zero", @"off", @"trigger", @"two_point_two", @"on", @"three", nil]; XCTAssertTrue([[stateMachineInstance inputNames] isEqualToArray: target]); - XCTAssertEqual([[stateMachineInstance inputFromName:@"zero"] isNumber], true); - XCTAssertEqual([[stateMachineInstance inputFromName:@"off"] isBoolean], true); - XCTAssertEqual([[stateMachineInstance inputFromName:@"trigger"] isTrigger], true); - XCTAssertEqual([[stateMachineInstance inputFromName:@"two_point_two"] isNumber], true); - XCTAssertEqual([[stateMachineInstance inputFromName:@"on"] isBoolean], true); - XCTAssertEqual([[stateMachineInstance inputFromName:@"three"] isNumber], true); + XCTAssertEqual([[stateMachineInstance inputFromName:@"zero" error:nil] isNumber], true); + XCTAssertEqual([[stateMachineInstance inputFromName:@"off" error:nil] isBoolean], true); + XCTAssertEqual([[stateMachineInstance inputFromName:@"trigger" error:nil] isTrigger], true); + XCTAssertEqual([[stateMachineInstance inputFromName:@"two_point_two" error:nil] isNumber], true); + XCTAssertEqual([[stateMachineInstance inputFromName:@"on" error:nil] isBoolean], true); + XCTAssertEqual([[stateMachineInstance inputFromName:@"three" error:nil] isNumber], true); - XCTAssertEqual([[stateMachineInstance inputFromName:@"zero"] isKindOfClass:[RiveSMINumber class]], true); - XCTAssertEqual([(RiveSMINumber *)[stateMachineInstance inputFromName:@"zero"] value], 0); - XCTAssertEqual([[stateMachineInstance inputFromName:@"two_point_two"] isKindOfClass:[RiveSMINumber class]], true); - XCTAssertEqual([(RiveSMINumber *)[stateMachineInstance inputFromName:@"two_point_two"] value], (float)2.2); - XCTAssertEqual([[stateMachineInstance inputFromName:@"three"] isKindOfClass:[RiveSMINumber class]], true); - XCTAssertEqual([(RiveSMINumber *)[stateMachineInstance inputFromName:@"three"] value], (float)3); + XCTAssertEqual([[stateMachineInstance inputFromName:@"zero" error:nil] isKindOfClass:[RiveSMINumber class]], true); + XCTAssertEqual([(RiveSMINumber *)[stateMachineInstance inputFromName:@"zero" error:nil] value], 0); + XCTAssertEqual([[stateMachineInstance inputFromName:@"two_point_two" error:nil] isKindOfClass:[RiveSMINumber class]], true); + XCTAssertEqual([(RiveSMINumber *)[stateMachineInstance inputFromName:@"two_point_two" error:nil] value], (float)2.2); + XCTAssertEqual([[stateMachineInstance inputFromName:@"three" error:nil] isKindOfClass:[RiveSMINumber class]], true); + XCTAssertEqual([(RiveSMINumber *)[stateMachineInstance inputFromName:@"three" error:nil] value], (float)3); - XCTAssertEqual([[stateMachineInstance inputFromName:@"on"] isKindOfClass:[RiveSMIBool class]], true); - XCTAssertEqual([(RiveSMIBool *)[stateMachineInstance inputFromName:@"on"] value], true); - XCTAssertEqual([[stateMachineInstance inputFromName:@"off"] isKindOfClass:[RiveSMIBool class]], true); - XCTAssertEqual([(RiveSMIBool *)[stateMachineInstance inputFromName:@"off"] value], false); + XCTAssertEqual([[stateMachineInstance inputFromName:@"on" error:nil] isKindOfClass:[RiveSMIBool class]], true); + XCTAssertEqual([(RiveSMIBool *)[stateMachineInstance inputFromName:@"on" error:nil] value], true); + XCTAssertEqual([[stateMachineInstance inputFromName:@"off" error:nil] isKindOfClass:[RiveSMIBool class]], true); + XCTAssertEqual([(RiveSMIBool *)[stateMachineInstance inputFromName:@"off" error:nil] value], false); - XCTAssertEqual([[stateMachineInstance inputFromName:@"trigger"] isKindOfClass:[RiveSMITrigger class]], true); + XCTAssertEqual([[stateMachineInstance inputFromName:@"trigger" error:nil] isKindOfClass:[RiveSMITrigger class]], true); } @end diff --git a/Tests/util.h b/Tests/util.h index 2c84d7b7..685424e5 100644 --- a/Tests/util.h +++ b/Tests/util.h @@ -10,7 +10,7 @@ #define util_h @interface Util : NSObject -+ (RiveFile*) loadTestFile: (NSString *)filename; ++ (RiveFile* __nullable) loadTestFile: (NSString *)filename error:(NSError**)error; @end diff --git a/Tests/util.mm b/Tests/util.mm index 6b23adf5..e88ac18a 100644 --- a/Tests/util.mm +++ b/Tests/util.mm @@ -12,14 +12,14 @@ @implementation Util -+ (RiveFile*) loadTestFile: (NSString *)name { ++ (RiveFile*) loadTestFile: (NSString *)name error:(NSError**)error { NSBundle *bundle = [NSBundle bundleForClass:[self class]]; NSString *path = [bundle pathForResource:name ofType:@"riv"]; NSData* nsData = [NSData dataWithContentsOfFile:path]; Byte* bytes = (Byte*)malloc(nsData.length); memcpy(bytes, [nsData bytes], nsData.length); - RiveFile* file = [[RiveFile alloc] initWithBytes: bytes byteLength:nsData.length]; + RiveFile* file = [[RiveFile alloc] initWithBytes: bytes byteLength:nsData.length error:error]; return file; }