Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Side by Side Diff: webrtc/sdk/objc/Framework/UnitTests/RTCCameraVideoCapturerTests.mm

Issue 2815823002: Add unit test class for RTCCameraVideoCapturer. (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/sdk/objc/Framework/Classes/RTCCameraVideoCapturer.m ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2017 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #import <OCMock/OCMock.h>
12 #import <UIKit/UIKit.h>
13
14 #include "webrtc/base/gunit.h"
15
16 #import <WebRTC/RTCCameraVideoCapturer.h>
17 #import <WebRTC/RTCDispatcher.h>
18 #import <WebRTC/RTCVideoFrame.h>
19
20 @interface RTCCameraVideoCapturer (Testing)<AVCaptureVideoDataOutputSampleBuffer Delegate>
21 @property(nonatomic, strong) AVCaptureVideoDataOutput *videoDataOutput;
22 @property(nonatomic, strong) AVCaptureDevice *currentDevice;
23 @property(nonatomic, strong) dispatch_queue_t frameQueue;
24 @property(nonatomic, assign) RTCVideoRotation rotation;
25 // Will the session be running once all asynchronous operations have been comple ted?
26 @property(nonatomic, assign) BOOL willBeRunning;
27
28 - (BOOL)setupCaptureSession;
29 - (void)setupVideoDataOutput;
30 - (void)updateOrientation:(UIDeviceOrientation)orientation;
31 - (BOOL)tryStartCaptureWithDevice:(AVCaptureDevice *)device
32 format:(AVCaptureDeviceFormat *)format
33 fps:(int)fps;
34 @end
35
36 @interface RTCCameraVideoCapturerTests : NSObject
37 @property(nonatomic, strong) id delegateMock;
38 @property(nonatomic, strong) id deviceMock;
39 @property(nonatomic, strong) id dispatchQueueMock;
40 @property(nonatomic, strong) RTCCameraVideoCapturer *capturer;
41 @end
42
43 @implementation RTCCameraVideoCapturerTests
44 @synthesize delegateMock = _delegateMock;
45 @synthesize capturer = _capturer;
46 @synthesize deviceMock = _deviceMock;
47 @synthesize dispatchQueueMock = _dispatchQueueMock;
48
49 - (void)setup {
50 self.delegateMock = OCMProtocolMock(@protocol(RTCVideoCapturerDelegate));
51 self.capturer = [[RTCCameraVideoCapturer alloc] initWithDelegate:self.delegate Mock];
52 // Needed when testing async methods so we don't dispatch for real.
53 self.dispatchQueueMock = [self createDispatcherMock];
54 self.deviceMock = [self createDeviceMock];
55 }
56
57 - (void)tearDown {
58 [self.delegateMock stopMocking];
59 [self.deviceMock stopMocking];
60 [self.dispatchQueueMock stopMocking];
61 self.delegateMock = nil;
62 self.deviceMock = nil;
63 self.dispatchQueueMock = nil;
64 self.capturer = nil;
65 }
66
67 #pragma mark - utils
68
69 - (id)createDispatcherMock {
70 id dispatcherMock = OCMClassMock([RTCDispatcher class]);
71 [[[dispatcherMock stub] ignoringNonObjectArgs] dispatchAsyncOnType:RTCDispatch erTypeCaptureSession
72 block:^(void){
73
74 }];
75 return dispatcherMock;
76 }
77
78 - (id)createDeviceMock {
79 return OCMClassMock([AVCaptureDevice class]);
80 }
81
82 #pragma mark - test cases
83
84 - (void)testSetupSession {
magjed_webrtc 2017/04/13 11:13:06 This test is good
85 AVCaptureSession *session = self.capturer.captureSession;
86 EXPECT_TRUE(session != nil);
87 EXPECT_EQ(session.sessionPreset, AVCaptureSessionPresetInputPriority);
88 EXPECT_EQ(session.usesApplicationAudioSession, NO);
89 EXPECT_EQ(session.outputs.count, 1u);
90 AVCaptureOutput *sessionOutput = session.outputs[0];
91 EXPECT_EQ(sessionOutput, self.capturer.videoDataOutput);
magjed_webrtc 2017/04/13 11:13:06 except that we can't make this check since it's an
92 }
93
94 // Test that setup session will assert when called twice
95 - (void)testSetupSessionSecondCall {
96 // TODO(denicija): Replace this whole block with XCTAssertThrows after migrati ng to XCTest.
97 BOOL asserts = NO;
98 @try {
99 // when
100 [self.capturer setupCaptureSession];
magjed_webrtc 2017/04/13 11:13:06 You can't test this directly since it's an interna
101 } @catch (NSException *exception) {
102 asserts = YES;
103 }
104
105 // then
106 EXPECT_TRUE(asserts);
107 }
108
109 - (void)testSetupSessionOutput {
110 AVCaptureVideoDataOutput *videoOutput = self.capturer.videoDataOutput;
magjed_webrtc 2017/04/13 11:13:06 Is it possible to extract this object through the
daniela-webrtc 2017/04/26 11:43:38 Done.
111
112 EXPECT_TRUE(videoOutput.videoSettings != nil);
113 EXPECT_EQ(videoOutput.alwaysDiscardsLateVideoFrames, NO);
114 EXPECT_EQ(videoOutput.sampleBufferDelegate, self.capturer);
115 EXPECT_EQ(videoOutput.sampleBufferCallbackQueue, self.capturer.frameQueue);
116 }
117
118 - (void)testSetupSessionOutputSecondCall {
magjed_webrtc 2017/04/13 11:13:06 Same here, we can't test this directly.
119 // TODO(denicija): Replace this whole block with XCTAssertThrows after migrati ng to XCTest.
120 BOOL asserts = NO;
121 @try {
122 // when
123 [self.capturer setupVideoDataOutput];
124 } @catch (NSException *exception) {
125 asserts = YES;
126 }
127 // then
128 EXPECT_TRUE(asserts);
129 }
130
131 // Test that start/stop mechanism dosen't fire unnecesarilly.
132 - (void)testWillBeRunningFlagIsFalse {
magjed_webrtc 2017/04/13 11:13:06 We have to change this test to check e.g. that we
daniela-webrtc 2017/04/26 11:43:38 This test case intends to test that dealloc doesn'
133 EXPECT_TRUE(!self.capturer.willBeRunning);
134
135 // given
136 self.capturer = nil;
137 self.capturer = [[RTCCameraVideoCapturer alloc] init];
138 // when
139 [self.capturer startCaptureWithDevice:self.deviceMock format:[AVCaptureDeviceF ormat new] fps:30];
140 [self.capturer stopCapture];
141 // then
142 EXPECT_TRUE(!self.capturer.willBeRunning);
143 }
144
145 // Test that start/stop mechanism check works.
146 - (void)testWillBeRunningFlagIsTrue {
147 // when
148 [self.capturer startCaptureWithDevice:self.deviceMock format:[AVCaptureDeviceF ormat new] fps:30];
149 // then
150 EXPECT_TRUE(self.capturer.willBeRunning);
151 }
152
153 - (void)testSupportedFormatsForDevice {
magjed_webrtc 2017/04/13 11:13:06 This test is good.
154 // given
155 id validFormat1 = OCMClassMock([AVCaptureDeviceFormat class]);
156 CMVideoFormatDescriptionRef format;
157 CMVideoFormatDescriptionCreate(nil, kCVPixelFormatType_420YpCbCr8PlanarFullRan ge, 123, 456, nil,
158 &format);
159 OCMStub([validFormat1 formatDescription]).andReturn(format);
160
161 id validFormat2 = OCMClassMock([AVCaptureDeviceFormat class]);
162 CMVideoFormatDescriptionCreate(nil, kCVPixelFormatType_420YpCbCr8BiPlanarVideo Range, 123, 456,
163 nil, &format);
164 OCMStub([validFormat2 formatDescription]).andReturn(format);
165
166 id invalidFormat = OCMClassMock([AVCaptureDeviceFormat class]);
167 CMVideoFormatDescriptionCreate(nil, kCVPixelFormatType_422YpCbCr8_yuvs, 123, 4 56, nil, &format);
168 OCMStub([invalidFormat formatDescription]).andReturn(format);
169
170 NSArray *formats = @[ validFormat1, validFormat2, invalidFormat ];
171 OCMStub([self.deviceMock formats]).andReturn(formats);
172
173 // when
174 NSArray *supportedFormats = [RTCCameraVideoCapturer supportedFormatsForDevice: self.deviceMock];
175
176 // then
177 EXPECT_EQ(supportedFormats.count, 2u);
178 EXPECT_TRUE([supportedFormats containsObject:validFormat1]);
179 EXPECT_TRUE([supportedFormats containsObject:validFormat2]);
180 // cleanup
181 [validFormat1 stopMocking];
182 [validFormat2 stopMocking];
183 [invalidFormat stopMocking];
184 validFormat1 = nil;
185 validFormat2 = nil;
186 invalidFormat = nil;
187 }
188
189 - (void)testStartCapture {
magjed_webrtc 2017/04/13 11:13:06 This test is interesting, but if we want to proper
daniela-webrtc 2017/04/26 11:43:38 If we want to change the API we should do that as
magjed_webrtc 2017/04/26 14:12:08 Ok, let's keep the API intact and not support pass
190 // given
191 OCMStub([self.deviceMock lockForConfiguration:[OCMArg setTo:nil]]).andReturn(N O);
192 // when
193 BOOL success = [self.capturer tryStartCaptureWithDevice:self.deviceMock format :nil fps:20];
194
195 // then
196 EXPECT_EQ(self.capturer.currentDevice, self.deviceMock);
197 EXPECT_TRUE(!success);
198 EXPECT_TRUE(!self.capturer.captureSession.isRunning);
199
200 // given
201 [self.deviceMock stopMocking];
202 self.deviceMock = [self createDeviceMock];
203 OCMStub([self.deviceMock lockForConfiguration:[OCMArg setTo:nil]]).andReturn(Y ES);
204 // when
205 success = [self.capturer tryStartCaptureWithDevice:self.deviceMock format:nil fps:20];
206 // then
207 EXPECT_TRUE(success);
208 EXPECT_TRUE(self.capturer.captureSession.isRunning);
209 }
210
211 - (void)testDelegateCallbackNotCalledWhenInvalidBuffer {
212 // given
213 CMSampleBufferRef sampleBuffer = nullptr;
214 [[self.delegateMock reject] capturer:[OCMArg any] didCaptureVideoFrame:[OCMArg any]];
215
216 // when
217 [self.capturer captureOutput:self.capturer.videoDataOutput
218 didOutputSampleBuffer:sampleBuffer
219 fromConnection:nil];
220
221 // then
222 [self.delegateMock verify];
223 }
224
225 - (void)testDelegateCallbackWithValidBuffer {
226 // TODO(denicija): Add this test case after creating util class for easy cmsam plebuffer mocking.
227 // It will probably be needed when adding unit tests for RTCVideoFrame.
228 }
229
230 - (void)testUpdateOrientationFrontCamera {
231 self.capturer.currentDevice = self.deviceMock;
232 OCMStub([(AVCaptureDevice *)self.deviceMock position]).andReturn(AVCaptureDevi cePositionFront);
233 // Portrait
234 [self.capturer updateOrientation:UIDeviceOrientationPortrait];
235 EXPECT_EQ(self.capturer.rotation, RTCVideoRotation_90);
236
237 // Left
238 [self.capturer updateOrientation:UIDeviceOrientationLandscapeLeft];
239 EXPECT_EQ(self.capturer.rotation, RTCVideoRotation_180);
240
241 // Upside down
242 [self.capturer updateOrientation:UIDeviceOrientationPortraitUpsideDown];
243 EXPECT_EQ(self.capturer.rotation, RTCVideoRotation_270);
244
245 // Right
246 [self.capturer updateOrientation:UIDeviceOrientationLandscapeRight];
247 EXPECT_EQ(self.capturer.rotation, RTCVideoRotation_0);
248 }
249
250 - (void)testUpdateOrientationBackCamera {
251 self.capturer.currentDevice = self.deviceMock;
252 OCMStub([(AVCaptureDevice *)self.deviceMock position]).andReturn(AVCaptureDevi cePositionBack);
253 // Portrait
254 [self.capturer updateOrientation:UIDeviceOrientationPortrait];
255 EXPECT_EQ(self.capturer.rotation, RTCVideoRotation_90);
256
257 // Left
258 [self.capturer updateOrientation:UIDeviceOrientationLandscapeLeft];
259 EXPECT_EQ(self.capturer.rotation, RTCVideoRotation_0);
260
261 // Upside down
262 [self.capturer updateOrientation:UIDeviceOrientationPortraitUpsideDown];
263 EXPECT_EQ(self.capturer.rotation, RTCVideoRotation_270);
264
265 // Right
266 [self.capturer updateOrientation:UIDeviceOrientationLandscapeRight];
267 EXPECT_EQ(self.capturer.rotation, RTCVideoRotation_180);
268 }
269 @end
270
271 TEST(RTCCameraVideoCapturerTests, SetupSession) {
272 RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init] ;
273 [test setup];
274 [test testSetupSession];
275 [test tearDown];
276 }
277
278 TEST(RTCCameraVideoCapturerTests, SetupSessionSecondCall) {
279 RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init] ;
280 [test setup];
281 [test testSetupSessionSecondCall];
282 [test tearDown];
283 }
284
285 TEST(RTCCameraVideoCapturerTests, SetupSessionOutput) {
286 RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init] ;
287 [test setup];
288 [test testSetupSessionOutput];
289 [test tearDown];
290 }
291
292 TEST(RTCCameraVideoCapturerTests, SetupSessionOutputSecondCall) {
293 RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init] ;
294 [test setup];
295 [test testSetupSessionOutputSecondCall];
296 [test tearDown];
297 }
298
299 TEST(RTCCameraVideoCapturerTests, WillBeRunningFlagIsFalse) {
300 RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init] ;
301 [test setup];
302 [test testWillBeRunningFlagIsFalse];
303 [test tearDown];
304 }
305
306 TEST(RTCCameraVideoCapturerTests, WillBeRunningFlagIsTrue) {
307 RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init] ;
308 [test setup];
309 [test testWillBeRunningFlagIsTrue];
310 [test tearDown];
311 }
312
313 TEST(RTCCameraVideoCapturerTests, SupportedFormatsForDevice) {
314 RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init] ;
315 [test setup];
316 [test testSupportedFormatsForDevice];
317 [test tearDown];
318 }
319
320 TEST(RTCCameraVideoCapturerTests, StartCapture) {
321 RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init] ;
322 [test setup];
323 [test testStartCapture];
324 [test tearDown];
325 }
326
327 TEST(RTCCameraVideoCapturerTests, DelegateCallbackNotCalledWhenInvalidBuffer) {
328 RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init] ;
329 [test setup];
330 [test testDelegateCallbackNotCalledWhenInvalidBuffer];
331 [test tearDown];
332 }
333
334 TEST(RTCCameraVideoCapturerTests, UpdateOrientationFrontCamera) {
335 RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init] ;
336 [test setup];
337 [test testUpdateOrientationFrontCamera];
338 [test tearDown];
339 }
340
341 TEST(RTCCameraVideoCapturerTests, UpdateOrientationBackCamera) {
342 RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init] ;
343 [test setup];
344 [test testUpdateOrientationBackCamera];
345 [test tearDown];
346 }
OLDNEW
« no previous file with comments | « webrtc/sdk/objc/Framework/Classes/RTCCameraVideoCapturer.m ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698