blob: d41850e5cf5816e02f39ef3fa4cd3dc5fa1f3dfe [file] [log] [blame]
// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package backport;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestRuntime.CfVm;
import com.android.tools.r8.desugar.backports.AbstractBackportTest;
import com.android.tools.r8.desugar.backports.IgnoreInvokes;
import com.android.tools.r8.utils.AndroidApiLevel;
import java.util.Objects;
import org.hamcrest.CoreMatchers;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public final class ObjectsBackportJava9Test extends AbstractBackportTest {
@Parameters(name = "{0}")
public static Iterable<?> data() {
return TestBase.getTestParameters()
.withDexRuntimes()
.withCfRuntimesStartingFromIncluding(CfVm.JDK9)
.withAllApiLevelsAlsoForCf()
.build();
}
public ObjectsBackportJava9Test(TestParameters parameters) {
super(parameters, Objects.class, ObjectsBackportJava9Main.class);
// Objects.checkFromIndexSize, Objects.checkFromToIndex, Objects.checkIndex,
// Objects.requireNonNullElse and Objects.requireNonNullElseGet added in API 30.
registerTarget(AndroidApiLevel.R, 28);
registerTarget(AndroidApiLevel.N, 0);
// Objects.requireNonNullElseGet is not desugared if Supplier is absent.
registerTarget(AndroidApiLevel.B, 4);
}
@Test
public void desugaringApiLevelR() throws Exception {
// TODO(b/154759404): This test should start to fail when testing on an Android R VM.
// This has now been checked with S, when R testing is added chck and remove this.
if (parameters.getRuntime().isDex() && parameters.getApiLevel().isEqualTo(AndroidApiLevel.R)) {
testForD8()
.setMinApi(AndroidApiLevel.R)
.addProgramClasses(MiniAssert.class, IgnoreInvokes.class)
.addProgramClasses(ObjectsBackportJava9Main.class)
.setIncludeClassesChecksum(true)
.compile()
.run(parameters.getRuntime(), ObjectsBackportJava9Main.class)
.assertFailureWithErrorThatMatches(
CoreMatchers.containsString("java.lang.NoSuchMethodError"));
}
}
public static class ObjectsBackportJava9Main {
public static void main(String[] args) {
boolean isAndroid = "Dalvik".equals(System.getProperty("java.vm.name"));
String majorVersion = System.getProperty("java.vm.version").split("\\.", -1)[0];
testRequireNonNullElse();
if (!isAndroid || Integer.parseInt(majorVersion) >= 7) {
// TODO desugaring desugaredlibrary is blocked by
// https://issuetracker.google.com/issues/114481425
testRequireNonNullElseGet();
}
testCheckIndex();
testCheckFromToIndex();
testCheckFromIndexSize();
}
private static void testRequireNonNullElse() {
Object one = new Object();
Object two = new Object();
assertSame(one, Objects.requireNonNullElse(one, two));
assertSame(two, Objects.requireNonNullElse(null, two));
try {
throw new AssertionError(Objects.requireNonNullElse(null, null));
} catch (NullPointerException expected) {
}
}
private static void testRequireNonNullElseGet() {
Object one = new Object();
Object two = new Object();
assertSame(one, Objects.requireNonNullElseGet(one, () -> two));
assertSame(two, Objects.requireNonNullElseGet(null, () -> two));
try {
throw new AssertionError(Objects.requireNonNullElseGet(null, null));
} catch (NullPointerException expected) {
}
try {
throw new AssertionError(Objects.requireNonNullElseGet(null, () -> null));
} catch (NullPointerException expected) {
}
}
private static void testCheckIndex() {
for (int i = 0; i < 10; i++) {
assertEquals(i, Objects.checkIndex(i, 10));
}
try {
throw new AssertionError(Objects.checkIndex(-1, 10));
} catch (IndexOutOfBoundsException expected) {
}
try {
throw new AssertionError(Objects.checkIndex(10, 0));
} catch (IndexOutOfBoundsException expected) {
}
try {
throw new AssertionError(Objects.checkIndex(0, 0));
} catch (IndexOutOfBoundsException expected) {
}
}
private static void testCheckFromToIndex() {
for (int i = 0; i <= 10; i++) {
for (int j = i; j <= 10; j++) {
assertEquals(i, Objects.checkFromToIndex(i, j, 10));
}
}
assertEquals(0, Objects.checkFromToIndex(0, 0, 0));
try {
throw new AssertionError(Objects.checkFromToIndex(4, 2, 10));
} catch (IndexOutOfBoundsException expected) {
}
try {
throw new AssertionError(Objects.checkFromToIndex(-1, 5, 10));
} catch (IndexOutOfBoundsException expected) {
}
try {
throw new AssertionError(Objects.checkFromToIndex(0, -1, 10));
} catch (IndexOutOfBoundsException expected) {
}
try {
throw new AssertionError(Objects.checkFromToIndex(11, 11, 10));
} catch (IndexOutOfBoundsException expected) {
}
try {
throw new AssertionError(Objects.checkFromToIndex(0, 1, 0));
} catch (IndexOutOfBoundsException expected) {
}
try {
throw new AssertionError(Objects.checkFromToIndex(1, 1, 0));
} catch (IndexOutOfBoundsException expected) {
}
}
private static void testCheckFromIndexSize() {
for (int i = 0; i <= 10; i++) {
for (int j = 10 - i; j >= 0; j--) {
assertEquals(i, Objects.checkFromIndexSize(i, j, 10));
}
}
assertEquals(0, Objects.checkFromIndexSize(0, 0, 0));
try {
throw new AssertionError(Objects.checkFromIndexSize(8, 4, 10));
} catch (IndexOutOfBoundsException expected) {
}
try {
throw new AssertionError(Objects.checkFromIndexSize(-1, 5, 10));
} catch (IndexOutOfBoundsException expected) {
}
try {
throw new AssertionError(Objects.checkFromIndexSize(11, 0, 10));
} catch (IndexOutOfBoundsException expected) {
}
try {
throw new AssertionError(Objects.checkFromIndexSize(0, 1, 0));
} catch (IndexOutOfBoundsException expected) {
}
try {
throw new AssertionError(Objects.checkFromIndexSize(1, 1, 0));
} catch (IndexOutOfBoundsException expected) {
}
// Check for cases where overflow might occur producing incorrect results.
try {
throw new AssertionError(
Objects.checkFromIndexSize(Integer.MAX_VALUE, 1, Integer.MAX_VALUE));
} catch (IndexOutOfBoundsException expected) {
}
try {
throw new AssertionError(Objects.checkFromIndexSize(0, 1, Integer.MIN_VALUE));
} catch (IndexOutOfBoundsException expected) {
}
}
private static void assertEquals(int expected, int actual) {
if (expected != actual) {
throw new AssertionError("Expected <" + expected + "> but was <" + actual + '>');
}
}
private static void assertSame(Object expected, Object actual) {
if (expected != actual) {
throw new AssertionError(
"Expected <" + expected + "> to be same instance as <" + actual + '>');
}
}
}
}