blob: 1d422eb09aa9b55e8a0b98414b30b9c605ea7e17 [file] [log] [blame]
kthelgason954d9b92017-03-09 03:36:58 -08001/*
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 <Foundation/Foundation.h>
12#import <OCMock/OCMock.h>
13
14#include "webrtc/base/gunit.h"
15
16#include <Metal/RTCMTLNV12Renderer.h>
17#include <WebRTC/RTCMTLVideoView.h>
18
19// Extension of RTCMTLVideoView for testing purposes.
20@interface RTCMTLVideoView (Testing)
21@property(nonatomic, strong) id<RTCMTLRenderer> renderer;
22@property(nonatomic, strong) UIView* metalView;
23@property(atomic, strong) RTCVideoFrame* videoFrame;
24
25+ (BOOL)isMetalAvailable;
26+ (UIView*)createMetalView:(CGRect)frame;
27+ (id<RTCMTLRenderer>)createMetalRenderer;
28- (void)drawInMTKView:(id)view;
29@end
30
31@interface RTCMTLVideoViewTests : NSObject
32@property(nonatomic, strong) id classMock;
33@property(nonatomic, strong) id metalViewMock;
34@property(nonatomic, strong) id rendererMock;
35@end
36
37@implementation RTCMTLVideoViewTests
38
39@synthesize classMock = _classMock;
40@synthesize metalViewMock = _metalViewMock;
41@synthesize rendererMock = _rendererMock;
42
43- (void)setup {
44 self.classMock = OCMClassMock([RTCMTLVideoView class]);
45
46 self.metalViewMock = OCMClassMock([RTCMTLVideoViewTests class]);
47 // NOTE: OCMock doesen't provide modern syntax for -ignoringNonObjectArgs.
48 [[[[self.classMock stub] ignoringNonObjectArgs] andReturn:self.metalViewMock]
49 createMetalView:CGRectZero];
50
51 self.rendererMock = OCMProtocolMock(@protocol(RTCMTLRenderer));
52 OCMStub([self.classMock createMetalRenderer]).andReturn(self.rendererMock);
53}
54
55- (void)tearDown {
56 [self.classMock stopMocking];
57 [self.rendererMock stopMocking];
58 [self.metalViewMock stopMocking];
59 self.classMock = nil;
60 self.rendererMock = nil;
61 self.metalViewMock = nil;
62}
63
64- (void)testMetalConfigureNotExecuted {
65 // when
66 OCMStub([self.classMock isMetalAvailable]).andReturn(NO);
67 RTCMTLVideoView *realView = [[RTCMTLVideoView alloc] init];
68
69 // then
70 EXPECT_TRUE(realView.renderer == nil);
71 EXPECT_TRUE(realView.metalView == nil);
72}
73
74- (void)testMetalConfigureExecuted {
75 // given
76 OCMStub([self.classMock isMetalAvailable]).andReturn(YES);
77 OCMStub([self.rendererMock addRenderingDestination:self.metalViewMock])
78 .andReturn(NO);
79
80 // when
81 RTCMTLVideoView *realView = [[RTCMTLVideoView alloc] init];
82
83 // then
84 EXPECT_TRUE(realView.renderer == nil);
85 EXPECT_TRUE(realView.metalView != nil);
86}
87
88- (void)testMetalDrawCallback {
89 // given
90 OCMStub([self.classMock isMetalAvailable]).andReturn(NO);
91 OCMExpect([self.rendererMock drawFrame:[OCMArg any]]);
92 RTCMTLVideoView *realView = [[RTCMTLVideoView alloc] init];
93 realView.metalView = self.metalViewMock;
94 realView.renderer = self.rendererMock;
95
96 // when
97 [realView drawInMTKView:self.metalViewMock];
98
99 // then
100 [self.rendererMock verify];
101}
102
103- (void)testRTCVideoRenderNilFrameCallback {
104 // given
105 OCMStub([self.classMock isMetalAvailable]).andReturn(NO);
106 RTCMTLVideoView *realView = [[RTCMTLVideoView alloc] init];
107
108 // when
109 [realView renderFrame:nil];
110
111 // then
112 EXPECT_TRUE(realView.videoFrame == nil);
113}
114
115- (void)testRTCVideoRenderFrameCallback {
116 // given
117 OCMStub([self.classMock isMetalAvailable]).andReturn(NO);
118 RTCMTLVideoView *realView = [[RTCMTLVideoView alloc] init];
119 id frame = OCMClassMock([RTCVideoFrame class]);
120 realView.metalView = self.metalViewMock;
121 realView.renderer = self.rendererMock;
122 OCMExpect([self.rendererMock drawFrame:frame]);
123
124 // when
125 [realView renderFrame:frame];
126 [realView drawInMTKView:self.metalViewMock];
127
128 // then
129 EXPECT_EQ(realView.videoFrame, frame);
130 [self.rendererMock verify];
131}
132@end
133
134TEST(RTCMTLVideoViewTests, MetalConfigureNotExecuted) {
135 RTCMTLVideoViewTests *test = [[RTCMTLVideoViewTests alloc] init];
136 [test setup];
137 [test testMetalConfigureNotExecuted];
138 [test tearDown];
139}
140
141
142TEST(RTCMTLVideoViewTests, MetalConfigureExecuted) {
143 RTCMTLVideoViewTests *test = [[RTCMTLVideoViewTests alloc] init];
144 [test setup];
145 [test testMetalConfigureExecuted];
146 [test tearDown];
147}
148
149TEST(RTCMTLVideoViewTests, MetalDrawCallback) {
150 RTCMTLVideoViewTests *test = [[RTCMTLVideoViewTests alloc] init];
151 [test setup];
152 [test testMetalDrawCallback];
153 [test tearDown];
154}
155
156TEST(RTCMTLVideoViewTests, RTCVideoRenderNilFrameCallback) {
157 RTCMTLVideoViewTests *test = [[RTCMTLVideoViewTests alloc] init];
158 [test setup];
159 [test testRTCVideoRenderNilFrameCallback];
160 [test tearDown];
161}
162
163TEST(RTCMTLVideoViewTests, RTCVideoRenderFrameCallback) {
164 RTCMTLVideoViewTests *test = [[RTCMTLVideoViewTests alloc] init];
165 [test setup];
166 [test testRTCVideoRenderFrameCallback];
167 [test tearDown];
168}