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

Side by Side Diff: services/shape_detection/android/junit/src/org/chromium/shape_detection/FaceDetectionImplTest.java

Issue 2863773005: Shape Detection: Face detection junit tests (Closed)
Patch Set: Created 3 years, 7 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
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.shape_detection;
6
7 import static org.junit.Assert.assertEquals;
8 import static org.junit.Assert.assertTrue;
9
10 import android.graphics.Bitmap;
11 import android.graphics.PointF;
12 import android.media.FaceDetector;
13 import android.media.FaceDetector.Face;
14
15 import org.junit.Before;
16 import org.junit.Test;
17 import org.junit.runner.RunWith;
18 import org.mockito.ArgumentCaptor;
19 import org.mockito.Mockito;
20 import org.mockito.MockitoAnnotations;
21 import org.mockito.invocation.InvocationOnMock;
22 import org.mockito.stubbing.Answer;
23 import org.robolectric.ParameterizedRobolectricTestRunner;
24 import org.robolectric.ParameterizedRobolectricTestRunner.Parameters;
25 import org.robolectric.annotation.Config;
26 import org.robolectric.shadows.ShadowLog;
27
28 import org.chromium.base.ThreadUtils;
29 import org.chromium.base.test.util.Feature;
30 import org.chromium.mojo.system.SharedBufferHandle;
31 import org.chromium.mojo.system.SharedBufferHandle.MapFlags;
32 import org.chromium.shape_detection.mojom.FaceDetection;
33 import org.chromium.shape_detection.mojom.FaceDetectionResult;
34 import org.chromium.shape_detection.mojom.FaceDetectorOptions;
35
36 import java.nio.ByteBuffer;
37 import java.util.Arrays;
38 import java.util.Collection;
39
40 /**
41 * Test suite for Java Face Detection.
42 */
43 @RunWith(ParameterizedRobolectricTestRunner.class)
44 @Config(sdk = 21, manifest = Config.NONE)
45 public class FaceDetectionImplTest {
46 private static final int VALID_WIDTH = 1;
47 private static final int VALID_HEIGHT = 1;
48 private static final int INVALID_WIDTH = 0;
49 private static final long NUM_BYTES = VALID_WIDTH * VALID_HEIGHT * 4;
50
51 @Parameters
52 public static Collection<Object[]> data() {
53 return Arrays.asList(new Object[][] {{true}, {false}});
54 }
55
56 // Class under test.
57 private final FaceDetectionImpl mFaceDetectionImpl;
58
59 public FaceDetectionImplTest(boolean fastMode) {
60 FaceDetectorOptions options = new FaceDetectorOptions();
61 options.fastMode = fastMode;
62 options.maxDetectedFaces = 1;
63 mFaceDetectionImpl = new FaceDetectionImpl(options);
64 }
65
66 @Before
67 public void setUp() {
68 ShadowLog.stream = System.out;
69 MockitoAnnotations.initMocks(this);
70 }
71
72 /**
73 * Verify construction works.
74 */
75 @Test
76 @Feature({"ShapeDetection"})
77 public void testConstruction() {
scheib 2017/05/17 00:55:39 Just testing that the member variable mFaceDetect
mcasas 2017/05/17 16:54:03 Yes, also because |options| in l.60 is parameteriz
78 assertTrue("Should be on UI thread", ThreadUtils.runningOnUiThread());
79 }
80
81 /**
82 * Verify detection fails if the SharedBufferHandle is invalid.
83 */
84 @Test
85 @Feature({"ShapeDetection"})
86 public void testDetectionFailsWithInvalidHandle() {
87 assertTrue("Should be on UI thread", ThreadUtils.runningOnUiThread());
88
89 SharedBufferHandle handle = Mockito.mock(SharedBufferHandle.class);
scheib 2017/05/17 00:55:39 renaming handle -> sharedBuffer would be clearer.
mcasas 2017/05/17 16:54:03 Done.
90 Mockito.when(handle.isValid()).thenReturn(false);
91
92 FaceDetection.DetectResponse callback = Mockito.mock(FaceDetection.Detec tResponse.class);
93 ArgumentCaptor<FaceDetectionResult[]> argument =
94 ArgumentCaptor.forClass(FaceDetectionResult[].class);
95
96 mFaceDetectionImpl.detect(handle, VALID_WIDTH, VALID_HEIGHT, callback);
97
98 Mockito.verify(handle, Mockito.times(1)).isValid();
99 Mockito.verify(callback, Mockito.times(1)).call(argument.capture());
100 assertEquals("result", 0, argument.getValue().length);
101 }
102
103 /**
104 * Verify detection fails if the sent dimensions are ugly.
105 */
106 @Test
107 @Feature({"ShapeDetection"})
108 public void testDetectionFailsWithInvalidDimensions() {
109 assertTrue("Should be on UI thread", ThreadUtils.runningOnUiThread());
110
111 SharedBufferHandle handle = Mockito.mock(SharedBufferHandle.class);
112 Mockito.when(handle.isValid()).thenReturn(true);
113
114 FaceDetection.DetectResponse callback = Mockito.mock(FaceDetection.Detec tResponse.class);
115 ArgumentCaptor<FaceDetectionResult[]> argument =
116 ArgumentCaptor.forClass(FaceDetectionResult[].class);
117
118 mFaceDetectionImpl.detect(handle, INVALID_WIDTH, VALID_HEIGHT, callback) ;
119
120 Mockito.verify(handle, Mockito.times(1)).isValid();
121 Mockito.verify(callback, Mockito.times(1)).call(argument.capture());
122 assertEquals("result", 0, argument.getValue().length);
123 }
124
125 /**
126 * Verify detection fails if SharedBufferHandle fails to map().
127 */
128 @Test
129 @Feature({"ShapeDetection"})
130 public void testDetectionFailsWithWronglyMappedBuffer() {
131 assertTrue("Should be on UI thread", ThreadUtils.runningOnUiThread());
132
133 SharedBufferHandle handle = Mockito.mock(SharedBufferHandle.class);
134 Mockito.when(handle.isValid()).thenReturn(true);
135 Mockito.when(handle.map(Mockito.eq(0L), Mockito.eq(NUM_BYTES), Mockito.a ny(MapFlags.class)))
136 .thenReturn(ByteBuffer.allocate(0));
137
138 FaceDetection.DetectResponse callback = Mockito.mock(FaceDetection.Detec tResponse.class);
139 ArgumentCaptor<FaceDetectionResult[]> argument =
140 ArgumentCaptor.forClass(FaceDetectionResult[].class);
141
142 mFaceDetectionImpl.detect(handle, VALID_WIDTH, VALID_HEIGHT, callback);
143
144 Mockito.verify(handle, Mockito.times(1)).isValid();
145 Mockito.verify(handle, Mockito.times(1))
146 .map(Mockito.eq(0L), Mockito.eq(NUM_BYTES), Mockito.any(MapFlags .class));
147 Mockito.verify(callback, Mockito.times(1)).call(argument.capture());
148 assertEquals("result", 0, argument.getValue().length);
149 }
150
151 /**
152 * Verify detection works.
153 */
154 @Test
155 @Feature({"ShapeDetection"})
156 public void testDetection() {
157 assertTrue("Should be on UI thread", ThreadUtils.runningOnUiThread());
158
159 SharedBufferHandle handle = Mockito.mock(SharedBufferHandle.class);
160 Mockito.when(handle.isValid()).thenReturn(true);
161 Mockito.when(handle.map(Mockito.eq(0L), Mockito.eq(NUM_BYTES), Mockito.a ny(MapFlags.class)))
162 .thenReturn(ByteBuffer.allocate((int) NUM_BYTES));
163
164 FaceDetection.DetectResponse callback = Mockito.mock(FaceDetection.Detec tResponse.class);
165 ArgumentCaptor<FaceDetectionResult[]> argument =
166 ArgumentCaptor.forClass(FaceDetectionResult[].class);
167
168 // We have to add a |faceDetector| mock that inside returns a |face| moc k. To spice things
169 // up, some methods, findFaces() and getMidPoint(), modify parameters so we need doAnswer().
170 final float eyesDistance = 1.0f;
171 final float faceCenterX = 2.0f;
172 final float faceCenterY = 3.0f;
173
174 Face face = Mockito.mock(Face.class);
175 Mockito.when(face.eyesDistance()).thenReturn(eyesDistance);
176 Mockito.doAnswer(new Answer<Void>() {
177 @Override
178 public Void answer(InvocationOnMock invocation) {
179 Object[] args = invocation.getArguments();
180 PointF midPoint = (PointF) args[0];
181 midPoint.set(faceCenterX, faceCenterY);
182 return null;
183 }
184 })
185 .when(face)
186 .getMidPoint(Mockito.any(PointF.class));
187
188 FaceDetector faceDetector = Mockito.mock(FaceDetector.class);
189 mFaceDetectionImpl.setFaceDetector(faceDetector);
190 Mockito.doAnswer(new Answer<Integer>() {
191 @Override
192 public Integer answer(InvocationOnMock invocation) throws Throwa ble {
193 Object[] args = invocation.getArguments();
194 Face[] faceArray = (Face[]) args[1];
195 faceArray[0] = face;
196 return 1;
197 }
198 })
199 .when(faceDetector)
200 .findFaces(Mockito.any(Bitmap.class), Mockito.any());
201
202 mFaceDetectionImpl.detect(handle, VALID_WIDTH, VALID_HEIGHT, callback);
203
204 Mockito.verify(handle, Mockito.times(1)).isValid();
205 Mockito.verify(handle, Mockito.times(1))
206 .map(Mockito.anyLong(), Mockito.anyLong(), Mockito.any(MapFlags. class));
207
208 Mockito.verify(faceDetector, Mockito.times(1))
209 .findFaces(Mockito.any(Bitmap.class), Mockito.any());
210
211 // Detection happens asynchronously: give some timeout.
212 Mockito.verify(callback, Mockito.timeout(1000 /* milliseconds */).times( 1))
213 .call(argument.capture());
214 assertEquals("result", 1, argument.getValue().length);
215 assertEquals("width", 2 * eyesDistance, argument.getValue()[0].boundingB ox.width, 0.1);
216 assertEquals("height", 2 * eyesDistance, argument.getValue()[0].bounding Box.height, 0.1);
217 assertEquals("x", faceCenterX - eyesDistance, argument.getValue()[0].bou ndingBox.x, 0.1);
218 assertEquals("y", faceCenterY - eyesDistance, argument.getValue()[0].bou ndingBox.y, 0.1);
219 }
220 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698