blob: ecd914c9b5f98c1afafa45357fc81faba8a7c8ba [file] [log] [blame]
Jorge Canizales62951152015-05-26 14:32:12 -07001/*
2 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02003 * Copyright 2015 gRPC authors.
Jorge Canizales62951152015-05-26 14:32:12 -07004 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02005 * 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
Jorge Canizales62951152015-05-26 14:32:12 -07008 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02009 * http://www.apache.org/licenses/LICENSE-2.0
Jorge Canizales62951152015-05-26 14:32:12 -070010 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +020011 * 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.
Jorge Canizales62951152015-05-26 14:32:12 -070016 *
17 */
18
19#import <UIKit/UIKit.h>
20#import <XCTest/XCTest.h>
21
Jorge Canizalesc42a38e2015-06-21 14:44:25 -070022#import <RxLibrary/GRXBufferedPipe.h>
23#import <RxLibrary/GRXWriteable.h>
24#import <RxLibrary/GRXWriter.h>
Jorge Canizalesad0965e2015-05-27 13:01:21 -070025
Muxi Yana8d40b52017-05-23 17:15:23 -070026#define TEST_TIMEOUT 1
27
Jorge Canizales6caf9112015-05-28 22:40:24 -070028// A mock of a GRXSingleValueHandler block that can be queried for how many times it was called and
29// what were the last values passed to it.
30//
31// TODO(jcanizales): Move this to a test util library, and add tests for it.
32@interface CapturingSingleValueHandler : NSObject
Muxi Yanc92d90a2018-04-11 18:10:02 -070033@property(nonatomic, readonly) void (^block)(id value, NSError *errorOrNil);
34@property(nonatomic, readonly) NSUInteger timesCalled;
35@property(nonatomic, readonly) id value;
36@property(nonatomic, readonly) NSError *errorOrNil;
Jorge Canizales6caf9112015-05-28 22:40:24 -070037+ (instancetype)handler;
38@end
Jorge Canizales62951152015-05-26 14:32:12 -070039
Jorge Canizales6caf9112015-05-28 22:40:24 -070040@implementation CapturingSingleValueHandler
41+ (instancetype)handler {
42 return [[self alloc] init];
43}
44
Jorge Canizalesf95ddba2015-08-12 10:51:56 -070045- (GRXSingleHandler)block {
Jorge Canizales6caf9112015-05-28 22:40:24 -070046 return ^(id value, NSError *errorOrNil) {
47 ++_timesCalled;
48 _value = value;
49 _errorOrNil = errorOrNil;
50 };
51}
52@end
53
Jorge Canizales232b6a82016-03-11 12:26:27 -080054// TODO(jcanizales): Split into one file per tested class.
55
Jorge Canizales6caf9112015-05-28 22:40:24 -070056@interface RxLibraryUnitTests : XCTestCase
Jorge Canizales62951152015-05-26 14:32:12 -070057@end
58
59@implementation RxLibraryUnitTests
60
Muxi Yan4b947d32017-11-30 09:36:29 -080061+ (void)setUp {
62 NSLog(@"GRPCClientTests Started");
63}
64
Jorge Canizales6caf9112015-05-28 22:40:24 -070065#pragma mark Writeable
66
Jorge Canizalesf95ddba2015-08-12 10:51:56 -070067- (void)testWriteableSingleHandlerIsCalledForValue {
Jorge Canizales6caf9112015-05-28 22:40:24 -070068 // Given:
69 CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
70 id anyValue = @7;
71
72 // If:
Jorge Canizalesf95ddba2015-08-12 10:51:56 -070073 id<GRXWriteable> writeable = [GRXWriteable writeableWithSingleHandler:handler.block];
Jorge Canizales6caf9112015-05-28 22:40:24 -070074 [writeable writeValue:anyValue];
Jorge Canizales232b6a82016-03-11 12:26:27 -080075 [writeable writesFinishedWithError:nil];
Jorge Canizales6caf9112015-05-28 22:40:24 -070076
77 // Then:
78 XCTAssertEqual(handler.timesCalled, 1);
79 XCTAssertEqualObjects(handler.value, anyValue);
80 XCTAssertEqualObjects(handler.errorOrNil, nil);
Jorge Canizales62951152015-05-26 14:32:12 -070081}
82
Jorge Canizalesf95ddba2015-08-12 10:51:56 -070083- (void)testWriteableSingleHandlerIsCalledForError {
Jorge Canizales6caf9112015-05-28 22:40:24 -070084 // Given:
85 CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
86 NSError *anyError = [NSError errorWithDomain:@"domain" code:7 userInfo:nil];
87
88 // If:
Jorge Canizalesf95ddba2015-08-12 10:51:56 -070089 id<GRXWriteable> writeable = [GRXWriteable writeableWithSingleHandler:handler.block];
Jorge Canizales6caf9112015-05-28 22:40:24 -070090 [writeable writesFinishedWithError:anyError];
91
92 // Then:
93 XCTAssertEqual(handler.timesCalled, 1);
94 XCTAssertEqualObjects(handler.value, nil);
95 XCTAssertEqualObjects(handler.errorOrNil, anyError);
Jorge Canizales62951152015-05-26 14:32:12 -070096}
97
Jorge Canizales232b6a82016-03-11 12:26:27 -080098- (void)testWriteableSingleHandlerIsCalledOnlyOnce_ValueThenError {
99 // Given:
100 CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
101 id anyValue = @7;
102 NSError *anyError = [NSError errorWithDomain:@"domain" code:7 userInfo:nil];
103
104 // If:
105 id<GRXWriteable> writeable = [GRXWriteable writeableWithSingleHandler:handler.block];
106 [writeable writeValue:anyValue];
107 [writeable writesFinishedWithError:anyError];
108
109 // Then:
110 XCTAssertEqual(handler.timesCalled, 1);
111 XCTAssertEqualObjects(handler.value, anyValue);
112 XCTAssertEqualObjects(handler.errorOrNil, nil);
113}
114
115- (void)testWriteableSingleHandlerIsCalledOnlyOnce_ValueThenValue {
116 // Given:
117 CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
118 id anyValue = @7;
119
120 // If:
121 id<GRXWriteable> writeable = [GRXWriteable writeableWithSingleHandler:handler.block];
122 [writeable writeValue:anyValue];
123 [writeable writeValue:anyValue];
124 [writeable writesFinishedWithError:nil];
125
126 // Then:
127 XCTAssertEqual(handler.timesCalled, 1);
128 XCTAssertEqualObjects(handler.value, anyValue);
129 XCTAssertEqualObjects(handler.errorOrNil, nil);
130}
131
132- (void)testWriteableSingleHandlerFailsOnEmptyWriter {
133 // Given:
134 CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
135
136 // If:
137 id<GRXWriteable> writeable = [GRXWriteable writeableWithSingleHandler:handler.block];
138 [writeable writesFinishedWithError:nil];
139
140 // Then:
141 XCTAssertEqual(handler.timesCalled, 1);
142 XCTAssertEqualObjects(handler.value, nil);
143 XCTAssertNotNil(handler.errorOrNil);
144}
145
Jorge Canizales6caf9112015-05-28 22:40:24 -0700146#pragma mark BufferedPipe
147
148- (void)testBufferedPipePropagatesValue {
Muxi Yana8d40b52017-05-23 17:15:23 -0700149 __weak XCTestExpectation *expectation = [self expectationWithDescription:@"Response received"];
Jorge Canizales6caf9112015-05-28 22:40:24 -0700150 // Given:
151 CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
Muxi Yanc92d90a2018-04-11 18:10:02 -0700152 id<GRXWriteable> writeable =
153 [GRXWriteable writeableWithSingleHandler:^(id value, NSError *errorOrNil) {
154 handler.block(value, errorOrNil);
155 [expectation fulfill];
156 }];
Muxi Yana8d40b52017-05-23 17:15:23 -0700157
Jorge Canizales6caf9112015-05-28 22:40:24 -0700158 id anyValue = @7;
159
160 // If:
161 GRXBufferedPipe *pipe = [GRXBufferedPipe pipe];
162 [pipe startWithWriteable:writeable];
163 [pipe writeValue:anyValue];
Muxi Yanec8e8252017-05-15 14:59:07 -0700164 [pipe writesFinishedWithError:nil];
Jorge Canizales6caf9112015-05-28 22:40:24 -0700165
166 // Then:
Muxi Yana8d40b52017-05-23 17:15:23 -0700167 [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
Jorge Canizales6caf9112015-05-28 22:40:24 -0700168 XCTAssertEqual(handler.timesCalled, 1);
169 XCTAssertEqualObjects(handler.value, anyValue);
170 XCTAssertEqualObjects(handler.errorOrNil, nil);
Jorge Canizales62951152015-05-26 14:32:12 -0700171}
172
Jorge Canizales6caf9112015-05-28 22:40:24 -0700173- (void)testBufferedPipePropagatesError {
Muxi Yand7d6a2e2017-06-06 14:39:15 -0700174 __weak XCTestExpectation *expectation = [self expectationWithDescription:@"Response received"];
Jorge Canizales6caf9112015-05-28 22:40:24 -0700175 // Given:
176 CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
Muxi Yanc92d90a2018-04-11 18:10:02 -0700177 id<GRXWriteable> writeable =
178 [GRXWriteable writeableWithSingleHandler:^(id value, NSError *errorOrNil) {
179 handler.block(value, errorOrNil);
180 [expectation fulfill];
181 }];
Jorge Canizales6caf9112015-05-28 22:40:24 -0700182 NSError *anyError = [NSError errorWithDomain:@"domain" code:7 userInfo:nil];
183
184 // If:
185 GRXBufferedPipe *pipe = [GRXBufferedPipe pipe];
186 [pipe startWithWriteable:writeable];
187 [pipe writesFinishedWithError:anyError];
188
189 // Then:
Muxi Yand7d6a2e2017-06-06 14:39:15 -0700190 [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
Jorge Canizales6caf9112015-05-28 22:40:24 -0700191 XCTAssertEqual(handler.timesCalled, 1);
192 XCTAssertEqualObjects(handler.value, nil);
193 XCTAssertEqualObjects(handler.errorOrNil, anyError);
Jorge Canizales62951152015-05-26 14:32:12 -0700194}
195
Test User9656eca2016-02-18 14:47:22 -0800196- (void)testBufferedPipeFinishWriteWhilePaused {
Muxi Yana8d40b52017-05-23 17:15:23 -0700197 __weak XCTestExpectation *expectation = [self expectationWithDescription:@"Response received"];
Test User9656eca2016-02-18 14:47:22 -0800198 // Given:
199 CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
Muxi Yanc92d90a2018-04-11 18:10:02 -0700200 id<GRXWriteable> writeable =
201 [GRXWriteable writeableWithSingleHandler:^(id value, NSError *errorOrNil) {
202 handler.block(value, errorOrNil);
203 [expectation fulfill];
204 }];
Test User9656eca2016-02-18 14:47:22 -0800205 id anyValue = @7;
206
207 // If:
208 GRXBufferedPipe *pipe = [GRXBufferedPipe pipe];
209 // Write something, then finish
210 [pipe writeValue:anyValue];
211 [pipe writesFinishedWithError:nil];
212 // then start the writeable
213 [pipe startWithWriteable:writeable];
214
215 // Then:
Muxi Yana8d40b52017-05-23 17:15:23 -0700216 [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
Test User9656eca2016-02-18 14:47:22 -0800217 XCTAssertEqual(handler.timesCalled, 1);
218 XCTAssertEqualObjects(handler.value, anyValue);
219 XCTAssertEqualObjects(handler.errorOrNil, nil);
220}
221
Muxi Yan860b1da2017-07-29 12:05:19 -0700222#define WRITE_ROUNDS (1000)
223- (void)testBufferedPipeResumeWhenDealloc {
224 id anyValue = @7;
Muxi Yanc92d90a2018-04-11 18:10:02 -0700225 id<GRXWriteable> writeable =
226 [GRXWriteable writeableWithSingleHandler:^(id value, NSError *errorOrNil){
227 }];
Muxi Yan860b1da2017-07-29 12:05:19 -0700228
229 // Release after alloc;
230 GRXBufferedPipe *pipe = [GRXBufferedPipe pipe];
231 pipe = nil;
232
233 // Release after write but before start
234 pipe = [GRXBufferedPipe pipe];
235 for (int i = 0; i < WRITE_ROUNDS; i++) {
236 [pipe writeValue:anyValue];
237 }
238 pipe = nil;
239
240 // Release after start but not write
241 pipe = [GRXBufferedPipe pipe];
242 [pipe startWithWriteable:writeable];
243 pipe = nil;
244
245 // Release after start and write
246 pipe = [GRXBufferedPipe pipe];
247 for (int i = 0; i < WRITE_ROUNDS; i++) {
248 [pipe writeValue:anyValue];
249 }
250 [pipe startWithWriteable:writeable];
251 pipe = nil;
252
253 // Release after start, write and pause
254 pipe = [GRXBufferedPipe pipe];
255 [pipe startWithWriteable:writeable];
256 for (int i = 0; i < WRITE_ROUNDS; i++) {
257 [pipe writeValue:anyValue];
258 }
259 pipe.state = GRXWriterStatePaused;
260 for (int i = 0; i < WRITE_ROUNDS; i++) {
261 [pipe writeValue:anyValue];
262 }
263 pipe = nil;
264
265 // Release after start, write, pause and finish
266 pipe = [GRXBufferedPipe pipe];
267 [pipe startWithWriteable:writeable];
268 for (int i = 0; i < WRITE_ROUNDS; i++) {
269 [pipe writeValue:anyValue];
270 }
271 pipe.state = GRXWriterStatePaused;
272 for (int i = 0; i < WRITE_ROUNDS; i++) {
273 [pipe writeValue:anyValue];
274 }
275 [pipe finishWithError:nil];
276 pipe = nil;
277
278 // Release after start, write, pause, finish and resume
279 pipe = [GRXBufferedPipe pipe];
280 [pipe startWithWriteable:writeable];
281 for (int i = 0; i < WRITE_ROUNDS; i++) {
282 [pipe writeValue:anyValue];
283 }
284 pipe.state = GRXWriterStatePaused;
285 for (int i = 0; i < WRITE_ROUNDS; i++) {
286 [pipe writeValue:anyValue];
287 }
288 [pipe finishWithError:nil];
289 pipe.state = GRXWriterStateStarted;
290 pipe = nil;
291}
292
Jorge Canizales62951152015-05-26 14:32:12 -0700293@end