Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Merge branch 'fetch-documentation' into experimental

  • Loading branch information...
commit 89fc82c3b40cf64a2c946bfb374c4f437d3fd39a 2 parents 4c47395 + 91d6dc3
tomaz tomaz authored

Showing 24 changed files with 927 additions and 287 deletions. Show diff stats Hide diff stats

  1. +2 10 AppledocTests/Common/SettingsTests.mm
  2. +267 0 AppledocTests/Processing/FetchDocumentationTaskTests.mm
  3. +33 86 AppledocTests/Processing/LinkKnownObjectsTaskTests.mm
  4. +32 139 AppledocTests/Processing/ProcessorTests.mm
  5. +27 0 AppledocTests/Store/InterfaceInfoBaseTests.mm
  6. +16 3 AppledocTests/Store/MethodInfoTests.mm
  7. +60 0 AppledocTests/TestingBase/StoreMocks.h
  8. +222 0 AppledocTests/TestingBase/StoreMocks.m
  9. +26 0 appledoc.xcodeproj/project.pbxproj
  10. +2 10 appledoc/Common/GBSettings+Appledoc.h
  11. +2 10 appledoc/Common/GBSettings+Appledoc.m
  12. +1 3 appledoc/Common/GBSettings+Helpers.m
  13. +17 0 appledoc/Processing/FetchDocumentationTask.h
  14. +137 0 appledoc/Processing/FetchDocumentationTask.m
  15. +7 7 appledoc/Processing/LinkKnownObjectsTask.m
  16. +1 0  appledoc/Processing/Processor.h
  17. +12 2 appledoc/Processing/Processor.m
  18. +2 0  appledoc/Store/InterfaceInfoBase.m
  19. +21 0 appledoc/Store/MemberInfoBase.h
  20. +17 0 appledoc/Store/MemberInfoBase.m
  21. +3 2 appledoc/Store/MethodInfo.h
  22. +15 6 appledoc/Store/MethodInfo.m
  23. +2 2 appledoc/Store/PropertyInfo.h
  24. +3 7 appledoc/main.m
