< prev index next > test/jdk/java/lang/ScopedValue/ScopedValueAPI.java
Print this page
/*
! * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
/*
! * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
private static Stream<ThreadFactory> factories() {
return Stream.of(Thread.ofPlatform().factory(), Thread.ofVirtual().factory());
}
/**
! * Test that the run method is invoked.
*/
@ParameterizedTest
@MethodSource("factories")
! void testRun(ThreadFactory factory) throws Exception {
test(factory, () -> {
class Box { static boolean executed; }
ScopedValue<String> name = ScopedValue.newInstance();
ScopedValue.runWhere(name, "duke", () -> { Box.executed = true; });
assertTrue(Box.executed);
});
}
/**
! * Test the run method throwing an exception.
*/
@ParameterizedTest
@MethodSource("factories")
! void testRunThrows(ThreadFactory factory) throws Exception {
test(factory, () -> {
class FooException extends RuntimeException { }
ScopedValue<String> name = ScopedValue.newInstance();
Runnable op = () -> { throw new FooException(); };
assertThrows(FooException.class, () -> ScopedValue.runWhere(name, "duke", op));
assertFalse(name.isBound());
});
}
/**
! * Test that the call method is invoked.
*/
@ParameterizedTest
@MethodSource("factories")
! void testCall(ThreadFactory factory) throws Exception {
test(factory, () -> {
ScopedValue<String> name = ScopedValue.newInstance();
String result = ScopedValue.callWhere(name, "duke", name::get);
assertEquals("duke", result);
});
}
/**
! * Test that the get method is invoked.
*/
@ParameterizedTest
@MethodSource("factories")
! void testGetWhere(ThreadFactory factory) throws Exception {
test(factory, () -> {
ScopedValue<String> name = ScopedValue.newInstance();
! String result = ScopedValue.getWhere(name, "duke", (Supplier<String>)(name::get));
! assertEquals("duke", result);
});
}
/**
! * Test the call method throwing an exception.
*/
@ParameterizedTest
@MethodSource("factories")
! void testCallThrows(ThreadFactory factory) throws Exception {
test(factory, () -> {
- class FooException extends RuntimeException { }
ScopedValue<String> name = ScopedValue.newInstance();
! Callable<Void> op = () -> { throw new FooException(); };
! assertThrows(FooException.class, () -> ScopedValue.callWhere(name, "duke", op));
- assertFalse(name.isBound());
});
}
/**
! * Test the get(Supplier) method throwing an exception.
*/
@ParameterizedTest
@MethodSource("factories")
! void testGetThrows(ThreadFactory factory) throws Exception {
test(factory, () -> {
class FooException extends RuntimeException { }
ScopedValue<String> name = ScopedValue.newInstance();
Supplier<Void> op = () -> { throw new FooException(); };
assertThrows(FooException.class, () -> ScopedValue.getWhere(name, "duke", op));
private static Stream<ThreadFactory> factories() {
return Stream.of(Thread.ofPlatform().factory(), Thread.ofVirtual().factory());
}
/**
! * Test that runWhere invokes the Runnable's run method.
*/
@ParameterizedTest
@MethodSource("factories")
! void testRunWhere(ThreadFactory factory) throws Exception {
test(factory, () -> {
class Box { static boolean executed; }
ScopedValue<String> name = ScopedValue.newInstance();
ScopedValue.runWhere(name, "duke", () -> { Box.executed = true; });
assertTrue(Box.executed);
});
}
/**
! * Test runWhere when the run method throws an exception.
*/
@ParameterizedTest
@MethodSource("factories")
! void testRunWhereThrows(ThreadFactory factory) throws Exception {
test(factory, () -> {
class FooException extends RuntimeException { }
ScopedValue<String> name = ScopedValue.newInstance();
Runnable op = () -> { throw new FooException(); };
assertThrows(FooException.class, () -> ScopedValue.runWhere(name, "duke", op));
assertFalse(name.isBound());
});
}
/**
! * Test that callWhere invokes the Callable's call method.
*/
@ParameterizedTest
@MethodSource("factories")
! void testCallWhere(ThreadFactory factory) throws Exception {
test(factory, () -> {
ScopedValue<String> name = ScopedValue.newInstance();
String result = ScopedValue.callWhere(name, "duke", name::get);
assertEquals("duke", result);
});
}
/**
! * Test callWhere when the call method throws an exception.
*/
@ParameterizedTest
@MethodSource("factories")
! void testCallWhereThrows(ThreadFactory factory) throws Exception {
test(factory, () -> {
+ class FooException extends RuntimeException { }
ScopedValue<String> name = ScopedValue.newInstance();
! Callable<Void> op = () -> { throw new FooException(); };
! assertThrows(FooException.class, () -> ScopedValue.callWhere(name, "duke", op));
+ assertFalse(name.isBound());
});
}
+
/**
! * Test that getWhere invokes the Supplier's get method.
*/
@ParameterizedTest
@MethodSource("factories")
! void testGetWhere(ThreadFactory factory) throws Exception {
test(factory, () -> {
ScopedValue<String> name = ScopedValue.newInstance();
! String result = ScopedValue.getWhere(name, "duke", name::get);
! assertEquals("duke", result);
});
}
/**
! * Test getWhere when the get method throws an exception.
*/
@ParameterizedTest
@MethodSource("factories")
! void testGetWhereThrows(ThreadFactory factory) throws Exception {
test(factory, () -> {
class FooException extends RuntimeException { }
ScopedValue<String> name = ScopedValue.newInstance();
Supplier<Void> op = () -> { throw new FooException(); };
assertThrows(FooException.class, () -> ScopedValue.getWhere(name, "duke", op));
ScopedValue<String> name1 = ScopedValue.newInstance();
ScopedValue<String> name2 = ScopedValue.newInstance();
assertThrows(NoSuchElementException.class, name1::get);
assertThrows(NoSuchElementException.class, name2::get);
! // run
ScopedValue.runWhere(name1, "duke", () -> {
assertEquals("duke", name1.get());
assertThrows(NoSuchElementException.class, name2::get);
});
assertThrows(NoSuchElementException.class, name1::get);
assertThrows(NoSuchElementException.class, name2::get);
! // call
ScopedValue.callWhere(name1, "duke", () -> {
assertEquals("duke", name1.get());
assertThrows(NoSuchElementException.class, name2::get);
return null;
});
assertThrows(NoSuchElementException.class, name1::get);
assertThrows(NoSuchElementException.class, name2::get);
! // get
ScopedValue.getWhere(name1, "duke", () -> {
assertEquals("duke", name1.get());
assertThrows(NoSuchElementException.class, name2::get);
return null;
});
ScopedValue<String> name1 = ScopedValue.newInstance();
ScopedValue<String> name2 = ScopedValue.newInstance();
assertThrows(NoSuchElementException.class, name1::get);
assertThrows(NoSuchElementException.class, name2::get);
! // runWhere
ScopedValue.runWhere(name1, "duke", () -> {
assertEquals("duke", name1.get());
assertThrows(NoSuchElementException.class, name2::get);
});
assertThrows(NoSuchElementException.class, name1::get);
assertThrows(NoSuchElementException.class, name2::get);
! // callWhere
ScopedValue.callWhere(name1, "duke", () -> {
assertEquals("duke", name1.get());
assertThrows(NoSuchElementException.class, name2::get);
return null;
});
assertThrows(NoSuchElementException.class, name1::get);
assertThrows(NoSuchElementException.class, name2::get);
! // getWhere
ScopedValue.getWhere(name1, "duke", () -> {
assertEquals("duke", name1.get());
assertThrows(NoSuchElementException.class, name2::get);
return null;
});
ScopedValue<String> name1 = ScopedValue.newInstance();
ScopedValue<String> name2 = ScopedValue.newInstance();
assertFalse(name1.isBound());
assertFalse(name2.isBound());
! // run
ScopedValue.runWhere(name1, "duke", () -> {
assertTrue(name1.isBound());
assertFalse(name2.isBound());
});
assertFalse(name1.isBound());
assertFalse(name2.isBound());
! // call
ScopedValue.callWhere(name1, "duke", () -> {
assertTrue(name1.isBound());
assertFalse(name2.isBound());
return null;
});
assertFalse(name1.isBound());
assertFalse(name2.isBound());
! // call
! ScopedValue.callWhere(name1, "duke", () -> {
assertTrue(name1.isBound());
assertFalse(name2.isBound());
return null;
});
assertFalse(name1.isBound());
ScopedValue<String> name1 = ScopedValue.newInstance();
ScopedValue<String> name2 = ScopedValue.newInstance();
assertFalse(name1.isBound());
assertFalse(name2.isBound());
! // runWhere
ScopedValue.runWhere(name1, "duke", () -> {
assertTrue(name1.isBound());
assertFalse(name2.isBound());
});
assertFalse(name1.isBound());
assertFalse(name2.isBound());
! // callWhere
ScopedValue.callWhere(name1, "duke", () -> {
assertTrue(name1.isBound());
assertFalse(name2.isBound());
return null;
});
assertFalse(name1.isBound());
assertFalse(name2.isBound());
! // getWhere
! ScopedValue.getWhere(name1, "duke", () -> {
assertTrue(name1.isBound());
assertFalse(name2.isBound());
return null;
});
assertFalse(name1.isBound());
test(factory, () -> {
ScopedValue<String> name = ScopedValue.newInstance();
assertNull(name.orElse(null));
assertEquals("default", name.orElse("default"));
! // run
ScopedValue.runWhere(name, "duke", () -> {
assertEquals("duke", name.orElse(null));
assertEquals("duke", name.orElse("default"));
});
! // call
ScopedValue.callWhere(name, "duke", () -> {
assertEquals("duke", name.orElse(null));
assertEquals("duke", name.orElse("default"));
return null;
});
});
}
/**
* Test orElseThrow method.
test(factory, () -> {
ScopedValue<String> name = ScopedValue.newInstance();
assertNull(name.orElse(null));
assertEquals("default", name.orElse("default"));
! // runWhere
ScopedValue.runWhere(name, "duke", () -> {
assertEquals("duke", name.orElse(null));
assertEquals("duke", name.orElse("default"));
});
! // callWhere
ScopedValue.callWhere(name, "duke", () -> {
assertEquals("duke", name.orElse(null));
assertEquals("duke", name.orElse("default"));
return null;
});
+
+ // getWhere
+ ScopedValue.getWhere(name, "duke", () -> {
+ assertEquals("duke", name.orElse(null));
+ assertEquals("duke", name.orElse("default"));
+ return null;
+ });
});
}
/**
* Test orElseThrow method.
test(factory, () -> {
class FooException extends RuntimeException { }
ScopedValue<String> name = ScopedValue.newInstance();
assertThrows(FooException.class, () -> name.orElseThrow(FooException::new));
! // run
ScopedValue.runWhere(name, "duke", () -> {
assertEquals("duke", name.orElseThrow(FooException::new));
});
! // call
ScopedValue.callWhere(name, "duke", () -> {
assertEquals("duke", name.orElseThrow(FooException::new));
return null;
});
});
}
/**
* Test two bindings.
test(factory, () -> {
class FooException extends RuntimeException { }
ScopedValue<String> name = ScopedValue.newInstance();
assertThrows(FooException.class, () -> name.orElseThrow(FooException::new));
! // runWhere
ScopedValue.runWhere(name, "duke", () -> {
assertEquals("duke", name.orElseThrow(FooException::new));
});
! // callWhere
ScopedValue.callWhere(name, "duke", () -> {
assertEquals("duke", name.orElseThrow(FooException::new));
return null;
});
+
+ // getWhere
+ ScopedValue.getWhere(name, "duke", () -> {
+ assertEquals("duke", name.orElseThrow(FooException::new));
+ return null;
+ });
});
}
/**
* Test two bindings.
void testTwoBindings(ThreadFactory factory) throws Exception {
test(factory, () -> {
ScopedValue<String> name = ScopedValue.newInstance();
ScopedValue<Integer> age = ScopedValue.newInstance();
! // run
! ScopedValue.where(name, "duke").where(age, 100).run(() -> {
assertTrue(name.isBound());
assertTrue(age.isBound());
assertEquals("duke", name.get());
assertEquals(100, (int) age.get());
});
assertFalse(name.isBound());
assertFalse(age.isBound());
! // call
! ScopedValue.where(name, "duke").where(age, 100).call(() -> {
assertTrue(name.isBound());
assertTrue(age.isBound());
assertEquals("duke", name.get());
assertEquals(100, (int) age.get());
return null;
});
assertFalse(name.isBound());
assertFalse(age.isBound());
! // get
! ScopedValue.where(name, "duke").where(age, 100).get(() -> {
assertTrue(name.isBound());
assertTrue(age.isBound());
assertEquals("duke", name.get());
assertEquals(100, (int) age.get());
return null;
});
assertFalse(name.isBound());
assertFalse(age.isBound());
-
});
}
/**
* Test rebinding.
void testTwoBindings(ThreadFactory factory) throws Exception {
test(factory, () -> {
ScopedValue<String> name = ScopedValue.newInstance();
ScopedValue<Integer> age = ScopedValue.newInstance();
! // runWhere
! var carrier = ScopedValue.where(name, "duke").where(age, 100);
+ ScopedValue.runWhere(carrier, () -> {
assertTrue(name.isBound());
assertTrue(age.isBound());
assertEquals("duke", name.get());
assertEquals(100, (int) age.get());
});
assertFalse(name.isBound());
assertFalse(age.isBound());
! // callWhere
! ScopedValue.callWhere(carrier, () -> {
assertTrue(name.isBound());
assertTrue(age.isBound());
assertEquals("duke", name.get());
assertEquals(100, (int) age.get());
return null;
});
assertFalse(name.isBound());
assertFalse(age.isBound());
! // getWhere
! ScopedValue.getWhere(carrier, () -> {
assertTrue(name.isBound());
assertTrue(age.isBound());
assertEquals("duke", name.get());
assertEquals(100, (int) age.get());
return null;
});
assertFalse(name.isBound());
assertFalse(age.isBound());
});
}
/**
* Test rebinding.
@MethodSource("factories")
void testRebinding(ThreadFactory factory) throws Exception {
test(factory, () -> {
ScopedValue<String> name = ScopedValue.newInstance();
! // run
ScopedValue.runWhere(name, "duke", () -> {
assertTrue(name.isBound());
assertEquals("duke", name.get());
ScopedValue.runWhere(name, "duchess", () -> {
@MethodSource("factories")
void testRebinding(ThreadFactory factory) throws Exception {
test(factory, () -> {
ScopedValue<String> name = ScopedValue.newInstance();
! // runWhere
ScopedValue.runWhere(name, "duke", () -> {
assertTrue(name.isBound());
assertEquals("duke", name.get());
ScopedValue.runWhere(name, "duchess", () -> {
assertTrue(name.isBound());
assertEquals("duke", name.get());
});
assertFalse(name.isBound());
! // call
ScopedValue.callWhere(name, "duke", () -> {
assertTrue(name.isBound());
assertEquals("duke", name.get());
ScopedValue.callWhere(name, "duchess", () -> {
assertTrue(name.isBound());
assertEquals("duke", name.get());
});
assertFalse(name.isBound());
! // callWhere
ScopedValue.callWhere(name, "duke", () -> {
assertTrue(name.isBound());
assertEquals("duke", name.get());
ScopedValue.callWhere(name, "duchess", () -> {
assertEquals("duke", name.get());
return null;
});
assertFalse(name.isBound());
! // get
ScopedValue.getWhere(name, "duke", () -> {
assertTrue(name.isBound());
assertEquals("duke", name.get());
! ScopedValue.where(name, "duchess").get(() -> {
assertTrue(name.isBound());
assertEquals("duchess", name.get());
return null;
});
assertEquals("duke", name.get());
return null;
});
assertFalse(name.isBound());
! // getWhere
ScopedValue.getWhere(name, "duke", () -> {
assertTrue(name.isBound());
assertEquals("duke", name.get());
! ScopedValue.getWhere(name, "duchess", () -> {
assertTrue(name.isBound());
assertEquals("duchess", name.get());
return null;
});
@MethodSource("factories")
void testRebindingFromNull(ThreadFactory factory) throws Exception {
test(factory, () -> {
ScopedValue<String> name = ScopedValue.newInstance();
! // run
ScopedValue.runWhere(name, null, () -> {
assertTrue(name.isBound());
assertNull(name.get());
ScopedValue.runWhere(name, "duchess", () -> {
@MethodSource("factories")
void testRebindingFromNull(ThreadFactory factory) throws Exception {
test(factory, () -> {
ScopedValue<String> name = ScopedValue.newInstance();
! // runWhere
ScopedValue.runWhere(name, null, () -> {
assertTrue(name.isBound());
assertNull(name.get());
ScopedValue.runWhere(name, "duchess", () -> {
assertTrue(name.isBound());
assertNull(name.get());
});
assertFalse(name.isBound());
! // call
ScopedValue.callWhere(name, null, () -> {
assertTrue(name.isBound());
assertNull(name.get());
ScopedValue.callWhere(name, "duchess", () -> {
assertTrue(name.isBound());
assertNull(name.get());
});
assertFalse(name.isBound());
! // callWhere
ScopedValue.callWhere(name, null, () -> {
assertTrue(name.isBound());
assertNull(name.get());
ScopedValue.callWhere(name, "duchess", () -> {
@MethodSource("factories")
void testRebindingToNull(ThreadFactory factory) throws Exception {
test(factory, () -> {
ScopedValue<String> name = ScopedValue.newInstance();
! // run
ScopedValue.runWhere(name, "duke", () -> {
assertTrue(name.isBound());
assertEquals("duke", name.get());
ScopedValue.runWhere(name, null, () -> {
@MethodSource("factories")
void testRebindingToNull(ThreadFactory factory) throws Exception {
test(factory, () -> {
ScopedValue<String> name = ScopedValue.newInstance();
! // runWhere
ScopedValue.runWhere(name, "duke", () -> {
assertTrue(name.isBound());
assertEquals("duke", name.get());
ScopedValue.runWhere(name, null, () -> {
assertTrue(name.isBound());
assertEquals("duke", name.get());
});
assertFalse(name.isBound());
! // call
ScopedValue.callWhere(name, "duke", () -> {
assertTrue(name.isBound());
assertEquals("duke", name.get());
ScopedValue.callWhere(name, null, () -> {
assertTrue(name.isBound());
assertEquals("duke", name.get());
});
assertFalse(name.isBound());
! // callWhere
ScopedValue.callWhere(name, "duke", () -> {
assertTrue(name.isBound());
assertEquals("duke", name.get());
ScopedValue.callWhere(name, null, () -> {
assertEquals("duke", name.get());
return null;
});
assertFalse(name.isBound());
! // get
! ScopedValue.where(name, "duke").get(() -> {
assertTrue(name.isBound());
assertEquals("duke", name.get());
! ScopedValue.where(name, null).get(() -> {
assertTrue(name.isBound());
assertNull(name.get());
return null;
});
assertEquals("duke", name.get());
return null;
});
assertFalse(name.isBound());
! // getWhere
! ScopedValue.getWhere(name, "duke", () -> {
assertTrue(name.isBound());
assertEquals("duke", name.get());
! ScopedValue.getWhere(name, null, () -> {
assertTrue(name.isBound());
assertNull(name.get());
return null;
});
*/
@Test
void testNullPointerException() {
ScopedValue<String> name = ScopedValue.newInstance();
! assertThrows(NullPointerException.class, () -> ScopedValue.where(null, "value"));
! assertThrows(NullPointerException.class, () -> ScopedValue.runWhere(null, "value", () -> { }));
! assertThrows(NullPointerException.class, () -> ScopedValue.getWhere(null, "value", () -> null));
assertThrows(NullPointerException.class, () -> name.orElseThrow(null));
var carrier = ScopedValue.where(name, "duke");
! assertThrows(NullPointerException.class, () -> carrier.where(null, "value"));
assertThrows(NullPointerException.class, () -> carrier.get((ScopedValue<?>)null));
- assertThrows(NullPointerException.class, () -> carrier.get((Supplier<?>)null));
- assertThrows(NullPointerException.class, () -> carrier.run(null));
- assertThrows(NullPointerException.class, () -> carrier.call(null));
}
@FunctionalInterface
private interface ThrowingRunnable {
void run() throws Exception;
*/
@Test
void testNullPointerException() {
ScopedValue<String> name = ScopedValue.newInstance();
! assertThrows(NullPointerException.class, () -> ScopedValue.where(null, "duke"));
!
! assertThrows(NullPointerException.class, () -> ScopedValue.runWhere(null, "duke", () -> { }));
+ assertThrows(NullPointerException.class, () -> ScopedValue.runWhere(name, "duke", null));
+
+ assertThrows(NullPointerException.class, () -> ScopedValue.callWhere(null, "duke", () -> ""));
+ assertThrows(NullPointerException.class, () -> ScopedValue.callWhere(name, "duke", null));
+
+ assertThrows(NullPointerException.class, () -> ScopedValue.getWhere(null, "duke", () -> ""));
+ assertThrows(NullPointerException.class, () -> ScopedValue.getWhere(name, "duke", null));
assertThrows(NullPointerException.class, () -> name.orElseThrow(null));
var carrier = ScopedValue.where(name, "duke");
! assertThrows(NullPointerException.class, () -> carrier.where(null, "duke"));
assertThrows(NullPointerException.class, () -> carrier.get((ScopedValue<?>)null));
}
@FunctionalInterface
private interface ThrowingRunnable {
void run() throws Exception;
< prev index next >