xcfit 2.0.4 → 2.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (151) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +7 -9
  3. data/Docs/InitialVersion.md +340 -0
  4. data/Package.swift +5 -0
  5. data/README.md +348 -145
  6. data/XCFit.gemspec +1 -1
  7. data/XCFit.podspec +17 -9
  8. data/XCFit/Classes/Cucumberish/Core/CCIBlockDefinitions.h +400 -0
  9. data/XCFit/Classes/Cucumberish/Core/Managers/CCIFeaturesManager.h +72 -0
  10. data/XCFit/Classes/Cucumberish/Core/Managers/CCIFeaturesManager.m +141 -0
  11. data/XCFit/Classes/Cucumberish/Core/Managers/CCIStepsManager.h +51 -0
  12. data/XCFit/Classes/Cucumberish/Core/Managers/CCIStepsManager.m +245 -0
  13. data/XCFit/Classes/Cucumberish/Core/Models/CCIArgument.h +62 -0
  14. data/XCFit/Classes/Cucumberish/Core/Models/CCIArgument.m +117 -0
  15. data/XCFit/Classes/Cucumberish/Core/Models/CCIAroundHock.h +37 -0
  16. data/XCFit/Classes/Cucumberish/Core/Models/CCIAroundHock.m +37 -0
  17. data/XCFit/Classes/Cucumberish/Core/Models/CCIBackground.h +46 -0
  18. data/XCFit/Classes/Cucumberish/Core/Models/CCIBackground.m +117 -0
  19. data/XCFit/Classes/Cucumberish/Core/Models/CCIExample.h +89 -0
  20. data/XCFit/Classes/Cucumberish/Core/Models/CCIExample.m +128 -0
  21. data/XCFit/Classes/Cucumberish/Core/Models/CCIFeature.h +49 -0
  22. data/XCFit/Classes/Cucumberish/Core/Models/CCIFeature.m +174 -0
  23. data/XCFit/Classes/Cucumberish/Core/Models/CCIHock.h +36 -0
  24. data/XCFit/Classes/Cucumberish/Core/Models/CCIHock.m +34 -0
  25. data/XCFit/Classes/Cucumberish/Core/Models/CCILocation.h +61 -0
  26. data/XCFit/Classes/Cucumberish/Core/Models/CCILocation.m +91 -0
  27. data/XCFit/Classes/Cucumberish/Core/Models/CCIScenarioDefinition.h +97 -0
  28. data/XCFit/Classes/Cucumberish/Core/Models/CCIScenarioDefinition.m +224 -0
  29. data/XCFit/Classes/Cucumberish/Core/Models/CCIStep.h +85 -0
  30. data/XCFit/Classes/Cucumberish/Core/Models/CCIStep.m +98 -0
  31. data/XCFit/Classes/Cucumberish/Core/Models/CCIStepDefinition.h +43 -0
  32. data/XCFit/Classes/Cucumberish/Core/Models/CCIStepDefinition.m +65 -0
  33. data/XCFit/Classes/Cucumberish/Cucumberish.h +133 -0
  34. data/XCFit/Classes/Cucumberish/Cucumberish.m +604 -0
  35. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHAstBuilder.h +15 -0
  36. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHAstBuilder.m +312 -0
  37. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHAstNode.h +20 -0
  38. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHAstNode.m +79 -0
  39. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHBackground.h +12 -0
  40. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHBackground.m +18 -0
  41. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHComment.h +11 -0
  42. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHComment.m +27 -0
  43. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHDataTable.h +14 -0
  44. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHDataTable.m +30 -0
  45. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHDocString.h +14 -0
  46. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHDocString.m +29 -0
  47. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHExamples.h +24 -0
  48. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHExamples.m +49 -0
  49. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHFeature.h +24 -0
  50. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHFeature.m +50 -0
  51. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHGherkinDialect.h +25 -0
  52. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHGherkinDialect.m +64 -0
  53. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHGherkinDialectProvider.h +9 -0
  54. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHGherkinDialectProvider.m +124 -0
  55. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHGherkinDialectProviderProtocol.h +10 -0
  56. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHGherkinLanguageConstants.h +9 -0
  57. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHGherkinLanguageConstants.m +10 -0
  58. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHGherkinLanguageSetting.h +17 -0
  59. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHGherkinLanguageSetting.m +18 -0
  60. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHGherkinLine.h +12 -0
  61. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHGherkinLine.m +179 -0
  62. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHGherkinLineProtocol.h +64 -0
  63. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHGherkinLineSpan.h +9 -0
  64. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHGherkinLineSpan.m +26 -0
  65. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHHasDescriptionProtocol.h +8 -0
  66. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHHasLocationProtocol.h +8 -0
  67. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHHasRowsProtocol.h +8 -0
  68. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHHasStepsProtocol.h +8 -0
  69. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHHasTagsProtocol.h +8 -0
  70. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHLocation.h +12 -0
  71. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHLocation.m +41 -0
  72. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHNode.h +4 -0
  73. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHNode.m +5 -0
  74. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHParser+Extensions.h +10 -0
  75. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHParser+Extensions.m +18 -0
  76. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHParser.h +132 -0
  77. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHParser.m +2735 -0
  78. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHParserException.h +55 -0
  79. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHParserException.m +192 -0
  80. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHScenario.h +14 -0
  81. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHScenario.m +18 -0
  82. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHScenarioDefinition.h +23 -0
  83. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHScenarioDefinition.m +41 -0
  84. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHScenarioDefinition_Private.h +6 -0
  85. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHScenarioOutline.h +15 -0
  86. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHScenarioOutline.m +26 -0
  87. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHStep.h +16 -0
  88. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHStep.m +35 -0
  89. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHStepArgument.h +4 -0
  90. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHStepArgument.m +5 -0
  91. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHTableCell.h +13 -0
  92. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHTableCell.m +28 -0
  93. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHTableRow.h +13 -0
  94. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHTableRow.m +29 -0
  95. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHTag.h +13 -0
  96. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHTag.m +28 -0
  97. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHToken.h +26 -0
  98. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHToken.m +50 -0
  99. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHTokenMatcher.h +29 -0
  100. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHTokenMatcher.m +283 -0
  101. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHTokenScanner.h +12 -0
  102. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/GHTokenScanner.m +59 -0
  103. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/NSString+Trim.h +7 -0
  104. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/NSString+Trim.m +28 -0
  105. data/XCFit/Classes/Cucumberish/Dependencies/Gherkin/gherkin-languages.json +2969 -0
  106. data/XCFit/Classes/Cucumberish/Utils/NSArray+Hashes.h +24 -0
  107. data/XCFit/Classes/Cucumberish/Utils/NSArray+Hashes.m +44 -0
  108. data/XCFit/Classes/Cucumberish/Utils/NSObject+Dictionary.h +7 -0
  109. data/XCFit/Classes/Cucumberish/Utils/NSObject+Dictionary.m +83 -0
  110. data/XCFit/Classes/Cucumberish/Utils/NSString+Formatter.h +32 -0
  111. data/XCFit/Classes/Cucumberish/Utils/NSString+Formatter.m +70 -0
  112. data/Xcode7-Templates/XCFit/Cucumberish UI Test Bundle Base.xctemplate/TemplateInfo.plist +13 -0
  113. data/Xcode7-Templates/XCFit/iOS UI Cucumberish Testing Bundle.xctemplate/TemplateInfo.plist +11 -0
  114. data/lib/XCFit/version.rb +1 -1
  115. metadata +108 -38
  116. data/XCFit/Assets/.gitkeep +0 -0
  117. data/XCFit/Assets/Gherkin/Cucumber Feature.xctemplate/TemplateIcon.png +0 -0
  118. data/XCFit/Assets/Gherkin/Cucumber Feature.xctemplate/TemplateIcon@2x.png +0 -0
  119. data/XCFit/Assets/Gherkin/Cucumber Feature.xctemplate/TemplateInfo.plist +0 -22
  120. data/XCFit/Assets/Gherkin/Cucumber Feature.xctemplate/___FILEBASENAME___.feature +0 -20
  121. data/XCFit/Assets/XCFit/Base Acceptance Tests.xctemplate/AcceptanceTests-Bridging-Header.h +0 -1
  122. data/XCFit/Assets/XCFit/Base Acceptance Tests.xctemplate/FixtureExample.swift +0 -31
  123. data/XCFit/Assets/XCFit/Base Acceptance Tests.xctemplate/SlimTables.h +0 -28
  124. data/XCFit/Assets/XCFit/Base Acceptance Tests.xctemplate/TemplateIcon.png +0 -0
  125. data/XCFit/Assets/XCFit/Base Acceptance Tests.xctemplate/TemplateIcon@2x.png +0 -0
  126. data/XCFit/Assets/XCFit/Base Acceptance Tests.xctemplate/TemplateInfo.plist +0 -150
  127. data/XCFit/Assets/XCFit/Base Acceptance Tests.xctemplate/___PACKAGENAMEASIDENTIFIER___-Bridging-Header.h +0 -1
  128. data/XCFit/Assets/XCFit/Base Acceptance Tests.xctemplate/___PACKAGENAMEASIDENTIFIER___.m +0 -15
  129. data/XCFit/Assets/XCFit/Cucumberish API Test Bundle Base.xctemplate/TemplateIcon.png +0 -0
  130. data/XCFit/Assets/XCFit/Cucumberish API Test Bundle Base.xctemplate/TemplateIcon@2x.png +0 -0
  131. data/XCFit/Assets/XCFit/Cucumberish API Test Bundle Base.xctemplate/TemplateInfo.plist +0 -123
  132. data/XCFit/Assets/XCFit/Cucumberish API Test Bundle Base.xctemplate/___PACKAGENAMEASIDENTIFIER___-Bridging-Header.h +0 -7
  133. data/XCFit/Assets/XCFit/Cucumberish API Test Bundle Base.xctemplate/___PACKAGENAMEASIDENTIFIER___.feature +0 -11
  134. data/XCFit/Assets/XCFit/Cucumberish API Test Bundle Base.xctemplate/___PACKAGENAMEASIDENTIFIER___.h +0 -14
  135. data/XCFit/Assets/XCFit/Cucumberish API Test Bundle Base.xctemplate/___PACKAGENAMEASIDENTIFIER___.m +0 -17
  136. data/XCFit/Assets/XCFit/Cucumberish API Test Bundle Base.xctemplate/___PACKAGENAMEASIDENTIFIER___.swift +0 -23
  137. data/XCFit/Assets/XCFit/Cucumberish UI Test Bundle Base.xctemplate/TemplateIcon.png +0 -0
  138. data/XCFit/Assets/XCFit/Cucumberish UI Test Bundle Base.xctemplate/TemplateIcon@2x.png +0 -0
  139. data/XCFit/Assets/XCFit/Cucumberish UI Test Bundle Base.xctemplate/TemplateInfo.plist +0 -123
  140. data/XCFit/Assets/XCFit/Cucumberish UI Test Bundle Base.xctemplate/___PACKAGENAMEASIDENTIFIER___-Bridging-Header.h +0 -7
  141. data/XCFit/Assets/XCFit/Cucumberish UI Test Bundle Base.xctemplate/___PACKAGENAMEASIDENTIFIER___.feature +0 -11
  142. data/XCFit/Assets/XCFit/Cucumberish UI Test Bundle Base.xctemplate/___PACKAGENAMEASIDENTIFIER___.h +0 -14
  143. data/XCFit/Assets/XCFit/Cucumberish UI Test Bundle Base.xctemplate/___PACKAGENAMEASIDENTIFIER___.m +0 -17
  144. data/XCFit/Assets/XCFit/Cucumberish UI Test Bundle Base.xctemplate/___PACKAGENAMEASIDENTIFIER___.swift +0 -25
  145. data/XCFit/Assets/XCFit/Mac Acceptance Tests.xctemplate/Empty.xib +0 -12
  146. data/XCFit/Assets/XCFit/Mac Acceptance Tests.xctemplate/TemplateInfo.plist +0 -54
  147. data/XCFit/Assets/XCFit/MacOS API Cucumberish Testing Bundle.xctemplate/TemplateInfo.plist +0 -39
  148. data/XCFit/Assets/XCFit/MacOS UI Cucumberish Testing Bundle.xctemplate/TemplateInfo.plist +0 -39
  149. data/XCFit/Assets/XCFit/iOS API Cucumberish Testing Bundle.xctemplate/TemplateInfo.plist +0 -39
  150. data/XCFit/Assets/XCFit/iOS Acceptance Tests.xctemplate/TemplateInfo.plist +0 -52
  151. data/XCFit/Assets/XCFit/iOS UI Cucumberish Testing Bundle.xctemplate/TemplateInfo.plist +0 -39
