Skip to content
This repository was archived by the owner on Jun 27, 2023. It is now read-only.

Commit 3beae27

Browse files
committed
Adding more coloring tests
(cherry picked from commit d2ea85c)
1 parent 88bf523 commit 3beae27

File tree

2 files changed

+220
-37
lines changed

2 files changed

+220
-37
lines changed

demo/src/test/java/me/angrybyte/sillyandroid/extras/ColoringTest.java

Lines changed: 219 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,22 @@
11
package me.angrybyte.sillyandroid.extras;
22

33
import android.annotation.SuppressLint;
4+
import android.annotation.TargetApi;
45
import android.app.Activity;
6+
import android.content.Context;
7+
import android.content.res.ColorStateList;
8+
import android.graphics.Bitmap;
59
import android.graphics.Color;
10+
import android.graphics.PorterDuff;
11+
import android.graphics.PorterDuffColorFilter;
12+
import android.graphics.Rect;
13+
import android.graphics.drawable.BitmapDrawable;
14+
import android.graphics.drawable.ColorDrawable;
15+
import android.graphics.drawable.Drawable;
16+
import android.graphics.drawable.VectorDrawable;
17+
import android.os.Build;
618
import android.support.annotation.NonNull;
19+
import android.support.graphics.drawable.VectorDrawableCompat;
720
import android.util.Pair;
821

922
import org.junit.After;
@@ -14,12 +27,17 @@
1427
import org.robolectric.RobolectricTestRunner;
1528
import org.robolectric.annotation.Config;
1629

30+
import java.lang.reflect.Constructor;
31+
import java.lang.reflect.InvocationTargetException;
32+
import java.nio.ByteBuffer;
33+
import java.nio.ByteOrder;
1734
import java.util.LinkedList;
1835
import java.util.List;
1936

2037
import me.angrybyte.sillyandroid.BuildConfig;
2138

2239
import static junit.framework.Assert.assertEquals;
40+
import static junit.framework.Assert.assertTrue;
2341

