blob: b178ff80cf1cd4be9fed375b39c37580da64d738 [file] [log] [blame]
/*
* Copyright 2022 The Android Open Source Project
*
* 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 androidx.wear.protolayout.expression;
import static androidx.wear.protolayout.expression.AnimationParameterBuilders.REPEAT_MODE_REVERSE;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;
import androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters;
import androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec;
import androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat;
import androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32;
import androidx.wear.protolayout.expression.DynamicBuilders.DynamicString;
import androidx.wear.protolayout.expression.proto.DynamicProto;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public final class DynamicFloatTest {
private static final String STATE_KEY = "state-key";
private static final float CONSTANT_VALUE = 42.42f;
private static final AnimationSpec SPEC =
new AnimationSpec.Builder()
.setAnimationParameters(
new AnimationParameters.Builder()
.setDurationMillis(2)
.setDelayMillis(1)
.build())
.setRepeatable(
new AnimationParameterBuilders.Repeatable.Builder()
.setRepeatMode(REPEAT_MODE_REVERSE)
.setIterations(10)
.build())
.build();
@Test
public void constantFloat() {
DynamicFloat constantFloat = DynamicFloat.constant(CONSTANT_VALUE);
assertThat(constantFloat.toDynamicFloatProto().getFixed().getValue())
.isWithin(0.0001f)
.of(CONSTANT_VALUE);
}
@Test
public void constantToString() {
assertThat(DynamicFloat.constant(1f).toString()).isEqualTo("FixedFloat{value=1.0}");
}
@Test
public void stateEntryValueFloat() {
DynamicFloat stateFloat = DynamicFloat.fromState(STATE_KEY);
assertThat(stateFloat.toDynamicFloatProto().getStateSource().getSourceKey())
.isEqualTo(STATE_KEY);
}
@Test
public void stateToString() {
assertThat(DynamicFloat.fromState("key").toString())
.isEqualTo("StateFloatSource{sourceKey=key}");
}
@Test
public void constantFloat_asInt() {
DynamicFloat constantFloat = DynamicFloat.constant(CONSTANT_VALUE);
DynamicInt32 dynamicInt32 = constantFloat.asInt();
assertThat(dynamicInt32.toDynamicInt32Proto().getFloatToInt().getInput().getFixed().getValue())
.isWithin(0.0001f)
.of(CONSTANT_VALUE);
}
@Test
public void constantFloat_asIntToString() {
assertThat(DynamicFloat.constant(1f).asInt().toString())
.isEqualTo("FloatToInt32Op{input=FixedFloat{value=1.0}, roundMode=1}");
}
@Test
public void formatFloat_defaultParameters() {
DynamicFloat constantFloat = DynamicFloat.constant(CONSTANT_VALUE);
DynamicString defaultFormat = constantFloat.format();
DynamicProto.FloatFormatOp floatFormatOp =
defaultFormat.toDynamicStringProto().getFloatFormatOp();
assertThat(floatFormatOp.getInput()).isEqualTo(constantFloat.toDynamicFloatProto());
assertThat(floatFormatOp.getGroupingUsed()).isFalse();
assertThat(floatFormatOp.hasMaxFractionDigits()).isFalse();
assertThat(floatFormatOp.getMinFractionDigits()).isEqualTo(0);
assertThat(floatFormatOp.hasMinIntegerDigits()).isFalse();
}
@Test
public void formatFloat_customFormatter() {
DynamicFloat constantFloat = DynamicFloat.constant(CONSTANT_VALUE);
boolean groupingUsed = true;
int minFractionDigits = 1;
int maxFractionDigits = 2;
int minIntegerDigits = 3;
DynamicFloat.FloatFormatter floatFormatter =
DynamicFloat.FloatFormatter.with()
.minFractionDigits(minFractionDigits)
.maxFractionDigits(maxFractionDigits)
.minIntegerDigits(minIntegerDigits)
.groupingUsed(groupingUsed);
DynamicString customFormat = constantFloat.format(floatFormatter);
DynamicProto.FloatFormatOp floatFormatOp =
customFormat.toDynamicStringProto().getFloatFormatOp();
assertThat(floatFormatOp.getInput()).isEqualTo(constantFloat.toDynamicFloatProto());
assertThat(floatFormatOp.getGroupingUsed()).isEqualTo(groupingUsed);
assertThat(floatFormatOp.getMaxFractionDigits()).isEqualTo(maxFractionDigits);
assertThat(floatFormatOp.getMinFractionDigits()).isEqualTo(minFractionDigits);
assertThat(floatFormatOp.getMinIntegerDigits()).isEqualTo(minIntegerDigits);
}
@Test
public void formatToString() {
assertThat(
DynamicFloat.constant(1f)
.format(
DynamicFloat.FloatFormatter.with()
.maxFractionDigits(2)
.minFractionDigits(3)
.minIntegerDigits(4)
.groupingUsed(true))
.toString())
.isEqualTo(
"FloatFormatOp{input=FixedFloat{value=1.0}, maxFractionDigits=2, "
+ "minFractionDigits=3, minIntegerDigits=4, groupingUsed=true}");
}
@Test
public void rangeAnimatedFloat() {
float startFloat = 100f;
float endFloat = 200f;
DynamicFloat animatedFloat = DynamicFloat.animate(startFloat, endFloat);
DynamicFloat animatedFloatWithSpec = DynamicFloat.animate(startFloat, endFloat, SPEC);
assertThat(animatedFloat.toDynamicFloatProto().getAnimatableFixed().hasAnimationSpec())
.isFalse();
assertThat(animatedFloatWithSpec.toDynamicFloatProto().getAnimatableFixed().getFromValue())
.isEqualTo(startFloat);
assertThat(animatedFloatWithSpec.toDynamicFloatProto().getAnimatableFixed().getToValue())
.isEqualTo(endFloat);
assertThat(animatedFloatWithSpec.toDynamicFloatProto().getAnimatableFixed().getAnimationSpec())
.isEqualTo(SPEC.toProto());
}
@Test
public void rangeAnimatedToString() {
assertThat(
DynamicFloat.animate(
/* start= */ 1f,
/* end= */ 2f,
new AnimationSpec.Builder().build())
.toString())
.isEqualTo(
"AnimatableFixedFloat{fromValue=1.0, toValue=2.0, animationSpec=AnimationSpec{"
+ "animationParameters=null, repeatable=null}}");
}
@Test
public void stateAnimatedFloat() {
DynamicFloat stateFloat = DynamicFloat.fromState(STATE_KEY);
DynamicFloat animatedFloat = DynamicFloat.animate(STATE_KEY);
DynamicFloat animatedFloatWithSpec = DynamicFloat.animate(STATE_KEY, SPEC);
assertThat(animatedFloat.toDynamicFloatProto().getAnimatableDynamic().hasAnimationSpec())
.isFalse();
assertThat(animatedFloatWithSpec.toDynamicFloatProto().getAnimatableDynamic().getInput())
.isEqualTo(stateFloat.toDynamicFloatProto());
assertThat(
animatedFloatWithSpec.toDynamicFloatProto().getAnimatableDynamic().getAnimationSpec()
).isEqualTo(SPEC.toProto());
assertThat(animatedFloat.toDynamicFloatProto())
.isEqualTo(stateFloat.animate().toDynamicFloatProto());
}
@Test
public void stateAnimatedToString() {
assertThat(
DynamicFloat.animate(
/* stateKey= */ "key",
new AnimationSpec.Builder()
.setAnimationParameters(
new AnimationParameters.Builder()
.setDelayMillis(1)
.build())
.build())
.toString())
.isEqualTo(
"AnimatableDynamicFloat{"
+ "input=StateFloatSource{sourceKey=key}, animationSpec=AnimationSpec{"
+ "animationParameters=AnimationParameters{durationMillis=0, easing=null, "
+ "delayMillis=1}, repeatable=null}}");
}
@Test
public void validProto() {
DynamicFloat from = DynamicFloat.constant(CONSTANT_VALUE);
DynamicFloat to = DynamicFloat.fromByteArray(from.toDynamicFloatByteArray());
assertThat(to.toDynamicFloatProto().getFixed().getValue()).isEqualTo(CONSTANT_VALUE);
}
@Test
public void invalidProto() {
assertThrows(IllegalArgumentException.class, () -> DynamicFloat.fromByteArray(new byte[] {1}));
}
}