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

Unified Diff: webrtc/sdk/objc/Framework/UnitTests/RTCCameraVideoCapturerTests.mm

Issue 2815823002: Add unit test class for RTCCameraVideoCapturer. (Closed)
Patch Set: Add tests that test only the public interface 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 side-by-side diff with in-line comments
Download patch
Index: webrtc/sdk/objc/Framework/UnitTests/RTCCameraVideoCapturerTests.mm
diff --git a/webrtc/sdk/objc/Framework/UnitTests/RTCCameraVideoCapturerTests.mm b/webrtc/sdk/objc/Framework/UnitTests/RTCCameraVideoCapturerTests.mm
new file mode 100644
index 0000000000000000000000000000000000000000..9aa91d6f34100459b6a2124a12faccd4b4c8c46c
--- /dev/null
+++ b/webrtc/sdk/objc/Framework/UnitTests/RTCCameraVideoCapturerTests.mm
@@ -0,0 +1,243 @@
+/*
+ * Copyright 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#import <OCMock/OCMock.h>
+#import <UIKit/UIKit.h>
+
+#include "webrtc/base/gunit.h"
+
+#import <WebRTC/RTCCameraVideoCapturer.h>
+#import <WebRTC/RTCDispatcher.h>
+#import <WebRTC/RTCVideoFrame.h>
+
+// Helper method.
+CMSampleBufferRef createMockSampleBufferRef() {
magjed_webrtc 2017/04/26 14:12:09 This is nice! We will probably need something simi
daniela-webrtc 2017/04/27 09:40:20 Done.
+ // This image is already in the testing bundle.
+ UIImage *image = [UIImage imageNamed:@"Default.png"];
+ CGSize size = image.size;
+ CGImageRef imageRef = [image CGImage];
+
+ CVPixelBufferRef pixelBuffer = nullptr;
+ CVPixelBufferCreate(kCFAllocatorDefault, size.width, size.height, kCVPixelFormatType_32ARGB, nil,
+ &pixelBuffer);
+
+ CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
+ CGContextRef context = CGBitmapContextCreate(nil, size.width, size.height, 8, 8 * size.width,
+ rgbColorSpace, kCGImageAlphaPremultipliedFirst);
+
+ CGContextDrawImage(
+ context, CGRectMake(0, 0, CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)), imageRef);
+
+ CGColorSpaceRelease(rgbColorSpace);
+ CGContextRelease(context);
+
+ // We don't really care about the timing.
+ CMSampleTimingInfo timing = {kCMTimeInvalid, kCMTimeInvalid, kCMTimeInvalid};
+ CMVideoFormatDescriptionRef description = nullptr;
+ CMVideoFormatDescriptionCreateForImageBuffer(NULL, pixelBuffer, &description);
+
+ CMSampleBufferRef sampleBuffer = nullptr;
+ CMSampleBufferCreateForImageBuffer(kCFAllocatorDefault, pixelBuffer, YES, NULL, NULL, description,
+ &timing, &sampleBuffer);
+ CFRelease(pixelBuffer);
+
+ return sampleBuffer;
+}
+
+@interface RTCCameraVideoCapturer (Tests)<AVCaptureVideoDataOutputSampleBufferDelegate>
+@end
+
+@interface RTCCameraVideoCapturerTests : NSObject
+@property(nonatomic, strong) id delegateMock;
+@property(nonatomic, strong) id deviceMock;
+@property(nonatomic, strong) RTCCameraVideoCapturer *capturer;
+@end
+
+@implementation RTCCameraVideoCapturerTests
+@synthesize delegateMock = _delegateMock;
+@synthesize capturer = _capturer;
+@synthesize deviceMock = _deviceMock;
+
+- (void)setup {
+ self.delegateMock = OCMProtocolMock(@protocol(RTCVideoCapturerDelegate));
+ self.capturer = [[RTCCameraVideoCapturer alloc] initWithDelegate:self.delegateMock];
+ self.deviceMock = [self createDeviceMock];
+}
+
+- (void)tearDown {
+ [self.delegateMock stopMocking];
+ [self.deviceMock stopMocking];
+ self.delegateMock = nil;
+ self.deviceMock = nil;
+ self.capturer = nil;
+}
+
+#pragma mark - utils
+
+- (id)createDeviceMock {
+ return OCMClassMock([AVCaptureDevice class]);
+}
+
+#pragma mark - test cases
+
+- (void)testSetupSession {
+ AVCaptureSession *session = self.capturer.captureSession;
+ EXPECT_TRUE(session != nil);
+ EXPECT_EQ(session.sessionPreset, AVCaptureSessionPresetInputPriority);
+ EXPECT_EQ(session.usesApplicationAudioSession, NO);
+ EXPECT_EQ(session.outputs.count, 1u);
+}
+
+- (void)testSetupSessionOutput {
+ AVCaptureVideoDataOutput *videoOutput = self.capturer.captureSession.outputs[0];
+ EXPECT_TRUE(videoOutput.videoSettings != nil);
+ EXPECT_EQ(videoOutput.alwaysDiscardsLateVideoFrames, NO);
+ EXPECT_EQ(videoOutput.sampleBufferDelegate, self.capturer);
+}
+
+- (void)testSupportedFormatsForDevice {
+ // given
+ id validFormat1 = OCMClassMock([AVCaptureDeviceFormat class]);
+ CMVideoFormatDescriptionRef format;
+ CMVideoFormatDescriptionCreate(nil, kCVPixelFormatType_420YpCbCr8PlanarFullRange, 123, 456, nil,
+ &format);
+ OCMStub([validFormat1 formatDescription]).andReturn(format);
+
+ id validFormat2 = OCMClassMock([AVCaptureDeviceFormat class]);
+ CMVideoFormatDescriptionCreate(nil, kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange, 123, 456,
+ nil, &format);
+ OCMStub([validFormat2 formatDescription]).andReturn(format);
+
+ id invalidFormat = OCMClassMock([AVCaptureDeviceFormat class]);
+ CMVideoFormatDescriptionCreate(nil, kCVPixelFormatType_422YpCbCr8_yuvs, 123, 456, nil, &format);
+ OCMStub([invalidFormat formatDescription]).andReturn(format);
+
+ NSArray *formats = @[ validFormat1, validFormat2, invalidFormat ];
+ OCMStub([self.deviceMock formats]).andReturn(formats);
+
+ // when
+ NSArray *supportedFormats = [RTCCameraVideoCapturer supportedFormatsForDevice:self.deviceMock];
+
+ // then
+ EXPECT_EQ(supportedFormats.count, 2u);
+ EXPECT_TRUE([supportedFormats containsObject:validFormat1]);
+ EXPECT_TRUE([supportedFormats containsObject:validFormat2]);
+ // cleanup
+ [validFormat1 stopMocking];
+ [validFormat2 stopMocking];
+ [invalidFormat stopMocking];
+ validFormat1 = nil;
+ validFormat2 = nil;
+ invalidFormat = nil;
+}
+
+- (void)testCaptureDevices {
+ OCMStub([self.deviceMock devicesWithMediaType:AVMediaTypeVideo]).andReturn(@[ [NSObject new] ]);
magjed_webrtc 2017/04/26 14:12:08 Remove duplicate line
daniela-webrtc 2017/04/27 09:40:20 This line is not duplicate. The first one mocks AV
magjed_webrtc 2017/04/27 14:48:12 Acknowledged.
+ OCMStub([self.deviceMock devicesWithMediaType:AVMediaTypeAudio]).andReturn(@[ [NSObject new] ]);
+
+ NSArray *captureDevices = [RTCCameraVideoCapturer captureDevices];
+
+ EXPECT_EQ(captureDevices.count, 1u);
+}
+
+- (void)testDelegateCallbackNotCalledWhenInvalidBuffer {
+ // given
+ CMSampleBufferRef sampleBuffer = nullptr;
+ [[self.delegateMock reject] capturer:[OCMArg any] didCaptureVideoFrame:[OCMArg any]];
+
+ // when
+
+ [self.capturer captureOutput:self.capturer.captureSession.outputs[0]
+ didOutputSampleBuffer:sampleBuffer
+ fromConnection:nil];
+
+ // then
+ [self.delegateMock verify];
+}
+
+- (void)testDelegateCallbackWithValideBufferAndOrientationUpdate {
magjed_webrtc 2017/04/26 14:12:08 spelling nit: Valide
daniela-webrtc 2017/04/27 09:40:20 Done.
+ // given
+ UIDevice *currentDeviceMock = OCMClassMock([UIDevice class]);
+ // UpsideDown -> RTCVideoRotation_270.
+ OCMStub(currentDeviceMock.orientation).andReturn(UIDeviceOrientationPortraitUpsideDown);
+ id classMock = OCMClassMock([UIDevice class]);
+ OCMStub([classMock currentDevice]).andReturn(currentDeviceMock);
+
+ CMSampleBufferRef sampleBuffer = createMockSampleBufferRef();
+
+ // then
+ [[self.delegateMock expect] capturer:self.capturer
+ didCaptureVideoFrame:[OCMArg checkWithBlock:^BOOL(RTCVideoFrame *expectedFrame) {
+ EXPECT_EQ(expectedFrame.rotation, RTCVideoRotation_270);
+ return YES;
+ }]];
+
+ // when
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
+ [center postNotificationName:UIDeviceOrientationDidChangeNotification object:nil];
+
+ // We need to wait for the dispatch to finish.
+ WAIT(0, 1000);
magjed_webrtc 2017/04/26 14:12:09 I think it's preferable in this case to expose '(v
daniela-webrtc 2017/04/27 09:40:20 I'd prefer to keep this test as is because it test
magjed_webrtc 2017/04/27 14:48:12 Ok, it's the WAIT in particular I don't like. Is i
+
+ [self.capturer captureOutput:self.capturer.captureSession.outputs[0]
+ didOutputSampleBuffer:sampleBuffer
+ fromConnection:nil];
+
+ [self.delegateMock verify];
+
+ [(id)currentDeviceMock stopMocking];
+ currentDeviceMock = nil;
+ [classMock stopMocking];
+ classMock = nil;
+ CFRelease(sampleBuffer);
+}
+@end
+
+TEST(RTCCameraVideoCapturerTests, SetupSession) {
+ RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init];
+ [test setup];
+ [test testSetupSession];
+ [test tearDown];
+}
+
+TEST(RTCCameraVideoCapturerTests, SetupSessionOutput) {
+ RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init];
+ [test setup];
+ [test testSetupSessionOutput];
+ [test tearDown];
+}
+
+TEST(RTCCameraVideoCapturerTests, SupportedFormatsForDevice) {
+ RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init];
+ [test setup];
+ [test testSupportedFormatsForDevice];
+ [test tearDown];
+}
+
+TEST(RTCCameraVideoCapturerTests, CaptureDevices) {
+ RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init];
+ [test setup];
+ [test testCaptureDevices];
+ [test tearDown];
+}
+
+TEST(RTCCameraVideoCapturerTests, DelegateCallbackNotCalledWhenInvalidBuffer) {
+ RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init];
+ [test setup];
+ [test testDelegateCallbackNotCalledWhenInvalidBuffer];
+ [test tearDown];
+}
+
+TEST(RTCCameraVideoCapturerTests, DelegateCallbackWithValideBufferAndOrientationUpdate) {
+ RTCCameraVideoCapturerTests *test = [[RTCCameraVideoCapturerTests alloc] init];
+ [test setup];
+ [test testDelegateCallbackWithValideBufferAndOrientationUpdate];
+ [test tearDown];
+}

Powered by Google App Engine
This is Rietveld 408576698