12 AppledocTests/Common/SettingsTests.mm
@@ -62,8 +62,10 @@ static void runWithSettings(void(^handler)(GBSettings *settings)) {
62 62 it(@"should work for comment related settings", ^{
63 63 runWithSettings(^(GBSettings *settings) {
64 64 // execute
  65 + [settings setBool:YES forKey:GBOptions.searchMissingComments];
65 66 [settings setObject:@"crossrefs" forKey:GBOptions.crossRefsFormat];
66 67 // verify
  68 + settings.searchForMissingComments should equal(YES);
67 69 settings.crossRefsFormat should equal(@"crossrefs");
68 70 });
69 71 });
@@ -73,19 +75,9 @@ static void runWithSettings(void(^handler)(GBSettings *settings)) {
73 75 // execute
74 76 [settings setInteger:2 forKey:GBOptions.loggingFormat];
75 77 [settings setInteger:3 forKey:GBOptions.loggingLevel];
76   - [settings setBool:YES forKey:GBOptions.loggingInternalEnabled];
77   - [settings setBool:YES forKey:GBOptions.loggingCommonEnabled];
78   - [settings setBool:YES forKey:GBOptions.loggingStoreEnabled];
79   - [settings setBool:YES forKey:GBOptions.loggingParsingEnabled];
80   - [settings setBool:YES forKey:GBOptions.loggingProcessingEnabled];
81 78 // verify
82 79 settings.loggingFormat should equal(2);
83 80 settings.loggingLevel should equal(3);
84   - settings.loggingInternalEnabled should equal(YES);
85   - settings.loggingCommonEnabled should equal(YES);
86   - settings.loggingStoreEnabled should equal(YES);
87   - settings.loggingParsingEnabled should equal(YES);
88   - settings.loggingProcessingEnabled should equal(YES);
89 81 });
90 82 });
91 83
267 AppledocTests/Processing/FetchDocumentationTaskTests.mm
... ... @@ -0,0 +1,267 @@
  1 +//
  2 +// FetchDocumentationTaskTests.m
  3 +// appledoc
  4 +//
  5 +// Created by Tomaz Kragelj on 7/12/12.
  6 +// Copyright (c) 2012 Tomaz Kragelj. All rights reserved.
  7 +//
  8 +
  9 +#import "StoreMocks.h"
  10 +#import "FetchDocumentationTask.h"
  11 +#import "TestCaseBase.hh"
  12 +
  13 +#define GBSections [comment sourceSections]
  14 +
  15 +#pragma mark -
  16 +
  17 +static void runWithTask(id store, id settings, void(^handler)(FetchDocumentationTask *task, id store, id settings)) {
  18 + FetchDocumentationTask *task = [[FetchDocumentationTask alloc] init];
  19 + task.settings = settings ? settings : mock([GBSettings class]);
  20 + task.store = store ? store : mock([Store class]);
  21 + handler(task, task.store, task.settings);
  22 + [task release];
  23 +}
  24 +
  25 +static void runWithTask(void(^handler)(FetchDocumentationTask *task, id store, id settings)) {
  26 + runWithTask(nil, nil, handler);
  27 +}
  28 +
  29 +static id createBaseClass() {
  30 + return [StoreMocks mockClass:@"BaseClass" block:^(id object) { }];
  31 +}
  32 +
  33 +static id createDerivedClass(id baseClass) {
  34 + return [StoreMocks mockClass:@"DerivedClass" block:^(id object) {
  35 + [StoreMocks add:object asDerivedClassFrom:baseClass];
  36 + }];
  37 +}
  38 +
  39 +static id createAdoptedProtocol(NSString *name, id adoptedInObject) {
  40 + return [StoreMocks mockProtocol:name block:^(id object) {
  41 + [StoreMocks add:adoptedInObject asAdopting:object];
  42 + }];
  43 +}
  44 +
  45 +static id createMethod(NSString *selector, id parent) {
  46 + BOOL isClassMethod = [selector hasPrefix:@"+"];
  47 + return [StoreMocks createMethod:selector block:^(MethodInfo *object) {
  48 + if (isClassMethod)
  49 + [StoreMocks add:object asClassMethodOf:parent];
  50 + else
  51 + [StoreMocks add:object asInstanceMethodOf:parent];
  52 + }];
  53 +}
  54 +
  55 +static id createCommentedMethod(NSString *selector, id parent) {
  56 + id result = createMethod(selector, parent);
  57 + [StoreMocks addMockCommentTo:result];
  58 + return result;
  59 +}
  60 +
  61 +static id createProperty(NSString *name, id parent) {
  62 + return [StoreMocks createProperty:name block:^(PropertyInfo *object) {
  63 + [StoreMocks add:object asPropertyOf:parent];
  64 + }];
  65 +}
  66 +
  67 +static id createCommentedProperty(NSString *name, id parent) {
  68 + id result = createProperty(name, parent);
  69 + [StoreMocks addMockCommentTo:result];
  70 + return result;
  71 +}
  72 +
  73 +#define GBSearch [info[@"search"] boolValue]
  74 +#define GBVerify(d,b) if (GBSearch) d.comment should equal(b.comment); else d.comment should be_nil()
  75 +
  76 +#pragma mark -
  77 +
  78 +TEST_BEGIN(FetchDocumentationTaskTests)
  79 +
  80 +describe(@"copy documentation from super classes:", ^{
  81 + sharedExamplesFor(@"examples", ^(NSDictionary *info) {
  82 + __block id settings;
  83 +
  84 + beforeEach(^{
  85 + settings = mock([GBSettings class]);
  86 + [given([settings searchForMissingComments]) willReturnBool:GBSearch];
  87 + });
  88 +
  89 + it(@"should handle class method", ^{
  90 + runWithTask(nil, settings, ^(FetchDocumentationTask *task, id store, id settings) {
  91 + // setup
  92 + id baseClass = createBaseClass();
  93 + id derivedClass = createDerivedClass(baseClass);
  94 + MethodInfo *baseMethod = createCommentedMethod(@"+method", baseClass);
  95 + MethodInfo *derivedMethod = createMethod(@"+method", derivedClass);
  96 + [given([store storeClasses]) willReturn:@[ baseClass, derivedClass ]];
  97 + // execute
  98 + [task runTask];
  99 + // verify
  100 + GBVerify(derivedMethod, baseMethod);
  101 + });
  102 + });
  103 +
  104 + it(@"should handle instance method", ^{
  105 + runWithTask(nil, settings, ^(FetchDocumentationTask *task, id store, id settings) {
  106 + // setup
  107 + id baseClass = createBaseClass();
  108 + id derivedClass = createDerivedClass(baseClass);
  109 + MethodInfo *baseMethod = createCommentedMethod(@"-method", baseClass);
  110 + MethodInfo *derivedMethod = createMethod(@"-method", derivedClass);
  111 + [given([store storeClasses]) willReturn:@[ baseClass, derivedClass ]];
  112 + // execute
  113 + [task runTask];
  114 + // verify
  115 + GBVerify(derivedMethod, baseMethod);
  116 + });
  117 + });
  118 +
  119 + it(@"should copy property from base class", ^{
  120 + runWithTask(nil, settings, ^(FetchDocumentationTask *task, id store, id settings) {
  121 + // setup
  122 + id baseClass = createBaseClass();
  123 + id derivedClass = createDerivedClass(baseClass);
  124 + PropertyInfo *baseProperty = createCommentedProperty(@"property", baseClass);
  125 + PropertyInfo *derivedProperty = createProperty(@"property", derivedClass);
  126 + [given([store storeClasses]) willReturn:@[ baseClass, derivedClass ]];
  127 + // execute
  128 + [task runTask];
  129 + // verify
  130 + GBVerify(derivedProperty, baseProperty);
  131 + });
  132 + });
  133 + });
  134 +
  135 + describe(@"search enabled:", ^{
  136 + beforeEach(^{
  137 + [[SpecHelper specHelper] sharedExampleContext][@"search"] = @(YES);
  138 + });
  139 + itShouldBehaveLike(@"examples");
  140 + });
  141 +
  142 + describe(@"search disabled:", ^{
  143 + beforeEach(^{
  144 + [[SpecHelper specHelper] sharedExampleContext][@"search"] = @(NO);
  145 + });
  146 + itShouldBehaveLike(@"examples");
  147 + });
  148 +});
  149 +
  150 +describe(@"adopted protocols:", ^{
  151 + // This block describes actual unit tests.
  152 + sharedExamplesFor(@"examples", ^(NSDictionary *info) {
  153 + __block id store;
  154 + __block id settings;
  155 +
  156 + beforeEach(^{
  157 + store = info[@"store"];
  158 + settings = mock([GBSettings class]);
  159 + [given([settings searchForMissingComments]) willReturnBool:GBSearch];
  160 + });
  161 +
  162 + it(@"should fetch for class methods", ^{
  163 + runWithTask(store, settings, ^(FetchDocumentationTask *task, id store, id settings) {
  164 + // setup
  165 + id object = info[@"object"];
  166 + id protocol = createAdoptedProtocol(@"Protocol", object);
  167 + MethodInfo *objectClassMethod = createMethod(@"+method", object);
  168 + ObjectInfoBase *protocolClassMethod = createCommentedMethod(@"+method", protocol);
  169 + // execute
  170 + [task runTask];
  171 + // verify
  172 + GBVerify(objectClassMethod, protocolClassMethod);
  173 + });
  174 + });
  175 +
  176 + it(@"should fetch for instance methods", ^{
  177 + runWithTask(store, settings, ^(FetchDocumentationTask *task, id store, id settings) {
  178 + // setup
  179 + id object = info[@"object"];
  180 + id protocol = createAdoptedProtocol(@"Protocol", object);
  181 + MethodInfo *objectInstanceMethod = createMethod(@"-method", object);
  182 + ObjectInfoBase *protocolInstanceMethod = createCommentedMethod(@"-method", protocol);
  183 + // execute
  184 + [task runTask];
  185 + // verify
  186 + GBVerify(objectInstanceMethod, protocolInstanceMethod);
  187 + });
  188 + });
  189 +
  190 + it(@"should fetch for properties", ^{
  191 + runWithTask(store, settings, ^(FetchDocumentationTask *task, id store, id settings) {
  192 + // setup
  193 + id object = info[@"object"];
  194 + id protocol = createAdoptedProtocol(@"Protocol", object);
  195 + PropertyInfo *objectProperty = createProperty(@"property", object);
  196 + ObjectInfoBase *protocolProperty = createCommentedProperty(@"property", protocol);
  197 + // execute
  198 + [task runTask];
  199 + // verify
  200 + GBVerify(objectProperty, protocolProperty);
  201 + });
  202 + });
  203 + });
  204 +
  205 + // This block described variants for above tests (repeats the tests for different types of objects).
  206 + sharedExamplesFor(@"variants", ^(NSDictionary *info) {
  207 + describe(@"classes:", ^{
  208 + beforeEach(^{
  209 + id store = mock([Store class]);
  210 + id object = mock([ClassInfo class]);
  211 + [given([store storeClasses]) willReturn:@[ object ]];
  212 + [[SpecHelper specHelper] sharedExampleContext][@"store"] = store;
  213 + [[SpecHelper specHelper] sharedExampleContext][@"object"] = object;
  214 + });
  215 + itShouldBehaveLike(@"examples");
  216 + });
  217 +
  218 + describe(@"extensions:", ^{
  219 + beforeEach(^{
  220 + id store = mock([Store class]);
  221 + id object = mock([CategoryInfo class]);
  222 + [given([store storeExtensions]) willReturn:@[ object ]];
  223 + [[SpecHelper specHelper] sharedExampleContext][@"store"] = store;
  224 + [[SpecHelper specHelper] sharedExampleContext][@"object"] = object;
  225 + });
  226 + itShouldBehaveLike(@"examples");
  227 + });
  228 +
  229 + describe(@"categories:", ^{
  230 + beforeEach(^{
  231 + id store = mock([Store class]);
  232 + id object = mock([CategoryInfo class]);
  233 + [given([store storeCategories]) willReturn:@[ object ]];
  234 + [[SpecHelper specHelper] sharedExampleContext][@"store"] = store;
  235 + [[SpecHelper specHelper] sharedExampleContext][@"object"] = object;
  236 + });
  237 + itShouldBehaveLike(@"examples");
  238 + });
  239 +
  240 + describe(@"protocols:", ^{
  241 + beforeEach(^{
  242 + id store = mock([Store class]);
  243 + id object = mock([ProtocolInfo class]);
  244 + [given([store storeProtocols]) willReturn:@[ object ]];
  245 + [[SpecHelper specHelper] sharedExampleContext][@"store"] = store;
  246 + [[SpecHelper specHelper] sharedExampleContext][@"object"] = object;
  247 + });
  248 + itShouldBehaveLike(@"examples");
  249 + });
  250 + });
  251 +
  252 + // These two blocks repeat all the variants, for all the examples, for search enabled or disabled.
  253 + describe(@"search enabled:", ^{
  254 + beforeEach(^{
  255 + [[SpecHelper specHelper] sharedExampleContext][@"search"] = @(YES);
  256 + });
  257 + itShouldBehaveLike(@"variants");
  258 + });
  259 + describe(@"search disabled:", ^{
  260 + beforeEach(^{
  261 + [[SpecHelper specHelper] sharedExampleContext][@"search"] = @(NO);
  262 + });
  263 + itShouldBehaveLike(@"variants");
  264 + });
  265 +});
  266 +
  267 +TEST_END
