From 3c1e93b7cb50d20abe08f1b95b8dc8d62ed4c38c Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Sun, 27 Nov 2022 21:11:39 +0100 Subject: feat: add cardinality interval abstraction --- .../cardinality/CardinalityIntervalTest.java | 122 +++++++++++++++++++++ .../cardinality/CardinalityIntervalsTest.java | 21 ++++ .../cardinality/EmptyCardinalityIntervalTest.java | 14 +++ .../cardinality/FiniteCardinalityIntervalTest.java | 20 ++++ .../cardinality/FiniteUpperCardinalityTest.java | 12 ++ .../cardinality/UpperCardinalitiesTest.java | 25 +++++ .../cardinality/UpperCardinalityTest.java | 110 +++++++++++++++++++ 7 files changed, 324 insertions(+) create mode 100644 subprojects/store/src/test/java/tools/refinery/store/model/representation/cardinality/CardinalityIntervalTest.java create mode 100644 subprojects/store/src/test/java/tools/refinery/store/model/representation/cardinality/CardinalityIntervalsTest.java create mode 100644 subprojects/store/src/test/java/tools/refinery/store/model/representation/cardinality/EmptyCardinalityIntervalTest.java create mode 100644 subprojects/store/src/test/java/tools/refinery/store/model/representation/cardinality/FiniteCardinalityIntervalTest.java create mode 100644 subprojects/store/src/test/java/tools/refinery/store/model/representation/cardinality/FiniteUpperCardinalityTest.java create mode 100644 subprojects/store/src/test/java/tools/refinery/store/model/representation/cardinality/UpperCardinalitiesTest.java create mode 100644 subprojects/store/src/test/java/tools/refinery/store/model/representation/cardinality/UpperCardinalityTest.java (limited to 'subprojects/store/src/test') diff --git a/subprojects/store/src/test/java/tools/refinery/store/model/representation/cardinality/CardinalityIntervalTest.java b/subprojects/store/src/test/java/tools/refinery/store/model/representation/cardinality/CardinalityIntervalTest.java new file mode 100644 index 00000000..8a39b9b5 --- /dev/null +++ b/subprojects/store/src/test/java/tools/refinery/store/model/representation/cardinality/CardinalityIntervalTest.java @@ -0,0 +1,122 @@ +package tools.refinery.store.model.representation.cardinality; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.stream.Stream; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static tools.refinery.store.model.representation.cardinality.CardinalityIntervals.*; + +class CardinalityIntervalTest { + @ParameterizedTest(name = "min({0}, {1}) == {2}") + @MethodSource + void minTest(CardinalityInterval a, CardinalityInterval b, CardinalityInterval expected) { + assertThat(a.min(b), equalTo(expected)); + } + + static Stream minTest() { + return Stream.of( + Arguments.of(atMost(1), atMost(1), atMost(1)), + Arguments.of(atMost(1), between(2, 3), atMost(1)), + Arguments.of(atMost(1), atLeast(2), atMost(1)), + Arguments.of(atMost(1), ERROR, ERROR), + Arguments.of(atLeast(1), atLeast(2), atLeast(1)), + Arguments.of(atLeast(1), ERROR, ERROR), + Arguments.of(ERROR, atLeast(2), ERROR), + Arguments.of(ERROR, ERROR, ERROR) + ); + } + + @ParameterizedTest(name = "max({0}, {1}) == {2}") + @MethodSource + void maxTest(CardinalityInterval a, CardinalityInterval b, CardinalityInterval expected) { + assertThat(a.max(b), equalTo(expected)); + } + + static Stream maxTest() { + return Stream.of( + Arguments.of(atMost(1), atMost(1), atMost(1)), + Arguments.of(atMost(1), between(2, 3), between(2, 3)), + Arguments.of(atMost(1), atLeast(2), atLeast(2)), + Arguments.of(atMost(1), ERROR, ERROR), + Arguments.of(atLeast(1), atLeast(2), atLeast(2)), + Arguments.of(atLeast(1), ERROR, ERROR), + Arguments.of(ERROR, atLeast(2), ERROR), + Arguments.of(ERROR, ERROR, ERROR) + ); + } + + @ParameterizedTest(name = "{0} + {1} == {2}") + @MethodSource + void addTest(CardinalityInterval a, CardinalityInterval b, CardinalityInterval expected) { + assertThat(a.add(b), equalTo(expected)); + } + + static Stream addTest() { + return Stream.of( + Arguments.of(atMost(1), atMost(1), atMost(2)), + Arguments.of(atMost(1), between(2, 3), between(2, 4)), + Arguments.of(atMost(1), atLeast(2), atLeast(2)), + Arguments.of(atMost(1), ERROR, ERROR), + Arguments.of(atLeast(1), atLeast(2), atLeast(3)), + Arguments.of(atLeast(1), ERROR, ERROR), + Arguments.of(ERROR, atLeast(2), ERROR), + Arguments.of(ERROR, ERROR, ERROR) + ); + } + + @ParameterizedTest(name = "{0} * {1} == {2}") + @MethodSource + void multiplyTest(CardinalityInterval a, CardinalityInterval b, CardinalityInterval expected) { + assertThat(a.multiply(b), equalTo(expected)); + } + + static Stream multiplyTest() { + return Stream.of( + Arguments.of(between(2, 3), between(4, 5), between(8, 15)), + Arguments.of(atLeast(2), between(4, 5), atLeast(8)), + Arguments.of(between(2, 3), atLeast(4), atLeast(8)), + Arguments.of(between(2, 3), ERROR, ERROR), + Arguments.of(ERROR, between(4, 5), ERROR), + Arguments.of(ERROR, ERROR, ERROR) + ); + } + + @ParameterizedTest(name = "{0} /\\ {1} == {2}") + @MethodSource + void meetTest(CardinalityInterval a, CardinalityInterval b, CardinalityInterval expected) { + assertThat(a.meet(b), equalTo(expected)); + } + + static Stream meetTest() { + return Stream.of( + Arguments.of(atMost(1), atMost(2), atMost(1)), + Arguments.of(atMost(2), between(1, 3), between(1, 2)), + Arguments.of(atMost(1), between(1, 3), exactly(1)), + Arguments.of(atMost(1), between(2, 3), ERROR), + Arguments.of(atMost(1), ERROR, ERROR), + Arguments.of(ERROR, atMost(1), ERROR), + Arguments.of(ERROR, ERROR, ERROR) + ); + } + + @ParameterizedTest(name = "{0} \\/ {1} == {2}") + @MethodSource + void joinTest(CardinalityInterval a, CardinalityInterval b, CardinalityInterval expected) { + assertThat(a.join(b), equalTo(expected)); + } + + static Stream joinTest() { + return Stream.of( + Arguments.of(atMost(1), atMost(2), atMost(2)), + Arguments.of(atMost(2), between(1, 3), atMost(3)), + Arguments.of(atMost(1), between(2, 3), atMost(3)), + Arguments.of(atMost(1), ERROR, atMost(1)), + Arguments.of(ERROR, atMost(1), atMost(1)), + Arguments.of(ERROR, ERROR, ERROR) + ); + } +} diff --git a/subprojects/store/src/test/java/tools/refinery/store/model/representation/cardinality/CardinalityIntervalsTest.java b/subprojects/store/src/test/java/tools/refinery/store/model/representation/cardinality/CardinalityIntervalsTest.java new file mode 100644 index 00000000..ef68a607 --- /dev/null +++ b/subprojects/store/src/test/java/tools/refinery/store/model/representation/cardinality/CardinalityIntervalsTest.java @@ -0,0 +1,21 @@ +package tools.refinery.store.model.representation.cardinality; + +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; + +class CardinalityIntervalsTest { + @Test + void betweenEmptyTest() { + var interval = CardinalityIntervals.between(2, 1); + assertThat(interval.isEmpty(), equalTo(true)); + } + + @Test + void betweenNegativeUpperBoundTest() { + var interval = CardinalityIntervals.between(0, -1); + assertThat(interval.upperBound(), equalTo(UpperCardinalities.UNBOUNDED)); + assertThat(interval.isEmpty(), equalTo(false)); + } +} diff --git a/subprojects/store/src/test/java/tools/refinery/store/model/representation/cardinality/EmptyCardinalityIntervalTest.java b/subprojects/store/src/test/java/tools/refinery/store/model/representation/cardinality/EmptyCardinalityIntervalTest.java new file mode 100644 index 00000000..41c884ec --- /dev/null +++ b/subprojects/store/src/test/java/tools/refinery/store/model/representation/cardinality/EmptyCardinalityIntervalTest.java @@ -0,0 +1,14 @@ +package tools.refinery.store.model.representation.cardinality; + +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.lessThan; + +class EmptyCardinalityIntervalTest { + @Test + void inconsistentBoundsTest() { + assertThat(CardinalityIntervals.ERROR.upperBound().compareToInt(CardinalityIntervals.ERROR.lowerBound()), + lessThan(0)); + } +} diff --git a/subprojects/store/src/test/java/tools/refinery/store/model/representation/cardinality/FiniteCardinalityIntervalTest.java b/subprojects/store/src/test/java/tools/refinery/store/model/representation/cardinality/FiniteCardinalityIntervalTest.java new file mode 100644 index 00000000..dfb37786 --- /dev/null +++ b/subprojects/store/src/test/java/tools/refinery/store/model/representation/cardinality/FiniteCardinalityIntervalTest.java @@ -0,0 +1,20 @@ +package tools.refinery.store.model.representation.cardinality; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +class FiniteCardinalityIntervalTest { + @Test + void invalidLowerBoundConstructorTest() { + assertThrows(IllegalArgumentException.class, () -> new NonEmptyCardinalityInterval(-1, + UpperCardinalities.UNBOUNDED)); + } + + @Test + void invalidUpperBoundConstructorTest() { + var upperCardinality = UpperCardinality.of(1); + assertThrows(IllegalArgumentException.class, () -> new NonEmptyCardinalityInterval(2, + upperCardinality)); + } +} diff --git a/subprojects/store/src/test/java/tools/refinery/store/model/representation/cardinality/FiniteUpperCardinalityTest.java b/subprojects/store/src/test/java/tools/refinery/store/model/representation/cardinality/FiniteUpperCardinalityTest.java new file mode 100644 index 00000000..3f0f7a4a --- /dev/null +++ b/subprojects/store/src/test/java/tools/refinery/store/model/representation/cardinality/FiniteUpperCardinalityTest.java @@ -0,0 +1,12 @@ +package tools.refinery.store.model.representation.cardinality; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +class FiniteUpperCardinalityTest { + @Test + void invalidConstructorTest() { + assertThrows(IllegalArgumentException.class, () -> new FiniteUpperCardinality(-1)); + } +} diff --git a/subprojects/store/src/test/java/tools/refinery/store/model/representation/cardinality/UpperCardinalitiesTest.java b/subprojects/store/src/test/java/tools/refinery/store/model/representation/cardinality/UpperCardinalitiesTest.java new file mode 100644 index 00000000..13171ae5 --- /dev/null +++ b/subprojects/store/src/test/java/tools/refinery/store/model/representation/cardinality/UpperCardinalitiesTest.java @@ -0,0 +1,25 @@ +package tools.refinery.store.model.representation.cardinality; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.instanceOf; + +class UpperCardinalitiesTest { + @ParameterizedTest + @ValueSource(ints = {0, 1, 255, 256, 1000, Integer.MAX_VALUE}) + void valueOfBoundedTest(int value) { + var upperCardinality = UpperCardinalities.valueOf(value); + assertThat(upperCardinality, instanceOf(FiniteUpperCardinality.class)); + assertThat(((FiniteUpperCardinality) upperCardinality).finiteUpperBound(), equalTo(value)); + } + + @Test + void valueOfUnboundedTest() { + var upperCardinality = UpperCardinalities.valueOf(-1); + assertThat(upperCardinality, instanceOf(UnboundedUpperCardinality.class)); + } +} diff --git a/subprojects/store/src/test/java/tools/refinery/store/model/representation/cardinality/UpperCardinalityTest.java b/subprojects/store/src/test/java/tools/refinery/store/model/representation/cardinality/UpperCardinalityTest.java new file mode 100644 index 00000000..f5763c2d --- /dev/null +++ b/subprojects/store/src/test/java/tools/refinery/store/model/representation/cardinality/UpperCardinalityTest.java @@ -0,0 +1,110 @@ +package tools.refinery.store.model.representation.cardinality; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.stream.Stream; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; + +class UpperCardinalityTest { + @ParameterizedTest(name = "min({0}, {1}) == {2}") + @MethodSource + void minTest(UpperCardinality a, UpperCardinality b, UpperCardinality expected) { + assertThat(a.min(b), equalTo(expected)); + } + + static Stream minTest() { + return Stream.of( + Arguments.of(UpperCardinality.of(0), UpperCardinality.of(0), UpperCardinality.of(0)), + Arguments.of(UpperCardinality.of(0), UpperCardinality.of(1), UpperCardinality.of(0)), + Arguments.of(UpperCardinality.of(1), UpperCardinality.of(0), UpperCardinality.of(0)), + Arguments.of(UpperCardinality.of(0), UpperCardinalities.UNBOUNDED, UpperCardinality.of(0)), + Arguments.of(UpperCardinalities.UNBOUNDED, UpperCardinality.of(0), UpperCardinality.of(0)), + Arguments.of(UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED) + ); + } + + @ParameterizedTest(name = "max({0}, {1}) == {2}") + @MethodSource + void maxTest(UpperCardinality a, UpperCardinality b, UpperCardinality expected) { + assertThat(a.max(b), equalTo(expected)); + } + + static Stream maxTest() { + return Stream.of( + Arguments.of(UpperCardinality.of(0), UpperCardinality.of(0), UpperCardinality.of(0)), + Arguments.of(UpperCardinality.of(0), UpperCardinality.of(1), UpperCardinality.of(1)), + Arguments.of(UpperCardinality.of(1), UpperCardinality.of(0), UpperCardinality.of(1)), + Arguments.of(UpperCardinality.of(0), UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED), + Arguments.of(UpperCardinalities.UNBOUNDED, UpperCardinality.of(0), UpperCardinalities.UNBOUNDED), + Arguments.of(UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED) + ); + } + + @ParameterizedTest(name = "{0} + {1} == {2}") + @MethodSource + void addTest(UpperCardinality a, UpperCardinality b, UpperCardinality expected) { + assertThat(a.add(b), equalTo(expected)); + } + + static Stream addTest() { + return Stream.of( + Arguments.of(UpperCardinality.of(2), UpperCardinality.of(3), UpperCardinality.of(5)), + Arguments.of(UpperCardinality.of(2), UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED), + Arguments.of(UpperCardinalities.UNBOUNDED, UpperCardinality.of(2), UpperCardinalities.UNBOUNDED), + Arguments.of(UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED) + ); + } + + @ParameterizedTest(name = "{0} * {1} == {2}") + @MethodSource + void multiplyTest(UpperCardinality a, UpperCardinality b, UpperCardinality expected) { + assertThat(a.multiply(b), equalTo(expected)); + } + + static Stream multiplyTest() { + return Stream.of( + Arguments.of(UpperCardinality.of(2), UpperCardinality.of(3), UpperCardinality.of(6)), + Arguments.of(UpperCardinality.of(2), UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED), + Arguments.of(UpperCardinalities.UNBOUNDED, UpperCardinality.of(2), UpperCardinalities.UNBOUNDED), + Arguments.of(UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED) + ); + } + + @ParameterizedTest(name = "{0}.compareTo({1}) == {2}") + @MethodSource + void compareToTest(UpperCardinality a, UpperCardinality b, int expected) { + assertThat(a.compareTo(b), equalTo(expected)); + } + + static Stream compareToTest() { + return Stream.of( + Arguments.of(UpperCardinality.of(0), UpperCardinality.of(0), 0), + Arguments.of(UpperCardinality.of(0), UpperCardinality.of(1), -1), + Arguments.of(UpperCardinality.of(1), UpperCardinality.of(0), 1), + Arguments.of(UpperCardinality.of(0), UpperCardinalities.UNBOUNDED, -1), + Arguments.of(UpperCardinalities.UNBOUNDED, UpperCardinality.of(0), 1), + Arguments.of(UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED, 0) + ); + } + + @ParameterizedTest(name = "{0}.compareToInt({1}) == {2}") + @MethodSource + void compareToIntTest(UpperCardinality a, int b, int expected) { + assertThat(a.compareToInt(b), equalTo(expected)); + } + + static Stream compareToIntTest() { + return Stream.of( + Arguments.of(UpperCardinality.of(3), -1, 1), + Arguments.of(UpperCardinality.of(3), 2, 1), + Arguments.of(UpperCardinality.of(3), 3, 0), + Arguments.of(UpperCardinality.of(3), 4, -1), + Arguments.of(UpperCardinalities.UNBOUNDED, -1, 1), + Arguments.of(UpperCardinalities.UNBOUNDED, 3, 1) + ); + } +} -- cgit v1.2.3-54-g00ecf