@@ -0,0 +1,141 @@
1
+ //
2
+ // CCIFeaturesManager.m
3
+
4
+ //
5
+ // Created by Ahmed Ali on 02/01/16.
6
+ // Copyright © 2016 Ahmed Ali. All rights reserved.
7
+ //
8
+ //
9
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ // of this software and associated documentation files (the "Software"), to deal
11
+ // in the Software without restriction, including without limitation the rights
12
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ // copies of the Software, and to permit persons to whom the Software is
14
+ // furnished to do so, subject to the following conditions:
15
+ //
16
+ // The above copyright notice and this permission notice shall be included in
17
+ // all copies or substantial portions of the Software.
18
+ //
19
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25
+ // THE SOFTWARE.
26
+
27
+ #import "CCIFeaturesManager.h"
28
+ #import "GHParser+Extensions.h"
29
+ #import "NSObject+Dictionary.h"
30
+ #import "CCIFeature.h"
31
+ #import "CCIStepsManager.h"
32
+ #import "Cucumberish.h"
33
+ #import "CCIStepDefinition.h"
34
+
35
+
36
+
37
+ @interface CCIFeaturesManager()
38
+
39
+ @property NSMutableDictionary * featureClassMap;
40
+
41
+ @end
42
+
43
+ @implementation CCIFeaturesManager
44
+ + (instancetype)instance {
45
+ static CCIFeaturesManager * instance = nil;
46
+ @synchronized(self) {
47
+ if(instance == nil){
48
+ instance = [[CCIFeaturesManager alloc] init];
49
+ }
50
+ }
51
+ return instance;
52
+ }
53
+
54
+
55
+ - (instancetype) init
56
+ {
57
+ self = [super init];
58
+ self.featureClassMap = [@{} mutableCopy];
59
+ return self;
60
+ }
61
+
62
+ - (void)parseFeatureFiles:(NSArray *)featureFiles bundle:(NSBundle *)bundle withTags:(NSArray *)tags execludeFeaturesWithTags:(NSArray *)execludedFeatures
63
+ {
64
+ NSMutableArray * parsedFeatures = [NSMutableArray array];
65
+
66
+ GHParser * featureParser = [[GHParser alloc] init];
67
+ for (NSURL * filePath in featureFiles) {
68
+
69
+ id result = [featureParser parse:filePath.path];
70
+
71
+ if(result){
72
+ NSMutableDictionary * featureData = [[result dictionary] mutableCopy];
73
+
74
+ NSString * testBundlePath = [bundle bundlePath];
75
+ NSString * localPath = [[[filePath.absoluteString stringByRemovingPercentEncoding]
76
+ stringByReplacingOccurrencesOfString:testBundlePath withString:@""]
77
+ stringByReplacingOccurrencesOfString:@"file://" withString:@""];
78
+
79
+ featureData[@"location"][@"filePath"] = localPath;
80
+ CCIFeature * feature = [[CCIFeature alloc] initWithDictionary:featureData];
81
+
82
+
83
+ if(tags.count == 0){
84
+ //If we don't have specific tags, make sure we are not in the execluded tags
85
+ if(execludedFeatures.count > 0 && feature.tags.count > 0){
86
+ if(![self featureTags:feature.tags intersectWithTags:execludedFeatures]){
87
+ [parsedFeatures addObject:feature];
88
+ }
89
+ }else{
90
+ [parsedFeatures addObject:feature];
91
+ }
92
+
93
+ }else{
94
+ //If one of the feature tag is in the allowed tags
95
+ if([self featureTags:feature.tags intersectWithTags:tags]){
96
+ if(execludedFeatures.count > 0){
97
+ //Make sure that the feature doesn't contain execluded tags, and if so, execlude it...
98
+ if(![self featureTags:feature.tags intersectWithTags:execludedFeatures]){
99
+ [parsedFeatures addObject:feature];
100
+ }
101
+ }else{
102
+ [parsedFeatures addObject:feature];
103
+ }
104
+
105
+ }
106
+ }
107
+
108
+ }
109
+ }
110
+
111
+ _features = parsedFeatures;
112
+ }
113
+
114
+
115
+ - (BOOL)featureTags:(NSArray *)featureTags intersectWithTags:(NSArray *)tags
116
+ {
117
+ BOOL intersect = NO;
118
+ for(NSString * tag in featureTags){
119
+ if([tags containsObject:tag]){
120
+ intersect = YES;
121
+ break;
122
+ }
123
+ }
124
+
125
+ return intersect;
126
+ }
127
+
128
+
129
+ - (void)setClass:(Class)klass forFeature:(CCIFeature *)feature
130
+ {
131
+ NSString * className = NSStringFromClass(klass);
132
+ self.featureClassMap[className] = feature;
133
+ }
134
+
135
+ - (CCIFeature *)getFeatureForClass:(Class)klass
136
+ {
137
+ NSString * className = NSStringFromClass(klass);
138
+ return self.featureClassMap[className];
139
+ }
140
+
141
+ @end
@@ -0,0 +1,51 @@
1
+ //
2
+ // CCIStepsManager.h
3
+
4
+ //
5
+ // Created by Ahmed Ali on 03/01/16.
6
+ // Copyright © 2016 Ahmed Ali. All rights reserved.
7
+ //
8
+ //
9
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ // of this software and associated documentation files (the "Software"), to deal
11
+ // in the Software without restriction, including without limitation the rights
12
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ // copies of the Software, and to permit persons to whom the Software is
14
+ // furnished to do so, subject to the following conditions:
15
+ //
16
+ // The above copyright notice and this permission notice shall be included in
17
+ // all copies or substantial portions of the Software.
18
+ //
19
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25
+ // THE SOFTWARE.
26
+
27
+ #import <Foundation/Foundation.h>
28
+
29
+
30
+
31
+ @class CCIStep;
32
+
33
+ /**
34
+ CCIStepsManager is a singleton class and its main purpose is to manage all step definitions and execute steps.
35
+ */
36
+ @interface CCIStepsManager : NSObject
37
+
38
+ /**
39
+ Returns the singleton class of CCIStepsManager
40
+ */
41
+ + (instancetype)instance;
42
+
43
+ /**
44
+ Executes the passed step if it matches any previously defined implementation. Or throw an error if there is no matching definiton.
45
+
46
+ @param step the to be executed
47
+ @param testCase the test case that is being executed when this step implementation is being called
48
+ */
49
+ - (void)executeStep:(CCIStep *)step inTestCase:(id)testCase;
50
+
51
+ @end
@@ -0,0 +1,245 @@
1
+ //
2
+ // CCIStepsManager.m
3
+
4
+ //
5
+ // Created by Ahmed Ali on 03/01/16.
6
+ // Copyright © 2016 Ahmed Ali. All rights reserved.
7
+ //
8
+ //
9
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ // of this software and associated documentation files (the "Software"), to deal
11
+ // in the Software without restriction, including without limitation the rights
12
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ // copies of the Software, and to permit persons to whom the Software is
14
+ // furnished to do so, subject to the following conditions:
15
+ //
16
+ // The above copyright notice and this permission notice shall be included in
17
+ // all copies or substantial portions of the Software.
18
+ //
19
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25
+ // THE SOFTWARE.
26
+
27
+ #import "CCIStepsManager.h"
28
+ #import "Cucumberish.h"
29
+ #import "CCIStep.h"
30
+ #import "CCIStepDefinition.h"
31
+
32
+ static CCIStepsManager * instance = nil;
33
+
34
+
35
+ const NSString * kDataTableKey = @"DataTable";
36
+ const NSString * kDocStringKey = @"DocString";
37
+ const NSString * kXCTestCaseKey = @"XCTestCase";
38
+
39
+ @interface CCIStepsManager()
40
+ @property NSMutableDictionary * definitions;
41
+ @end
42
+
43
+ @implementation CCIStepsManager
44
+
45
+
46
+
47
+ + (instancetype)instance {
48
+
49
+ @synchronized(self) {
50
+ if(instance == nil){
51
+ instance = [[CCIStepsManager alloc] init];
52
+ }
53
+ }
54
+ return instance;
55
+ }
56
+
57
+ - (instancetype)init
58
+ {
59
+ self = [super init];
60
+
61
+ self.definitions = [NSMutableDictionary dictionary];
62
+
63
+ return self;
64
+ }
65
+
66
+
67
+ - (NSMutableArray *)definitionsCluster:(NSString *)type
68
+ {
69
+ NSMutableArray * cluster = self.definitions[type];
70
+ if(cluster == nil){
71
+ cluster = [NSMutableArray array];
72
+ self.definitions[type] = cluster;
73
+ }
74
+
75
+ return cluster;
76
+ }
77
+
78
+
79
+ - (CCIStepDefinition *)findMatchDefinitionForStep:(CCIStep *)step inTestCase:(id)testCase
80
+ {
81
+ if(step.keyword == nil){
82
+ //We should try to match it using all available definitions
83
+ NSMutableArray * allDefinitions = [NSMutableArray array];
84
+ for(NSArray * definitions in self.definitions.allValues){
85
+ [allDefinitions addObjectsFromArray:definitions];
86
+ }
87
+ return [self findDefinitionForStep:step amongDefinitions:allDefinitions inTestCase:testCase];
88
+ }
89
+ NSArray * definitionGroup = self.definitions[step.keyword];
90
+ return [self findDefinitionForStep:step amongDefinitions:definitionGroup inTestCase:testCase];
91
+
92
+ }
93
+
94
+ - (CCIStepDefinition *)findDefinitionForStep:(CCIStep *)step amongDefinitions:(NSArray *)definitions inTestCase:(id)testCase
95
+ {
96
+ NSError * error;
97
+ CCIStepDefinition * retDefinition = nil;
98
+
99
+ for(CCIStepDefinition * d in definitions){
100
+ NSString * pattern = d.regexString;
101
+
102
+ if ([d.regexString isEqualToString:step.text]) {
103
+ //It has no params, it is just plain perfect match
104
+ retDefinition = [d copy];
105
+ break;
106
+ }
107
+ NSRegularExpression * regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionAnchorsMatchLines error:&error];
108
+ if(error && d == definitions.lastObject){
109
+ //Only return nil if we reached the last definition without finding a match
110
+ break;
111
+ }
112
+ NSRange searchRange = NSMakeRange(0, [step.text lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
113
+ NSTextCheckingResult * match = [[regex matchesInString:step.text options:NSMatchingReportCompletion range:searchRange] firstObject];
114
+
115
+ if (match.numberOfRanges > 1) {
116
+ //Looks like a perfect match!
117
+ CCIStepDefinition * definition = [d copy];
118
+ NSMutableArray * values = [NSMutableArray arrayWithCapacity:match.numberOfRanges - 1];
119
+ for(int i = 1; i < match.numberOfRanges; i++){
120
+ NSRange range = [match rangeAtIndex:i];
121
+ NSString * value = [step.text substringWithRange:range];
122
+ [values addObject:value];
123
+ }
124
+
125
+ definition.matchedValues = values;
126
+ retDefinition = definition;
127
+ break;
128
+ }
129
+ }
130
+
131
+ if (retDefinition) {
132
+ if(step.argument.rows.count > 0){
133
+ retDefinition.additionalContent = @{kDataTableKey : step.argument.rows};
134
+ }else if(step.argument.content.length > 0){
135
+ retDefinition.additionalContent = @{kDocStringKey : step.argument.content};
136
+ }
137
+ }
138
+ if([testCase isKindOfClass:[XCTestCase class]]){
139
+ NSMutableDictionary * additionalContent = [retDefinition.additionalContent mutableCopy] ? :[NSMutableDictionary new];
140
+ additionalContent[kXCTestCaseKey] = testCase;
141
+ retDefinition.additionalContent = additionalContent;
142
+ }
143
+
144
+
145
+ return retDefinition;
146
+ }
147
+
148
+ - (void)executeStep:(CCIStep *)step inTestCase:(id)testCase
149
+ {
150
+ CCIStepDefinition * implementation = [self findMatchDefinitionForStep:step inTestCase:testCase];
151
+ NSString * errorMessage = nil;
152
+ if(step.keyword.length > 0){
153
+ errorMessage = [NSString stringWithFormat:@"The step \"%@ %@\" is not implemented", step.keyword, [step.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
154
+ }else{
155
+ //It is a step that is called from an step definition
156
+ errorMessage = [NSString stringWithFormat:@"The implementation of this step, calls another step that is not implemented: %@", [step.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
157
+ }
158
+ CCIAssert(implementation != nil, errorMessage);
159
+ if(step.keyword.length > 0){
160
+ NSLog(@"Currently executing: \"%@ %@\"", step.keyword, step.text);
161
+ }
162
+
163
+ implementation.body(implementation.matchedValues, implementation.additionalContent);
164
+ //Clean up the step additional content to avoid keeping unwanted objects in memory
165
+ implementation.additionalContent = nil;
166
+ if(step.keyword.length > 0){
167
+ NSLog(@"Step: \"%@ %@\" passed", step.keyword, step.text);
168
+ }
169
+ step.status = CCIStepStatusPassed;
170
+ }
171
+
172
+
173
+
174
+ @end
175
+
176
+
177
+ void addDefinition(NSString * definitionString, CCIStepBody body, NSString * type);
178
+
179
+ #pragma mark - C Routines
180
+
181
+ void Given(NSString * definitionString, CCIStepBody body)
182
+ {
183
+ addDefinition(definitionString, body, @"Given");
184
+ }
185
+ void When(NSString * definitionString, CCIStepBody body)
186
+ {
187
+ addDefinition(definitionString, body, @"When");
188
+ }
189
+ void Then(NSString * definitionString, CCIStepBody body)
190
+ {
191
+ addDefinition(definitionString, body, @"Then");
192
+ }
193
+ void And(NSString * definitionString, CCIStepBody body)
194
+ {
195
+ addDefinition(definitionString, body, @"And");
196
+ }
197
+ void But(NSString * definitionString, CCIStepBody body)
198
+ {
199
+ addDefinition(definitionString, body, @"But");
200
+ }
201
+
202
+ void MatchAll(NSString * definitionString, CCIStepBody body)
203
+ {
204
+ When(definitionString, body);
205
+ Then(definitionString, body);
206
+ And(definitionString, body);
207
+ But(definitionString, body);
208
+ }
209
+
210
+ void Match(NSArray *types, NSString * definitionString, CCIStepBody body)
211
+ {
212
+ for (NSString * type in types) {
213
+ addDefinition(definitionString, body, type);
214
+ }
215
+ }
216
+ void addDefinition(NSString * definitionString, CCIStepBody body, NSString * type)
217
+ {
218
+ CCIStepDefinition * definition = [CCIStepDefinition definitionWithType:type regexString:definitionString implementationBody:body];
219
+ NSMutableArray * cluster = [[CCIStepsManager instance] definitionsCluster:type];
220
+ [cluster insertObject:definition atIndex:0];
221
+ }
222
+
223
+ void step(id testCase, NSString * stepLine, ...)
224
+ {
225
+ va_list args;
226
+ va_start(args, stepLine);
227
+ NSString * line = [[NSString alloc] initWithFormat:stepLine arguments:args];
228
+ va_end(args);
229
+
230
+ CCIStep * step = [CCIStep new];
231
+ step.text = line;
232
+ [[CCIStepsManager instance] executeStep:step inTestCase:testCase];
233
+ }
234
+
235
+ void SStep(id testCase, NSString * stepLine)
236
+ {
237
+ step(testCase, stepLine);
238
+ }
239
+
240
+
241
+
242
+
243
+
244
+
245
+
@@ -0,0 +1,62 @@
1
+ //
2
+ // CCIArgument.h
3
+ //
4
+ // Created by Ahmed Ali on 2/1/2016
5
+ // Copyright © 2016 Ahmed Ali. All rights reserved.
6
+ //
7
+ //
8
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ // of this software and associated documentation files (the "Software"), to deal
10
+ // in the Software without restriction, including without limitation the rights
11
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ // copies of the Software, and to permit persons to whom the Software is
13
+ // furnished to do so, subject to the following conditions:
14
+ //
15
+ // The above copyright notice and this permission notice shall be included in
16
+ // all copies or substantial portions of the Software.
17
+ //
18
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ // THE SOFTWARE.
25
+
26
+ // Model file Generated using JSONExport: https://github.com/Ahmed-Ali/JSONExport
27
+
28
+ #import <Foundation/Foundation.h>
29
+
30
+ /**
31
+ Represents a DocString arguemnt or a DataTable argument passed to a step
32
+ */
33
+ @interface CCIArgument : NSObject
34
+
35
+
36
+ /**
37
+ In case this is a DataTable arguemnt, then this property will contain array of arrays where each item in the array is a row, that has an array of cells
38
+ */
39
+ @property (nonatomic, strong) NSArray<NSArray *> * rows;
40
+
41
+
42
+ /**
43
+ The string content in case it is a DocString argument
44
+ */
45
+ @property (nonatomic, copy) NSString * content;
46
+
47
+ /**
48
+ Creates an instance with properties filled from the passed dictionary
49
+
50
+ @param dictionary the dictionary that contains all the argument data
51
+
52
+ @return argument instance
53
+ */
54
+ -(instancetype)initWithDictionary:(NSDictionary *)dictionary;
55
+
56
+ /**
57
+ Creates a dictionary from the class properties
58
+
59
+ @return the created dictionary
60
+ */
61
+ -(NSDictionary *)toDictionary;
62
+ @end