RxLibraryUnitTests.m 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. /*
  2. *
  3. * Copyright 2015 gRPC authors.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. #import <XCTest/XCTest.h>
  19. #import <RxLibrary/GRXBufferedPipe.h>
  20. #import <RxLibrary/GRXWriteable.h>
  21. #import <RxLibrary/GRXWriter.h>
  22. #define TEST_TIMEOUT 1
  23. // A mock of a GRXSingleValueHandler block that can be queried for how many times it was called and
  24. // what were the last values passed to it.
  25. //
  26. // TODO(jcanizales): Move this to a test util library, and add tests for it.
  27. @interface CapturingSingleValueHandler : NSObject
  28. @property(nonatomic, readonly) void (^block)(id value, NSError *errorOrNil);
  29. @property(nonatomic, readonly) NSUInteger timesCalled;
  30. @property(nonatomic, readonly) id value;
  31. @property(nonatomic, readonly) NSError *errorOrNil;
  32. + (instancetype)handler;
  33. @end
  34. @implementation CapturingSingleValueHandler
  35. + (instancetype)handler {
  36. return [[self alloc] init];
  37. }
  38. - (GRXSingleHandler)block {
  39. return ^(id value, NSError *errorOrNil) {
  40. ++self->_timesCalled;
  41. self->_value = value;
  42. self->_errorOrNil = errorOrNil;
  43. };
  44. }
  45. @end
  46. // TODO(jcanizales): Split into one file per tested class.
  47. @interface RxLibraryUnitTests : XCTestCase
  48. @end
  49. @implementation RxLibraryUnitTests
  50. + (void)setUp {
  51. NSLog(@"GRPCClientTests Started");
  52. }
  53. #pragma mark Writeable
  54. - (void)testWriteableSingleHandlerIsCalledForValue {
  55. // Given:
  56. CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
  57. id anyValue = @7;
  58. // If:
  59. id<GRXWriteable> writeable = [GRXWriteable writeableWithSingleHandler:handler.block];
  60. [writeable writeValue:anyValue];
  61. [writeable writesFinishedWithError:nil];
  62. // Then:
  63. XCTAssertEqual(handler.timesCalled, 1);
  64. XCTAssertEqualObjects(handler.value, anyValue);
  65. XCTAssertEqualObjects(handler.errorOrNil, nil);
  66. }
  67. - (void)testWriteableSingleHandlerIsCalledForError {
  68. // Given:
  69. CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
  70. NSError *anyError = [NSError errorWithDomain:@"domain" code:7 userInfo:nil];
  71. // If:
  72. id<GRXWriteable> writeable = [GRXWriteable writeableWithSingleHandler:handler.block];
  73. [writeable writesFinishedWithError:anyError];
  74. // Then:
  75. XCTAssertEqual(handler.timesCalled, 1);
  76. XCTAssertEqualObjects(handler.value, nil);
  77. XCTAssertEqualObjects(handler.errorOrNil, anyError);
  78. }
  79. - (void)testWriteableSingleHandlerIsCalledOnlyOnce_ValueThenError {
  80. // Given:
  81. CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
  82. id anyValue = @7;
  83. NSError *anyError = [NSError errorWithDomain:@"domain" code:7 userInfo:nil];
  84. // If:
  85. id<GRXWriteable> writeable = [GRXWriteable writeableWithSingleHandler:handler.block];
  86. [writeable writeValue:anyValue];
  87. [writeable writesFinishedWithError:anyError];
  88. // Then:
  89. XCTAssertEqual(handler.timesCalled, 1);
  90. XCTAssertEqualObjects(handler.value, anyValue);
  91. XCTAssertEqualObjects(handler.errorOrNil, nil);
  92. }
  93. - (void)testWriteableSingleHandlerIsCalledOnlyOnce_ValueThenValue {
  94. // Given:
  95. CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
  96. id anyValue = @7;
  97. // If:
  98. id<GRXWriteable> writeable = [GRXWriteable writeableWithSingleHandler:handler.block];
  99. [writeable writeValue:anyValue];
  100. [writeable writeValue:anyValue];
  101. [writeable writesFinishedWithError:nil];
  102. // Then:
  103. XCTAssertEqual(handler.timesCalled, 1);
  104. XCTAssertEqualObjects(handler.value, anyValue);
  105. XCTAssertEqualObjects(handler.errorOrNil, nil);
  106. }
  107. - (void)testWriteableSingleHandlerFailsOnEmptyWriter {
  108. // Given:
  109. CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
  110. // If:
  111. id<GRXWriteable> writeable = [GRXWriteable writeableWithSingleHandler:handler.block];
  112. [writeable writesFinishedWithError:nil];
  113. // Then:
  114. XCTAssertEqual(handler.timesCalled, 1);
  115. XCTAssertEqualObjects(handler.value, nil);
  116. XCTAssertNotNil(handler.errorOrNil);
  117. }
  118. #pragma mark BufferedPipe
  119. - (void)testBufferedPipePropagatesValue {
  120. __weak XCTestExpectation *expectation = [self expectationWithDescription:@"Response received"];
  121. // Given:
  122. CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
  123. id<GRXWriteable> writeable =
  124. [GRXWriteable writeableWithSingleHandler:^(id value, NSError *errorOrNil) {
  125. handler.block(value, errorOrNil);
  126. [expectation fulfill];
  127. }];
  128. id anyValue = @7;
  129. // If:
  130. GRXBufferedPipe *pipe = [GRXBufferedPipe pipe];
  131. [pipe startWithWriteable:writeable];
  132. [pipe writeValue:anyValue];
  133. [pipe writesFinishedWithError:nil];
  134. // Then:
  135. [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
  136. XCTAssertEqual(handler.timesCalled, 1);
  137. XCTAssertEqualObjects(handler.value, anyValue);
  138. XCTAssertEqualObjects(handler.errorOrNil, nil);
  139. }
  140. - (void)testBufferedPipePropagatesError {
  141. __weak XCTestExpectation *expectation = [self expectationWithDescription:@"Response received"];
  142. // Given:
  143. CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
  144. id<GRXWriteable> writeable =
  145. [GRXWriteable writeableWithSingleHandler:^(id value, NSError *errorOrNil) {
  146. handler.block(value, errorOrNil);
  147. [expectation fulfill];
  148. }];
  149. NSError *anyError = [NSError errorWithDomain:@"domain" code:7 userInfo:nil];
  150. // If:
  151. GRXBufferedPipe *pipe = [GRXBufferedPipe pipe];
  152. [pipe startWithWriteable:writeable];
  153. [pipe writesFinishedWithError:anyError];
  154. // Then:
  155. [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
  156. XCTAssertEqual(handler.timesCalled, 1);
  157. XCTAssertEqualObjects(handler.value, nil);
  158. XCTAssertEqualObjects(handler.errorOrNil, anyError);
  159. }
  160. - (void)testBufferedPipeFinishWriteWhilePaused {
  161. __weak XCTestExpectation *expectation = [self expectationWithDescription:@"Response received"];
  162. // Given:
  163. CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
  164. id<GRXWriteable> writeable =
  165. [GRXWriteable writeableWithSingleHandler:^(id value, NSError *errorOrNil) {
  166. handler.block(value, errorOrNil);
  167. [expectation fulfill];
  168. }];
  169. id anyValue = @7;
  170. // If:
  171. GRXBufferedPipe *pipe = [GRXBufferedPipe pipe];
  172. // Write something, then finish
  173. [pipe writeValue:anyValue];
  174. [pipe writesFinishedWithError:nil];
  175. // then start the writeable
  176. [pipe startWithWriteable:writeable];
  177. // Then:
  178. [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
  179. XCTAssertEqual(handler.timesCalled, 1);
  180. XCTAssertEqualObjects(handler.value, anyValue);
  181. XCTAssertEqualObjects(handler.errorOrNil, nil);
  182. }
  183. #define WRITE_ROUNDS (1000)
  184. - (void)testBufferedPipeResumeWhenDealloc {
  185. id anyValue = @7;
  186. id<GRXWriteable> writeable =
  187. [GRXWriteable writeableWithSingleHandler:^(id value, NSError *errorOrNil){
  188. }];
  189. // Release after alloc;
  190. GRXBufferedPipe *pipe = [GRXBufferedPipe pipe];
  191. pipe = nil;
  192. // Release after write but before start
  193. pipe = [GRXBufferedPipe pipe];
  194. for (int i = 0; i < WRITE_ROUNDS; i++) {
  195. [pipe writeValue:anyValue];
  196. }
  197. pipe = nil;
  198. // Release after start but not write
  199. pipe = [GRXBufferedPipe pipe];
  200. [pipe startWithWriteable:writeable];
  201. pipe = nil;
  202. // Release after start and write
  203. pipe = [GRXBufferedPipe pipe];
  204. for (int i = 0; i < WRITE_ROUNDS; i++) {
  205. [pipe writeValue:anyValue];
  206. }
  207. [pipe startWithWriteable:writeable];
  208. pipe = nil;
  209. // Release after start, write and pause
  210. pipe = [GRXBufferedPipe pipe];
  211. [pipe startWithWriteable:writeable];
  212. for (int i = 0; i < WRITE_ROUNDS; i++) {
  213. [pipe writeValue:anyValue];
  214. }
  215. pipe.state = GRXWriterStatePaused;
  216. for (int i = 0; i < WRITE_ROUNDS; i++) {
  217. [pipe writeValue:anyValue];
  218. }
  219. pipe = nil;
  220. // Release after start, write, pause and finish
  221. pipe = [GRXBufferedPipe pipe];
  222. [pipe startWithWriteable:writeable];
  223. for (int i = 0; i < WRITE_ROUNDS; i++) {
  224. [pipe writeValue:anyValue];
  225. }
  226. pipe.state = GRXWriterStatePaused;
  227. for (int i = 0; i < WRITE_ROUNDS; i++) {
  228. [pipe writeValue:anyValue];
  229. }
  230. [pipe finishWithError:nil];
  231. pipe = nil;
  232. // Release after start, write, pause, finish and resume
  233. pipe = [GRXBufferedPipe pipe];
  234. [pipe startWithWriteable:writeable];
  235. for (int i = 0; i < WRITE_ROUNDS; i++) {
  236. [pipe writeValue:anyValue];
  237. }
  238. pipe.state = GRXWriterStatePaused;
  239. for (int i = 0; i < WRITE_ROUNDS; i++) {
  240. [pipe writeValue:anyValue];
  241. }
  242. [pipe finishWithError:nil];
  243. pipe.state = GRXWriterStateStarted;
  244. pipe = nil;
  245. }
  246. @end