119 AppledocTests/Processing/LinkKnownObjectsTaskTests.mm
@@ -7,8 +7,9 @@
7 7 //
8 8
9 9 #import "Store.h"
10   -#import "LinkKnownObjectsTask.h"
11 10 #import "TestCaseBase.hh"
  11 +#import "StoreMocks.h"
  12 +#import "LinkKnownObjectsTask.h"
12 13
13 14 #define GBSections [comment sourceSections]
14 15
@@ -21,59 +22,25 @@ static void runWithTask(void(^handler)(LinkKnownObjectsTask *task, id store)) {
21 22 [task release];
22 23 }
23 24
24   -static id createInterface(void(^handler)(InterfaceInfoBase *interface)) {
25   - InterfaceInfoBase *result = [[InterfaceInfoBase alloc] init];
26   - handler(result);
27   - return result;
28   -}
29   -
30   -static id createClass(void(^handler)(ClassInfo *info)) {
31   - ClassInfo *result = [[ClassInfo alloc] init];
32   - handler(result);
33   - return result;
34   -}
35   -
36 25 static id createClass(NSString *name) {
37   - id result = mock([ClassInfo class]);
38   - [given([result nameOfClass]) willReturn:name];
39   - return result;
40   -}
41   -
42   -static id createCategory(void(^handler)(CategoryInfo *info)) {
43   - CategoryInfo *result = [[CategoryInfo alloc] init];
44   - handler(result);
45   - return result;
46   -}
47   -
48   -static id createProtocol(void(^handler)(ProtocolInfo *info)) {
49   - ProtocolInfo *result = [[ProtocolInfo alloc] init];
50   - handler(result);
51   - return result;
  26 + return [StoreMocks mockClass:name block:^(id object) { }];
52 27 }
53 28
54 29 static id createProtocol(NSString *name) {
55   - id result = mock([ProtocolInfo class]);
56   - [given([result nameOfProtocol]) willReturn:name];
57   - return result;
58   -}
59   -
60   -static void deriveClass(ClassInfo *object, NSString *name) {
61   - object.classSuperClass.nameOfObject = name;
  30 + return [StoreMocks mockProtocol:name block:^(id object) { }];
62 31 }
63 32
64   -static void extendClass(CategoryInfo *object, NSString *name) {
65   - object.categoryClass.nameOfObject = name;
  33 +static id createDerivedClass(NSString *name, NSString *baseName) {
  34 + return [StoreMocks createClass:^(ClassInfo *object) {
  35 + object.nameOfClass = name;
  36 + [object derive:baseName];
  37 + }];
66 38 }
67 39
68   -static void adoptProtocols(InterfaceInfoBase *interface, NSString *first, ...) {
69   - va_list args;
70   - va_start(args, first);
71   - for (NSString *arg=first; arg!=nil; arg=va_arg(args, NSString *)) {
72   - ObjectLinkInfo *link = [[ObjectLinkInfo alloc] init];
73   - link.nameOfObject = arg;
74   - [interface.interfaceAdoptedProtocols addObject:link];
75   - }
76   - va_end(args);
  40 +static id createCategory(NSString *className) {
  41 + return [StoreMocks createCategory:^(CategoryInfo *object) {
  42 + [object extend:className];
  43 + }];
77 44 }
78 45
79 46 #pragma mark -
@@ -85,9 +52,9 @@ static void adoptProtocols(InterfaceInfoBase *interface, NSString *first, ...) {
85 52 it(@"should link classes to known protocols", ^{
86 53 runWithTask(^(LinkKnownObjectsTask *task, id store) {
87 54 // setup
88   - InterfaceInfoBase *class1 = createInterface(^(InterfaceInfoBase *interface) {
89   - adoptProtocols(interface, @"MyProtocol1", @"MyProtocol2", @"UnknownProtocol", nil);
90   - });
  55 + ClassInfo *class1 = [StoreMocks createClass:^(ClassInfo *object) {
  56 + [object adopt:@"MyProtocol1", @"MyProtocol2", @"UnknownProtocol", nil];
  57 + }];
91 58 id protocol1 = createProtocol(@"MyProtocol1");
92 59 id protocol2 = createProtocol(@"MyProtocol2");
93 60 [given([store storeProtocols]) willReturn:@[ protocol1, protocol2 ]];
@@ -104,10 +71,9 @@ static void adoptProtocols(InterfaceInfoBase *interface, NSString *first, ...) {
104 71
105 72 it(@"should link extensions to known protocols", ^{
106 73 runWithTask(^(LinkKnownObjectsTask *task, id store) {
107   - // setup
108   - InterfaceInfoBase *extension1 = createCategory(^(CategoryInfo *interface) {
109   - adoptProtocols(interface, @"MyProtocol1", @"MyProtocol2", @"UnknownProtocol", nil);
110   - });
  74 + CategoryInfo *extension1 = [StoreMocks createCategory:^(CategoryInfo *object) {
  75 + [object adopt:@"MyProtocol1", @"MyProtocol2", @"UnknownProtocol", nil];
  76 + }];
111 77 id protocol1 = createProtocol(@"MyProtocol1");
112 78 id protocol2 = createProtocol(@"MyProtocol2");
113 79 [given([store storeProtocols]) willReturn:@[ protocol1, protocol2 ]];
@@ -124,9 +90,9 @@ static void adoptProtocols(InterfaceInfoBase *interface, NSString *first, ...) {
124 90 it(@"should link categories to known protocols", ^{
125 91 runWithTask(^(LinkKnownObjectsTask *task, id store) {
126 92 // setup
127   - InterfaceInfoBase *category1 = createCategory(^(CategoryInfo *interface) {
128   - adoptProtocols(interface, @"MyProtocol1", @"MyProtocol2", @"UnknownProtocol", nil);
129   - });
  93 + CategoryInfo *category1 = [StoreMocks createCategory:^(CategoryInfo *object) {
  94 + [object adopt:@"MyProtocol1", @"MyProtocol2", @"UnknownProtocol", nil];
  95 + }];
130 96 id protocol1 = createProtocol(@"MyProtocol1");
131 97 id protocol2 = createProtocol(@"MyProtocol2");
132 98 [given([store storeProtocols]) willReturn:@[ protocol1, protocol2 ]];
@@ -143,9 +109,9 @@ static void adoptProtocols(InterfaceInfoBase *interface, NSString *first, ...) {
143 109 it(@"should link protocols to known protocols", ^{
144 110 runWithTask(^(LinkKnownObjectsTask *task, id store) {
145 111 // setup
146   - ProtocolInfo *protocol1 = createProtocol(^(ProtocolInfo *info) {
147   - adoptProtocols(info, @"MyProtocol1", @"MyProtocol2", @"UnknownProtocol", nil);
148   - });
  112 + ProtocolInfo *protocol1 = [StoreMocks createProtocol:^(ProtocolInfo *object) {
  113 + [object adopt:@"MyProtocol1", @"MyProtocol2", @"UnknownProtocol", nil];
  114 + }];
149 115 id protocol2 = createProtocol(@"MyProtocol1");
150 116 id protocol3 = createProtocol(@"MyProtocol2");
151 117 [given([store storeProtocols]) willReturn:@[ protocol1, protocol2, protocol3 ]];
@@ -163,9 +129,7 @@ static void adoptProtocols(InterfaceInfoBase *interface, NSString *first, ...) {
163 129 it(@"should link to known super classes", ^{
164 130 runWithTask(^(LinkKnownObjectsTask *task, id store) {
165 131 // setup
166   - ClassInfo *class1 = createClass(^(ClassInfo *info) {
167   - deriveClass(info, @"MyBaseClass");
168   - });
  132 + ClassInfo *class1 = createDerivedClass(@"MyClass", @"MyBaseClass");
169 133 id class2 = createClass(@"MyBaseClass");
170 134 [given([store storeClasses]) willReturn:@[ class1, class2 ]];
171 135 // execute
@@ -178,18 +142,9 @@ static void adoptProtocols(InterfaceInfoBase *interface, NSString *first, ...) {
178 142 it(@"should handle multiple depths of class hierarchies", ^{
179 143 runWithTask(^(LinkKnownObjectsTask *task, id store) {
180 144 // setup
181   - ClassInfo *class1 = createClass(^(ClassInfo *info) {
182   - info.nameOfClass = @"Class1";
183   - deriveClass(info, @"Class2");
184   - });
185   - ClassInfo *class2 = createClass(^(ClassInfo *info) {
186   - info.nameOfClass = @"Class2";
187   - deriveClass(info, @"Class3");
188   - });
189   - ClassInfo *class3 = createClass(^(ClassInfo *info) {
190   - info.nameOfClass = @"Class3";
191   - deriveClass(info, @"Unknown");
192   - });
  145 + ClassInfo *class1 = createDerivedClass(@"Class1", @"Class2");
  146 + ClassInfo *class2 = createDerivedClass(@"Class2", @"Class3");
  147 + ClassInfo *class3 = createDerivedClass(@"Class3", @"UnknownClass");
193 148 [given([store storeClasses]) willReturn:@[ class1, class2, class3 ]];
194 149 // execute
195 150 [task runTask];
@@ -205,12 +160,8 @@ static void adoptProtocols(InterfaceInfoBase *interface, NSString *first, ...) {
205 160 it(@"should link extensions to known classes", ^{
206 161 runWithTask(^(LinkKnownObjectsTask *task, id store) {
207 162 // setup
208   - CategoryInfo *extension1 = createCategory(^(CategoryInfo *info) {
209   - extendClass(info, @"Class1");
210   - });
211   - CategoryInfo *extension2 = createCategory(^(CategoryInfo *info) {
212   - extendClass(info, @"UnknownClass");
213   - });
  163 + CategoryInfo *extension1 = createCategory(@"Class1");
  164 + CategoryInfo *extension2 = createCategory(@"UnknownClass");
214 165 ClassInfo *class1 = createClass(@"Class1");
215 166 [given([store storeExtensions]) willReturn:@[ extension1, extension2 ]];
216 167 [given([store storeClasses]) willReturn:@[ class1 ]];
@@ -225,12 +176,8 @@ static void adoptProtocols(InterfaceInfoBase *interface, NSString *first, ...) {
225 176 it(@"should link categories to known classes", ^{
226 177 runWithTask(^(LinkKnownObjectsTask *task, id store) {
227 178 // setup
228   - CategoryInfo *category1 = createCategory(^(CategoryInfo *info) {
229   - extendClass(info, @"Class1");
230   - });
231   - CategoryInfo *category2 = createCategory(^(CategoryInfo *info) {
232   - extendClass(info, @"UnknownClass");
233   - });
  179 + CategoryInfo *category1 = createCategory(@"Class1");
  180 + CategoryInfo *category2 = createCategory(@"UnknownClass");
234 181 ClassInfo *class1 = createClass(@"Class1");
235 182 [given([store storeCategories]) willReturn:@[ category1, category2 ]];
236 183 [given([store storeClasses]) willReturn:@[ class1 ]];
171 AppledocTests/Processing/ProcessorTests.mm
@@ -10,13 +10,22 @@
10 10 #import "Processor.h"
11 11 #import "TestCaseBase.hh"
12 12
13   -static void runWithProcessor(void(^handler)(Processor *processor)) {
  13 +static void runWithProcessor(BOOL mockedTasks, void(^handler)(Processor *processor)) {
14 14 Processor *processor = [[Processor alloc] init];
  15 + if (mockedTasks) {
  16 + processor.linkKnownObjectsTask = mock([ProcessorTask class]);
  17 + processor.mergeKnownObjectsTask = mock([ProcessorTask class]);
  18 + processor.fetchDocumentationTask = mock([ProcessorTask class]);
  19 + }
15 20 handler(processor);
16 21 [processor release];
17 22 }
18 23
19   -#pragma mark -
  24 +static void runWithProcessor(void(^handler)(Processor *processor)) {
  25 + runWithProcessor(NO, handler);
  26 +}
  27 +
  28 +#pragma mark -
20 29
21 30 @interface Processor (UnitTestingPrivateAPI)
22 31 - (NSInteger)processCommentForObject:(ObjectInfoBase *)object context:(ObjectInfoBase *)parent;
@@ -59,6 +68,13 @@ - (NSInteger)processCommentForObject:(ObjectInfoBase *)object context:(ObjectInf
59 68 itShouldBehaveLike(@"tasks");
60 69 });
61 70
  71 + describe(@"fetch documentation task:", ^{
  72 + beforeEach(^{
  73 + [[SpecHelper specHelper] sharedExampleContext][@"task"] = @"fetchDocumentationTask";
  74 + });
  75 + itShouldBehaveLike(@"tasks");
  76 + });
  77 +
62 78 describe(@"split comment to sections task:", ^{
63 79 beforeEach(^{
64 80 [[SpecHelper specHelper] sharedExampleContext][@"task"] = @"splitCommentToSectionsTask";
@@ -109,146 +125,23 @@ - (NSInteger)processCommentForObject:(ObjectInfoBase *)object context:(ObjectInf
109 125 gbcatch([verify(task) runTask]);
110 126 });
111 127 });
112   -});
113   -
114   -describe(@"comment processing:", ^{
115   - describe(@"enumerating objects:", ^{
116   - describe(@"top level objects:", ^{
117   - it(@"should enumerate classes", ^{
118   - runWithProcessor(^(Processor *processor) {
119   - // setup
120   - id settings = mock([GBSettings class]);
121   - id classes = mock([NSArray class]);
122   - id store = mock([Store class]);
123   - [given([store storeClasses]) willReturn:classes];
124   - // execute
125   - [processor runWithSettings:settings store:store];
126   - // verify
127   - gbcatch([verify(classes) enumerateObjectsUsingBlock:(id)anything()]);
128   - });
129   - });
130   -
131   - it(@"should enumerate extensions", ^{
132   - runWithProcessor(^(Processor *processor) {
133   - // setup
134   - id settings = mock([GBSettings class]);
135   - id extensions = mock([NSArray class]);
136   - id store = mock([Store class]);
137   - [given([store storeExtensions]) willReturn:extensions];
138   - // execute
139   - [processor runWithSettings:settings store:store];
140   - // verify
141   - gbcatch([verify(extensions) enumerateObjectsUsingBlock:(id)anything()]);
142   - });
143   - });
144   -
145   - it(@"should enumerate categories", ^{
146   - runWithProcessor(^(Processor *processor) {
147   - // setup
148   - id settings = mock([GBSettings class]);
149   - id categories = mock([NSArray class]);
150   - id store = mock([Store class]);
151   - [given([store storeCategories]) willReturn:categories];
152   - // execute
153   - [processor runWithSettings:settings store:store];
154   - // verify
155   - gbcatch([verify(categories) enumerateObjectsUsingBlock:(id)anything()]);
156   - });
157   - });
158   -
159   - it(@"should enumerate protocols", ^{
160   - runWithProcessor(^(Processor *processor) {
161   - // setup
162   - id settings = mock([GBSettings class]);
163   - id protocols = mock([NSArray class]);
164   - id store = mock([Store class]);
165   - [given([store storeProtocols]) willReturn:protocols];
166   - // execute
167   - [processor runWithSettings:settings store:store];
168   - // verify
169   - gbcatch([verify(protocols) enumerateObjectsUsingBlock:(id)anything()]);
170   - });
171   - });
172   - });
173   -
174   - describe(@"members:", ^{
175   - __block InterfaceInfoBase *object;
176   - __block id classMethods;
177   - __block id interfaceMethods;
178   - __block id properties;
179   -
180   - beforeEach(^{
181   - classMethods = mock([NSArray class]);
182   - interfaceMethods = mock([NSArray class]);
183   - properties = mock([NSArray class]);
184   - object = [[[InterfaceInfoBase alloc] init] autorelease];
185   - object.interfaceClassMethods = classMethods;
186   - object.interfaceInstanceMethods = interfaceMethods;
187   - object.interfaceProperties = properties;
188   - });
189   -
190   - it(@"should enumerate class members", ^{
191   - runWithProcessor(^(Processor *processor) {
192   - // setup
193   - id settings = mock([GBSettings class]);
194   - id store = mock([Store class]);
195   - [given([store storeClasses]) willReturn:@[object]];
196   - // execute
197   - [processor runWithSettings:settings store:store];
198   - // verify
199   - gbcatch([verify(classMethods) enumerateObjectsUsingBlock:(id)anything()]);
200   - gbcatch([verify(interfaceMethods) enumerateObjectsUsingBlock:(id)anything()]);
201   - gbcatch([verify(properties) enumerateObjectsUsingBlock:(id)anything()]);
202   - });
203   - });
204   -
205   - it(@"should enumerate extension members", ^{
206   - runWithProcessor(^(Processor *processor) {
207   - // setup
208   - id settings = mock([GBSettings class]);
209   - id store = mock([Store class]);
210   - [given([store storeExtensions]) willReturn:@[object]];
211   - // execute
212   - [processor runWithSettings:settings store:store];
213   - // verify
214   - gbcatch([verify(classMethods) enumerateObjectsUsingBlock:(id)anything()]);
215   - gbcatch([verify(interfaceMethods) enumerateObjectsUsingBlock:(id)anything()]);
216   - gbcatch([verify(properties) enumerateObjectsUsingBlock:(id)anything()]);
217   - });
218   - });
219   -
220   - it(@"should enumerate category members", ^{
221   - runWithProcessor(^(Processor *processor) {
222   - // setup
223   - id settings = mock([GBSettings class]);
224   - id store = mock([Store class]);
225   - [given([store storeCategories]) willReturn:@[object]];
226   - // execute
227   - [processor runWithSettings:settings store:store];
228   - // verify
229   - gbcatch([verify(classMethods) enumerateObjectsUsingBlock:(id)anything()]);
230   - gbcatch([verify(interfaceMethods) enumerateObjectsUsingBlock:(id)anything()]);
231   - gbcatch([verify(properties) enumerateObjectsUsingBlock:(id)anything()]);
232   - });
233   - });
234   -
235   - it(@"should enumerate protocol members", ^{
236   - runWithProcessor(^(Processor *processor) {
237   - // setup
238   - id settings = mock([GBSettings class]);
239   - id store = mock([Store class]);
240   - [given([store storeProtocols]) willReturn:@[object]];
241   - // execute
242   - [processor runWithSettings:settings store:store];
243   - // verify
244   - gbcatch([verify(classMethods) enumerateObjectsUsingBlock:(id)anything()]);
245   - gbcatch([verify(interfaceMethods) enumerateObjectsUsingBlock:(id)anything()]);
246   - gbcatch([verify(properties) enumerateObjectsUsingBlock:(id)anything()]);
247   - });
248   - });
  128 +
  129 + it(@"should invoke fetch documentation task", ^{
  130 + runWithProcessor(^(Processor *processor) {
  131 + // setup
  132 + id settings = mock([GBSettings class]);
  133 + id store = mock([Store class]);
  134 + id task = mock([ProcessorTask class]);
  135 + processor.fetchDocumentationTask = task;
  136 + // execute
  137 + [processor runWithSettings:settings store:store];
  138 + // verify
  139 + gbcatch([verify(task) runTask]);
249 140 });
250 141 });
  142 +});
251 143
  144 +describe(@"comment processing:", ^{
252 145 describe(@"processing comments:", ^{
253 146 __block id context;
254 147 __block id object;
27 AppledocTests/Store/InterfaceInfoBaseTests.mm
@@ -117,6 +117,15 @@ static void runWithInterfaceInfoBaseWithRegistrar(void(^handler)(InterfaceInfoBa
117 117 });
118 118 });
119 119
  120 + it(@"should set self as parent of created property", ^{
  121 + runWithInterfaceInfoBaseWithRegistrar(^(InterfaceInfoBase *info, Store *store) {
  122 + // exexute
  123 + [info beginPropertyDefinition];
  124 + // verify
  125 + [info.currentRegistrationObject memberParent] should equal(info);
  126 + });
  127 + });
  128 +
120 129 it(@"should set current source info to class", ^{
121 130 runWithInterfaceInfoBaseWithRegistrar(^(InterfaceInfoBase *info, Store *store) {
122 131 // setup
@@ -179,6 +188,15 @@ static void runWithInterfaceInfoBaseWithRegistrar(void(^handler)(InterfaceInfoBa
179 188 });
180 189 });
181 190
  191 + it(@"should set self as parent of created method", ^{
  192 + runWithInterfaceInfoBaseWithRegistrar(^(InterfaceInfoBase *info, Store *store) {
  193 + // exexute
  194 + [info beginMethodDefinitionWithType:GBStoreTypes.classMethod];
  195 + // verify
  196 + [info.currentRegistrationObject memberParent] should equal(info);
  197 + });
  198 + });
  199 +
182 200 it(@"should set current source info to class", ^{
183 201 runWithInterfaceInfoBaseWithRegistrar(^(InterfaceInfoBase *info, Store *store) {
184 202 // setup
@@ -240,6 +258,15 @@ static void runWithInterfaceInfoBaseWithRegistrar(void(^handler)(InterfaceInfoBa
240 258 });
241 259 });
242 260
  261 + it(@"should set self as parent of created method", ^{
  262 + runWithInterfaceInfoBaseWithRegistrar(^(InterfaceInfoBase *info, Store *store) {
  263 + // exexute
  264 + [info beginMethodDefinitionWithType:GBStoreTypes.instanceMethod];
  265 + // verify
  266 + [info.currentRegistrationObject memberParent] should equal(info);
  267 + });
  268 + });
  269 +
243 270 it(@"should set current source info to class", ^{
244 271 runWithInterfaceInfoBaseWithRegistrar(^(InterfaceInfoBase *info, Store *store) {
245 272 // setup
19 AppledocTests/Store/MethodInfoTests.mm
@@ -40,6 +40,19 @@ static void runWithMethodInfoWithRegistrar(void(^handler)(MethodInfo *info, Stor
40 40 });
41 41
42 42 describe(@"selector, unique ID & cross reference template:", ^{
  43 + it(@"should handle class method", ^{
  44 + runWithMethodInfo(^(MethodInfo *info) {
  45 + // setup
  46 + MethodArgumentInfo *argument = [[MethodArgumentInfo alloc] init];
  47 + argument.argumentSelector = @"method";
  48 + [info.methodArguments addObject:argument];
  49 + info.methodType = GBStoreTypes.classMethod;
  50 + // execute & verify
  51 + info.uniqueObjectID should equal(@"+method");
  52 + info.objectCrossRefPathTemplate should equal(@"#+method");
  53 + });
  54 + });
  55 +
43 56 it(@"should handle single argument", ^{
44 57 runWithMethodInfo(^(MethodInfo *info) {
45 58 // setup
@@ -47,7 +60,7 @@ static void runWithMethodInfoWithRegistrar(void(^handler)(MethodInfo *info, Stor
47 60 argument.argumentSelector = @"method";
48 61 [info.methodArguments addObject:argument];
49 62 // execute & verify
50   - info.uniqueObjectID should equal(@"method");
  63 + info.uniqueObjectID should equal(@"-method");
51 64 info.objectCrossRefPathTemplate should equal(@"#-method");
52 65 });
53 66 });
@@ -60,7 +73,7 @@ static void runWithMethodInfoWithRegistrar(void(^handler)(MethodInfo *info, Stor
60 73 argument.argumentVariable = @"var";
61 74 [info.methodArguments addObject:argument];
62 75 // execute & verify
63   - info.uniqueObjectID should equal(@"method:");
  76 + info.uniqueObjectID should equal(@"-method:");
64 77 info.objectCrossRefPathTemplate should equal(@"#-method:");
65 78 });
66 79 });
@@ -77,7 +90,7 @@ static void runWithMethodInfoWithRegistrar(void(^handler)(MethodInfo *info, Stor
77 90 argument2.argumentVariable = @"var";
78 91 [info.methodArguments addObject:argument2];
79 92 // execute & verify
80   - info.uniqueObjectID should equal(@"method:withArg:");
  93 + info.uniqueObjectID should equal(@"-method:withArg:");
81 94 info.objectCrossRefPathTemplate should equal(@"#-method:withArg:");
82 95 });
83 96 });
60 AppledocTests/TestingBase/StoreMocks.h
... ... @@ -0,0 +1,60 @@
  1 +//
  2 +// StoreMocks.h
  3 +// appledoc
  4 +//
  5 +// Created by Tomaz Kragelj on 11.12.12.
  6 +// Copyright (c) 2012 Tomaz Kragelj. All rights reserved.
  7 +//
  8 +
  9 +#import "Store.h"
  10 +
  11 +typedef void(^GBCreateObjectBlock)(id object);
  12 +
  13 +@interface StoreMocks : NSObject
  14 +
  15 ++ (InterfaceInfoBase *)createInterface:(void(^)(InterfaceInfoBase *object))handler;
  16 ++ (ClassInfo *)createClass:(void(^)(ClassInfo *object))handler;
  17 ++ (CategoryInfo *)createCategory:(void(^)(CategoryInfo *object))handler;
  18 ++ (ProtocolInfo *)createProtocol:(void(^)(ProtocolInfo *object))handler;
  19 +
  20 ++ (MethodInfo *)createMethod:(NSString *)uniqueID;
  21 ++ (MethodInfo *)createMethod:(NSString *)uniqueID block:(void(^)(MethodInfo *object))handler;
  22 ++ (PropertyInfo *)createProperty:(NSString *)uniqueID;
  23 ++ (PropertyInfo *)createProperty:(NSString *)uniqueID block:(void(^)(PropertyInfo *object))handler;
  24 ++ (ObjectLinkInfo *)link:(id)nameOrObject;
  25 +
  26 ++ (id)mockClass:(NSString *)name block:(GBCreateObjectBlock)handler;
  27 ++ (id)mockCategory:(NSString *)name onClass:(NSString *)className block:(GBCreateObjectBlock)handler;
  28 ++ (id)mockProtocol:(NSString *)name block:(GBCreateObjectBlock)handler;
  29 +
  30 ++ (id)mockMethod:(NSString *)uniqueID;
  31 ++ (id)mockMethod:(NSString *)uniqueID block:(GBCreateObjectBlock)handler;
  32 ++ (id)mockProperty:(NSString *)uniqueID;
  33 ++ (id)mockProperty:(NSString *)uniqueID block:(GBCreateObjectBlock)handler;
  34 +
  35 ++ (void)addMockCommentTo:(id)objectOrMock;
  36 ++ (void)add:(id)classOrMock asDerivedClassFrom:(id)baseOrMock;
  37 ++ (void)add:(id)objectOrMock asAdopting:(id)protocolOrMock;
  38 ++ (void)add:(id)methodOrMock asClassMethodOf:(id)interfaceOrMock;
  39 ++ (void)add:(id)methodOrMock asInstanceMethodOf:(id)interfaceOrMock;
  40 ++ (void)add:(id)propertyOrMock asPropertyOf:(id)interfaceOrMock;
  41 +
  42 +@end
  43 +
  44 +#pragma mark -
  45 +
  46 +@interface InterfaceInfoBase (UnitTestsMocks)
  47 +- (void)adopt:(NSString *)first, ... NS_REQUIRES_NIL_TERMINATION;
  48 +@end
  49 +
  50 +#pragma mark -
  51 +
  52 +@interface CategoryInfo (UnitTestsMocks)
  53 +- (void)extend:(NSString *)name;
  54 +@end
  55 +
  56 +#pragma mark -
  57 +
  58 +@interface ClassInfo (UnitTestsMocks)
  59 +- (void)derive:(NSString *)name;
  60 +@end
222 AppledocTests/TestingBase/StoreMocks.m
... ... @@ -0,0 +1,222 @@
  1 +//
  2 +// StoreMocks.m
  3 +// appledoc
  4 +//
  5 +// Created by Tomaz Kragelj on 11.12.12.
  6 +// Copyright (c) 2012 Tomaz Kragelj. All rights reserved.
  7 +//
  8 +
  9 +#define MOCKITO_SHORTHAND
  10 +#import <OCMockito/OCMockito.h>
  11 +#import "Objects.h"
  12 +#import "StoreMocks.h"
  13 +
  14 +@implementation StoreMocks
  15 +
  16 +#pragma mark - Real interfaces
  17 +
  18 ++ (InterfaceInfoBase *)createInterface:(void(^)(InterfaceInfoBase *object))handler {
  19 + InterfaceInfoBase *result = [[InterfaceInfoBase alloc] init];
  20 + handler(result);
  21 + return result;
  22 +}
  23 +
  24 ++ (ClassInfo *)createClass:(void(^)(ClassInfo *object))handler {
  25 + ClassInfo *result = [[ClassInfo alloc] init];
  26 + handler(result);
  27 + return result;
  28 +}
  29 +
  30 ++ (CategoryInfo *)createCategory:(void(^)(CategoryInfo *object))handler {
  31 + CategoryInfo *result = [[CategoryInfo alloc] init];
  32 + handler(result);
  33 + return result;
  34 +}
  35 +
  36 ++ (ProtocolInfo *)createProtocol:(void(^)(ProtocolInfo *object))handler {
  37 + ProtocolInfo *result = [[ProtocolInfo alloc] init];
  38 + handler(result);
  39 + return result;
  40 +}
  41 +
  42 +#pragma mark - Real members
  43 +
  44 ++ (MethodInfo *)createMethod:(NSString *)uniqueID block:(void(^)(MethodInfo *object))handler {
  45 + MethodInfo *result = [[MethodInfo alloc] init];
  46 + NSRange range = NSMakeRange(1, uniqueID.length - 1);
  47 + NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"([^:]+)(:?)" options:0 error:nil];
  48 + [regex enumerateMatchesInString:uniqueID options:0 range:range usingBlock:^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop) {
  49 + NSString *selector = [match gb_stringAtIndex:1 in:uniqueID];
  50 + NSString *colon = [match gb_stringAtIndex:2 in:uniqueID];
  51 + MethodArgumentInfo *argument = [[MethodArgumentInfo alloc] init];
  52 + argument.argumentSelector = selector;
  53 + argument.argumentVariable = (colon.length > 0) ? selector : nil;
  54 + [result.methodArguments addObject:argument];
  55 + }];
  56 + result.methodType = ([uniqueID characterAtIndex:0] == '+') ? GBStoreTypes.classMethod : GBStoreTypes.instanceMethod;
  57 + handler(result);
  58 + return result;
  59 +}
  60 +
  61 ++ (MethodInfo *)createMethod:(NSString *)uniqueID {
  62 + return [self createMethod:uniqueID block:^(MethodInfo *object) { }];
  63 +}
  64 +
  65 ++ (PropertyInfo *)createProperty:(NSString *)uniqueID block:(void(^)(PropertyInfo *object))handler {
  66 + PropertyInfo *result = [[PropertyInfo alloc] init];
  67 + result.propertyName = uniqueID;
  68 + handler(result);
  69 + return result;
  70 +}
  71 +
  72 ++ (PropertyInfo *)createProperty:(NSString *)uniqueID {
  73 + return [self createProperty:uniqueID block:^(PropertyInfo *object) { }];
  74 +}
  75 +
  76 ++ (ObjectLinkInfo *)link:(id)nameOrObject {
  77 + ObjectLinkInfo *result = [[ObjectLinkInfo alloc] init];
  78 + if ([nameOrObject isKindOfClass:[NSString class]])
  79 + result.nameOfObject = nameOrObject;
  80 + else
  81 + result.linkToObject = nameOrObject;
  82 + return result;
  83 +}
  84 +
  85 +#pragma mark - Mock interfaces
  86 +
  87 ++ (id)mockClass:(NSString *)name block:(GBCreateObjectBlock)handler {
  88 + id result = mock([ClassInfo class]);
  89 + [given([result nameOfClass]) willReturn:name];
  90 + handler(result);
  91 + return result;
  92 +}
  93 +
  94 ++ (id)mockCategory:(NSString *)name onClass:(NSString *)className block:(GBCreateObjectBlock)handler {
  95 + id result = mock([CategoryInfo class]);
  96 + [given([result nameOfCategory]) willReturn:name];
  97 + [given([result nameOfClass]) willReturn:className];
  98 + [given([result categoryClass]) willReturn:[self link:className]];
  99 + handler(result);
  100 + return result;
  101 +}
  102 +
  103 ++ (id)mockProtocol:(NSString *)name block:(GBCreateObjectBlock)handler {
  104 + id result = mock([ProtocolInfo class]);
  105 + [given([result nameOfProtocol]) willReturn:name];
  106 + handler(result);
  107 + return result;
  108 +}
  109 +
  110 +#pragma mark - Mock members
  111 +
  112 ++ (id)mockMethod:(NSString *)uniqueID {
  113 + return [self mockMethod:uniqueID block:^(id object) { }];
  114 +}
  115 +
  116 ++ (id)mockMethod:(NSString *)uniqueID block:(void(^)(id object))handler {
  117 + id result = mock([MethodInfo class]);
  118 + [given([result uniqueObjectID]) willReturn:uniqueID];
  119 + handler(result);
  120 + return result;
  121 +}
  122 +
  123 ++ (id)mockProperty:(NSString *)uniqueID {
  124 + return [self mockProperty:uniqueID block:^(id object) { }];
  125 +}
  126 +
  127 ++ (id)mockProperty:(NSString *)uniqueID block:(void(^)(id object))handler {
  128 + id result = mock([PropertyInfo class]);
  129 + [given([result uniqueObjectID]) willReturn:uniqueID];
  130 + handler(result);
  131 + return result;
  132 +}
  133 +
  134 +#pragma mark - Common stuff
  135 +
  136 ++ (void)addMockCommentTo:(id)objectOrMock {
  137 + id comment = mock([CommentInfo class]);
  138 + if ([self isMock:objectOrMock])
  139 + [given([objectOrMock comment]) willReturn:comment];
  140 + else
  141 + [objectOrMock setComment:comment];
  142 +}
  143 +
  144 ++ (void)add:(id)classOrMock asDerivedClassFrom:(id)baseOrMock {
  145 + ObjectLinkInfo *link = [self link:baseOrMock];
  146 + if ([self isMock:classOrMock])
  147 + [given([classOrMock classSuperClass]) willReturn:link];
  148 + else
  149 + [classOrMock setClassSuperClass:link];
  150 +}
  151 +
  152 ++ (void)add:(id)objectOrMock asAdopting:(id)protocolOrMock {
  153 + ObjectLinkInfo *link = [self link:protocolOrMock];
  154 + if ([self isMock:objectOrMock])
  155 + [given([objectOrMock interfaceAdoptedProtocols]) willReturn:@[ link ]];
  156 + else
  157 + [[objectOrMock interfaceAdoptedProtocols] addObject:link];
  158 +}
  159 +
  160 ++ (void)add:(id)methodOrMock asClassMethodOf:(id)interfaceOrMock {
  161 + if ([self isMock:interfaceOrMock])
  162 + [given([interfaceOrMock interfaceClassMethods]) willReturn:@[ methodOrMock ]];
  163 + else
  164 + [[interfaceOrMock interfaceClassMethods] addObject:methodOrMock];
  165 +}
  166 +
  167 ++ (void)add:(id)methodOrMock asInstanceMethodOf:(id)interfaceOrMock {
  168 + if ([self isMock:interfaceOrMock])
  169 + [given([interfaceOrMock interfaceInstanceMethods]) willReturn:@[ methodOrMock ]];
  170 + else
  171 + [[interfaceOrMock interfaceInstanceMethods] addObject:methodOrMock];
  172 +}
  173 +
  174 ++ (void)add:(id)propertyOrMock asPropertyOf:(id)interfaceOrMock {
  175 + if ([self isMock:interfaceOrMock])
  176 + [given([interfaceOrMock interfaceProperties]) willReturn:@[ propertyOrMock ]];
  177 + else
  178 + [[interfaceOrMock interfaceProperties] addObject:propertyOrMock];
  179 +}
  180 +
  181 ++ (BOOL)isMock:(id)objectOrMock {
  182 + return ![objectOrMock isKindOfClass:[ObjectInfoBase class]];
  183 +}
  184 +
  185 +@end
  186 +
  187 +#pragma mark -
  188 +
  189 +@implementation InterfaceInfoBase (UnitTestsMocks)
  190 +
  191 +- (void)adopt:(NSString *)first, ... {
  192 + va_list args;
  193 + va_start(args, first);
  194 + for (NSString *arg=first; arg!=nil; arg=va_arg(args, NSString *)) {
  195 + ObjectLinkInfo *link = [[ObjectLinkInfo alloc] init];
  196 + link.nameOfObject = arg;
  197 + [self.interfaceAdoptedProtocols addObject:link];
  198 + }
  199 + va_end(args);
  200 +}
  201 +
  202 +@end
  203 +
  204 +#pragma mark -
  205 +
  206 +@implementation CategoryInfo (UnitTestsMocks)
  207 +
  208 +- (void)extend:(NSString *)name {
  209 + self.categoryClass.nameOfObject = name;
  210 +}
  211 +
  212 +@end
  213 +
  214 +#pragma mark -
  215 +
  216 +@implementation ClassInfo (UnitTestsMocks)
  217 +
  218 +- (void)derive:(NSString *)name {
  219 + self.classSuperClass.nameOfObject = name;
  220 +}
  221 +
  222 +@end
26 appledoc.xcodeproj/project.pbxproj
@@ -49,6 +49,9 @@
49 49 73297915151899CA00592A9D /* ObjectiveCParserState.m in Sources */ = {isa = PBXBuildFile; fileRef = 73297913151899CA00592A9D /* ObjectiveCParserState.m */; };
50 50 7329791815189D1B00592A9D /* ObjectiveCFileState.m in Sources */ = {isa = PBXBuildFile; fileRef = 7329791715189D1B00592A9D /* ObjectiveCFileState.m */; };
51 51 7329791915189D1B00592A9D /* ObjectiveCFileState.m in Sources */ = {isa = PBXBuildFile; fileRef = 7329791715189D1B00592A9D /* ObjectiveCFileState.m */; };