2442
/**
2543
* A set of tests related to the {@link Coloring}.
@@ -371,45 +389,209 @@ public final void testContrastColor() {
371389
}
372390
}
373391

392+
/**
393+
* Tests the {@link Coloring#colorBitmap(Bitmap, int)} method.
394+
* <p>
395+
* Due to {@link org.robolectric.shadows.ShadowBitmap}'s empty implementation, this won't really work, so we can only test the transparency.
396+
*/
397+
@Test
398+
public final void testColorBitmap() {
399+
final Bitmap.Config config = Bitmap.Config.ARGB_8888;
400+
final int width = 10, height = 10;
401+
final int[] allReds = new int[width * height];
402+
for (int i = 0; i < width * height; i++) {
403+
allReds[i] = Color.RED;
404+
}
405+
406+
final Bitmap redSquare = Bitmap.createBitmap(allReds, width, height, config);
407+
408+
// initialize red Bitmap's internal structures, otherwise it won't draw properly
409+
redSquare.prepareToDraw();
410+
final byte[] redPixels = new byte[redSquare.getWidth() * redSquare.getHeight() * 8];
411+
final ByteBuffer redBuffer = ByteBuffer.wrap(redPixels);
412+
redBuffer.order(ByteOrder.nativeOrder());
413+
redSquare.copyPixelsToBuffer(redBuffer);
414+
redSquare.copyPixelsFromBuffer(redBuffer);
415+
redSquare.prepareToDraw();
416+
417+
final String redPixel = hex(redSquare.getPixel(width / 2, height / 2));
418+
final String errorRed = String.format("Error while creating red bitmap, middle pixel is %s", redPixel);
419+
assertEquals(errorRed, hex(Color.TRANSPARENT), redPixel);
420+
421+
final Bitmap greenSquare = Coloring.colorBitmap(redSquare, Color.GREEN);
422+
final String greenPixel = hex(greenSquare.getPixel(width / 2, height / 2));
423+
final String errorGreen = String.format("Error while coloring bitmap, middle pixel is %s", greenPixel);
424+
assertEquals(errorGreen, hex(Color.TRANSPARENT), greenPixel);
425+
}
426+
427+
/**
428+
* Tests the {@link Coloring#createColoredDrawable(int, Rect)} method.
429+
*/
430+
@Test
431+
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
432+
public final void testCreateColoredDrawable() {
433+
final Drawable transparentNoBounds = Coloring.createColoredDrawable(Color.TRANSPARENT, null);
434+
assertTrue("Drawable not a ColorDrawable", transparentNoBounds instanceof ColorDrawable);
435+
assertEquals("Drawable color is not transparent", Color.TRANSPARENT, ((ColorDrawable) transparentNoBounds).getColor());
436+
assertEquals("Bounds are not 0", new Rect(0, 0, 0, 0), transparentNoBounds.getBounds());
437+
// noinspection RedundantCast - it's not. alpha getter was added for Drawable in KITKAT
438+
assertEquals("Alpha is not 0", 0, ((ColorDrawable) transparentNoBounds).getAlpha());
439+
440+
final Drawable transparentWithBounds = Coloring.createColoredDrawable(Color.TRANSPARENT, new Rect(0, 0, 100, 100));
441+
assertTrue("Drawable not a ColorDrawable", transparentWithBounds instanceof ColorDrawable);
442+
assertEquals("Drawable color is not transparent", Color.TRANSPARENT, ((ColorDrawable) transparentWithBounds).getColor());
443+
assertEquals("Bounds are not null", new Rect(0, 0, 100, 100), transparentWithBounds.getBounds());
444+
// noinspection RedundantCast - it's not. alpha getter was added for Drawable in KITKAT
445+
assertEquals("Alpha is not 0", 0, ((ColorDrawable) transparentWithBounds).getAlpha());
446+
447+
final Drawable redNoBounds = Coloring.createColoredDrawable(Color.RED, null);
448+
assertTrue("Drawable not a ColorDrawable", redNoBounds instanceof ColorDrawable);
449+
assertEquals("Drawable color is not red", hex(((ColorDrawable) redNoBounds).getColor()), hex(Color.RED));
450+
assertEquals("Bounds are not null", new Rect(0, 0, 0, 0), redNoBounds.getBounds());
451+
// noinspection RedundantCast - it's not. alpha getter was added for Drawable in KITKAT
452+
assertEquals("Alpha is not 255", 255, ((ColorDrawable) redNoBounds).getAlpha());
453+
454+
final Drawable redWithBounds = Coloring.createColoredDrawable(Color.RED, new Rect(0, 0, 100, 100));
455+
assertTrue("Drawable not a ColorDrawable", redWithBounds instanceof ColorDrawable);
456+
assertEquals("Drawable color is not red", hex(((ColorDrawable) redWithBounds).getColor()), hex(Color.RED));
457+
assertEquals("Bounds are not null", new Rect(0, 0, 100, 100), redWithBounds.getBounds());
458+
// noinspection RedundantCast - it's not. alpha getter was added for Drawable in KITKAT
459+
assertEquals("Alpha is not 255", 255, ((ColorDrawable) redWithBounds).getAlpha());
460+
}
461+
462+
/**
463+
* Tests the {@link Coloring#colorDrawable(Context, int, int)} method.
464+
* <p>
465+
* Due to {@link org.robolectric.shadows.ShadowBitmap}'s empty implementation, this won't really work, so we can only test the transparency.
466+
*/
467+
@Test
468+
public final void testColorDrawableInt() {
469+
// noinspection deprecation - can't enforce Lollipop here
470+
final BitmapDrawable colored = (BitmapDrawable) Coloring.colorDrawable(mActivityContext, android.R.drawable.btn_star_big_on, Color.RED);
471+
final int coloredPixel = colored.getBitmap().getPixel(colored.getBitmap().getWidth() / 2, colored.getBitmap().getHeight() / 2);
472+
assertEquals("Colored middle pixel is not transparent", hex(Color.TRANSPARENT), hex(coloredPixel));
473+
}
474+
475+
/**
476+
* Tests the {@link Coloring#colorDrawable(Context, Drawable, int)} method.
477+
* <p>
478+
* Due to {@link org.robolectric.shadows.ShadowBitmap}'s empty implementation, this won't really work, so we can only test the transparency.
479+
*/
480+
@Test
481+
public final void testColorDrawableObject() {
482+
// noinspection deprecation - can't enforce Lollipop here
483+
final BitmapDrawable original = (BitmapDrawable) mActivityContext.getResources().getDrawable(android.R.drawable.btn_star_big_on);
484+
final int originalPixel = original.getBitmap().getPixel(original.getBitmap().getWidth() / 2, original.getBitmap().getHeight() / 2);
485+
assertEquals("Original middle pixel is not transparent", hex(Color.TRANSPARENT), hex(originalPixel));
486+
487+
final BitmapDrawable colored = (BitmapDrawable) Coloring.colorDrawable(mActivityContext, original, Color.RED);
488+
final int coloredPixel = colored.getBitmap().getPixel(colored.getBitmap().getWidth() / 2, colored.getBitmap().getHeight() / 2);
489+
assertEquals("Colored middle pixel is not transparent", hex(Color.TRANSPARENT), hex(coloredPixel));
490+
}
491+
492+
/**
493+
* Tests the {@link Coloring#colorDrawableWrapped(Drawable, int)} method.
494+
* <p>
495+
* Due to {@link org.robolectric.shadows.ShadowBitmap}'s empty implementation, this won't really work, so we can only test the transparency.
496+
*/
497+
@Test
498+
public final void testColorDrawableWrappedInt() {
499+
// noinspection deprecation - can't enforce Lollipop here
500+
final BitmapDrawable original = (BitmapDrawable) mActivityContext.getResources().getDrawable(android.R.drawable.btn_star_big_on);
501+
final int originalPixel = original.getBitmap().getPixel(original.getBitmap().getWidth() / 2, original.getBitmap().getHeight() / 2);
502+
assertEquals("Original middle pixel is not transparent", hex(Color.TRANSPARENT), hex(originalPixel));
503+
504+
final BitmapDrawable colored = (BitmapDrawable) Coloring.colorDrawableWrapped(original, Color.RED);
505+
final int coloredPixel = colored.getBitmap().getPixel(colored.getBitmap().getWidth() / 2, colored.getBitmap().getHeight() / 2);
506+
assertEquals("Colored middle pixel is not transparent", hex(Color.TRANSPARENT), hex(coloredPixel));
507+
}
508+
509+
/**
510+
* Tests the {@link Coloring#colorDrawableWrapped(Drawable, ColorStateList)} method.
511+
* <p>
512+
* Due to {@link org.robolectric.shadows.ShadowBitmap}'s empty implementation, this won't really work, so we can only test the transparency.
513+
*/
514+
@Test
515+
public final void testColorDrawableWrappedObject() {
516+
// noinspection deprecation - can't enforce Lollipop here
517+
final BitmapDrawable original = (BitmapDrawable) mActivityContext.getResources().getDrawable(android.R.drawable.btn_star_big_on);
518+
final int originalPixel = original.getBitmap().getPixel(original.getBitmap().getWidth() / 2, original.getBitmap().getHeight() / 2);
519+
assertEquals("Original middle pixel is not transparent", hex(Color.TRANSPARENT), hex(originalPixel));
520+
521+
final BitmapDrawable colored = (BitmapDrawable) Coloring.colorDrawableWrapped(original, ColorStateList.valueOf(Color.RED));
522+
final int coloredPixel = colored.getBitmap().getPixel(colored.getBitmap().getWidth() / 2, colored.getBitmap().getHeight() / 2);
523+
assertEquals("Colored middle pixel is not transparent", hex(Color.TRANSPARENT), hex(coloredPixel));
524+
}
525+
526+
/**
527+
* Tests the {@link Coloring#colorUnknownDrawable(Drawable, int)} method.
528+
* <p>
529+
* Due to {@link org.robolectric.shadows.ShadowBitmap}'s empty implementation, this won't really work, so we can only test the transparency.
530+
*/
531+
@Test
532+
public final void testColorUnknownDrawable() {
533+
// noinspection deprecation - can't enforce Lollipop here
534+
final BitmapDrawable original = (BitmapDrawable) mActivityContext.getResources().getDrawable(android.R.drawable.btn_star_big_on);
535+
final int originalPixel = original.getBitmap().getPixel(original.getBitmap().getWidth() / 2, original.getBitmap().getHeight() / 2);
536+
assertEquals("Original middle pixel is not transparent", hex(Color.TRANSPARENT), hex(originalPixel));
537+
538+
final BitmapDrawable colored = (BitmapDrawable) Coloring.colorUnknownDrawable(original, Color.RED);
539+
final int coloredPixel = colored.getBitmap().getPixel(colored.getBitmap().getWidth() / 2, colored.getBitmap().getHeight() / 2);
540+
assertEquals("Colored middle pixel is not transparent", hex(Color.TRANSPARENT), hex(coloredPixel));
541+
}
542+
543+
/**
544+
* Tests the {@link Coloring#colorVectorDrawable(VectorDrawable, int)} method.
545+
* <p>
546+
* Unfortunately {@link VectorDrawable#setColorFilter(int, PorterDuff.Mode)} is not mocked in Android JAR yet.
547+
*/
548+
@Test
549+
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
550+
public final void testColorVectorDrawable() {
551+
try {
552+
final VectorDrawable vectorDrawable = new VectorDrawable();
553+
final VectorDrawable colored = (VectorDrawable) Coloring.colorVectorDrawable(vectorDrawable, Color.RED);
554+
final PorterDuff.Mode mode = PorterDuff.Mode.SRC_ATOP;
555+
assertEquals("Vector color filter does not match", new PorterDuffColorFilter(Color.RED, mode), colored.getColorFilter());
556+
} catch (RuntimeException e) {
557+
boolean knownIssue = e.getMessage().contains("not mocked");
558+
if (!knownIssue) {
559+
e.printStackTrace();
560+
}
561+
assertTrue("Unknown error: " + e.getMessage(), knownIssue);
562+
}
563+
}
564+
565+
/**
566+
* Tests the {@link Coloring#colorVectorDrawable(VectorDrawableCompat, int)} method.
567+
* <p>
568+
* Unfortunately {@link VectorDrawableCompat#setColorFilter(int, PorterDuff.Mode)} is not shadowed by Robolectric yet.
569+
*/
570+
@Test
571+
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
572+
public final void testColorVectorDrawableCompat() {
573+
try {
574+
// not accessible outside of
575+
Class<?> cl = Class.forName(VectorDrawableCompat.class.getCanonicalName());
576+
Constructor<?> constructor = cl.getConstructor();
577+
constructor.setAccessible(true);
578+
final VectorDrawableCompat vectorDrawable = (VectorDrawableCompat) constructor.newInstance();
579+
final VectorDrawableCompat colored = (VectorDrawableCompat) Coloring.colorVectorDrawable(vectorDrawable, Color.RED);
580+
final PorterDuff.Mode mode = PorterDuff.Mode.SRC_ATOP;
581+
assertEquals("VectorCompat color filter does not match", null, colored.getColorFilter());
582+
} catch (RuntimeException e) {
583+
boolean knownIssue = e.getMessage().contains("no such method");
584+
if (!knownIssue) {
585+
e.printStackTrace();
586+
}
587+
assertTrue("Unknown error: " + e.getMessage(), knownIssue);
588+
} catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) {
589+
e.printStackTrace();
590+
}
591+
}
592+
374593
// FIXME Untested:
375594
//
376-
//
377-
// public final void testColorBitmap() {
378-
//
379-
// }
380-
//
381-
// public final void testCreateColoredDrawable() {
382-
//
383-
// }
384-
//
385-
// public final void testColorDrawable() {
386-
//
387-
// }
388-
//
389-
// public final void testColorDrawable1() {
390-
//
391-
// }
392-
//
393-
// public final void testColorDrawableWrapped() {
394-
//
395-
// }
396-
//
397-
// public final void testColorDrawableWrapped1() {
398-
//
399-
// }
400-
//
401-
// public final void testColorUnknownDrawable() {
402-
//
403-
// }
404-
//
405-
// public final void testColorVectorDrawable() {
406-
//
407-
// }
408-
//
409-
// public final void testColorVectorDrawable1() {
410-
//
411-
// }
412-
//
413595
// public final void testCreateStateList() {
414596
//
415597
// }

sillyandroid/src/main/java/me/angrybyte/sillyandroid/extras/Coloring.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ public static Bitmap colorBitmap(@NonNull final Bitmap bitmap, @ColorInt final i
297297
paint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP));
298298
c.drawBitmap(bitmap, 0, 0, paint);
299299

300+
result.prepareToDraw();
300301
return result;
301302
}
302303

0 commit comments

Comments
 (0)