Closed rpolton closed 2 years ago
There is a TrialsApi.stream
method that takes a CaseFactory
that allows this to be done (mapping to Instant
also works off Trials.longs
) - but it would be nice to have parity between Trials.instants
and Trials.integers
/ Trials.characters
.
Released in version 1.4.6, GIT SHA: 13474b963286baa851d79771abd17a897fb40d13
Evidence made using JShell running against Americium version 1.4.6 follows...
Code:
import com.sageserpent.americium.java.Trials;
import com.sageserpent.americium.java.TrialsApi;
import java.time.Instant;
import static org.junit.Assert.assertThrows;
final TrialsApi api = Trials.api();
final Instant shrinkageTarget = Instant.now();
System.out.println("Shrinkage target inside the interval:");
assertThrows(RuntimeException.class, () -> api.instants(shrinkageTarget.minusSeconds(60 * 100), shrinkageTarget.plusSeconds(60 * 1000), shrinkageTarget).withLimit(10).supplyTo(caze -> {
System.out.println(caze);
throw new RuntimeException();
}));
System.out.println("Shrinkage target at high end of interval:");
assertThrows(RuntimeException.class, () -> api.instants(shrinkageTarget.minusSeconds(60 * 100), shrinkageTarget, shrinkageTarget).withLimit(10).supplyTo(caze -> {
System.out.println(caze);
throw new RuntimeException();
}));
System.out.println("Shrinkage target at low end of interval:");
assertThrows(RuntimeException.class, () -> api.instants(shrinkageTarget, shrinkageTarget.plusSeconds(60 * 1000), shrinkageTarget).withLimit(10).supplyTo(caze -> {
System.out.println(caze);
throw new RuntimeException();
}));
System.out.println("Shrinkage target is implicitly defined at the epoch.");
assertThrows(RuntimeException.class, () -> api.instants(Instant.EPOCH.minusSeconds(2), Instant.EPOCH.plusSeconds(1)).withLimit(10).supplyTo(caze -> {
System.out.println(caze);
throw new RuntimeException();
}));
Output:
import com.sageserpent.americium.java.Trials
import com.sageserpent.americium.java.TrialsApi
import java.time.Instant
static import org.junit.Assert.assertThrows
field TrialsApi api = com.sageserpent.americium.TrialsApis$$anon$1@5f8ed237
field Instant shrinkageTarget = 2022-06-19T12:05:39.942376Z
System.out.println("Shrinkage target inside the interval:")
Shrinkage target inside the interval:
assertThrows(RuntimeException.class, () -> api.instants(shrinkageTarget.minusSeconds(60 * 100), shrinkageTarget.plusSeconds(60 * 1000), shrinkageTarget).withLimit(10).supplyTo(caze -> {
System.out.println(caze);
throw new RuntimeException();
})) = Trial exception with underlying cause:
java.lang.RuntimeException
Case:
2022-06-19T12:05:39.942Z
Reproduce via Java property:
trials.recipeHash=73b6b673871eb35b932019ab78b9262d
Reproduce via `withLimits` using recipe:
[
{
"FactoryInputOf" : {
"input" : 1655640339942
}
}
]
2022-06-19T22:59:59.175Z
2022-06-19T11:14:52.731Z
2022-06-19T11:46:14.415Z
2022-06-19T12:01:57.632Z
2022-06-19T12:04:29.799Z
2022-06-19T12:04:31.662Z
2022-06-19T12:05:09.203Z
2022-06-19T12:05:18.963Z
2022-06-19T12:05:37.356Z
2022-06-19T12:05:37.676Z
2022-06-19T12:05:38.582Z
2022-06-19T12:05:39.013Z
2022-06-19T12:05:39.772Z
2022-06-19T12:05:39.934Z
2022-06-19T12:05:39.941Z
2022-06-19T12:05:39.942Z
System.out.println("Shrinkage target at high end of interval:")
Shrinkage target at high end of interval:
assertThrows(RuntimeException.class, () -> api.instants(shrinkageTarget.minusSeconds(60 * 100), shrinkageTarget, shrinkageTarget).withLimit(10).supplyTo(caze -> {
System.out.println(caze);
throw new RuntimeException();
})) = Trial exception with underlying cause:
java.lang.RuntimeException
Case:
2022-06-19T12:05:39.942Z
Reproduce via Java property:
trials.recipeHash=73b6b673871eb35b932019ab78b9262d
Reproduce via `withLimits` using recipe:
[
{
"FactoryInputOf" : {
"input" : 1655640339942
}
}
]
2022-06-19T11:34:14.418Z
2022-06-19T12:05:12.870Z
2022-06-19T12:05:34.264Z
2022-06-19T12:05:38.257Z
2022-06-19T12:05:39.375Z
2022-06-19T12:05:39.676Z
2022-06-19T12:05:39.752Z
2022-06-19T12:05:39.840Z
2022-06-19T12:05:39.877Z
2022-06-19T12:05:39.909Z
2022-06-19T12:05:39.936Z
2022-06-19T12:05:39.937Z
2022-06-19T12:05:39.941Z
2022-06-19T12:05:39.942Z
System.out.println("Shrinkage target at low end of interval:")
Shrinkage target at low end of interval:
assertThrows(RuntimeException.class, () -> api.instants(shrinkageTarget, shrinkageTarget.plusSeconds(60 * 1000), shrinkageTarget).withLimit(10).supplyTo(caze -> {
System.out.println(caze);
throw new RuntimeException();
})) = Trial exception with underlying cause:
java.lang.RuntimeException
Case:
2022-06-19T12:05:39.942Z
Reproduce via Java property:
trials.recipeHash=73b6b673871eb35b932019ab78b9262d
Reproduce via `withLimits` using recipe:
[
{
"FactoryInputOf" : {
"input" : 1655640339942
}
}
]
2022-06-19T23:31:24.699Z
2022-06-19T12:50:24.295Z
2022-06-19T12:45:09.018Z
2022-06-19T12:17:58.667Z
2022-06-19T12:12:50.178Z
2022-06-19T12:08:32.126Z
2022-06-19T12:07:12.415Z
2022-06-19T12:06:47.053Z
2022-06-19T12:06:27.638Z
2022-06-19T12:06:07.044Z
2022-06-19T12:05:48.878Z
2022-06-19T12:05:47.060Z
2022-06-19T12:05:40.269Z
2022-06-19T12:05:39.984Z
2022-06-19T12:05:39.961Z
2022-06-19T12:05:39.949Z
2022-06-19T12:05:39.945Z
2022-06-19T12:05:39.942Z
System.out.println("Shrinkage target is implicitly defined at the epoch.")
Shrinkage target is implicitly defined at the epoch.
assertThrows(RuntimeException.class, () -> api.instants(Instant.EPOCH.minusSeconds(2), Instant.EPOCH.plusSeconds(1)).withLimit(10).supplyTo(caze -> {
System.out.println(caze);
throw new RuntimeException();
})) = Trial exception with underlying cause:
java.lang.RuntimeException
Case:
1970-01-01T00:00:00Z
Reproduce via Java property:
trials.recipeHash=ebab32843e515600e60954a197da9391
Reproduce via `withLimits` using recipe:
[
{
"FactoryInputOf" : {
"input" : 0
}
}
]
1970-01-01T00:00:00.057Z
1969-12-31T23:59:59.945Z
1969-12-31T23:59:59.951Z
1969-12-31T23:59:59.997Z
1969-12-31T23:59:59.999Z
1970-01-01T00:00:00Z
Similarly to integers(), longs() etc, instants() should provide an overloaded factory that accepts a lower bound and an upper bound. Instant MAX defines the maximum supported Instant, '1000000000-12-31T23:59:59.999999999Z' and this is far in the future. The issue is that the standard DateTimeFormatter renders any year larger than 9999 with a '+' prefix which is potentially unexpected. In order to avoid having to code for the year 10000 (I'd like to think that Java will have been updated to handle 5-digit years consistently by the time we approach that point) it would be better to restrict the range of possible values in the factory method. The application of a filter() after construction works sometimes but often simply produces an empty stream -> Precondition violation in Trials.