1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package androidx.wear.widget.util; 18 19import static android.support.test.espresso.matcher.ViewMatchers.assertThat; 20 21import android.support.test.espresso.NoMatchingViewException; 22import android.support.test.espresso.ViewAssertion; 23import android.support.test.espresso.util.HumanReadables; 24import android.view.View; 25 26import androidx.recyclerview.widget.RecyclerView; 27 28import org.hamcrest.Description; 29import org.hamcrest.Matcher; 30import org.hamcrest.TypeSafeMatcher; 31 32public class MoreViewAssertions { 33 34 public static ViewAssertion left(final Matcher<Integer> matcher) { 35 return new ViewAssertion() { 36 @Override 37 public void check(View view, NoMatchingViewException noViewException) { 38 assertThat("View left: " + HumanReadables.describe(view), view.getLeft(), matcher); 39 } 40 }; 41 } 42 43 public static ViewAssertion approximateTop(final Matcher<Double> matcher) { 44 return new ViewAssertion() { 45 @Override 46 public void check(View view, NoMatchingViewException noViewException) { 47 assertThat("View top: " + HumanReadables.describe(view), ((double) view.getTop()), 48 matcher); 49 } 50 }; 51 } 52 53 public static ViewAssertion top(final Matcher<Integer> matcher) { 54 return new ViewAssertion() { 55 @Override 56 public void check(View view, NoMatchingViewException noViewException) { 57 assertThat("View top: " + HumanReadables.describe(view), view.getTop(), matcher); 58 } 59 }; 60 } 61 62 public static ViewAssertion right(final Matcher<Integer> matcher) { 63 return new ViewAssertion() { 64 @Override 65 public void check(View view, NoMatchingViewException noViewException) { 66 assertThat("View right: " + HumanReadables.describe(view), view.getRight(), 67 matcher); 68 } 69 }; 70 } 71 72 public static ViewAssertion bottom(final Matcher<Integer> matcher) { 73 return new ViewAssertion() { 74 @Override 75 public void check(View view, NoMatchingViewException noViewException) { 76 assertThat("View bottom: " + HumanReadables.describe(view), view.getBottom(), 77 matcher); 78 } 79 }; 80 } 81 82 public static ViewAssertion approximateBottom(final Matcher<Double> matcher) { 83 return new ViewAssertion() { 84 @Override 85 public void check(View view, NoMatchingViewException noViewException) { 86 assertThat("View bottom: " + HumanReadables.describe(view), ((double) view 87 .getBottom()), matcher); 88 } 89 }; 90 } 91 92 /** 93 * Returns a new ViewAssertion against a match of the view's left position, relative to the 94 * left 95 * edge of the containing window. 96 * 97 * @param matcher matcher for the left position 98 */ 99 public static ViewAssertion screenLeft(final Matcher<Integer> matcher) { 100 return new ViewAssertion() { 101 @Override 102 public void check(View view, NoMatchingViewException noViewException) { 103 int[] screenXy = {0, 0}; 104 view.getLocationInWindow(screenXy); 105 assertThat("View screenLeft: " + HumanReadables.describe(view), screenXy[0], 106 matcher); 107 } 108 }; 109 } 110 111 /** 112 * Returns a new ViewAssertion against a match of the view's top position, relative to the top 113 * edge of the containing window. 114 * 115 * @param matcher matcher for the top position 116 */ 117 public static ViewAssertion screenTop(final Matcher<Integer> matcher) { 118 return new ViewAssertion() { 119 @Override 120 public void check(View view, NoMatchingViewException noViewException) { 121 int[] screenXy = {0, 0}; 122 view.getLocationInWindow(screenXy); 123 assertThat("View screenTop: " + HumanReadables.describe(view), screenXy[1], 124 matcher); 125 } 126 }; 127 } 128 129 /** 130 * Returns a new ViewAssertion against a match of the view's right position, relative to the 131 * left 132 * edge of the containing window. 133 * 134 * @param matcher matcher for the right position 135 */ 136 public static ViewAssertion screenRight(final Matcher<Integer> matcher) { 137 return new ViewAssertion() { 138 @Override 139 public void check(View view, NoMatchingViewException noViewException) { 140 int[] screenXy = {0, 0}; 141 view.getLocationInWindow(screenXy); 142 assertThat("View screenRight: " + HumanReadables.describe(view), 143 screenXy[0] + view.getWidth(), matcher); 144 } 145 }; 146 } 147 148 /** 149 * Returns a new ViewAssertion against a match of the view's bottom position, relative to the 150 * top 151 * edge of the containing window. 152 * 153 * @param matcher matcher for the bottom position 154 */ 155 public static ViewAssertion screenBottom(final Matcher<Integer> matcher) { 156 return new ViewAssertion() { 157 @Override 158 public void check(View view, NoMatchingViewException noViewException) { 159 int[] screenXy = {0, 0}; 160 view.getLocationInWindow(screenXy); 161 assertThat("View screenBottom: " + HumanReadables.describe(view), 162 screenXy[1] + view.getHeight(), matcher); 163 } 164 }; 165 } 166 167 public static Matcher<View> withTranslationX(final int xTranslation) { 168 return new TypeSafeMatcher<View>() { 169 @Override 170 public void describeTo(Description description) { 171 description.appendText("with x translation == " + xTranslation); 172 } 173 174 @Override 175 public boolean matchesSafely(View view) { 176 return view.getTranslationX() == xTranslation; 177 } 178 }; 179 } 180 181 public static Matcher<RecyclerView> withPositiveVerticalScrollOffset() { 182 return new TypeSafeMatcher<RecyclerView>() { 183 @Override 184 public void describeTo(Description description) { 185 description.appendText("with positive y scroll offset"); 186 } 187 188 @Override 189 public boolean matchesSafely(RecyclerView view) { 190 return view.computeVerticalScrollOffset() > 0; 191 } 192 }; 193 } 194 195 public static Matcher<RecyclerView> withNoVerticalScrollOffset() { 196 return new TypeSafeMatcher<RecyclerView>() { 197 @Override 198 public void describeTo(Description description) { 199 description.appendText("with no y scroll offset"); 200 } 201 202 @Override 203 public boolean matchesSafely(RecyclerView view) { 204 return view.computeVerticalScrollOffset() == 0; 205 } 206 }; 207 } 208} 209