1244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov/* 2244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov * Copyright (C) 2015 The Android Open Source Project 3244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov * 4244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov * Licensed under the Apache License, Version 2.0 (the "License"); 5244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov * you may not use this file except in compliance with the License. 6244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov * You may obtain a copy of the License at 7244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov * 8244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov * http://www.apache.org/licenses/LICENSE-2.0 9244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov * 10244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov * Unless required by applicable law or agreed to in writing, software 11244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov * distributed under the License is distributed on an "AS IS" BASIS, 12244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov * See the License for the specific language governing permissions and 14244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov * limitations under the License. 15244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov */ 16244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov 17244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikovpackage android.support.v7.testutils; 18244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov 191d8515a3b783e9b091bea2891606b466515b4fddKirill Grouchnikovimport android.database.sqlite.SQLiteCursor; 201d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikovimport android.graphics.Bitmap; 21244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikovimport android.graphics.drawable.Drawable; 22244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikovimport android.support.annotation.ColorInt; 23244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikovimport android.support.test.espresso.matcher.BoundedMatcher; 24ee9519c17254b5e992164ff278173c4b2c7c5fceKirill Grouchnikovimport android.support.v4.view.TintableBackgroundView; 251d8515a3b783e9b091bea2891606b466515b4fddKirill Grouchnikovimport android.text.TextUtils; 26244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikovimport android.view.View; 271d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikovimport android.view.ViewGroup; 282d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikovimport android.widget.CheckedTextView; 29244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikovimport android.widget.ImageView; 3027644c071b7fc0e1e4f91194f2a08b4aa2cf1465Aurimas Liutikas 31244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikovimport org.hamcrest.Description; 32244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikovimport org.hamcrest.Matcher; 33ee9519c17254b5e992164ff278173c4b2c7c5fceKirill Grouchnikovimport org.hamcrest.TypeSafeMatcher; 34244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov 3521f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikovimport java.util.List; 3621f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov 37244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikovpublic class TestUtilsMatchers { 38244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov /** 39244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov * Returns a matcher that matches <code>ImageView</code>s which have drawable flat-filled 40244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov * with the specific color. 41244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov */ 42244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov public static Matcher drawable(@ColorInt final int color) { 43244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov return new BoundedMatcher<View, ImageView>(ImageView.class) { 44244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov private String failedComparisonDescription; 45244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov 46244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov @Override 47244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov public void describeTo(final Description description) { 48244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov description.appendText("with drawable of color: "); 49244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov 50244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov description.appendText(failedComparisonDescription); 51244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov } 52244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov 53244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov @Override 54244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov public boolean matchesSafely(final ImageView view) { 55244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov Drawable drawable = view.getDrawable(); 56244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov if (drawable == null) { 57244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov return false; 58244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov } 59244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov 60244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov // One option is to check if we have a ColorDrawable and then call getColor 61244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov // but that API is v11+. Instead, we call our helper method that checks whether 62244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov // all pixels in a Drawable are of the same specified color. 63244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov try { 64244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov TestUtils.assertAllPixelsOfColor("", drawable, view.getWidth(), 651b81f288853d60e25e870fd522c927fd72f2efb5Kirill Grouchnikov view.getHeight(), true, color, 0, true); 66244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov // If we are here, the color comparison has passed. 67244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov failedComparisonDescription = null; 68244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov return true; 69244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov } catch (Throwable t) { 70244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov // If we are here, the color comparison has failed. 71244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov failedComparisonDescription = t.getMessage(); 72244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov return false; 73244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov } 74244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov } 75244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov }; 76244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov } 772d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov 782d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov /** 791d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov * Returns a matcher that matches <code>View</code>s which have background flat-filled 801d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov * with the specific color. 811d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov */ 821d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov public static Matcher isBackground(@ColorInt final int color) { 831cd642752286e1fba44d8ec87e9793f116a22240Chris Banes return isBackground(color, false); 841cd642752286e1fba44d8ec87e9793f116a22240Chris Banes } 851cd642752286e1fba44d8ec87e9793f116a22240Chris Banes 861cd642752286e1fba44d8ec87e9793f116a22240Chris Banes /** 871cd642752286e1fba44d8ec87e9793f116a22240Chris Banes * Returns a matcher that matches <code>View</code>s which have background flat-filled 881cd642752286e1fba44d8ec87e9793f116a22240Chris Banes * with the specific color. 891cd642752286e1fba44d8ec87e9793f116a22240Chris Banes */ 901cd642752286e1fba44d8ec87e9793f116a22240Chris Banes public static Matcher isBackground(@ColorInt final int color, final boolean onlyTestCenter) { 911d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov return new BoundedMatcher<View, View>(View.class) { 921d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov private String failedComparisonDescription; 931d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov 941d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov @Override 951d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov public void describeTo(final Description description) { 961d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov description.appendText("with background of color: "); 971d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov 981d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov description.appendText(failedComparisonDescription); 991d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov } 1001d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov 1011d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov @Override 1021d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov public boolean matchesSafely(final View view) { 1031d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov Drawable drawable = view.getBackground(); 1041d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov if (drawable == null) { 1051d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov return false; 1061d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov } 1071d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov try { 1081cd642752286e1fba44d8ec87e9793f116a22240Chris Banes if (onlyTestCenter) { 1091cd642752286e1fba44d8ec87e9793f116a22240Chris Banes TestUtils.assertCenterPixelOfColor("", drawable, view.getWidth(), 1101cd642752286e1fba44d8ec87e9793f116a22240Chris Banes view.getHeight(), false, color, 0, true); 1111cd642752286e1fba44d8ec87e9793f116a22240Chris Banes } else { 1121cd642752286e1fba44d8ec87e9793f116a22240Chris Banes TestUtils.assertAllPixelsOfColor("", drawable, view.getWidth(), 1131cd642752286e1fba44d8ec87e9793f116a22240Chris Banes view.getHeight(), false, color, 0, true); 1141cd642752286e1fba44d8ec87e9793f116a22240Chris Banes } 1151d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov // If we are here, the color comparison has passed. 1161d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov failedComparisonDescription = null; 1171d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov return true; 1181d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov } catch (Throwable t) { 1191d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov // If we are here, the color comparison has failed. 1201d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov failedComparisonDescription = t.getMessage(); 1211d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov return false; 1221d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov } 1231d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov } 1241d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov }; 1251d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov } 1261d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov 1271d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov /** 1281d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov * Returns a matcher that matches <code>View</code>s whose combined background starting 1291d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov * from the view and up its ancestor chain matches the specified color. 1301d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov */ 1313ab41277a085b829e15eca69442cfe45cae58a8cKirill Grouchnikov public static Matcher isCombinedBackground(@ColorInt final int color, 1323ab41277a085b829e15eca69442cfe45cae58a8cKirill Grouchnikov final boolean onlyTestCenterPixel) { 1331d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov return new BoundedMatcher<View, View>(View.class) { 1341d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov private String failedComparisonDescription; 1351d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov 1361d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov @Override 1371d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov public void describeTo(final Description description) { 1381d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov description.appendText("with ascendant background of color: "); 1391d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov 1401d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov description.appendText(failedComparisonDescription); 1411d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov } 1421d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov 1431d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov @Override 1441d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov public boolean matchesSafely(View view) { 1451d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov // Create a bitmap with combined backgrounds of the view and its ancestors. 1461d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov Bitmap combinedBackgroundBitmap = TestUtils.getCombinedBackgroundBitmap(view); 1471d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov try { 1483ab41277a085b829e15eca69442cfe45cae58a8cKirill Grouchnikov if (onlyTestCenterPixel) { 1493ab41277a085b829e15eca69442cfe45cae58a8cKirill Grouchnikov TestUtils.assertCenterPixelOfColor("", combinedBackgroundBitmap, 1503ab41277a085b829e15eca69442cfe45cae58a8cKirill Grouchnikov color, 0, true); 1513ab41277a085b829e15eca69442cfe45cae58a8cKirill Grouchnikov } else { 1523ab41277a085b829e15eca69442cfe45cae58a8cKirill Grouchnikov TestUtils.assertAllPixelsOfColor("", combinedBackgroundBitmap, 1533ab41277a085b829e15eca69442cfe45cae58a8cKirill Grouchnikov combinedBackgroundBitmap.getWidth(), 1543ab41277a085b829e15eca69442cfe45cae58a8cKirill Grouchnikov combinedBackgroundBitmap.getHeight(), color, 0, true); 1553ab41277a085b829e15eca69442cfe45cae58a8cKirill Grouchnikov } 1561d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov // If we are here, the color comparison has passed. 1571d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov failedComparisonDescription = null; 1581d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov return true; 1591d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov } catch (Throwable t) { 1601d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov failedComparisonDescription = t.getMessage(); 1611d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov return false; 1621d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov } finally { 1631d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov combinedBackgroundBitmap.recycle(); 1641d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov } 1651d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov } 1661d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov }; 1671d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov } 1681d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov 1691d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov /** 1702d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov * Returns a matcher that matches <code>CheckedTextView</code>s which are in checked state. 1712d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov */ 1722d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov public static Matcher isCheckedTextView() { 1732d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov return new BoundedMatcher<View, CheckedTextView>(CheckedTextView.class) { 1742d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov private String failedDescription; 1752d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov 1762d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov @Override 1772d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov public void describeTo(final Description description) { 1782d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov description.appendText("checked text view: "); 1792d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov 1802d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov description.appendText(failedDescription); 1812d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov } 1822d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov 1832d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov @Override 1842d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov public boolean matchesSafely(final CheckedTextView view) { 1852d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov if (view.isChecked()) { 1862d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov return true; 1872d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov } 1882d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov 1892d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov failedDescription = "not checked"; 1902d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov return false; 1912d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov } 1922d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov }; 1932d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov } 1942d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov 1952d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov /** 1962d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov * Returns a matcher that matches <code>CheckedTextView</code>s which are in checked state. 1972d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov */ 1982d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov public static Matcher isNonCheckedTextView() { 1992d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov return new BoundedMatcher<View, CheckedTextView>(CheckedTextView.class) { 2002d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov private String failedDescription; 2012d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov 2022d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov @Override 2032d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov public void describeTo(final Description description) { 2042d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov description.appendText("non checked text view: "); 2052d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov 2062d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov description.appendText(failedDescription); 2072d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov } 2082d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov 2092d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov @Override 2102d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov public boolean matchesSafely(final CheckedTextView view) { 2112d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov if (!view.isChecked()) { 2122d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov return true; 2132d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov } 2142d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov 2152d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov failedDescription = "checked"; 2162d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov return false; 2172d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov } 2182d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov }; 2192d18d3a4b92369971ed446cf54d98fb0fc55646aKirill Grouchnikov } 2201d8515a3b783e9b091bea2891606b466515b4fddKirill Grouchnikov 2211d8515a3b783e9b091bea2891606b466515b4fddKirill Grouchnikov /** 2221d8515a3b783e9b091bea2891606b466515b4fddKirill Grouchnikov * Returns a matcher that matches data entry in <code>SQLiteCursor</code> that has 2231d8515a3b783e9b091bea2891606b466515b4fddKirill Grouchnikov * the specified text in the specified column. 2241d8515a3b783e9b091bea2891606b466515b4fddKirill Grouchnikov */ 2251d8515a3b783e9b091bea2891606b466515b4fddKirill Grouchnikov public static Matcher<Object> withCursorItemContent(final String columnName, 2261d8515a3b783e9b091bea2891606b466515b4fddKirill Grouchnikov final String expectedText) { 2271d8515a3b783e9b091bea2891606b466515b4fddKirill Grouchnikov return new BoundedMatcher<Object, SQLiteCursor>(SQLiteCursor.class) { 2281d8515a3b783e9b091bea2891606b466515b4fddKirill Grouchnikov @Override 2291d8515a3b783e9b091bea2891606b466515b4fddKirill Grouchnikov public void describeTo(Description description) { 2301d8515a3b783e9b091bea2891606b466515b4fddKirill Grouchnikov description.appendText("doesn't match " + expectedText); 2311d8515a3b783e9b091bea2891606b466515b4fddKirill Grouchnikov } 2321d8515a3b783e9b091bea2891606b466515b4fddKirill Grouchnikov 2331d8515a3b783e9b091bea2891606b466515b4fddKirill Grouchnikov @Override 2341d8515a3b783e9b091bea2891606b466515b4fddKirill Grouchnikov protected boolean matchesSafely(SQLiteCursor cursor) { 2351d8515a3b783e9b091bea2891606b466515b4fddKirill Grouchnikov return TextUtils.equals(expectedText, 2361d8515a3b783e9b091bea2891606b466515b4fddKirill Grouchnikov cursor.getString(cursor.getColumnIndex(columnName))); 2371d8515a3b783e9b091bea2891606b466515b4fddKirill Grouchnikov } 2381d8515a3b783e9b091bea2891606b466515b4fddKirill Grouchnikov }; 2391d8515a3b783e9b091bea2891606b466515b4fddKirill Grouchnikov } 240ee9519c17254b5e992164ff278173c4b2c7c5fceKirill Grouchnikov 241ee9519c17254b5e992164ff278173c4b2c7c5fceKirill Grouchnikov /** 242ee9519c17254b5e992164ff278173c4b2c7c5fceKirill Grouchnikov * Returns a matcher that matches Views which implement TintableBackgroundView. 243ee9519c17254b5e992164ff278173c4b2c7c5fceKirill Grouchnikov */ 244ee9519c17254b5e992164ff278173c4b2c7c5fceKirill Grouchnikov public static Matcher<View> isTintableBackgroundView() { 245ee9519c17254b5e992164ff278173c4b2c7c5fceKirill Grouchnikov return new TypeSafeMatcher<View>() { 246ee9519c17254b5e992164ff278173c4b2c7c5fceKirill Grouchnikov @Override 247ee9519c17254b5e992164ff278173c4b2c7c5fceKirill Grouchnikov public void describeTo(Description description) { 248ee9519c17254b5e992164ff278173c4b2c7c5fceKirill Grouchnikov description.appendText("is TintableBackgroundView"); 249ee9519c17254b5e992164ff278173c4b2c7c5fceKirill Grouchnikov } 250ee9519c17254b5e992164ff278173c4b2c7c5fceKirill Grouchnikov 251ee9519c17254b5e992164ff278173c4b2c7c5fceKirill Grouchnikov @Override 252ee9519c17254b5e992164ff278173c4b2c7c5fceKirill Grouchnikov public boolean matchesSafely(View view) { 253ee9519c17254b5e992164ff278173c4b2c7c5fceKirill Grouchnikov return TintableBackgroundView.class.isAssignableFrom(view.getClass()); 254ee9519c17254b5e992164ff278173c4b2c7c5fceKirill Grouchnikov } 255ee9519c17254b5e992164ff278173c4b2c7c5fceKirill Grouchnikov }; 256ee9519c17254b5e992164ff278173c4b2c7c5fceKirill Grouchnikov } 257ee9519c17254b5e992164ff278173c4b2c7c5fceKirill Grouchnikov 25821f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov /** 25921f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov * Returns a matcher that matches lists of float values that fall into the specified range. 26021f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov */ 26121f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov public static Matcher<List<Float>> inRange(final float from, final float to) { 26221f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov return new TypeSafeMatcher<List<Float>>() { 26321f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov private String mFailedDescription; 26421f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov 26521f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov @Override 26621f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov public void describeTo(Description description) { 26721f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov description.appendText(mFailedDescription); 26821f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov } 26921f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov 27021f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov @Override 27121f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov protected boolean matchesSafely(List<Float> item) { 27221f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov int itemCount = item.size(); 27321f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov 27421f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov for (int i = 0; i < itemCount; i++) { 27521f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov float curr = item.get(i); 27621f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov 27721f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov if ((curr < from) || (curr > to)) { 27821f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov mFailedDescription = "Value #" + i + ":" + curr + " should be between " + 27921f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov from + " and " + to; 28021f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov return false; 28121f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov } 28221f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov } 28321f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov 28421f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov return true; 28521f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov } 28621f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov }; 28721f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov } 28821f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov 28921f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov /** 29021f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov * Returns a matcher that matches lists of float values that are in ascending order. 29121f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov */ 29221f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov public static Matcher<List<Float>> inAscendingOrder() { 29321f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov return new TypeSafeMatcher<List<Float>>() { 29421f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov private String mFailedDescription; 29521f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov 29621f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov @Override 29721f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov public void describeTo(Description description) { 29821f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov description.appendText(mFailedDescription); 29921f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov } 30021f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov 30121f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov @Override 30221f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov protected boolean matchesSafely(List<Float> item) { 30321f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov int itemCount = item.size(); 30421f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov 30521f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov if (itemCount >= 2) { 30621f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov for (int i = 0; i < itemCount - 1; i++) { 30721f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov float curr = item.get(i); 30821f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov float next = item.get(i + 1); 30921f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov 31021f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov if (curr > next) { 31121f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov mFailedDescription = "Values should increase between #" + i + 31221f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov ":" + curr + " and #" + (i + 1) + ":" + next; 31321f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov return false; 31421f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov } 31521f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov } 31621f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov } 31721f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov 31821f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov return true; 31921f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov } 32021f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov }; 32121f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov } 32221f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov 32321f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov /** 32421f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov * Returns a matcher that matches lists of float values that are in descending order. 32521f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov */ 32621f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov public static Matcher<List<Float>> inDescendingOrder() { 32721f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov return new TypeSafeMatcher<List<Float>>() { 32821f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov private String mFailedDescription; 32921f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov 33021f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov @Override 33121f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov public void describeTo(Description description) { 33221f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov description.appendText(mFailedDescription); 33321f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov } 33421f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov 33521f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov @Override 33621f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov protected boolean matchesSafely(List<Float> item) { 33721f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov int itemCount = item.size(); 33821f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov 33921f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov if (itemCount >= 2) { 34021f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov for (int i = 0; i < itemCount - 1; i++) { 34121f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov float curr = item.get(i); 34221f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov float next = item.get(i + 1); 34321f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov 34421f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov if (curr < next) { 34521f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov mFailedDescription = "Values should decrease between #" + i + 34621f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov ":" + curr + " and #" + (i + 1) + ":" + next; 34721f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov return false; 34821f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov } 34921f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov } 35021f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov } 35121f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov 35221f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov return true; 35321f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov } 35421f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov }; 35521f78eb90b3217aa5cf69c3ffd359506468b55f4Kirill Grouchnikov } 3561d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov 3571d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov 3581d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov /** 3591d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov * Returns a matcher that matches {@link View}s based on the given child type. 3601d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov * 3611d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov * @param childMatcher the type of the child to match on 3621d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov */ 3631d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov public static Matcher<ViewGroup> hasChild(final Matcher<View> childMatcher) { 3641d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov return new TypeSafeMatcher<ViewGroup>() { 3651d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov @Override 3661d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov public void describeTo(Description description) { 3671d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov description.appendText("has child: "); 3681d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov childMatcher.describeTo(description); 3691d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov } 3701d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov 3711d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov @Override 3721d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov public boolean matchesSafely(ViewGroup view) { 3731d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov final int childCount = view.getChildCount(); 3741d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov for (int i = 0; i < childCount; i++) { 3751d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov if (childMatcher.matches(view.getChildAt(i))) { 3761d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov return true; 3771d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov } 3781d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov } 3791d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov return false; 3801d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov } 3811d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov }; 3821d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov } 3831d6e3840486930e276d142861afb6c7e72d5ce72Kirill Grouchnikov 384244abf1fee3fe4fab72a1d8925407e29219940beKirill Grouchnikov} 385