KWContextNode.m 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. //
  2. // Licensed under the terms in License.txt
  3. //
  4. // Copyright 2010 Allen Ding. All rights reserved.
  5. //
  6. #import "KWAfterAllNode.h"
  7. #import "KWAfterEachNode.h"
  8. #import "KWBeforeAllNode.h"
  9. #import "KWBeforeEachNode.h"
  10. #import "KWLetNode.h"
  11. #import "KWCallSite.h"
  12. #import "KWContextNode.h"
  13. #import "KWExampleNodeVisitor.h"
  14. #import "KWExample.h"
  15. #import "KWFailure.h"
  16. #import "KWRegisterMatchersNode.h"
  17. #import "KWSymbolicator.h"
  18. static NSString * const KWContextNodeException = @"KWContextNodeException";
  19. @interface KWContextNode()
  20. @property (nonatomic, assign) NSUInteger performedExampleCount;
  21. @end
  22. @implementation KWContextNode
  23. @synthesize description = _description;
  24. #pragma mark - Initializing
  25. - (id)initWithCallSite:(KWCallSite *)aCallSite parentContext:(KWContextNode *)node description:(NSString *)aDescription {
  26. self = [super init];
  27. if (self) {
  28. _parentContext = node;
  29. _callSite = aCallSite;
  30. _description = [aDescription copy];
  31. _nodes = [NSMutableArray array];
  32. _registerMatchersNodes = [NSMutableArray array];
  33. _letNodes = [NSMutableArray array];
  34. _performedExampleCount = 0;
  35. }
  36. return self;
  37. }
  38. + (id)contextNodeWithCallSite:(KWCallSite *)aCallSite parentContext:(KWContextNode *)contextNode description:(NSString *)aDescription {
  39. return [[self alloc] initWithCallSite:aCallSite parentContext:contextNode description:aDescription];
  40. }
  41. - (void)addContextNode:(KWContextNode *)aNode {
  42. [(NSMutableArray *)self.nodes addObject:aNode];
  43. }
  44. - (void)setBeforeEachNode:(KWBeforeEachNode *)aNode {
  45. [self raiseIfNodeAlreadyExists:self.beforeEachNode];
  46. _beforeEachNode = aNode;
  47. }
  48. - (void)setAfterEachNode:(KWAfterEachNode *)aNode {
  49. [self raiseIfNodeAlreadyExists:self.afterEachNode];
  50. _afterEachNode = aNode;
  51. }
  52. - (void)addLetNode:(KWLetNode *)aNode {
  53. [(NSMutableArray *)self.letNodes addObject:aNode];
  54. }
  55. - (void)addRegisterMatchersNode:(KWRegisterMatchersNode *)aNode {
  56. [(NSMutableArray *)self.registerMatchersNodes addObject:aNode];
  57. }
  58. - (KWLetNode *)letNodeTree {
  59. KWLetNode *tree = [self.parentContext letNodeTree];
  60. for (KWLetNode *letNode in self.letNodes) {
  61. if (!tree) {
  62. tree = letNode;
  63. }
  64. else {
  65. [tree addLetNode:letNode];
  66. }
  67. }
  68. return tree;
  69. }
  70. - (void)addItNode:(KWItNode *)aNode {
  71. [(NSMutableArray *)self.nodes addObject:aNode];
  72. }
  73. - (void)addPendingNode:(KWPendingNode *)aNode {
  74. [(NSMutableArray *)self.nodes addObject:aNode];
  75. }
  76. - (void)performExample:(KWExample *)example withBlock:(void (^)(void))exampleBlock
  77. {
  78. void (^innerExampleBlock)(void) = [exampleBlock copy];
  79. void (^outerExampleBlock)(void) = ^{
  80. @try {
  81. for (KWRegisterMatchersNode *registerNode in self.registerMatchersNodes) {
  82. [registerNode acceptExampleNodeVisitor:example];
  83. }
  84. if (self.performedExampleCount == 0) {
  85. [self.beforeAllNode acceptExampleNodeVisitor:example];
  86. }
  87. KWLetNode *letNodeTree = [self letNodeTree];
  88. [letNodeTree acceptExampleNodeVisitor:example];
  89. [self.beforeEachNode acceptExampleNodeVisitor:example];
  90. innerExampleBlock();
  91. [self.afterEachNode acceptExampleNodeVisitor:example];
  92. if ([example isLastInContext:self]) {
  93. [self.afterAllNode acceptExampleNodeVisitor:example];
  94. [letNodeTree unlink];
  95. }
  96. } @catch (NSException *exception) {
  97. KWFailure *failure = [KWFailure failureWithCallSite:self.callSite format:@"%@ \"%@\" raised", [exception name], [exception reason]];
  98. [example reportFailure:failure];
  99. }
  100. self.performedExampleCount++;
  101. };
  102. if (self.parentContext == nil) {
  103. outerExampleBlock();
  104. }
  105. else {
  106. [self.parentContext performExample:example withBlock:outerExampleBlock];
  107. }
  108. }
  109. - (void)raiseIfNodeAlreadyExists:(id<KWExampleNode>)node {
  110. if (node) {
  111. [NSException raise:KWContextNodeException
  112. format:@"A %@ already exists in this context.", NSStringFromClass([node class])];
  113. }
  114. }
  115. #pragma mark - Accepting Visitors
  116. - (void)acceptExampleNodeVisitor:(id<KWExampleNodeVisitor>)aVisitor {
  117. [aVisitor visitContextNode:self];
  118. }
  119. @end