summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Fischer <joeljfischer@gmail.com>2018-05-01 10:42:26 -0400
committerJoel Fischer <joeljfischer@gmail.com>2018-05-01 10:42:26 -0400
commit1f132906f6e172b01dd4d55d3404c1b837a57cb4 (patch)
treec85945ded643462d6c3c6edff823574f02cbf8e6
parent957d96ae1984d814f1a3496b1bdc574e960f366c (diff)
downloadsdl_ios-1f132906f6e172b01dd4d55d3404c1b837a57cb4.tar.gz
Fix bug with running subcell handlersfeature/issue_927_mobile_menu_manager
* Add tests for handlers, cells, voice commands, and exiting the menu / HMI NONE when there are cells waiting
-rw-r--r--SmartDeviceLink-iOS.xcodeproj/project.pbxproj16
-rw-r--r--SmartDeviceLink/SDLMenuManager.m36
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLMenuCellSpec.m47
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m123
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLVoiceCommandManagerSpec.m123
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLVoiceCommandSpec.m113
6 files changed, 334 insertions, 124 deletions
diff --git a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
index 19fccee2f..2ebce40e7 100644
--- a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
+++ b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
@@ -974,6 +974,8 @@
5DA49CE61F1EA83300E65FC5 /* SDLControlFramePayloadRPCStartService.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DA49CE41F1EA83300E65FC5 /* SDLControlFramePayloadRPCStartService.m */; };
5DA8A0E91E955F710039C50D /* SDLStreamingMediaManagerConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = DA8966F31E56977C00413EAB /* SDLStreamingMediaManagerConstants.m */; };
5DA8A0EA1E955FE00039C50D /* SDLLogModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DBF06301E64A9C600A5CF03 /* SDLLogModel.m */; };
+ 5DAB5F512098994C00A020C8 /* SDLMenuCellSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DAB5F502098994C00A020C8 /* SDLMenuCellSpec.m */; };
+ 5DAB5F5320989A8300A020C8 /* SDLVoiceCommandSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DAB5F5220989A8300A020C8 /* SDLVoiceCommandSpec.m */; };
5DAD5F7F204DEDEB0025624C /* SDLScreenManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DAD5F7D204DEDEB0025624C /* SDLScreenManager.h */; settings = {ATTRIBUTES = (Public, ); }; };
5DAD5F80204DEDEB0025624C /* SDLScreenManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DAD5F7E204DEDEB0025624C /* SDLScreenManager.m */; };
5DAD5F8520507E1F0025624C /* SDLScreenManagerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DAD5F8420507E1F0025624C /* SDLScreenManagerSpec.m */; };
@@ -1060,7 +1062,7 @@
5DF40B22208E761A00DD6FDA /* SDLVoiceCommandManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DF40B20208E761A00DD6FDA /* SDLVoiceCommandManager.h */; };
5DF40B23208E761A00DD6FDA /* SDLVoiceCommandManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DF40B21208E761A00DD6FDA /* SDLVoiceCommandManager.m */; };
5DF40B26208FA7DE00DD6FDA /* SDLMenuManagerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DF40B25208FA7DE00DD6FDA /* SDLMenuManagerSpec.m */; };
- 5DF40B28208FDA9700DD6FDA /* SDLVoiceCommandSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DF40B27208FDA9700DD6FDA /* SDLVoiceCommandSpec.m */; };
+ 5DF40B28208FDA9700DD6FDA /* SDLVoiceCommandManagerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DF40B27208FDA9700DD6FDA /* SDLVoiceCommandManagerSpec.m */; };
5DFFB9151BD7C89700DB3F04 /* SDLConnectionManagerType.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DFFB9141BD7C89700DB3F04 /* SDLConnectionManagerType.h */; };
880E8C2920697FEE00CF86C2 /* SDLSystemCapabilityManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 880E8C2720697FEE00CF86C2 /* SDLSystemCapabilityManager.h */; settings = {ATTRIBUTES = (Public, ); }; };
880E8C2A20697FEE00CF86C2 /* SDLSystemCapabilityManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 880E8C2820697FEE00CF86C2 /* SDLSystemCapabilityManager.m */; };
@@ -2243,6 +2245,8 @@
5DA3F36F1BC4489A0026F2D0 /* SDLManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLManager.m; sourceTree = "<group>"; };
5DA49CE31F1EA83300E65FC5 /* SDLControlFramePayloadRPCStartService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLControlFramePayloadRPCStartService.h; sourceTree = "<group>"; };
5DA49CE41F1EA83300E65FC5 /* SDLControlFramePayloadRPCStartService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLControlFramePayloadRPCStartService.m; sourceTree = "<group>"; };
+ 5DAB5F502098994C00A020C8 /* SDLMenuCellSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SDLMenuCellSpec.m; path = DevAPISpecs/SDLMenuCellSpec.m; sourceTree = "<group>"; };
+ 5DAB5F5220989A8300A020C8 /* SDLVoiceCommandSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SDLVoiceCommandSpec.m; path = DevAPISpecs/SDLVoiceCommandSpec.m; sourceTree = "<group>"; };
5DAD5F7D204DEDEB0025624C /* SDLScreenManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLScreenManager.h; sourceTree = "<group>"; };
5DAD5F7E204DEDEB0025624C /* SDLScreenManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLScreenManager.m; sourceTree = "<group>"; };
5DAD5F8420507E1F0025624C /* SDLScreenManagerSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLScreenManagerSpec.m; sourceTree = "<group>"; };
@@ -2339,7 +2343,7 @@
5DF40B20208E761A00DD6FDA /* SDLVoiceCommandManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLVoiceCommandManager.h; sourceTree = "<group>"; };
5DF40B21208E761A00DD6FDA /* SDLVoiceCommandManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLVoiceCommandManager.m; sourceTree = "<group>"; };
5DF40B25208FA7DE00DD6FDA /* SDLMenuManagerSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SDLMenuManagerSpec.m; path = DevAPISpecs/SDLMenuManagerSpec.m; sourceTree = "<group>"; };
- 5DF40B27208FDA9700DD6FDA /* SDLVoiceCommandSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SDLVoiceCommandSpec.m; path = DevAPISpecs/SDLVoiceCommandSpec.m; sourceTree = "<group>"; };
+ 5DF40B27208FDA9700DD6FDA /* SDLVoiceCommandManagerSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SDLVoiceCommandManagerSpec.m; path = DevAPISpecs/SDLVoiceCommandManagerSpec.m; sourceTree = "<group>"; };
5DFFB9141BD7C89700DB3F04 /* SDLConnectionManagerType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLConnectionManagerType.h; sourceTree = "<group>"; };
880E8C2720697FEE00CF86C2 /* SDLSystemCapabilityManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLSystemCapabilityManager.h; sourceTree = "<group>"; };
880E8C2820697FEE00CF86C2 /* SDLSystemCapabilityManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLSystemCapabilityManager.m; sourceTree = "<group>"; };
@@ -4730,7 +4734,9 @@
isa = PBXGroup;
children = (
5DF40B25208FA7DE00DD6FDA /* SDLMenuManagerSpec.m */,
- 5DF40B27208FDA9700DD6FDA /* SDLVoiceCommandSpec.m */,
+ 5DF40B27208FDA9700DD6FDA /* SDLVoiceCommandManagerSpec.m */,
+ 5DAB5F502098994C00A020C8 /* SDLMenuCellSpec.m */,
+ 5DAB5F5220989A8300A020C8 /* SDLVoiceCommandSpec.m */,
);
name = Menu;
sourceTree = "<group>";
@@ -5945,6 +5951,7 @@
5DBEFA581F436132009EE295 /* SDLFakeSecurityManager.m in Sources */,
162E82D91A9BDE8A00906325 /* SDLDisplayTypeSpec.m in Sources */,
162E83871A9BDE8B00906325 /* SDLPermissionItemSpec.m in Sources */,
+ 5DAB5F5320989A8300A020C8 /* SDLVoiceCommandSpec.m in Sources */,
162E82E31A9BDE8B00906325 /* SDLIgnitionStatusSpec.m in Sources */,
162E83511A9BDE8B00906325 /* SDLDeleteInteractionChoiceSetResponseSpec.m in Sources */,
DA9F7EB41DCC086400ACAE48 /* SDLDateTimeSpec.m in Sources */,
@@ -5969,6 +5976,7 @@
162E83681A9BDE8B00906325 /* SDLSpeakResponseSpec.m in Sources */,
162E83661A9BDE8B00906325 /* SDLShowResponseSpec.m in Sources */,
5D9F50831BEA5C6100FEF399 /* SDLFileManagerSpec.m in Sources */,
+ 5DAB5F512098994C00A020C8 /* SDLMenuCellSpec.m in Sources */,
1EE8C4481F38430900FDC2CF /* SDLRadioControlCapabilitiesSpec.m in Sources */,
162E83221A9BDE8B00906325 /* SDLAddCommandSpec.m in Sources */,
162E83121A9BDE8B00906325 /* SDLOnButtonPressSpec.m in Sources */,
@@ -6232,7 +6240,7 @@
162E82CF1A9BDE8A00906325 /* SDLBitsPerSampleSpec.m in Sources */,
162E831E1A9BDE8B00906325 /* SDLOnTBTClientStateSpec.m in Sources */,
162E83351A9BDE8B00906325 /* SDLReadDIDSpec.m in Sources */,
- 5DF40B28208FDA9700DD6FDA /* SDLVoiceCommandSpec.m in Sources */,
+ 5DF40B28208FDA9700DD6FDA /* SDLVoiceCommandManagerSpec.m in Sources */,
162E836F1A9BDE8B00906325 /* SDLUnsubscribeVehicleDataResponseSpec.m in Sources */,
162E82DB1A9BDE8B00906325 /* SDLECallConfirmationStatusSpec.m in Sources */,
162E82D81A9BDE8A00906325 /* SDLDimensionSpec.m in Sources */,
diff --git a/SmartDeviceLink/SDLMenuManager.m b/SmartDeviceLink/SDLMenuManager.m
index de75ce96d..39b6bc91c 100644
--- a/SmartDeviceLink/SDLMenuManager.m
+++ b/SmartDeviceLink/SDLMenuManager.m
@@ -361,17 +361,30 @@ UInt32 const MenuCellIdMin = 1;
return submenu;
}
+#pragma mark - Calling handlers
+
+- (BOOL)sdl_callHandlerForCells:(NSArray<SDLMenuCell *> *)cells command:(SDLOnCommand *)onCommand {
+ for (SDLMenuCell *cell in cells) {
+ if (cell.cellId == onCommand.cmdID.unsignedIntegerValue) {
+ cell.handler(onCommand.triggerSource);
+ return YES;
+ }
+
+ if (cell.subCells.count > 0) {
+ BOOL succeeded = [self sdl_callHandlerForCells:cell.subCells command:onCommand];
+ if (succeeded) { return YES; }
+ }
+ }
+
+ return NO;
+}
+
#pragma mark - Observers
- (void)sdl_commandNotification:(SDLRPCNotificationNotification *)notification {
SDLOnCommand *onCommand = (SDLOnCommand *)notification.notification;
- for (SDLMenuCell *cell in self.menuCells) {
- if (onCommand.cmdID.unsignedIntegerValue != cell.cellId) { continue; }
-
- cell.handler(onCommand.triggerSource);
- break;
- }
+ [self sdl_callHandlerForCells:self.menuCells command:onCommand];
}
- (void)sdl_registerResponse:(SDLRPCResponseNotification *)notification {
@@ -390,11 +403,12 @@ UInt32 const MenuCellIdMin = 1;
self.currentHMILevel = hmiStatus.hmiLevel;
// Auto-send an updated menu if we were in NONE and now we are not, and we need an update
- if ([oldHMILevel isEqualToString:SDLHMILevelNone] && ![self.currentHMILevel isEqualToString:SDLHMILevelNone]) {
+ if ([oldHMILevel isEqualToString:SDLHMILevelNone] && ![self.currentHMILevel isEqualToString:SDLHMILevelNone] &&
+ ![self.currentSystemContext isEqualToEnum:SDLSystemContextMenu]) {
if (self.waitingOnHMIUpdate) {
- [self setMenuCells:_menuCells];
- } else {
- [self sdl_updateWithCompletionHandler:nil];
+ [self setMenuCells:self.waitingUpdateMenuCells];
+ self.waitingUpdateMenuCells = @[];
+ return;
}
}
@@ -402,7 +416,7 @@ UInt32 const MenuCellIdMin = 1;
SDLSystemContext oldSystemContext = self.currentSystemContext;
self.currentSystemContext = hmiStatus.systemContext;
- if ([oldSystemContext isEqualToEnum:SDLSystemContextMenu] && ![self.currentSystemContext isEqualToEnum:SDLSystemContextMenu]) {
+ if ([oldSystemContext isEqualToEnum:SDLSystemContextMenu] && ![self.currentSystemContext isEqualToEnum:SDLSystemContextMenu] && ![self.currentHMILevel isEqualToEnum:SDLHMILevelNone]) {
if (self.waitingOnHMIUpdate) {
[self setMenuCells:self.waitingUpdateMenuCells];
self.waitingUpdateMenuCells = @[];
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLMenuCellSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLMenuCellSpec.m
new file mode 100644
index 000000000..b6b52f0a0
--- /dev/null
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLMenuCellSpec.m
@@ -0,0 +1,47 @@
+#import <Quick/Quick.h>
+#import <Nimble/Nimble.h>
+
+#import "SDLArtwork.h"
+#import "SDLMenuCell.h"
+
+QuickSpecBegin(SDLMenuCellSpec)
+
+describe(@"a menu cell", ^{
+ __block SDLMenuCell *testCell = nil;
+
+ describe(@"initializing", ^{
+ __block NSString *someTitle = nil;
+ __block SDLArtwork *someArtwork = nil;
+ __block NSArray<NSString *> *someVoiceCommands = nil;
+ __block NSArray<SDLMenuCell *> *someSubcells = nil;
+
+ beforeEach(^{
+ someTitle = @"Some Title";
+ someArtwork = [[SDLArtwork alloc] initWithData:[[NSData alloc] initWithBase64EncodedString:@"data" options:kNilOptions] name:@"Some artwork" fileExtension:@"png" persistent:NO];
+ someVoiceCommands = @[@"some command"];
+
+ SDLMenuCell *subcell = [[SDLMenuCell alloc] initWithTitle:@"Hello" icon:nil voiceCommands:nil handler:^(SDLTriggerSource _Nonnull triggerSource) {}];
+ someSubcells = @[subcell];
+ });
+
+ it(@"should initialize properly as a menu item", ^{
+ testCell = [[SDLMenuCell alloc] initWithTitle:someTitle icon:someArtwork voiceCommands:someVoiceCommands handler:^(SDLTriggerSource _Nonnull triggerSource) {}];
+
+ expect(testCell.title).to(equal(someTitle));
+ expect(testCell.icon).to(equal(someArtwork));
+ expect(testCell.voiceCommands).to(equal(someVoiceCommands));
+ expect(testCell.subCells).to(beNil());
+ });
+
+ it(@"should initialize properly as a submenu item", ^{
+ testCell = [[SDLMenuCell alloc] initWithTitle:someTitle subCells:someSubcells];
+
+ expect(testCell.title).to(equal(someTitle));
+ expect(testCell.icon).to(beNil());
+ expect(testCell.voiceCommands).to(beNil());
+ expect(testCell.subCells).to(equal(someSubcells));
+ });
+ });
+});
+
+QuickSpecEnd
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m
index f47748e0b..68678e230 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m
@@ -13,6 +13,10 @@
#import "SDLImageFieldName.h"
#import "SDLMenuCell.h"
#import "SDLMenuManager.h"
+#import "SDLOnCommand.h"
+#import "SDLOnHMIStatus.h"
+#import "SDLRPCNotificationNotification.h"
+#import "SDLSystemContext.h"
#import "TestConnectionManager.h"
@interface SDLMenuCell()
@@ -28,11 +32,13 @@
@property (weak, nonatomic) SDLFileManager *fileManager;
@property (copy, nonatomic, nullable) SDLHMILevel currentHMILevel;
+@property (copy, nonatomic, nullable) SDLSystemContext currentSystemContext;
@property (strong, nonatomic, nullable) SDLDisplayCapabilities *displayCapabilities;
@property (strong, nonatomic, nullable) NSArray<SDLRPCRequest *> *inProgressUpdate;
@property (assign, nonatomic) BOOL hasQueuedUpdate;
@property (assign, nonatomic) BOOL waitingOnHMIUpdate;
+@property (copy, nonatomic) NSArray<SDLMenuCell *> *waitingUpdateMenuCells;
@property (assign, nonatomic) UInt32 lastMenuId;
@property (copy, nonatomic) NSArray<SDLMenuCell *> *oldMenuCells;
@@ -75,31 +81,72 @@ describe(@"menu manager", ^{
context(@"when in HMI NONE", ^{
beforeEach(^{
testManager.currentHMILevel = SDLHMILevelNone;
+ testManager.menuCells = @[textOnlyCell];
});
it(@"should not update", ^{
- testManager.menuCells = @[textOnlyCell];
+ expect(mockConnectionManager.receivedRequests).to(beEmpty());
+ });
+
+ describe(@"when entering the foreground", ^{
+ beforeEach(^{
+ SDLOnHMIStatus *onHMIStatus = [[SDLOnHMIStatus alloc] init];
+ onHMIStatus.hmiLevel = SDLHMILevelFull;
+ onHMIStatus.systemContext = SDLSystemContextMain;
+
+ SDLRPCNotificationNotification *testSystemContextNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidChangeHMIStatusNotification object:nil rpcNotification:onHMIStatus];
+ [[NSNotificationCenter defaultCenter] postNotification:testSystemContextNotification];
+ });
- expect(testManager.inProgressUpdate).to(beNil());
+ it(@"should update", ^{
+ expect(mockConnectionManager.receivedRequests).toNot(beEmpty());
+ });
});
});
context(@"when no HMI level has been received", ^{
beforeEach(^{
testManager.currentHMILevel = nil;
+ testManager.menuCells = @[textOnlyCell];
});
it(@"should not update", ^{
+ expect(mockConnectionManager.receivedRequests).to(beEmpty());
+ });
+ });
+
+ context(@"when in the menu", ^{
+ beforeEach(^{
+ testManager.currentHMILevel = SDLHMILevelFull;
+ testManager.currentSystemContext = SDLSystemContextMenu;
testManager.menuCells = @[textOnlyCell];
+ });
- expect(testManager.inProgressUpdate).to(beNil());
+ it(@"should not update", ^{
+ expect(mockConnectionManager.receivedRequests).to(beEmpty());
+ });
+
+ describe(@"when exiting the menu", ^{
+ beforeEach(^{
+ SDLOnHMIStatus *onHMIStatus = [[SDLOnHMIStatus alloc] init];
+ onHMIStatus.hmiLevel = SDLHMILevelFull;
+ onHMIStatus.systemContext = SDLSystemContextMain;
+
+ SDLRPCNotificationNotification *testSystemContextNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidChangeHMIStatusNotification object:nil rpcNotification:onHMIStatus];
+ [[NSNotificationCenter defaultCenter] postNotification:testSystemContextNotification];
+ });
+
+ it(@"should update", ^{
+ expect(mockConnectionManager.receivedRequests).toNot(beEmpty());
+ });
});
});
});
- describe(@"updating menu cell", ^{
+ describe(@"updating menu cells", ^{
beforeEach(^{
testManager.currentHMILevel = SDLHMILevelFull;
+ testManager.currentSystemContext = SDLSystemContextMain;
testManager.displayCapabilities = [[SDLDisplayCapabilities alloc] init];
SDLImageField *commandIconField = [[SDLImageField alloc] init];
@@ -194,6 +241,74 @@ describe(@"menu manager", ^{
});
});
});
+
+ describe(@"running menu cell handlers", ^{
+ __block SDLMenuCell *cellWithHandler = nil;
+ __block BOOL cellCalled = NO;
+ __block SDLTriggerSource testTriggerSource = nil;
+
+ beforeEach(^{
+ testManager.currentHMILevel = SDLHMILevelFull;
+ testManager.currentSystemContext = SDLSystemContextMain;
+
+ testManager.displayCapabilities = [[SDLDisplayCapabilities alloc] init];
+ SDLImageField *commandIconField = [[SDLImageField alloc] init];
+ commandIconField.name = SDLImageFieldNameCommandIcon;
+ testManager.displayCapabilities.imageFields = @[commandIconField];
+ testManager.displayCapabilities.graphicSupported = @YES;
+
+ cellCalled = NO;
+ testTriggerSource = nil;
+ });
+
+ context(@"on a main menu cell", ^{
+ beforeEach(^{
+ cellWithHandler = [[SDLMenuCell alloc] initWithTitle:@"Hello" icon:nil voiceCommands:nil handler:^(SDLTriggerSource _Nonnull triggerSource) {
+ cellCalled = YES;
+ testTriggerSource = triggerSource;
+ }];
+
+ testManager.menuCells = @[cellWithHandler];
+ });
+
+ it(@"should call the cell handler", ^{
+ SDLOnCommand *onCommand = [[SDLOnCommand alloc] init];
+ onCommand.cmdID = @1;
+ onCommand.triggerSource = SDLTriggerSourceMenu;
+
+ SDLRPCNotificationNotification *notification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveCommandNotification object:nil rpcNotification:onCommand];
+ [[NSNotificationCenter defaultCenter] postNotification:notification];
+
+ expect(cellCalled).to(beTrue());
+ expect(testTriggerSource).to(equal(SDLTriggerSourceMenu));
+ });
+ });
+
+ context(@"on a submenu menu cell", ^{
+ beforeEach(^{
+ cellWithHandler = [[SDLMenuCell alloc] initWithTitle:@"Hello" icon:nil voiceCommands:nil handler:^(SDLTriggerSource _Nonnull triggerSource) {
+ cellCalled = YES;
+ testTriggerSource = triggerSource;
+ }];
+
+ SDLMenuCell *submenuCell = [[SDLMenuCell alloc] initWithTitle:@"Submenu" subCells:@[cellWithHandler]];
+
+ testManager.menuCells = @[submenuCell];
+ });
+
+ it(@"should call the cell handler", ^{
+ SDLOnCommand *onCommand = [[SDLOnCommand alloc] init];
+ onCommand.cmdID = @2;
+ onCommand.triggerSource = SDLTriggerSourceMenu;
+
+ SDLRPCNotificationNotification *notification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveCommandNotification object:nil rpcNotification:onCommand];
+ [[NSNotificationCenter defaultCenter] postNotification:notification];
+
+ expect(cellCalled).to(beTrue());
+ expect(testTriggerSource).to(equal(SDLTriggerSourceMenu));
+ });
+ });
+ });
});
QuickSpecEnd
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLVoiceCommandManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLVoiceCommandManagerSpec.m
new file mode 100644
index 000000000..d9cda0f5d
--- /dev/null
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLVoiceCommandManagerSpec.m
@@ -0,0 +1,123 @@
+#import <Quick/Quick.h>
+#import <Nimble/Nimble.h>
+#import <OCMock/OCMock.h>
+
+#import "SDLAddCommand.h"
+#import "SDLDeleteCommand.h"
+#import "SDLFileManager.h"
+#import "SDLHMILevel.h"
+#import "SDLVoiceCommand.h"
+#import "SDLVoiceCommandManager.h"
+#import "TestConnectionManager.h"
+
+@interface SDLVoiceCommand()
+
+@property (assign, nonatomic) UInt32 commandId;
+
+@end
+
+@interface SDLVoiceCommandManager()
+
+@property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager;
+
+@property (assign, nonatomic) BOOL waitingOnHMIUpdate;
+@property (copy, nonatomic, nullable) SDLHMILevel currentHMILevel;
+
+@property (strong, nonatomic, nullable) NSArray<SDLRPCRequest *> *inProgressUpdate;
+@property (assign, nonatomic) BOOL hasQueuedUpdate;
+
+@property (assign, nonatomic) UInt32 lastVoiceCommandId;
+@property (copy, nonatomic) NSArray<SDLVoiceCommand *> *oldVoiceCommands;
+
+@end
+
+UInt32 const VoiceCommandIdMin = 1900000000;
+
+QuickSpecBegin(SDLVoiceCommandManagerSpec)
+
+describe(@"voice command manager", ^{
+ __block SDLVoiceCommandManager *testManager = nil;
+ __block TestConnectionManager *mockConnectionManager = nil;
+
+ __block SDLVoiceCommand *testVoiceCommand = [[SDLVoiceCommand alloc] initWithVoiceCommands:@[@"Test 1"] handler:^{}];
+ __block SDLVoiceCommand *testVoiceCommand2 = [[SDLVoiceCommand alloc] initWithVoiceCommands:@[@"Test 2"] handler:^{}];
+
+ beforeEach(^{
+ mockConnectionManager = [[TestConnectionManager alloc] init];
+ testManager = [[SDLVoiceCommandManager alloc] initWithConnectionManager:mockConnectionManager];
+ });
+
+ it(@"should instantiate correctly", ^{
+ expect(testManager.voiceCommands).to(beEmpty());
+ expect(testManager.connectionManager).to(equal(mockConnectionManager));
+ expect(testManager.currentHMILevel).to(beNil());
+ expect(testManager.inProgressUpdate).to(beNil());
+ expect(testManager.hasQueuedUpdate).to(beFalse());
+ expect(testManager.waitingOnHMIUpdate).to(beFalse());
+ expect(testManager.lastVoiceCommandId).to(equal(VoiceCommandIdMin));
+ expect(testManager.oldVoiceCommands).to(beEmpty());
+ });
+
+ describe(@"updating voice commands before HMI is ready", ^{
+ context(@"when in HMI NONE", ^{
+ beforeEach(^{
+ testManager.currentHMILevel = SDLHMILevelNone;
+ });
+
+ it(@"should not update", ^{
+ testManager.voiceCommands = @[testVoiceCommand];
+ expect(testManager.inProgressUpdate).to(beNil());
+ });
+ });
+
+ context(@"when no HMI level has been received", ^{
+ beforeEach(^{
+ testManager.currentHMILevel = nil;
+ });
+
+ it(@"should not update", ^{
+ testManager.voiceCommands = @[testVoiceCommand];
+ expect(testManager.inProgressUpdate).to(beNil());
+ });
+ });
+ });
+
+ describe(@"updating voice commands", ^{
+ beforeEach(^{
+ testManager.currentHMILevel = SDLHMILevelFull;
+ });
+
+ it(@"should properly update a command", ^{
+ testManager.voiceCommands = @[testVoiceCommand];
+
+ NSPredicate *deleteCommandPredicate = [NSPredicate predicateWithFormat:@"self isMemberOfClass: %@", [SDLDeleteCommand class]];
+ NSArray *deletes = [[mockConnectionManager.receivedRequests copy] filteredArrayUsingPredicate:deleteCommandPredicate];
+ expect(deletes).to(beEmpty());
+
+ NSPredicate *addCommandPredicate = [NSPredicate predicateWithFormat:@"self isMemberOfClass: %@", [SDLAddCommand class]];
+ NSArray *add = [[mockConnectionManager.receivedRequests copy] filteredArrayUsingPredicate:addCommandPredicate];
+ expect(add).toNot(beEmpty());
+ });
+
+ context(@"when a menu already exists", ^{
+ beforeEach(^{
+ testManager.voiceCommands = @[testVoiceCommand];
+ });
+
+ it(@"should send deletes first", ^{
+ testManager.voiceCommands = @[testVoiceCommand2];
+
+ NSPredicate *deleteCommandPredicate = [NSPredicate predicateWithFormat:@"self isMemberOfClass: %@", [SDLDeleteCommand class]];
+ NSArray *deletes = [[mockConnectionManager.receivedRequests copy] filteredArrayUsingPredicate:deleteCommandPredicate];
+
+ NSPredicate *addCommandPredicate = [NSPredicate predicateWithFormat:@"self isMemberOfClass: %@", [SDLAddCommand class]];
+ NSArray *adds = [[mockConnectionManager.receivedRequests copy] filteredArrayUsingPredicate:addCommandPredicate];
+
+ expect(deletes).to(haveCount(1));
+ expect(adds).to(haveCount(2));
+ });
+ });
+ });
+});
+
+QuickSpecEnd
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLVoiceCommandSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLVoiceCommandSpec.m
index 7b7c77799..8e8a2e7c3 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLVoiceCommandSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLVoiceCommandSpec.m
@@ -1,121 +1,24 @@
#import <Quick/Quick.h>
#import <Nimble/Nimble.h>
-#import <OCMock/OCMock.h>
-#import "SDLAddCommand.h"
-#import "SDLDeleteCommand.h"
-#import "SDLFileManager.h"
-#import "SDLHMILevel.h"
#import "SDLVoiceCommand.h"
-#import "SDLVoiceCommandManager.h"
-#import "TestConnectionManager.h"
-
-@interface SDLVoiceCommand()
-
-@property (assign, nonatomic) UInt32 commandId;
-
-@end
-
-@interface SDLVoiceCommandManager()
-
-@property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager;
-
-@property (assign, nonatomic) BOOL waitingOnHMIUpdate;
-@property (copy, nonatomic, nullable) SDLHMILevel currentHMILevel;
-
-@property (strong, nonatomic, nullable) NSArray<SDLRPCRequest *> *inProgressUpdate;
-@property (assign, nonatomic) BOOL hasQueuedUpdate;
-
-@property (assign, nonatomic) UInt32 lastVoiceCommandId;
-@property (copy, nonatomic) NSArray<SDLVoiceCommand *> *oldVoiceCommands;
-
-@end
-
-UInt32 const VoiceCommandIdMin = 1900000000;
QuickSpecBegin(SDLVoiceCommandSpec)
-describe(@"voice command manager", ^{
- __block SDLVoiceCommandManager *testManager = nil;
- __block TestConnectionManager *mockConnectionManager = nil;
-
- __block SDLVoiceCommand *testVoiceCommand = [[SDLVoiceCommand alloc] initWithVoiceCommands:@[@"Test 1"] handler:^{}];
- __block SDLVoiceCommand *testVoiceCommand2 = [[SDLVoiceCommand alloc] initWithVoiceCommands:@[@"Test 2"] handler:^{}];
-
- beforeEach(^{
- mockConnectionManager = [[TestConnectionManager alloc] init];
- testManager = [[SDLVoiceCommandManager alloc] initWithConnectionManager:mockConnectionManager];
- });
-
- it(@"should instantiate correctly", ^{
- expect(testManager.voiceCommands).to(beEmpty());
- expect(testManager.connectionManager).to(equal(mockConnectionManager));
- expect(testManager.currentHMILevel).to(beNil());
- expect(testManager.inProgressUpdate).to(beNil());
- expect(testManager.hasQueuedUpdate).to(beFalse());
- expect(testManager.waitingOnHMIUpdate).to(beFalse());
- expect(testManager.lastVoiceCommandId).to(equal(VoiceCommandIdMin));
- expect(testManager.oldVoiceCommands).to(beEmpty());
- });
-
- describe(@"updating voice commands before HMI is ready", ^{
- context(@"when in HMI NONE", ^{
- beforeEach(^{
- testManager.currentHMILevel = SDLHMILevelNone;
- });
-
- it(@"should not update", ^{
- testManager.voiceCommands = @[testVoiceCommand];
- expect(testManager.inProgressUpdate).to(beNil());
- });
- });
+describe(@"a voice command", ^{
+ __block SDLVoiceCommand *testCommand = nil;
- context(@"when no HMI level has been received", ^{
- beforeEach(^{
- testManager.currentHMILevel = nil;
- });
-
- it(@"should not update", ^{
- testManager.voiceCommands = @[testVoiceCommand];
- expect(testManager.inProgressUpdate).to(beNil());
- });
- });
- });
+ describe(@"initializing", ^{
+ __block NSArray<NSString *> *someVoiceCommands = nil;
- describe(@"updating voice commands", ^{
beforeEach(^{
- testManager.currentHMILevel = SDLHMILevelFull;
+ someVoiceCommands = @[@"some command"];
});
- it(@"should properly update a command", ^{
- testManager.voiceCommands = @[testVoiceCommand];
-
- NSPredicate *deleteCommandPredicate = [NSPredicate predicateWithFormat:@"self isMemberOfClass: %@", [SDLDeleteCommand class]];
- NSArray *deletes = [[mockConnectionManager.receivedRequests copy] filteredArrayUsingPredicate:deleteCommandPredicate];
- expect(deletes).to(beEmpty());
-
- NSPredicate *addCommandPredicate = [NSPredicate predicateWithFormat:@"self isMemberOfClass: %@", [SDLAddCommand class]];
- NSArray *add = [[mockConnectionManager.receivedRequests copy] filteredArrayUsingPredicate:addCommandPredicate];
- expect(add).toNot(beEmpty());
- });
-
- context(@"when a menu already exists", ^{
- beforeEach(^{
- testManager.voiceCommands = @[testVoiceCommand];
- });
-
- it(@"should send deletes first", ^{
- testManager.voiceCommands = @[testVoiceCommand2];
-
- NSPredicate *deleteCommandPredicate = [NSPredicate predicateWithFormat:@"self isMemberOfClass: %@", [SDLDeleteCommand class]];
- NSArray *deletes = [[mockConnectionManager.receivedRequests copy] filteredArrayUsingPredicate:deleteCommandPredicate];
-
- NSPredicate *addCommandPredicate = [NSPredicate predicateWithFormat:@"self isMemberOfClass: %@", [SDLAddCommand class]];
- NSArray *adds = [[mockConnectionManager.receivedRequests copy] filteredArrayUsingPredicate:addCommandPredicate];
+ it(@"should initialize properly", ^{
+ testCommand = [[SDLVoiceCommand alloc] initWithVoiceCommands:someVoiceCommands handler:^{}];
- expect(deletes).to(haveCount(1));
- expect(adds).to(haveCount(2));
- });
+ expect(testCommand.voiceCommands).to(equal(someVoiceCommands));
});
});
});