blob: 80f675a190f3dd0723ff697a426e2a0008d3a495 [file] [log] [blame]
// Copyright 2018 The Feed Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.android.libraries.feed.piet.ui;
import static com.google.android.libraries.feed.common.testing.RunnableSubject.assertThatRunnable;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import android.graphics.Color;
import android.graphics.RectF;
import com.google.android.libraries.feed.common.functional.Suppliers;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/**
* Tests for the {@link GradientShader}.
*
* <p>Note that on Android, the Y axis starts at the top and increases to the bottom, so some of the
* math is backward.
*/
@RunWith(RobolectricTestRunner.class)
public class GradientShaderTest {
private static final boolean RTL = true;
private static final boolean LTR = false;
@Test
public void testGradientLine_leftToRight() {
RectF points = GradientShader.calculateGradientLine(12, 12, Math.toRadians(90), 0, LTR);
checkGradientLine(points, 0, 6, 12, 6);
}
@Test
public void testGradientLine_bottomToTop() {
RectF points = GradientShader.calculateGradientLine(12, 12, 0, 0, LTR);
checkGradientLine(points, 6, 12, 6, 0);
}
@Test
public void testGradientLine_bottomLeftToTopRight() {
RectF points =
GradientShader.calculateGradientLine(12, 12, Math.toRadians(45), Math.toRadians(45), LTR);
checkGradientLine(points, 0, 12, 12, 0);
}
@Test
public void testGradientLine_bottomRightToTopLeft() {
RectF points =
GradientShader.calculateGradientLine(
12, 12, Math.toRadians(315), Math.toRadians(315 % 90), LTR);
checkGradientLine(points, 12, 12, 0, 0);
}
@Test
public void testGradientLine_thirtyDegrees() {
RectF points =
GradientShader.calculateGradientLine(12, 12, Math.toRadians(30), Math.toRadians(30), LTR);
checkGradientLine(points, 1.9019f, 13.0981f, 10.0981f, -1.0981f);
}
@Test
public void testGradientLine_threeThirtyDegrees() {
RectF points =
GradientShader.calculateGradientLine(
12, 12, Math.toRadians(330), Math.toRadians(330 % 90), LTR);
checkGradientLine(points, 10.0981f, 13.0981f, 1.9019f, -1.0981f);
}
@Test
public void testGradientLine_horizontalRtL() {
RectF points = GradientShader.calculateGradientLine(12, 12, Math.toRadians(90), 0, RTL);
checkGradientLine(points, 12, 6, 0, 6);
// Flip the angle 180; should be the same as the RtL version
RectF pointsLtR = GradientShader.calculateGradientLine(12, 12, Math.toRadians(270), 0, LTR);
checkGradientLine(points, pointsLtR.left, pointsLtR.top, pointsLtR.right, pointsLtR.bottom);
}
@Test
public void testGradientLine_verticalRtL() {
RectF points = GradientShader.calculateGradientLine(12, 12, 0, 0, LTR);
checkGradientLine(points, 6, 12, 6, 0);
// RtL should not change the points for a vertical line
RectF pointsLtR = GradientShader.calculateGradientLine(12, 12, 0, 0, LTR);
checkGradientLine(points, pointsLtR.left, pointsLtR.top, pointsLtR.right, pointsLtR.bottom);
}
@Test
public void testGradientLine_angleRtL() {
RectF points =
GradientShader.calculateGradientLine(12, 12, Math.toRadians(45), Math.toRadians(45), RTL);
checkGradientLine(points, 12, 12, 0, 0);
RectF pointsLtR =
GradientShader.calculateGradientLine(
12, 12, Math.toRadians(360 - 45), Math.toRadians(45), LTR);
checkGradientLine(points, pointsLtR.left, pointsLtR.top, pointsLtR.right, pointsLtR.bottom);
}
@Test
public void testGradientLine_invalidDegrees() {
GradientShader shader =
new GradientShader(
new int[] {Color.BLUE, Color.RED}, new float[] {0, 1}, 999, Suppliers.of(LTR));
assertThat(shader.angleRadians).isEqualTo(Math.toRadians(999 % 360));
assertThat(shader.angleRadiansSmall).isEqualTo(Math.toRadians(999 % 90));
}
@Test
public void testGradientLine_invalidStops() {
GradientShader shader =
new GradientShader(
new int[] {Color.BLUE, Color.RED}, new float[] {999, -1}, 45, Suppliers.of(LTR));
shader.resize(123, 456);
// assert no failures
}
@Test
public void testGradientLine_lengthMismatch() {
assertThatRunnable(
() ->
new GradientShader(
new int[] {Color.BLUE, Color.RED}, new float[] {1}, 45, Suppliers.of(LTR)))
.throwsAnExceptionOfType(IllegalStateException.class)
.that()
.hasMessageThat()
.contains("Mismatch: got 2 colors and 1 stops");
}
@Test
public void testGradientLine_nullLtRSupplier() {
GradientShader shader =
new GradientShader(new int[] {Color.BLUE, Color.RED}, new float[] {0, 1}, 45, null);
shader.resize(123, 456);
// assert no failures
}
private void checkGradientLine(RectF result, float startx, float starty, float endx, float endy) {
String testFailOutput =
String.format("expected: %s\nbut was : %s", new RectF(startx, starty, endx, endy), result);
assertWithMessage(testFailOutput).that(result.left).isWithin(0.01f).of(startx);
assertWithMessage(testFailOutput).that(result.top).isWithin(0.01f).of(starty);
assertWithMessage(testFailOutput).that(result.right).isWithin(0.01f).of(endx);
assertWithMessage(testFailOutput).that(result.bottom).isWithin(0.01f).of(endy);
}
}