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 android.support.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.support.v7.widget.RecyclerView; 25import android.view.View; 26 27import org.hamcrest.Description; 28import org.hamcrest.Matcher; 29import org.hamcrest.TypeSafeMatcher; 30 31public class MoreViewAssertions { 32 33 public static ViewAssertion left(final Matcher<Integer> matcher) { 34 return new ViewAssertion() { 35 @Override 36 public void check(View view, NoMatchingViewException noViewException) { 37 assertThat("View left: " + HumanReadables.describe(view), view.getLeft(), matcher); 38 } 39 }; 40 } 41 42 public static ViewAssertion approximateTop(final Matcher<Double> matcher) { 43 return new ViewAssertion() { 44 @Override 45 public void check(View view, NoMatchingViewException noViewException) { 46 assertThat("View top: " + HumanReadables.describe(view), ((double) view.getTop()), 47 matcher); 48 } 49 }; 50 } 51 52 public static ViewAssertion top(final Matcher<Integer> matcher) { 53 return new ViewAssertion() { 54 @Override 55 public void check(View view, NoMatchingViewException noViewException) { 56 assertThat("View top: " + HumanReadables.describe(view), view.getTop(), matcher); 57 } 58 }; 59 } 60 61 public static ViewAssertion right(final Matcher<Integer> matcher) { 62 return new ViewAssertion() { 63 @Override 64 public void check(View view, NoMatchingViewException noViewException) { 65 assertThat("View right: " + HumanReadables.describe(view), view.getRight(), 66 matcher); 67 } 68 }; 69 } 70 71 public static ViewAssertion bottom(final Matcher<Integer> matcher) { 72 return new ViewAssertion() { 73 @Override 74 public void check(View view, NoMatchingViewException noViewException) { 75 assertThat("View bottom: " + HumanReadables.describe(view), view.getBottom(), 76 matcher); 77 } 78 }; 79 } 80 81 public static ViewAssertion approximateBottom(final Matcher<Double> matcher) { 82 return new ViewAssertion() { 83 @Override 84 public void check(View view, NoMatchingViewException noViewException) { 85 assertThat("View bottom: " + HumanReadables.describe(view), ((double) view 86 .getBottom()), matcher); 87 } 88 }; 89 } 90 91 /** 92 * Returns a new ViewAssertion against a match of the view's left position, relative to the 93 * left 94 * edge of the containing window. 95 * 96 * @param matcher matcher for the left position 97 */ 98 public static ViewAssertion screenLeft(final Matcher<Integer> matcher) { 99 return new ViewAssertion() { 100 @Override 101 public void check(View view, NoMatchingViewException noViewException) { 102 int[] screenXy = {0, 0}; 103 view.getLocationInWindow(screenXy); 104 assertThat("View screenLeft: " + HumanReadables.describe(view), screenXy[0], 105 matcher); 106 } 107 }; 108 } 109 110 /** 111 * Returns a new ViewAssertion against a match of the view's top position, relative to the top 112 * edge of the containing window. 113 * 114 * @param matcher matcher for the top position 115 */ 116 public static ViewAssertion screenTop(final Matcher<Integer> matcher) { 117 return new ViewAssertion() { 118 @Override 119 public void check(View view, NoMatchingViewException noViewException) { 120 int[] screenXy = {0, 0}; 121 view.getLocationInWindow(screenXy); 122 assertThat("View screenTop: " + HumanReadables.describe(view), screenXy[1], 123 matcher); 124 } 125 }; 126 } 127 128 /** 129 * Returns a new ViewAssertion against a match of the view's right position, relative to the 130 * left 131 * edge of the containing window. 132 * 133 * @param matcher matcher for the right position 134 */ 135 public static ViewAssertion screenRight(final Matcher<Integer> matcher) { 136 return new ViewAssertion() { 137 @Override 138 public void check(View view, NoMatchingViewException noViewException) { 139 int[] screenXy = {0, 0}; 140 view.getLocationInWindow(screenXy); 141 assertThat("View screenRight: " + HumanReadables.describe(view), 142 screenXy[0] + view.getWidth(), matcher); 143 } 144 }; 145 } 146 147 /** 148 * Returns a new ViewAssertion against a match of the view's bottom position, relative to the 149 * top 150 * edge of the containing window. 151 * 152 * @param matcher matcher for the bottom position 153 */ 154 public static ViewAssertion screenBottom(final Matcher<Integer> matcher) { 155 return new ViewAssertion() { 156 @Override 157 public void check(View view, NoMatchingViewException noViewException) { 158 int[] screenXy = {0, 0}; 159 view.getLocationInWindow(screenXy); 160 assertThat("View screenBottom: " + HumanReadables.describe(view), 161 screenXy[1] + view.getHeight(), matcher); 162 } 163 }; 164 } 165 166 public static Matcher<View> withTranslationX(final int xTranslation) { 167 return new TypeSafeMatcher<View>() { 168 @Override 169 public void describeTo(Description description) { 170 description.appendText("with x translation == " + xTranslation); 171 } 172 173 @Override 174 public boolean matchesSafely(View view) { 175 return view.getTranslationX() == xTranslation; 176 } 177 }; 178 } 179 180 public static Matcher<RecyclerView> withPositiveVerticalScrollOffset() { 181 return new TypeSafeMatcher<RecyclerView>() { 182 @Override 183 public void describeTo(Description description) { 184 description.appendText("with positive y scroll offset"); 185 } 186 187 @Override 188 public boolean matchesSafely(RecyclerView view) { 189 return view.computeVerticalScrollOffset() > 0; 190 } 191 }; 192 } 193 194 public static Matcher<RecyclerView> withNoVerticalScrollOffset() { 195 return new TypeSafeMatcher<RecyclerView>() { 196 @Override 197 public void describeTo(Description description) { 198 description.appendText("with no y scroll offset"); 199 } 200 201 @Override 202 public boolean matchesSafely(RecyclerView view) { 203 return view.computeVerticalScrollOffset() == 0; 204 } 205 }; 206 } 207} 208