Imported Upstream version 1.21.3
[platform/upstream/grpc.git] / src / objective-c / tests / RxLibraryUnitTests.m
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
19 #import <XCTest/XCTest.h>
20
21 #import <RxLibrary/GRXBufferedPipe.h>
22 #import <RxLibrary/GRXWriteable.h>
23 #import <RxLibrary/GRXWriter.h>
24
25 #define TEST_TIMEOUT 1
26
27 // A mock of a GRXSingleValueHandler block that can be queried for how many times it was called and
28 // what were the last values passed to it.
29 //
30 // TODO(jcanizales): Move this to a test util library, and add tests for it.
31 @interface CapturingSingleValueHandler : NSObject
32 @property(nonatomic, readonly) void (^block)(id value, NSError *errorOrNil);
33 @property(nonatomic, readonly) NSUInteger timesCalled;
34 @property(nonatomic, readonly) id value;
35 @property(nonatomic, readonly) NSError *errorOrNil;
36 + (instancetype)handler;
37 @end
38
39 @implementation CapturingSingleValueHandler
40 + (instancetype)handler {
41   return [[self alloc] init];
42 }
43
44 - (GRXSingleHandler)block {
45   return ^(id value, NSError *errorOrNil) {
46     ++self->_timesCalled;
47     self->_value = value;
48     self->_errorOrNil = errorOrNil;
49   };
50 }
51 @end
52
53 // TODO(jcanizales): Split into one file per tested class.
54
55 @interface RxLibraryUnitTests : XCTestCase
56 @end
57
58 @implementation RxLibraryUnitTests
59
60 + (void)setUp {
61   NSLog(@"GRPCClientTests Started");
62 }
63
64 #pragma mark Writeable
65
66 - (void)testWriteableSingleHandlerIsCalledForValue {
67   // Given:
68   CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
69   id anyValue = @7;
70
71   // If:
72   id<GRXWriteable> writeable = [GRXWriteable writeableWithSingleHandler:handler.block];
73   [writeable writeValue:anyValue];
74   [writeable writesFinishedWithError:nil];
75
76   // Then:
77   XCTAssertEqual(handler.timesCalled, 1);
78   XCTAssertEqualObjects(handler.value, anyValue);
79   XCTAssertEqualObjects(handler.errorOrNil, nil);
80 }
81
82 - (void)testWriteableSingleHandlerIsCalledForError {
83   // Given:
84   CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
85   NSError *anyError = [NSError errorWithDomain:@"domain" code:7 userInfo:nil];
86
87   // If:
88   id<GRXWriteable> writeable = [GRXWriteable writeableWithSingleHandler:handler.block];
89   [writeable writesFinishedWithError:anyError];
90
91   // Then:
92   XCTAssertEqual(handler.timesCalled, 1);
93   XCTAssertEqualObjects(handler.value, nil);
94   XCTAssertEqualObjects(handler.errorOrNil, anyError);
95 }
96
97 - (void)testWriteableSingleHandlerIsCalledOnlyOnce_ValueThenError {
98   // Given:
99   CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
100   id anyValue = @7;
101   NSError *anyError = [NSError errorWithDomain:@"domain" code:7 userInfo:nil];
102
103   // If:
104   id<GRXWriteable> writeable = [GRXWriteable writeableWithSingleHandler:handler.block];
105   [writeable writeValue:anyValue];
106   [writeable writesFinishedWithError:anyError];
107
108   // Then:
109   XCTAssertEqual(handler.timesCalled, 1);
110   XCTAssertEqualObjects(handler.value, anyValue);
111   XCTAssertEqualObjects(handler.errorOrNil, nil);
112 }
113
114 - (void)testWriteableSingleHandlerIsCalledOnlyOnce_ValueThenValue {
115   // Given:
116   CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
117   id anyValue = @7;
118
119   // If:
120   id<GRXWriteable> writeable = [GRXWriteable writeableWithSingleHandler:handler.block];
121   [writeable writeValue:anyValue];
122   [writeable writeValue:anyValue];
123   [writeable writesFinishedWithError:nil];
124
125   // Then:
126   XCTAssertEqual(handler.timesCalled, 1);
127   XCTAssertEqualObjects(handler.value, anyValue);
128   XCTAssertEqualObjects(handler.errorOrNil, nil);
129 }
130
131 - (void)testWriteableSingleHandlerFailsOnEmptyWriter {
132   // Given:
133   CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
134
135   // If:
136   id<GRXWriteable> writeable = [GRXWriteable writeableWithSingleHandler:handler.block];
137   [writeable writesFinishedWithError:nil];
138
139   // Then:
140   XCTAssertEqual(handler.timesCalled, 1);
141   XCTAssertEqualObjects(handler.value, nil);
142   XCTAssertNotNil(handler.errorOrNil);
143 }
144
145 #pragma mark BufferedPipe
146
147 - (void)testBufferedPipePropagatesValue {
148   __weak XCTestExpectation *expectation = [self expectationWithDescription:@"Response received"];
149   // Given:
150   CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
151   id<GRXWriteable> writeable =
152       [GRXWriteable writeableWithSingleHandler:^(id value, NSError *errorOrNil) {
153         handler.block(value, errorOrNil);
154         [expectation fulfill];
155       }];
156
157   id anyValue = @7;
158
159   // If:
160   GRXBufferedPipe *pipe = [GRXBufferedPipe pipe];
161   [pipe startWithWriteable:writeable];
162   [pipe writeValue:anyValue];
163   [pipe writesFinishedWithError:nil];
164
165   // Then:
166   [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
167   XCTAssertEqual(handler.timesCalled, 1);
168   XCTAssertEqualObjects(handler.value, anyValue);
169   XCTAssertEqualObjects(handler.errorOrNil, nil);
170 }
171
172 - (void)testBufferedPipePropagatesError {
173   __weak XCTestExpectation *expectation = [self expectationWithDescription:@"Response received"];
174   // Given:
175   CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
176   id<GRXWriteable> writeable =
177       [GRXWriteable writeableWithSingleHandler:^(id value, NSError *errorOrNil) {
178         handler.block(value, errorOrNil);
179         [expectation fulfill];
180       }];
181   NSError *anyError = [NSError errorWithDomain:@"domain" code:7 userInfo:nil];
182
183   // If:
184   GRXBufferedPipe *pipe = [GRXBufferedPipe pipe];
185   [pipe startWithWriteable:writeable];
186   [pipe writesFinishedWithError:anyError];
187
188   // Then:
189   [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
190   XCTAssertEqual(handler.timesCalled, 1);
191   XCTAssertEqualObjects(handler.value, nil);
192   XCTAssertEqualObjects(handler.errorOrNil, anyError);
193 }
194
195 - (void)testBufferedPipeFinishWriteWhilePaused {
196   __weak XCTestExpectation *expectation = [self expectationWithDescription:@"Response received"];
197   // Given:
198   CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
199   id<GRXWriteable> writeable =
200       [GRXWriteable writeableWithSingleHandler:^(id value, NSError *errorOrNil) {
201         handler.block(value, errorOrNil);
202         [expectation fulfill];
203       }];
204   id anyValue = @7;
205
206   // If:
207   GRXBufferedPipe *pipe = [GRXBufferedPipe pipe];
208   // Write something, then finish
209   [pipe writeValue:anyValue];
210   [pipe writesFinishedWithError:nil];
211   // then start the writeable
212   [pipe startWithWriteable:writeable];
213
214   // Then:
215   [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
216   XCTAssertEqual(handler.timesCalled, 1);
217   XCTAssertEqualObjects(handler.value, anyValue);
218   XCTAssertEqualObjects(handler.errorOrNil, nil);
219 }
220
221 #define WRITE_ROUNDS (1000)
222 - (void)testBufferedPipeResumeWhenDealloc {
223   id anyValue = @7;
224   id<GRXWriteable> writeable =
225       [GRXWriteable writeableWithSingleHandler:^(id value, NSError *errorOrNil){
226       }];
227
228   // Release after alloc;
229   GRXBufferedPipe *pipe = [GRXBufferedPipe pipe];
230   pipe = nil;
231
232   // Release after write but before start
233   pipe = [GRXBufferedPipe pipe];
234   for (int i = 0; i < WRITE_ROUNDS; i++) {
235     [pipe writeValue:anyValue];
236   }
237   pipe = nil;
238
239   // Release after start but not write
240   pipe = [GRXBufferedPipe pipe];
241   [pipe startWithWriteable:writeable];
242   pipe = nil;
243
244   // Release after start and write
245   pipe = [GRXBufferedPipe pipe];
246   for (int i = 0; i < WRITE_ROUNDS; i++) {
247     [pipe writeValue:anyValue];
248   }
249   [pipe startWithWriteable:writeable];
250   pipe = nil;
251
252   // Release after start, write and pause
253   pipe = [GRXBufferedPipe pipe];
254   [pipe startWithWriteable:writeable];
255   for (int i = 0; i < WRITE_ROUNDS; i++) {
256     [pipe writeValue:anyValue];
257   }
258   pipe.state = GRXWriterStatePaused;
259   for (int i = 0; i < WRITE_ROUNDS; i++) {
260     [pipe writeValue:anyValue];
261   }
262   pipe = nil;
263
264   // Release after start, write, pause and finish
265   pipe = [GRXBufferedPipe pipe];
266   [pipe startWithWriteable:writeable];
267   for (int i = 0; i < WRITE_ROUNDS; i++) {
268     [pipe writeValue:anyValue];
269   }
270   pipe.state = GRXWriterStatePaused;
271   for (int i = 0; i < WRITE_ROUNDS; i++) {
272     [pipe writeValue:anyValue];
273   }
274   [pipe finishWithError:nil];
275   pipe = nil;
276
277   // Release after start, write, pause, finish and resume
278   pipe = [GRXBufferedPipe pipe];
279   [pipe startWithWriteable:writeable];
280   for (int i = 0; i < WRITE_ROUNDS; i++) {
281     [pipe writeValue:anyValue];
282   }
283   pipe.state = GRXWriterStatePaused;
284   for (int i = 0; i < WRITE_ROUNDS; i++) {
285     [pipe writeValue:anyValue];
286   }
287   [pipe finishWithError:nil];
288   pipe.state = GRXWriterStateStarted;
289   pipe = nil;
290 }
291
292 @end