SizeSelectorParser and CameraUtils tests

pull/507/head
Mattia Iavarone 6 years ago
parent 7e541fc5bf
commit 6e7e6f3fa1
  1. 128
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraUtilsTest.java
  2. 211
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/size/SizeSelectorParserTest.java
  3. 5
      demo/src/main/java/com/otaliastudios/cameraview/demo/CameraActivity.java

@ -8,6 +8,9 @@ import android.graphics.Color;
import com.otaliastudios.cameraview.internal.utils.Op;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.test.annotation.UiThreadTest;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
@ -15,6 +18,11 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.Charset;
import static org.mockito.Mockito.*;
import static org.junit.Assert.*;
@ -28,44 +36,93 @@ public class CameraUtilsTest extends BaseTest {
Context context = mock(Context.class);
PackageManager pm = mock(PackageManager.class);
when(context.getPackageManager()).thenReturn(pm);
when(pm.hasSystemFeature(anyString())).thenReturn(true);
when(pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)).thenReturn(true);
when(pm.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT)).thenReturn(true);
assertTrue(CameraUtils.hasCameras(context));
when(pm.hasSystemFeature(anyString())).thenReturn(false);
when(pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)).thenReturn(false);
when(pm.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT)).thenReturn(true);
assertTrue(CameraUtils.hasCameras(context));
when(pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)).thenReturn(false);
when(pm.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT)).thenReturn(false);
assertFalse(CameraUtils.hasCameras(context));
}
// Encodes bitmap and decodes again using our utility.
private Op<Bitmap> encodeDecodeTask(Bitmap source) {
return encodeDecodeTask(source, 0, 0);
@NonNull
private Op<String> writeAndReadString(@NonNull String data) {
final File file = new File(getContext().getFilesDir(), "string.txt");
final byte[] bytes = data.getBytes(Charset.forName("UTF-8"));
final Op<String> result = new Op<>(true);
final FileCallback callback = new FileCallback() {
@Override
public void onFileReady(@Nullable File file) {
if (file == null) {
result.end(null);
} else {
// Read back the file.
try {
FileInputStream stream = new FileInputStream(file);
byte[] bytes = new byte[stream.available()];
stream.read(bytes);
result.end(new String(bytes, Charset.forName("UTF-8")));
} catch (IOException e) {
result.end(null);
}
}
}
};
uiSync(new Runnable() {
@Override
public void run() {
CameraUtils.writeToFile(bytes, file, callback);
}
});
return result;
}
@Test
public void testWriteToFile() {
Op<String> op = writeAndReadString("testString");
String result = op.await(2000);
assertEquals("testString", result);
}
// Encodes bitmap and decodes again using our utility.
private Op<Bitmap> encodeDecodeTask(Bitmap source, final int maxWidth, final int maxHeight) {
private Op<Bitmap> encodeDecodeTask(@NonNull Bitmap source, final int maxWidth, final int maxHeight, boolean async) {
final ByteArrayOutputStream os = new ByteArrayOutputStream();
// Using lossy JPG we can't have strict comparison of values after compression.
source.compress(Bitmap.CompressFormat.PNG, 100, os);
final byte[] data = os.toByteArray();
final Op<Bitmap> decode = new Op<>(true);
final BitmapCallback callback = new BitmapCallback() {
@Override
public void onBitmapReady(Bitmap bitmap) {
decode.end(bitmap);
}
};
// Run on ui because it involves handlers.
uiSync(new Runnable() {
@Override
public void run() {
if (maxWidth > 0 && maxHeight > 0) {
CameraUtils.decodeBitmap(data, maxWidth, maxHeight, callback);
} else {
CameraUtils.decodeBitmap(data, callback);
if (async) {
final BitmapCallback callback = new BitmapCallback() {
@Override
public void onBitmapReady(Bitmap bitmap) {
decode.end(bitmap);
}
};
// Run on ui because it involves handlers.
uiSync(new Runnable() {
@Override
public void run() {
if (maxWidth > 0 && maxHeight > 0) {
CameraUtils.decodeBitmap(data, maxWidth, maxHeight, callback);
} else {
CameraUtils.decodeBitmap(data, callback);
}
}
});
} else {
Bitmap result;
if (maxWidth > 0 && maxHeight > 0) {
result = CameraUtils.decodeBitmap(data, maxWidth, maxHeight);
} else {
result = CameraUtils.decodeBitmap(data);
}
});
decode.end(result);
}
return decode;
}
@ -75,7 +132,24 @@ public class CameraUtilsTest extends BaseTest {
Bitmap source = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
source.setPixel(0, 0, color);
Op<Bitmap> decode = encodeDecodeTask(source);
Op<Bitmap> decode = encodeDecodeTask(source, 0, 0, true);
Bitmap other = decode.await(800);
assertNotNull(other);
assertEquals(100, w);
assertEquals(200, h);
assertEquals(color, other.getPixel(0, 0));
assertEquals(0, other.getPixel(0, h-1));
assertEquals(0, other.getPixel(w-1, 0));
assertEquals(0, other.getPixel(w-1, h-1));
}
@Test
public void testDecodeBitmapSync() {
int w = 100, h = 200, color = Color.WHITE;
Bitmap source = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
source.setPixel(0, 0, color);
Op<Bitmap> decode = encodeDecodeTask(source, 0, 0, false);
Bitmap other = decode.await(800);
assertNotNull(other);
assertEquals(100, w);
@ -94,19 +168,19 @@ public class CameraUtilsTest extends BaseTest {
Op<Bitmap> op;
Bitmap other;
op = encodeDecodeTask(source, 100, 100);
op = encodeDecodeTask(source, 100, 100, true);
other = op.await(800);
assertNotNull(other);
assertTrue(other.getWidth() <= 100);
assertTrue(other.getHeight() <= 100);
op = encodeDecodeTask(source, Integer.MAX_VALUE, Integer.MAX_VALUE);
op = encodeDecodeTask(source, Integer.MAX_VALUE, Integer.MAX_VALUE, true);
other = op.await(800);
assertNotNull(other);
assertEquals(other.getWidth(), width);
assertEquals(other.getHeight(), height);
op = encodeDecodeTask(source, 6000, 6000);
op = encodeDecodeTask(source, 6000, 6000, true);
other = op.await(800);
assertNotNull(other);
assertEquals(other.getWidth(), width);

@ -0,0 +1,211 @@
package com.otaliastudios.cameraview.size;
import android.content.res.TypedArray;
import androidx.annotation.NonNull;
import androidx.annotation.StyleableRes;
import androidx.arch.core.util.Function;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.otaliastudios.cameraview.BaseTest;
import com.otaliastudios.cameraview.R;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class SizeSelectorParserTest extends BaseTest {
private MockTypedArray input;
private List<Size> sizes = Arrays.asList(
new Size(100, 200),
new Size(150, 300),
new Size(600, 900),
new Size(600, 600),
new Size(1600, 900),
new Size(30, 40),
new Size(40, 30),
new Size(2000, 4000)
);
@Before
public void setUp() {
input = new MockTypedArray();
}
@After
public void tearDown() {
input = null;
}
private void doAssert(@NonNull Function<List<Size>, Void> assertions) {
SizeSelectorParser parser = new SizeSelectorParser(input.array);
assertions.apply(parser.getPictureSizeSelector().select(sizes));
assertions.apply(parser.getVideoSizeSelector().select(sizes));
}
@Test
public void testWidth() {
input.setMinWidth(1500);
input.setMaxWidth(1700);
doAssert(new Function<List<Size>, Void>() {
@Override
public Void apply(List<Size> input) {
assertEquals(1, input.size());
assertEquals(new Size(1600, 900), input.get(0));
return null;
}
});
}
@Test
public void testHeight() {
input.setMinHeight(25);
input.setMaxHeight(35);
doAssert(new Function<List<Size>, Void>() {
@Override
public Void apply(List<Size> input) {
assertEquals(1, input.size());
assertEquals(new Size(40, 30), input.get(0));
return null;
}
});
}
@Test
public void testArea() {
input.setMinArea(30 * 30);
input.setMaxArea(40 * 40);
doAssert(new Function<List<Size>, Void>() {
@Override
public Void apply(List<Size> input) {
assertEquals(2, input.size());
assertTrue(input.contains(new Size(40, 30)));
assertTrue(input.contains(new Size(30, 40)));
return null;
}
});
}
@Test
public void testSmallest() {
input.setSmallest(true);
doAssert(new Function<List<Size>, Void>() {
@Override
public Void apply(List<Size> input) {
assertEquals(sizes.size(), input.size());
Size first = input.get(0);
assertEquals(30 * 40, first.getWidth() * first.getHeight());
return null;
}
});
}
@Test
public void testBiggest() {
input.setBiggest(true);
doAssert(new Function<List<Size>, Void>() {
@Override
public Void apply(List<Size> input) {
assertEquals(sizes.size(), input.size());
assertEquals(new Size(2000, 4000), input.get(0));
return null;
}
});
}
@Test
public void testAspectRatio() {
input.setAspectRatio("16:9");
doAssert(new Function<List<Size>, Void>() {
@Override
public Void apply(List<Size> input) {
assertEquals(1, input.size());
assertEquals(new Size(1600, 900), input.get(0));
return null;
}
});
}
@SuppressWarnings("SameParameterValue")
private class MockTypedArray {
private TypedArray array = mock(TypedArray.class);
private void setIntValue(@StyleableRes int index, int value) {
when(array.hasValue(index)).thenReturn(true);
when(array.getInteger(eq(index), anyInt())).thenReturn(value);
}
private void setBooleanValue(@StyleableRes int index, boolean value) {
when(array.hasValue(index)).thenReturn(true);
when(array.getBoolean(eq(index), anyBoolean())).thenReturn(value);
}
private void setStringValue(@StyleableRes int index, @NonNull String value) {
when(array.hasValue(index)).thenReturn(true);
when(array.getString(index)).thenReturn(value);
}
private void setMinWidth(int value) {
setIntValue(R.styleable.CameraView_cameraPictureSizeMinWidth, value);
setIntValue(R.styleable.CameraView_cameraVideoSizeMinWidth, value);
}
private void setMaxWidth(int value) {
setIntValue(R.styleable.CameraView_cameraPictureSizeMaxWidth, value);
setIntValue(R.styleable.CameraView_cameraVideoSizeMaxWidth, value);
}
private void setMinHeight(int value) {
setIntValue(R.styleable.CameraView_cameraPictureSizeMinHeight, value);
setIntValue(R.styleable.CameraView_cameraVideoSizeMinHeight, value);
}
private void setMaxHeight(int value) {
setIntValue(R.styleable.CameraView_cameraPictureSizeMaxHeight, value);
setIntValue(R.styleable.CameraView_cameraVideoSizeMaxHeight, value);
}
private void setMinArea(int value) {
setIntValue(R.styleable.CameraView_cameraPictureSizeMinArea, value);
setIntValue(R.styleable.CameraView_cameraVideoSizeMinArea, value);
}
private void setMaxArea(int value) {
setIntValue(R.styleable.CameraView_cameraPictureSizeMaxArea, value);
setIntValue(R.styleable.CameraView_cameraVideoSizeMaxArea, value);
}
private void setSmallest(boolean value) {
setBooleanValue(R.styleable.CameraView_cameraPictureSizeSmallest, value);
setBooleanValue(R.styleable.CameraView_cameraVideoSizeSmallest, value);
}
private void setBiggest(boolean value) {
setBooleanValue(R.styleable.CameraView_cameraPictureSizeBiggest, value);
setBooleanValue(R.styleable.CameraView_cameraVideoSizeBiggest, value);
}
private void setAspectRatio(@NonNull String value) {
setStringValue(R.styleable.CameraView_cameraPictureSizeAspectRatio, value);
setStringValue(R.styleable.CameraView_cameraVideoSizeAspectRatio, value);
}
}
}

@ -174,20 +174,23 @@ public class CameraActivity extends AppCompatActivity implements View.OnClickLis
// This can happen if picture was taken with a gesture.
long callbackTime = System.currentTimeMillis();
if (mCaptureTime == 0) mCaptureTime = callbackTime - 300;
LOG.w("onPictureTaken called! Launching activity. Delay:", callbackTime - mCaptureTime);
PicturePreviewActivity.setPictureResult(result);
Intent intent = new Intent(CameraActivity.this, PicturePreviewActivity.class);
intent.putExtra("delay", callbackTime - mCaptureTime);
LOG.w("Picture delay:", callbackTime - mCaptureTime);
startActivity(intent);
mCaptureTime = 0;
LOG.w("onPictureTaken called! Launched activity.");
}
@Override
public void onVideoTaken(@NonNull VideoResult result) {
super.onVideoTaken(result);
LOG.w("onVideoTaken called! Launching activity.");
VideoPreviewActivity.setVideoResult(result);
Intent intent = new Intent(CameraActivity.this, VideoPreviewActivity.class);
startActivity(intent);
LOG.w("onVideoTaken called! Launched activity.");
}
@Override

Loading…
Cancel
Save