summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorAdrien Hopkins <adrien.p.hopkins@gmail.com>2025-06-15 19:42:01 -0500
committerAdrien Hopkins <adrien.p.hopkins@gmail.com>2025-06-15 19:42:01 -0500
commit2fdbc084fd1d78f0b7633db34460b1195de264f3 (patch)
tree4c908950d9b049394f8160b8159b498aec586ecc /src/test
parented53492243ecad8d975401a97f5b634328ad2c71 (diff)
parentbccb5b5e3452421c81c1fb58f83391ba6584807c (diff)
Merge release 1.0.0 into stable branchHEADstable
See the tag 'v1.0.0' or the changelog for more information about this release.
Diffstat (limited to 'src/test')
-rw-r--r--src/test/java/sevenUnits/unit/MultiUnitTest.java110
-rw-r--r--src/test/java/sevenUnits/unit/UnitDatabaseTest.java324
-rw-r--r--src/test/java/sevenUnits/unit/UnitTest.java135
-rw-r--r--src/test/java/sevenUnits/unit/UnitValueTest.java240
-rw-r--r--src/test/java/sevenUnits/utils/ConditionalExistenceCollectionsTest.java63
-rw-r--r--src/test/java/sevenUnits/utils/ExpressionParserTest.java91
-rw-r--r--src/test/java/sevenUnits/utils/NameSymbolTest.java108
-rw-r--r--src/test/java/sevenUnits/utils/ObjectProductTest.java10
-rw-r--r--src/test/java/sevenUnits/utils/SemanticVersionTest.java93
-rw-r--r--src/test/java/sevenUnits/utils/UncertainDoubleTest.java39
-rw-r--r--src/test/java/sevenUnitsGUI/I18nTest.java95
-rw-r--r--src/test/java/sevenUnitsGUI/PrefixRepetitionTest.java20
-rw-r--r--src/test/java/sevenUnitsGUI/PrefixSearchTest.java36
-rw-r--r--src/test/java/sevenUnitsGUI/PresenterTest.java159
-rw-r--r--src/test/java/sevenUnitsGUI/RoundingTest.java35
-rw-r--r--src/test/java/sevenUnitsGUI/TabbedViewTest.java22
16 files changed, 1023 insertions, 557 deletions
diff --git a/src/test/java/sevenUnits/unit/MultiUnitTest.java b/src/test/java/sevenUnits/unit/MultiUnitTest.java
deleted file mode 100644
index 949a1f1..0000000
--- a/src/test/java/sevenUnits/unit/MultiUnitTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/**
- * Copyright (C) 2020 Adrien Hopkins
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-package sevenUnits.unit;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Random;
-import java.util.concurrent.ThreadLocalRandom;
-
-import org.junit.jupiter.api.Test;
-
-/**
- * Tests related to the {@code MultiUnit}.
- *
- * @since 2020-10-03
- */
-class MultiUnitTest {
-
- /**
- * Ensures that the {@code MultiUnit} can convert properly.
- */
- @Test
- final void testConvert() {
- final Random rng = ThreadLocalRandom.current();
- final MultiUnit footInch = MultiUnit.of(BritishImperial.Length.FOOT,
- BritishImperial.Length.INCH);
-
- assertEquals(1702.0,
- footInch.convertTo(Metric.METRE.withPrefix(Metric.MILLI),
- Arrays.asList(5.0, 7.0)),
- 1.0);
-
- for (int i = 0; i < 1000; i++) {
- final double feet = rng.nextInt(1000);
- final double inches = rng.nextDouble() * 12;
- final double millimetres = feet * 304.8 + inches * 25.4;
-
- final List<Double> feetAndInches = Metric.METRE
- .withPrefix(Metric.MILLI).convertTo(footInch, millimetres);
- assertEquals(feet, feetAndInches.get(0), 1e-10);
- assertEquals(inches, feetAndInches.get(1), 1e-10);
- }
- }
-
- /**
- * Test method for {@link sevenUnits.unit.MultiUnit#convertFromBase(double)}.
- */
- @Test
- final void testConvertFromBase() {
- final Random rng = ThreadLocalRandom.current();
- final MultiUnit footInch = MultiUnit.of(BritishImperial.Length.FOOT,
- BritishImperial.Length.INCH);
-
- // 1.7 m =~ 5' + 7"
- final List<Double> values = footInch.convertFromBase(1.7018);
-
- assertEquals(5, values.get(0));
- assertEquals(7, values.get(1), 1e-12);
-
- for (int i = 0; i < 1000; i++) {
- final double feet = rng.nextInt(1000);
- final double inches = rng.nextDouble() * 12;
- final double metres = feet * 0.3048 + inches * 0.0254;
-
- final List<Double> feetAndInches = footInch.convertFromBase(metres);
- assertEquals(feet, feetAndInches.get(0), 1e-10);
- assertEquals(inches, feetAndInches.get(1), 1e-10);
- }
- }
-
- /**
- * Test method for
- * {@link sevenUnits.unit.MultiUnit#convertToBase(java.util.List)}.
- */
- @Test
- final void testConvertToBase() {
- final Random rng = ThreadLocalRandom.current();
- final MultiUnit footInch = MultiUnit.of(BritishImperial.Length.FOOT,
- BritishImperial.Length.INCH);
-
- // 1.7 m =~ 5' + 7"
- assertEquals(1.7018, footInch.convertToBase(Arrays.asList(5.0, 7.0)),
- 1e-12);
-
- for (int i = 0; i < 1000; i++) {
- final double feet = rng.nextInt(1000);
- final double inches = rng.nextDouble() * 12;
- final double metres = feet * 0.3048 + inches * 0.0254;
-
- assertEquals(metres,
- footInch.convertToBase(Arrays.asList(feet, inches)), 1e-12);
- }
- }
-}
diff --git a/src/test/java/sevenUnits/unit/UnitDatabaseTest.java b/src/test/java/sevenUnits/unit/UnitDatabaseTest.java
index 9d650f0..3d6d663 100644
--- a/src/test/java/sevenUnits/unit/UnitDatabaseTest.java
+++ b/src/test/java/sevenUnits/unit/UnitDatabaseTest.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2019 Adrien Hopkins
+ * Copyright (C) 2019, 2021, 2022, 2024, 2025 Adrien Hopkins
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -23,20 +23,21 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import java.io.IOException;
-import java.io.InputStream;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Set;
+import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource;
import sevenUnits.utils.NameSymbol;
@@ -45,7 +46,7 @@ import sevenUnits.utils.UncertainDouble;
/**
* A test for the {@link UnitDatabase} class. This is NOT part of this program's
* public API.
- *
+ *
* @author Adrien Hopkins
* @since 2019-04-14
* @since v0.2.0
@@ -57,8 +58,8 @@ class UnitDatabaseTest {
private V value;
/**
- *
* @since 2021-10-07
+ * @since v0.3.2
*/
public SimpleEntry(K key, V value) {
this.key = key;
@@ -94,7 +95,7 @@ class UnitDatabaseTest {
@Override
public V setValue(V value) {
- final V oldValue = this.value;
+ final var oldValue = this.value;
this.value = value;
return oldValue;
}
@@ -135,6 +136,7 @@ class UnitDatabaseTest {
* @param value value in entry
* @return entry
* @since 2021-10-07
+ * @since v0.3.2
*/
private static <K, V> Map.Entry<K, V> entry(K key, V value) {
return new SimpleEntry<>(key, value);
@@ -146,14 +148,18 @@ class UnitDatabaseTest {
*
* @param loadTo database to load to
* @param path path of file to load
+ * @return exceptions returned by file loading
* @since 2021-10-04
+ * @since v0.3.2
*/
- private static void loadDimensionFile(UnitDatabase loadTo, String path) {
- try (final InputStream testFile = UnitDatabaseTest.class
+ private static List<LoadingException> loadDimensionFile(UnitDatabase loadTo,
+ String path) {
+ try (final var testFile = UnitDatabaseTest.class
.getResourceAsStream(path)) {
- loadTo.loadDimensionsFromStream(testFile);
+ return loadTo.loadDimensionsFromStream(testFile);
} catch (final IOException e) {
fail(e.getClass() + " occurred upon loading file \"" + path + "\".");
+ return Collections.emptyList();
}
}
@@ -163,26 +169,89 @@ class UnitDatabaseTest {
*
* @param loadTo database to load to
* @param path path of file to load
+ * @return exceptions returned by file loading
* @since 2021-09-22
+ * @since v0.3.2
*/
- private static void loadUnitsFile(UnitDatabase loadTo, String path) {
- try (final InputStream testFile = UnitDatabaseTest.class
+ private static List<LoadingException> loadUnitsFile(UnitDatabase loadTo,
+ String path) {
+ try (final var testFile = UnitDatabaseTest.class
.getResourceAsStream(path)) {
- loadTo.loadUnitsFromStream(testFile);
+ return loadTo.loadUnitsFromStream(testFile);
} catch (final IOException e) {
fail(e.getClass() + " occurred upon loading file \"" + path + "\".");
+ return Collections.emptyList();
}
}
+ private static final Stream<Arguments> testEvaluateExpressionInvalid() {
+ return Stream.of(Arguments.of("K^K"), Arguments.of("1 + K"));
+ }
+
+ private static final Stream<Arguments> testEvaluateExpressionValid() {
+ final var uncertainTwoThirds = UncertainDouble.of(2.0, 1.0)
+ .dividedBy(UncertainDouble.of(3.0, 1.0));
+ return Stream.of(
+ Arguments.of("J + (2 * 3) J + (20 / 4) J",
+ LinearUnitValue.of(J,
+ UncertainDouble.of(12, Math.sqrt(14.625)))),
+ Arguments.of("J + 2 * 3 * J + 20 / 4 * J",
+ LinearUnitValue.of(J,
+ UncertainDouble.of(12, Math.sqrt(14.625)))),
+ Arguments.of("J - -1 * J",
+ LinearUnitValue.of(J, UncertainDouble.of(2, 1))),
+ Arguments.of("K^2",
+ LinearUnitValue.of(K.times(K), UncertainDouble.of(1, 0))),
+ Arguments.of("2 J / 3 J",
+ LinearUnitValue.of(J.dividedBy(J), uncertainTwoThirds)));
+ }
+
+ private static final Stream<Arguments> testFormatExpression() {
+ return Stream.of(Arguments.of("1*2", "1 * 2"),
+ Arguments.of("1/2", "1 / 2"), Arguments.of("1|2", "1 | 2"),
+ Arguments.of("1^2", "1 ^ 2"), Arguments.of("1 * 2", "1 * 2"),
+ Arguments.of("+1", "+1"), Arguments.of("-1", "-1"),
+ Arguments.of("1.1e+5", "1.1e+5"),
+ Arguments.of("1.25e-5", "1.25e-5"));
+ }
+
+ /**
+ * Tests expressions that are valid to the parser, but semantically invalid
+ * (e.g. adding different dimensions)
+ *
+ * @param expression expression to test - should throw
+ * {@link IllegalArgumentException}
+ */
+ @ParameterizedTest
+ @MethodSource
+ public void testEvaluateExpressionInvalid(String expression) {
+ final var database = new UnitDatabase();
+
+ database.addUnit("J", J);
+ database.addUnit("K", K);
+
+ database.addPrefix("A", A);
+ database.addPrefix("B", B);
+ database.addPrefix("C", C);
+
+ assertThrows(IllegalArgumentException.class,
+ () -> database.getUnitFromExpression(expression));
+ assertThrows(IllegalArgumentException.class,
+ () -> database.evaluateUnitExpression(expression));
+ }
+
/**
* A test for the {@link UnitDatabase#evaluateUnitExpression(String)}
* function. Simple because the expression parser has its own test.
- *
+ *
* @since 2021-09-27
+ * @since v0.3.2
*/
- @Test
- public void testEvaluateExpression() {
- final UnitDatabase database = new UnitDatabase();
+ @ParameterizedTest
+ @MethodSource
+ public void testEvaluateExpressionValid(String expression,
+ LinearUnitValue expected) {
+ final var database = new UnitDatabase();
database.addUnit("J", J);
database.addUnit("K", K);
@@ -191,27 +260,30 @@ class UnitDatabaseTest {
database.addPrefix("B", B);
database.addPrefix("C", C);
- final LinearUnitValue expected = LinearUnitValue.of(J,
- UncertainDouble.of(12, Math.sqrt(14.625)));
- // note: units are exact, each number has an uncertainty of 1
- final LinearUnitValue actual = database
- .evaluateUnitExpression("J + (2 * 3) J + (20 / 4) J");
+ final var actual = database.evaluateUnitExpression(expression);
assertEquals(expected, actual);
- // check that negation works properly
- assertEquals(2,
- database.evaluateUnitExpression("J - -1 * J").getValueExact());
+ final var expectedU = expected.getUnit().times(expected.getValueExact());
+ final var actualU = database.getUnitFromExpression(expression);
+ assertEquals(expectedU, actualU);
+ }
+
+ @ParameterizedTest
+ @MethodSource
+ public void testFormatExpression(String expression, String expected) {
+ assertEquals(expected, UnitDatabase.formatExpression(expression));
}
/**
* Test for {@link UnitDatabase#getUnit}, {@link UnitDatabase#getLinearUnit}
* and {@link UnitDatabase#getLinearUnitValue}.
- *
+ *
* @since 2021-10-07
+ * @since v0.3.2
*/
@Test
public void testGetUnit() {
- final UnitDatabase database = new UnitDatabase();
+ final var database = new UnitDatabase();
database.addUnit("m", Metric.METRE);
database.addUnit("meter", Metric.METRE);
@@ -239,14 +311,15 @@ class UnitDatabaseTest {
/**
* Confirms that operations that shouldn't function for infinite databases
* throw an {@code IllegalStateException}.
- *
+ *
* @since 2019-05-03
+ * @since v0.3.0
*/
// @Test
// @Timeout(value = 1, unit = TimeUnit.SECONDS)
public void testInfiniteSetExceptions() {
// load units
- final UnitDatabase infiniteDatabase = new UnitDatabase();
+ final var infiniteDatabase = new UnitDatabase();
infiniteDatabase.addUnit("J", J);
infiniteDatabase.addUnit("K", K);
@@ -255,9 +328,8 @@ class UnitDatabaseTest {
infiniteDatabase.addPrefix("B", B);
infiniteDatabase.addPrefix("C", C);
- final Set<Entry<String, Unit>> entrySet = infiniteDatabase.unitMap()
- .entrySet();
- final Set<String> keySet = infiniteDatabase.unitMap().keySet();
+ final var entrySet = infiniteDatabase.unitMap().entrySet();
+ final var keySet = infiniteDatabase.unitMap().keySet();
assertThrows(IllegalStateException.class, () -> entrySet.toArray());
assertThrows(IllegalStateException.class, () -> keySet.toArray());
}
@@ -267,18 +339,20 @@ class UnitDatabaseTest {
*
* @param num which file to test
* @since 2021-10-04
+ * @since v0.3.2
*/
@ParameterizedTest
@ValueSource(ints = { 1, 2, 3 })
public void testLoadingInvalidDimensionFile(int num) {
- final UnitDatabase database = new UnitDatabase();
+ final var database = new UnitDatabase();
database.addDimension("LENGTH", Metric.Dimensions.LENGTH);
database.addDimension("MASS", Metric.Dimensions.MASS);
database.addDimension("TIME", Metric.Dimensions.TIME);
- final String filename = String.format("/test-dimensionfile-invalid%d.txt",
+ final var filename = String.format("/test-dimensionfile-invalid%d.txt",
num);
- final RuntimeException e = assertThrows(RuntimeException.class,
- () -> loadDimensionFile(database, filename));
+ final var errs = loadDimensionFile(database, filename);
+ assertFalse(errs.isEmpty(), "no error from invalid file " + filename);
+ final var e = errs.get(0).problem();
assertTrue(e instanceof IllegalArgumentException
|| e instanceof NoSuchElementException);
}
@@ -288,27 +362,29 @@ class UnitDatabaseTest {
*
* @param num which file to test
* @since 2021-09-27
+ * @since v0.3.2
*/
@ParameterizedTest
@ValueSource(ints = { 1, 2, 3, 4, 5 })
public void testLoadingInvalidUnitFile(int num) {
- final UnitDatabase database = new UnitDatabase();
- final String filename = String.format("/test-unitsfile-invalid%d.txt",
- num);
- final RuntimeException e = assertThrows(RuntimeException.class,
- () -> loadUnitsFile(database, filename));
+ final var database = new UnitDatabase();
+ final var filename = String.format("/test-unitsfile-invalid%d.txt", num);
+ final var errs = loadUnitsFile(database, filename);
+ assertFalse(errs.isEmpty(), "no error from invalid file " + filename);
+ final var e = errs.get(0).problem();
assertTrue(e instanceof IllegalArgumentException
|| e instanceof NoSuchElementException);
}
/**
* Tests loading a valid dimension-file with some derived dimensions.
- *
+ *
* @since 2021-10-04
+ * @since v0.3.2
*/
@Test
public void testLoadingValidDimensions() {
- final UnitDatabase database = new UnitDatabase();
+ final var database = new UnitDatabase();
database.addDimension("LENGTH", Metric.Dimensions.LENGTH);
database.addDimension("MASS", Metric.Dimensions.MASS);
database.addDimension("TIME", Metric.Dimensions.TIME);
@@ -321,27 +397,33 @@ class UnitDatabaseTest {
/**
* Tests loading a valid unitfile with some prefixes and no units.
- *
+ *
* @since 2021-09-22
+ * @since v0.3.2
*/
@Test
public void testLoadingValidPrefixes() {
- final UnitDatabase database = new UnitDatabase();
+ final var database = new UnitDatabase();
loadUnitsFile(database, "/test-unitsfile-valid2.txt");
assertEquals(7, database.getPrefix("A").getMultiplier());
assertEquals(11, database.getPrefix("B").getMultiplier());
assertEquals(13, database.getPrefix("C").getMultiplier());
+
+ // test invalid prefixes
+ assertThrows(NoSuchElementException.class,
+ () -> database.getPrefix("N/A"));
}
/**
* Tests loading a valid unitfile with some units and preloaded prefixes
- *
+ *
* @since 2021-09-22
+ * @since v0.3.2
*/
@Test
public void testLoadingValidUnits() {
- final UnitDatabase database = new UnitDatabase();
+ final var database = new UnitDatabase();
database.addUnit("U", U);
database.addUnit("V", V);
@@ -357,21 +439,21 @@ class UnitDatabaseTest {
final Unit expected1 = ((LinearUnit) U).withPrefix(A).withPrefix(B)
.withPrefix(C);
- final Unit actual1 = database.getUnit("test1");
+ final var actual1 = database.getUnit("test1");
assertEquals(expected1, actual1);
final Unit expected2 = ((LinearUnit) W).withPrefix(B)
.times(((LinearUnit) V).withPrefix(C));
- final Unit actual2 = database.getUnit("test2");
+ final var actual2 = database.getUnit("test2");
assertEquals(expected2, actual2);
final Unit expected3 = ((LinearUnit) U)
.times(A.getMultiplier() + C.getMultiplier() - B.getMultiplier());
- final Unit actual3 = database.getUnit("test3");
+ final var actual3 = database.getUnit("test3");
assertEquals(expected3, actual3);
- final UnitValue expected4 = UnitValue.of(U, 1);
- final UnitValue actual4 = database
+ final var expected4 = UnitValue.of(U, 1);
+ final var actual4 = database
.evaluateUnitExpression("-5 * U + -3 * U + 12 * U - 3 * U")
.asUnitValue();
assertEquals(expected4, actual4);
@@ -382,21 +464,21 @@ class UnitDatabaseTest {
/**
* Tests the iterator of the prefixless unit map. These tests are simple, as
* the unit map iterator is simple.
- *
+ *
* @since 2021-10-07
+ * @since v0.3.2
*/
@Test
public void testPrefixedUnitMapIterator() {
- final UnitDatabase database1 = new UnitDatabase();
+ final var database1 = new UnitDatabase();
database1.addUnit("U", U);
database1.addUnit("V", V);
database1.addUnit("W", W);
- final Map<String, Unit> map1 = database1.unitMap();
- final Iterator<String> keyIterator1 = map1.keySet().iterator();
- final Iterator<Map.Entry<String, Unit>> entryIterator1 = map1.entrySet()
- .iterator();
+ final var map1 = database1.unitMap();
+ final var keyIterator1 = map1.keySet().iterator();
+ final var entryIterator1 = map1.entrySet().iterator();
final Set<String> expectedKeys = Set.of("U", "V", "W");
final Set<String> actualKeys = new HashSet<>();
@@ -418,13 +500,13 @@ class UnitDatabaseTest {
/**
* Test that prefixes correctly apply to units.
- *
+ *
* @since 2019-04-14
* @since v0.2.0
*/
@Test
public void testPrefixes() {
- final UnitDatabase database = new UnitDatabase();
+ final var database = new UnitDatabase();
database.addUnit("U", U);
database.addUnit("V", V);
@@ -439,29 +521,28 @@ class UnitDatabaseTest {
assertEquals(expected, database.getPrefixesFromName("ABCU"));
// get the product
- final Unit abcuNonlinear = database.getUnit("ABCU");
+ final var abcuNonlinear = database.getUnit("ABCU");
assert abcuNonlinear instanceof LinearUnit;
- final LinearUnit abcu = (LinearUnit) abcuNonlinear;
+ final var abcu = (LinearUnit) abcuNonlinear;
assertEquals(A.getMultiplier() * B.getMultiplier() * C.getMultiplier(),
abcu.getConversionFactor(), 1e-15);
}
/**
* Tests the functionnalites of the prefixless unit map.
- *
+ *
* <p>
* The map should be an auto-updating view of the units in the database.
* </p>
- *
+ *
* @since 2019-04-14
* @since v0.2.0
*/
@Test
public void testPrefixlessUnitMap() {
- final UnitDatabase database = new UnitDatabase();
- final Map<String, Unit> prefixlessUnits = database
- .unitMapPrefixless(true);
+ final var database = new UnitDatabase();
+ final var prefixlessUnits = database.unitMapPrefixless(true);
database.addUnit("U", U);
database.addUnit("V", V);
@@ -478,13 +559,13 @@ class UnitDatabaseTest {
/**
* Tests that the database correctly stores and retrieves units, ignoring
* prefixes.
- *
+ *
* @since 2019-04-14
* @since v0.2.0
*/
@Test
public void testPrefixlessUnits() {
- final UnitDatabase database = new UnitDatabase();
+ final var database = new UnitDatabase();
database.addUnit("U", U);
database.addUnit("V", V);
@@ -517,7 +598,7 @@ class UnitDatabaseTest {
@Test
public void testToString() {
- final UnitDatabase database = new UnitDatabase();
+ final var database = new UnitDatabase();
database.addUnit("J", J);
database.addUnit("K", J);
@@ -538,14 +619,14 @@ class UnitDatabaseTest {
/**
* Test that unit expressions return the correct value.
- *
+ *
* @since 2019-04-14
* @since v0.2.0
*/
@Test
public void testUnitExpressions() {
// load units
- final UnitDatabase database = new UnitDatabase();
+ final var database = new UnitDatabase();
database.addUnit("U", U);
database.addUnit("V", V);
@@ -560,13 +641,13 @@ class UnitDatabaseTest {
// first test - test prefixes and operations
final Unit expected1 = J.withPrefix(A).withPrefix(B).withPrefix(C)
.withPrefix(C);
- final Unit actual1 = database.getUnitFromExpression("ABV * CU^2 / W / W");
+ final var actual1 = database.getUnitFromExpression("ABV * CU^2 / W / W");
assertEquals(expected1, actual1);
// second test - test addition and subtraction
final Unit expected2 = J.times(58);
- final Unit actual2 = database.getUnitFromExpression("2 fj + 6 ej");
+ final var actual2 = database.getUnitFromExpression("2 fj + 6 ej");
assertEquals(expected2, actual2);
@@ -579,14 +660,14 @@ class UnitDatabaseTest {
/**
* Tests both the unit name iterator and the name-unit entry iterator
- *
+ *
* @since 2019-04-14
* @since v0.2.0
*/
@Test
public void testUnitIterator() {
// load units
- final UnitDatabase database = new UnitDatabase();
+ final var database = new UnitDatabase();
database.addUnit("J", J);
database.addUnit("K", K);
@@ -595,19 +676,17 @@ class UnitDatabaseTest {
database.addPrefix("B", B);
database.addPrefix("C", C);
- final int NUM_UNITS = database.unitMapPrefixless(true).size();
- final int NUM_PREFIXES = database.prefixMap(true).size();
+ final var NUM_UNITS = database.unitMapPrefixless(true).size();
+ final var NUM_PREFIXES = database.prefixMap(true).size();
- final Iterator<String> nameIterator = database.unitMap().keySet()
- .iterator();
- final Iterator<Entry<String, Unit>> entryIterator = database.unitMap()
- .entrySet().iterator();
+ final var nameIterator = database.unitMap().keySet().iterator();
+ final var entryIterator = database.unitMap().entrySet().iterator();
- int expectedLength = 1;
- int unitsWithThisLengthSoFar = 0;
+ var expectedLength = 1;
+ var unitsWithThisLengthSoFar = 0;
// loop 1000 times
- for (int i = 0; i < 1000; i++) {
+ for (var i = 0; i < 1000; i++) {
// expected length of next
if (unitsWithThisLengthSoFar >= NUM_UNITS
* (int) Math.pow(NUM_PREFIXES, expectedLength - 1)) {
@@ -616,9 +695,9 @@ class UnitDatabaseTest {
}
// test that stuff is valid
- final String nextName = nameIterator.next();
- final Unit nextUnit = database.getUnit(nextName);
- final Entry<String, Unit> nextEntry = entryIterator.next();
+ final var nextName = nameIterator.next();
+ final var nextUnit = database.getUnit(nextName);
+ final var nextEntry = entryIterator.next();
assertEquals(expectedLength, nextName.length());
assertEquals(nextName, nextEntry.getKey());
@@ -628,13 +707,13 @@ class UnitDatabaseTest {
}
// test toString for consistency
- final String entryIteratorString = entryIterator.toString();
- for (int i = 0; i < 3; i++) {
+ final var entryIteratorString = entryIterator.toString();
+ for (var i = 0; i < 3; i++) {
assertEquals(entryIteratorString, entryIterator.toString());
}
- final String nameIteratorString = nameIterator.toString();
- for (int i = 0; i < 3; i++) {
+ final var nameIteratorString = nameIterator.toString();
+ for (var i = 0; i < 3; i++) {
assertEquals(nameIteratorString, nameIterator.toString());
}
}
@@ -646,14 +725,14 @@ class UnitDatabaseTest {
* For example, "ABCU" could mean "A-B-C-U", "AB-C-U", or "A-BC-U". In this
* case, "AB-C-U" is the correct choice.
* </p>
- *
+ *
* @since 2019-04-14
* @since v0.2.0
*/
@Test
public void testUnitPrefixCombinations() {
// load units
- final UnitDatabase database = new UnitDatabase();
+ final var database = new UnitDatabase();
database.addUnit("J", J);
@@ -665,7 +744,7 @@ class UnitDatabaseTest {
// test 1 - AB-C-J vs A-BC-J vs A-B-C-J
final Unit expected1 = J.withPrefix(AB).withPrefix(C);
- final Unit actual1 = database.getUnit("ABCJ");
+ final var actual1 = database.getUnit("ABCJ");
assertEquals(expected1, actual1);
@@ -674,8 +753,61 @@ class UnitDatabaseTest {
database.addPrefix("ABC", UnitPrefix.valueOf(17));
final Unit expected2 = J.times(17);
- final Unit actual2 = database.getUnit("ABCJ");
+ final var actual2 = database.getUnit("ABCJ");
assertEquals(expected2, actual2);
}
+
+ /**
+ * Tests the ability to create, read, and delete unit sets.
+ *
+ * @since 2025-04-30
+ * @since v1.0.0
+ */
+ @Test
+ void testUnitSetsInvalid() {
+ final List<LinearUnit> units = List.of(Metric.SECOND,
+ BritishImperial.Length.INCH);
+
+ final var database = new UnitDatabase();
+
+ assertThrows(IllegalArgumentException.class,
+ () -> database.addUnitSet("badtest", units));
+ assertThrows(NoSuchElementException.class,
+ () -> database.getUnitSet("badtest"));
+
+ database.addUnit("ft", BritishImperial.Length.FOOT);
+ database.addUnit("s", Metric.SECOND);
+ database.addUnit("dC", Metric.CELSIUS);
+ database.addUnit("K", Metric.KELVIN);
+
+ assertThrows(IllegalArgumentException.class,
+ () -> database.getUnitSetFromExpression("K; dC"),
+ "getUnitSetFromExpression allowed nonlinear unit.");
+ assertThrows(IllegalArgumentException.class,
+ () -> database.getUnitSetFromExpression("ft; s"),
+ "getUnitSetFromExpression allowed units of different dimension.");
+ }
+
+ /**
+ * Tests the ability to create, read, and delete unit sets.
+ *
+ * @since 2025-04-30
+ * @since v1.0.0
+ */
+ @Test
+ void testUnitSetsValid() {
+ final List<LinearUnit> units = List.of(BritishImperial.Length.FOOT,
+ BritishImperial.Length.INCH);
+
+ final var database = new UnitDatabase();
+
+ database.addUnitSet("ftintest", units);
+ assertEquals(units, database.getUnitSet("ftintest"));
+
+ database.addUnit("ft", BritishImperial.Length.FOOT);
+ database.addUnit("in", BritishImperial.Length.INCH);
+ assertEquals(units, database.getUnitSetFromExpression("ft; in"));
+ }
+
}
diff --git a/src/test/java/sevenUnits/unit/UnitTest.java b/src/test/java/sevenUnits/unit/UnitTest.java
index c93043b..fb21723 100644
--- a/src/test/java/sevenUnits/unit/UnitTest.java
+++ b/src/test/java/sevenUnits/unit/UnitTest.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 Adrien Hopkins
+ * Copyright (C) 2018, 2021, 2022, 2024, 2025 Adrien Hopkins
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -21,7 +21,6 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import java.math.RoundingMode;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
@@ -29,12 +28,11 @@ import org.junit.jupiter.api.Test;
import sevenUnits.utils.DecimalComparison;
import sevenUnits.utils.NameSymbol;
-import sevenUnits.utils.UncertainDouble;
/**
* Testing the various Unit classes. This is NOT part of this program's public
* API.
- *
+ *
* @author Adrien Hopkins
* @since 2018-12-22
* @since v0.1.0
@@ -45,21 +43,25 @@ class UnitTest {
@Test
public void testAdditionAndSubtraction() {
- final LinearUnit inch = Metric.METRE.times(0.0254)
+ final var inch = Metric.METRE.times(0.0254)
.withName(NameSymbol.of("inch", "in"));
- final LinearUnit foot = Metric.METRE.times(0.3048)
+ final var foot = Metric.METRE.times(0.3048)
.withName(NameSymbol.of("foot", "ft"));
- assertEquals(inch.plus(foot), Metric.METRE.times(0.3302));
- assertEquals(foot.minus(inch), Metric.METRE.times(0.2794));
+ assertTrue(
+ inch.plus(foot).equalsApproximately(Metric.METRE.times(0.3302)),
+ String.format("Expected: %s, Actual: %s", inch.plus(foot),
+ Metric.METRE.times(0.3302)));
+ assertTrue(
+ foot.minus(inch).equalsApproximately(Metric.METRE.times(0.2794)),
+ String.format("Expected: %s, Actual: %s", foot.minus(inch),
+ Metric.METRE.times(0.2794)));
// test with LinearUnitValue
- final LinearUnitValue value1 = LinearUnitValue.getExact(Metric.METRE, 15);
- final LinearUnitValue value2 = LinearUnitValue.getExact(foot, 120);
- final LinearUnitValue value3 = LinearUnitValue.getExact(Metric.METRE,
- 0.5);
- final LinearUnitValue value4 = LinearUnitValue.getExact(Metric.KILOGRAM,
- 60);
+ final var value1 = LinearUnitValue.getExact(Metric.METRE, 15);
+ final var value2 = LinearUnitValue.getExact(foot, 120);
+ final var value3 = LinearUnitValue.getExact(Metric.METRE, 0.5);
+ final var value4 = LinearUnitValue.getExact(Metric.KILOGRAM, 60);
// make sure addition is done correctly
assertEquals(51.576, value1.plus(value2).getValueExact(), 0.001);
@@ -81,24 +83,24 @@ class UnitTest {
@Test
public void testConversion() {
- final LinearUnit metre = Metric.METRE;
+ final var metre = Metric.METRE;
final Unit inch = metre.times(0.0254);
- final UnitValue value = UnitValue.of(inch, 75);
+ final var value = UnitValue.of(inch, 75);
assertEquals(1.9, inch.convertTo(metre, 75), 0.01);
assertEquals(1.9, value.convertTo(metre).getValue(), 0.01);
// try random stuff
- for (int i = 0; i < 1000; i++) {
+ for (var i = 0; i < 1000; i++) {
// initiate random values
- final double conversionFactor = UnitTest.rng.nextDouble() * 1000000;
- final double testValue = UnitTest.rng.nextDouble() * 1000000;
- final double expected = testValue * conversionFactor;
+ final var conversionFactor = UnitTest.rng.nextDouble() * 1000000;
+ final var testValue = UnitTest.rng.nextDouble() * 1000000;
+ final var expected = testValue * conversionFactor;
// test
final Unit unit = Metric.METRE.times(conversionFactor);
- final double actual = unit.convertToBase(testValue);
+ final var actual = unit.convertToBase(testValue);
assertEquals(actual, expected,
expected * DecimalComparison.DOUBLE_EPSILON);
@@ -107,7 +109,7 @@ class UnitTest {
@Test
public void testEquals() {
- final LinearUnit metre = Metric.METRE;
+ final var metre = Metric.METRE;
final Unit meter = Metric.BaseUnits.METRE.asLinearUnit();
assertEquals(metre, meter);
@@ -127,19 +129,19 @@ class UnitTest {
@Test
public void testMultiplicationAndDivision() {
// test unit-times-unit multiplication
- final LinearUnit generatedJoule = Metric.KILOGRAM
+ final var generatedJoule = Metric.KILOGRAM
.times(Metric.METRE.toExponent(2))
.dividedBy(Metric.SECOND.toExponent(2));
- final LinearUnit actualJoule = Metric.JOULE;
+ final var actualJoule = Metric.JOULE;
assertEquals(generatedJoule, actualJoule);
// test multiplication by conversion factors
- final LinearUnit kilometre = Metric.METRE.times(1000);
- final LinearUnit hour = Metric.SECOND.times(3600);
- final LinearUnit generatedKPH = kilometre.dividedBy(hour);
+ final var kilometre = Metric.METRE.times(1000);
+ final var hour = Metric.SECOND.times(3600);
+ final var generatedKPH = kilometre.dividedBy(hour);
- final LinearUnit actualKPH = Metric.METRE.dividedBy(Metric.SECOND)
+ final var actualKPH = Metric.METRE.dividedBy(Metric.SECOND)
.dividedBy(3.6);
assertEquals(generatedKPH, actualKPH);
@@ -147,82 +149,9 @@ class UnitTest {
@Test
public void testPrefixes() {
- final LinearUnit generatedKilometre = Metric.METRE
- .withPrefix(Metric.KILO);
- final LinearUnit actualKilometre = Metric.METRE.times(1000);
+ final var generatedKilometre = Metric.METRE.withPrefix(Metric.KILO);
+ final var actualKilometre = Metric.METRE.times(1000);
assertEquals(generatedKilometre, actualKilometre);
}
-
- /**
- * Tests converting an uncertain LinearUnitValue to a string.
- *
- * @since 2021-11-04
- */
- @Test
- public void testValueToString1() {
- final LinearUnitValue value = LinearUnitValue.of(Metric.METRE,
- UncertainDouble.of(10, 0.24));
-
- assertEquals("(10.0 � 0.2) m", value.toString());
- assertEquals("(10.0 � 0.2) m",
- value.toString(true, RoundingMode.HALF_EVEN));
- assertEquals("10.0 m", value.toString(false, RoundingMode.HALF_EVEN));
- }
-
- /**
- * Tests converting a certain LinearUnitValue to a string.
- *
- * @since 2021-11-04
- */
- @Test
- public void testValueToString2() {
- final LinearUnitValue value = LinearUnitValue.of(Metric.METRE,
- UncertainDouble.of(10, 0));
-
- assertEquals("10.0 m", value.toString());
- assertEquals("(10.0 � 0.0) m",
- value.toString(true, RoundingMode.HALF_EVEN));
- assertEquals("10.0 m", value.toString(false, RoundingMode.HALF_EVEN));
- }
-
- /**
- * Tests converting an unnamed LinearUnitValue to a string.
- *
- * @since 2021-11-04
- */
- @Test
- public void testValueToString3() {
- final LinearUnitValue value = LinearUnitValue.of(
- Metric.METRE.withName(NameSymbol.EMPTY),
- UncertainDouble.of(10, 0.24));
-
- assertEquals("10.0 unnamed unit (= 10.0 m)",
- value.toString(false, RoundingMode.HALF_EVEN));
- }
-
- /**
- * Tests converting a named UnitValue to a string.
- *
- * @since 2021-11-04
- */
- @Test
- public void testValueToString4() {
- final UnitValue value = UnitValue.of(BritishImperial.FAHRENHEIT, 80);
-
- assertEquals("80.0 \u00B0F", value.toString());
- }
-
- /**
- * Tests converting an unnamed UnitValue to a string.
- *
- * @since 2021-11-04
- */
- @Test
- public void testValueToString5() {
- final UnitValue value = UnitValue
- .of(USCustomary.FAHRENHEIT.withName(NameSymbol.EMPTY), 50);
-
- assertEquals("50.0 unnamed unit (= 283.15 K)", value.toString());
- }
}
diff --git a/src/test/java/sevenUnits/unit/UnitValueTest.java b/src/test/java/sevenUnits/unit/UnitValueTest.java
new file mode 100644
index 0000000..3679703
--- /dev/null
+++ b/src/test/java/sevenUnits/unit/UnitValueTest.java
@@ -0,0 +1,240 @@
+/**
+ * Copyright (C) 2021, 2025 Adrien Hopkins
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+package sevenUnits.unit;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.math.RoundingMode;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Stream;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import sevenUnits.utils.NameSymbol;
+import sevenUnits.utils.UncertainDouble;
+
+/**
+ * Tests for the UnitValue and LinearUnitValue classes
+ *
+ * @since v1.0.0
+ */
+public final class UnitValueTest {
+ private static Stream<Arguments> testConvertToMultiple() {
+ return Stream.of(
+ Arguments.of(
+ LinearUnitValue.getExact(BritishImperial.Length.INCH, 64),
+ List.of(BritishImperial.Length.FOOT,
+ BritishImperial.Length.INCH),
+ List.of(5.0, 4.0)),
+ Arguments.of(LinearUnitValue.getExact(Metric.SECOND, 44102.5),
+ List.of(Metric.HOUR, Metric.MINUTE, Metric.SECOND),
+ List.of(12.0, 15.0, 2.5)));
+ }
+
+ @ParameterizedTest
+ @MethodSource
+ public void testConvertToMultiple(LinearUnitValue valFrom,
+ List<LinearUnit> others, List<Double> expectedValues) {
+ final var actual = valFrom.convertToMultiple(others);
+ assertEquals(others.size(), expectedValues.size(), String.format(
+ "%s converted to %s had the wrong number of resulting units (expected: %d, actual: %d).",
+ valFrom, others, others.size(), actual.size()));
+
+ for (var i = 0; i < others.size(); i++) {
+ final var expectedValue = LinearUnitValue.getExact(others.get(i),
+ expectedValues.get(i));
+ assertTrue(expectedValue.equivalent(actual.get(i)),
+ String.format("Value %d: expected %s, actual %s.", i,
+ expectedValue, actual.get(i)));
+ }
+ }
+
+ @Test
+ public void testConvertToMultipleErrors() {
+ assertThrows(IllegalArgumentException.class,
+ () -> LinearUnitValue.ONE.convertToMultiple(List.of()));
+ assertThrows(IllegalArgumentException.class,
+ () -> LinearUnitValue.ONE.convertToMultiple(List.of(Metric.METRE)));
+ }
+
+ // I am intentionally testing whether or not equals gracefully returns false
+ // when it gets an argument of the wrong type
+ @SuppressWarnings("unlikely-arg-type")
+ @Test
+ public void testEqualsHashCode() {
+ final var v1 = LinearUnitValue.of(Metric.METRE,
+ UncertainDouble.of(1.0, 0.01));
+ final var v2 = LinearUnitValue.of(Metric.METRE,
+ UncertainDouble.of(1.0, 0.01));
+ final var v3 = LinearUnitValue.of(Metric.MILLIMETRE,
+ UncertainDouble.of(1000.0, 10.0));
+ final var v4 = LinearUnitValue.of(Metric.MILLIMETRE,
+ UncertainDouble.of(1000.0, 20.0));
+
+ assertTrue(Objects.equals(v1, v2),
+ "Two identical values are not equal()");
+ assertTrue(Objects.equals(v1.hashCode(), v2.hashCode()),
+ "Two identical values have different hash codes.");
+ assertTrue(Objects.equals(v1, v3),
+ "Two values with the same value but different units are not equal()");
+ assertTrue(Objects.equals(v1.hashCode(), v3.hashCode()),
+ "Two values with the same value but different units have different hash codes.");
+ assertFalse(Objects.equals(v1, v4),
+ "Two values with the same value but different uncertainties are equal()");
+ assertFalse(Objects.equals(v1, "Hello"));
+ assertFalse(v1.equals("Hello", true));
+ }
+
+ @Test
+ public void testEqualsNoFP() {
+ final var v1 = LinearUnitValue.of(Metric.METRE,
+ UncertainDouble.of(1.0, 0.01));
+ final var v2 = LinearUnitValue.of(Metric.METRE,
+ UncertainDouble.of(1.0, 0.01));
+ final var v3 = LinearUnitValue.of(Metric.METRE,
+ UncertainDouble.of(1.0 + 5e-16, 0.01));
+ assertTrue(v1.equals(v2, false));
+ assertFalse(v1.equals(v3, false));
+ assertTrue(v1.equals(v3, true));
+ }
+
+ @Test
+ public void testOperations() {
+ final var v1 = LinearUnitValue.getExact(Metric.METRE, 2.0);
+ final var v2 = LinearUnitValue.getExact(Metric.METRE, 4.0);
+
+ assertEquals(v2, v1.times(2));
+ assertEquals(v1, v2.dividedBy(2));
+ assertEquals(LinearUnitValue.getExact(Metric.SQUARE_METRE, 8.0),
+ v1.times(v2));
+ assertEquals(LinearUnitValue.getExact(Metric.ONE, 0.5), v1.dividedBy(v2));
+ assertEquals(LinearUnitValue.getExact(Metric.SQUARE_METRE, 4.0),
+ v1.toExponent(2));
+ assertEquals(LinearUnitValue.getExact(Metric.SQUARE_METRE, 4.0),
+ v1.toExponentRounded(2.0));
+ }
+
+ @Test
+ public void testValueEquivalent() {
+ final var v1 = LinearUnitValue.of(BritishImperial.Length.INCH,
+ UncertainDouble.of(1.0, 0.0));
+ final var v2 = LinearUnitValue.of(Metric.METRE,
+ UncertainDouble.of(0.0255, 0.0));
+ assertFalse(v1.equivalent(v2));
+
+ final var v3 = LinearUnitValue.of(BritishImperial.Length.INCH,
+ UncertainDouble.of(1.0, 1.0));
+ final var v4 = LinearUnitValue.of(Metric.METRE,
+ UncertainDouble.of(0.0255, 0.025));
+ assertTrue(v3.equivalent(v4));
+ }
+
+ @Test
+ public void testValueEquivalentErrors() {
+ final var v1 = LinearUnitValue.of(BritishImperial.Length.INCH,
+ UncertainDouble.of(1.0, 0.0));
+ final var v2 = LinearUnitValue.of(BritishImperial.CALORIE,
+ UncertainDouble.of(1.0, 0.0));
+ assertFalse(v1.equivalent(v2));
+
+ assertFalse(v1.equivalent(null));
+ }
+
+ /**
+ * Tests converting an uncertain LinearUnitValue to a string.
+ *
+ * @since 2021-11-04
+ * @since v0.3.2
+ */
+ @Test
+ public void testValueToString1() {
+ final var value = LinearUnitValue.of(Metric.METRE,
+ UncertainDouble.of(10, 0.24));
+
+ assertEquals("(10.0 ± 0.2) m", value.toString());
+ assertEquals("(10.0 ± 0.2) m",
+ value.toString(true, RoundingMode.HALF_EVEN));
+ assertEquals("10.0 m", value.toString(false, RoundingMode.HALF_EVEN));
+ }
+
+ /**
+ * Tests converting a certain LinearUnitValue to a string.
+ *
+ * @since 2021-11-04
+ * @since v0.3.2
+ */
+ @Test
+ public void testValueToString2() {
+ final var value = LinearUnitValue.of(Metric.METRE,
+ UncertainDouble.of(10, 0));
+
+ assertEquals("10.0 m", value.toString());
+ assertEquals("(10.0 ± 0.0) m",
+ value.toString(true, RoundingMode.HALF_EVEN));
+ assertEquals("10.0 m", value.toString(false, RoundingMode.HALF_EVEN));
+ }
+
+ /**
+ * Tests converting an unnamed LinearUnitValue to a string.
+ *
+ * @since 2021-11-04
+ * @since v0.3.2
+ */
+ @Test
+ public void testValueToString3() {
+ final var value = LinearUnitValue.of(
+ Metric.METRE.withName(NameSymbol.EMPTY),
+ UncertainDouble.of(10, 0.24));
+
+ assertEquals("10.0 unnamed unit (= 10.0 m)",
+ value.toString(false, RoundingMode.HALF_EVEN));
+ }
+
+ /**
+ * Tests converting a named UnitValue to a string.
+ *
+ * @since 2021-11-04
+ * @since v0.3.2
+ */
+ @Test
+ public void testValueToString4() {
+ final var value = UnitValue.of(BritishImperial.FAHRENHEIT, 80);
+
+ assertEquals("80.0 \u00B0F", value.toString());
+ }
+
+ /**
+ * Tests converting an unnamed UnitValue to a string.
+ *
+ * @since 2021-11-04
+ * @since v0.3.2
+ */
+ @Test
+ public void testValueToString5() {
+ final var value = UnitValue
+ .of(USCustomary.FAHRENHEIT.withName(NameSymbol.EMPTY), 50);
+
+ assertEquals("50.0 unnamed unit (= 283.15 K)", value.toString());
+ }
+}
diff --git a/src/test/java/sevenUnits/utils/ConditionalExistenceCollectionsTest.java b/src/test/java/sevenUnits/utils/ConditionalExistenceCollectionsTest.java
index 868385b..8711847 100644
--- a/src/test/java/sevenUnits/utils/ConditionalExistenceCollectionsTest.java
+++ b/src/test/java/sevenUnits/utils/ConditionalExistenceCollectionsTest.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2019 Adrien Hopkins
+ * Copyright (C) 2019, 2021, 2022, 2024, 2025 Adrien Hopkins
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -23,7 +23,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.Arrays;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -38,31 +37,34 @@ import sevenUnits.utils.ConditionalExistenceCollections.ConditionalExistenceIter
* normal operations on conditional existence collections and ensures that
* elements that do not pass the existence condition are not included in the
* results.
- *
+ *
* @author Adrien Hopkins
* @since 2019-10-16
+ * @since v0.3.0
*/
class ConditionalExistenceCollectionsTest {
/**
* The returned iterator ignores elements that don't start with "a".
- *
+ *
* @return test iterator
* @since 2019-10-17
+ * @since v0.3.0
*/
ConditionalExistenceIterator<String> getTestIterator() {
final List<String> items = Arrays.asList("aa", "ab", "ba");
- final Iterator<String> it = items.iterator();
- final ConditionalExistenceIterator<String> cit = (ConditionalExistenceIterator<String>) ConditionalExistenceCollections
+ final var it = items.iterator();
+ final var cit = (ConditionalExistenceIterator<String>) ConditionalExistenceCollections
.conditionalExistenceIterator(it, s -> s.startsWith("a"));
return cit;
}
/**
* The returned map ignores mappings where the value is zero.
- *
+ *
* @return map to be used for test data
* @since 2019-10-16
+ * @since v0.3.0
*/
Map<String, Integer> getTestMap() {
final Map<String, Integer> map = new HashMap<>();
@@ -76,60 +78,49 @@ class ConditionalExistenceCollectionsTest {
return conditionalMap;
}
- /**
- * Test method for the ConditionalExistenceMap's containsKey method.
- */
+ /** Test method for the ConditionalExistenceMap's containsKey method. */
@Test
void testContainsKeyObject() {
- final Map<String, Integer> map = this.getTestMap();
+ final var map = this.getTestMap();
assertTrue(map.containsKey("one"));
assertTrue(map.containsKey("ten"));
assertFalse(map.containsKey("five"));
assertFalse(map.containsKey("zero"));
}
- /**
- * Test method for the ConditionalExistenceMap's containsValue method.
- */
+ /** Test method for the ConditionalExistenceMap's containsValue method. */
@Test
void testContainsValueObject() {
- final Map<String, Integer> map = this.getTestMap();
+ final var map = this.getTestMap();
assertTrue(map.containsValue(1));
assertTrue(map.containsValue(10));
assertFalse(map.containsValue(5));
assertFalse(map.containsValue(0));
}
- /**
- * Test method for the ConditionalExistenceMap's entrySet method.
- */
+ /** Test method for the ConditionalExistenceMap's entrySet method. */
@Test
void testEntrySet() {
- final Map<String, Integer> map = this.getTestMap();
+ final var map = this.getTestMap();
for (final Entry<String, Integer> e : map.entrySet()) {
assertTrue(e.getValue() != 0);
}
}
- /**
- * Test method for the ConditionalExistenceMap's get method.
- */
+ /** Test method for the ConditionalExistenceMap's get method. */
@Test
void testGetObject() {
- final Map<String, Integer> map = this.getTestMap();
+ final var map = this.getTestMap();
assertEquals(1, map.get("one"));
assertEquals(10, map.get("ten"));
assertEquals(null, map.get("five"));
assertEquals(null, map.get("zero"));
}
- /**
- * Test method for the ConditionalExistenceCollection's iterator.
- */
+ /** Test method for the ConditionalExistenceCollection's iterator. */
@Test
void testIterator() {
- final ConditionalExistenceIterator<String> testIterator = this
- .getTestIterator();
+ final var testIterator = this.getTestIterator();
assertTrue(testIterator.hasNext);
assertTrue(testIterator.hasNext());
@@ -147,22 +138,18 @@ class ConditionalExistenceCollectionsTest {
assertThrows(NoSuchElementException.class, testIterator::next);
}
- /**
- * Test method for the ConditionalExistenceMap's keySet operation.
- */
+ /** Test method for the ConditionalExistenceMap's keySet operation. */
@Test
void testKeySet() {
- final Map<String, Integer> map = this.getTestMap();
- assertFalse(map.keySet().contains("zero"));
+ final var map = this.getTestMap();
+ assertFalse(map.containsKey("zero"));
}
- /**
- * Test method for the ConditionalExistenceMap's values operation.
- */
+ /** Test method for the ConditionalExistenceMap's values operation. */
@Test
void testValues() {
- final Map<String, Integer> map = this.getTestMap();
- assertFalse(map.values().contains(0));
+ final var map = this.getTestMap();
+ assertFalse(map.containsValue(0));
}
}
diff --git a/src/test/java/sevenUnits/utils/ExpressionParserTest.java b/src/test/java/sevenUnits/utils/ExpressionParserTest.java
index 3a95285..2e0b4b0 100644
--- a/src/test/java/sevenUnits/utils/ExpressionParserTest.java
+++ b/src/test/java/sevenUnits/utils/ExpressionParserTest.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2019 Adrien Hopkins
+ * Copyright (C) 2019, 2021, 2024, 2025 Adrien Hopkins
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -17,6 +17,7 @@
package sevenUnits.utils;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import java.util.List;
import java.util.stream.IntStream;
@@ -26,11 +27,10 @@ import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
-// TODO add tests for expression-to-RPN and RPN-to-result
/**
* A test for the {@code ExpressionParser} class. This is NOT part of this
* program's public API.
- *
+ *
* @author Adrien Hopkins
* @since 2019-03-22
* @since v0.2.0
@@ -39,13 +39,13 @@ class ExpressionParserTest {
private static final ExpressionParser<Integer> numberParser = new ExpressionParser.Builder<>(
Integer::parseInt).addBinaryOperator("+", (o1, o2) -> o1 + o2, 0)
.addBinaryOperator("-", (o1, o2) -> o1 - o2, 0)
- .addBinaryOperator("*", (o1, o2) -> o1 * o2, 1)
- .addBinaryOperator("/", (o1, o2) -> o1 / o2, 1)
- .addBinaryOperator("^", (o1, o2) -> (int) Math.pow(o1, o2), 2).build();
+ .addUnaryOperator("neg", o1 -> -o1, 1)
+ .addBinaryOperator("*", (o1, o2) -> o1 * o2, 2)
+ .addBinaryOperator("/", (o1, o2) -> o1 / o2, 2)
+ .addUnaryOperator("recip", o1 -> 1 / o1, 3)
+ .addBinaryOperator("^", (o1, o2) -> (int) Math.pow(o1, o2), 4).build();
- /**
- * The expressions used in the expression parsing tests
- */
+ /** The expressions used in the expression parsing tests */
private static final List<String> TEST_EXPRESSIONS = List.of(
// test parsing of expressions
"1 + 2 ^ 5 * 3", "(1 + 2) ^ 5 * 3",
@@ -54,21 +54,81 @@ class ExpressionParserTest {
// ensure it normally goes from left to right
"1 + 2 + 3 + 4", "12 - 4 - 3", "12 - (4 - 3)", "1 / 2 + 3");
- /**
- * The expected results for evaluating these expressions
- */
+ /** The expected results for evaluating these expressions */
private static final int[] RESULTS = { 97, 729, 133, 10, 5, 11, 3 };
+ private static final Stream<Arguments> testConvertExpressionToRPN() {
+ return Stream.of(Arguments.of("1 + 2 ^ 5 * 3", "1 2 5 ^ 3 * +"),
+ Arguments.of("(1 + 2) ^ 5 * 3", "1 2 + 5 ^ 3 *"),
+ Arguments.of("12 * 5 + (3 ^ (2 * 3) - 72) / (3 + 3 * 2)",
+ "12 5 * 3 2 3 * ^ 72 - 3 3 2 * + / +"),
+ Arguments.of("1 + 2 + 3 + 4", "1 2 + 3 + 4 +"),
+ Arguments.of("12 - 4 - 3", "12 4 - 3 -"),
+ Arguments.of("12 - (4 - 3)", "12 4 3 - -"),
+ Arguments.of("1 / 2 + 3", "1 2 / 3 +"), Arguments.of("12", "12"),
+ Arguments.of("2 * 3 + 4", "2 3 * 4 +"),
+ Arguments.of("(2 * 3) + 4", "2 3 * 4 +"),
+ Arguments.of("2 * 3 - 4", "2 3 * 4 -"),
+ Arguments.of("(2 * 3) - 4", "2 3 * 4 -"),
+ Arguments.of("2 * (3 + 4)", "2 3 4 + *"),
+ Arguments.of("2 * (3 - 4)", "2 3 4 - *"),
+ Arguments.of("neg 2", "2 neg"),
+ Arguments.of("1 + neg 2", "1 2 neg +"));
+ }
+
+ private static final Stream<String> testInvalidExpression() {
+ return Stream.of("+", "1 +", "1 + * 2", "1 (+ 1)", "neg");
+ }
+
+ private static final Stream<String> testInvalidRPN() {
+ return Stream.of("+", "1 +", "1 + * 2", "1 * 2", "1 2", "neg");
+ }
+
/**
* @return A stream of objects, where each one is an expression and the
* expected result
* @since 2021-09-27
+ * @since v0.3.2
*/
private static final Stream<Arguments> testParseExpressionData() {
return IntStream.range(0, TEST_EXPRESSIONS.size())
.mapToObj(i -> Arguments.of(TEST_EXPRESSIONS.get(i), RESULTS[i]));
}
+ private static final Stream<Arguments> testParseRPN() {
+ return Stream.of(Arguments.of("1 2 5 ^ 3 * +", 97),
+ Arguments.of("1 2 + 5 ^ 3 *", 729),
+ Arguments.of("12 5 * 3 2 3 * ^ 72 - 3 3 2 * + / +", 133),
+ Arguments.of("1 2 + 3 + 4 +", 10), Arguments.of("12 4 - 3 -", 5),
+ Arguments.of("12 4 3 - -", 11), Arguments.of("1 2 / 3 +", 3),
+ Arguments.of("12", 12), Arguments.of("2 3 * 4 +", 10),
+ Arguments.of("2 3 * 4 -", 2), Arguments.of("2 3 4 + *", 14),
+ Arguments.of("2 3 4 - *", -2), Arguments.of("2 neg", -2),
+ Arguments.of("1 2 neg +", -1));
+ }
+
+ @ParameterizedTest
+ @MethodSource
+ public void testConvertExpressionToRPN(String expression,
+ String expectedRPN) {
+ assertEquals(expectedRPN,
+ numberParser.convertExpressionToReversePolish(expression));
+ }
+
+ @ParameterizedTest
+ @MethodSource
+ public void testInvalidExpression(String expression) {
+ assertThrows(RuntimeException.class,
+ () -> numberParser.convertExpressionToReversePolish(expression));
+ }
+
+ @ParameterizedTest
+ @MethodSource
+ public void testInvalidRPN(String expressionRPN) {
+ assertThrows(RuntimeException.class,
+ () -> numberParser.parseReversePolishExpression(expressionRPN));
+ }
+
/**
* Test method for
* {@link sevenUnits.utils.ExpressionParser#parseExpression(java.lang.String)}.
@@ -78,4 +138,11 @@ class ExpressionParserTest {
public void testParseExpression(String expression, int value) {
assertEquals(value, numberParser.parseExpression(expression));
}
+
+ @ParameterizedTest
+ @MethodSource
+ public void testParseRPN(String expressionRPN, int value) {
+ assertEquals(value,
+ numberParser.parseReversePolishExpression(expressionRPN));
+ }
}
diff --git a/src/test/java/sevenUnits/utils/NameSymbolTest.java b/src/test/java/sevenUnits/utils/NameSymbolTest.java
new file mode 100644
index 0000000..f8843e0
--- /dev/null
+++ b/src/test/java/sevenUnits/utils/NameSymbolTest.java
@@ -0,0 +1,108 @@
+/**
+ * Copyright (C) 2025 Adrien Hopkins
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+package sevenUnits.utils;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Stream;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+/**
+ * Tests for the {@link NameSymbol} class.
+ *
+ * @since v1.0.0
+ */
+class NameSymbolTest {
+ private static Stream<Arguments> testEqualsHashCode() {
+ return Stream.of(
+ Arguments.of(NameSymbol.ofName("test"), NameSymbol.ofName("test"),
+ true),
+ Arguments.of(NameSymbol.ofName("a"), NameSymbol.ofName("b"), false),
+ Arguments.of(NameSymbol.ofSymbol("test"),
+ NameSymbol.ofSymbol("test"), true),
+ Arguments.of(NameSymbol.ofSymbol("a"), NameSymbol.ofSymbol("b"),
+ false),
+ Arguments.of(NameSymbol.ofName("test"), NameSymbol.ofSymbol("test"),
+ false),
+ Arguments.of(NameSymbol.of("main", "s"), NameSymbol.of("main", "s"),
+ true),
+ Arguments.of(NameSymbol.of("main", "s"),
+ NameSymbol.of("main", "s", "m"), false),
+ Arguments.of(new NameSymbol(null, null, new HashSet<>()),
+ new NameSymbol(null, null, new HashSet<>()), true),
+ Arguments.of(
+ new NameSymbol(Optional.of("main"), Optional.of("s"),
+ new HashSet<>()),
+ new NameSymbol(null, null, new HashSet<>()), false),
+ Arguments.of(new NameSymbol(null, null, new HashSet<>()),
+ new NameSymbol(Optional.of("main"), Optional.of("s"),
+ new HashSet<>()),
+ false),
+ Arguments.of(
+ new NameSymbol(Optional.of("main"), null, new HashSet<>()),
+ new NameSymbol(Optional.of("main"), Optional.of("s"),
+ new HashSet<>()),
+ false));
+ }
+
+ @Test
+ public void testCreate() {
+ final Set<String> names = Set.of("a", "b", "c");
+ final var ns = NameSymbol.ofNullable(null, null, names);
+ assertTrue(ns.getPrimaryName().isPresent(),
+ "NameSymbol created without primary name.");
+ assertTrue(names.contains(ns.getPrimaryName().orElseThrow()),
+ String.format("Primary name (%s) was not obtained from names set.",
+ ns.getPrimaryName()));
+ assertFalse(
+ ns.getOtherNames().contains(ns.getPrimaryName().orElseThrow()),
+ String.format("Primary name (%s) was included in other names set.",
+ ns.getPrimaryName()));
+ assertEquals(Set.of("a", "b", "c"), names,
+ "names input was changed by ofNullable()");
+ }
+
+ /**
+ * Tests that two NameSymbols are or are not equal. If they are equal, also
+ * ensures they have the same hash code.
+ *
+ * @param a first NameSymbol to test
+ * @param b second NameSymbol to test
+ * @param equal true iff a should be equal to be, otherwise false
+ */
+ @ParameterizedTest
+ @MethodSource
+ public void testEqualsHashCode(NameSymbol a, NameSymbol b, boolean equal) {
+ if (equal) {
+ assertTrue(Objects.equals(a, b));
+ assertEquals(a.hashCode(), b.hashCode(),
+ "Equal NameSymbol instances have different hash codes.");
+ } else {
+ assertFalse(Objects.equals(a, b));
+ }
+ }
+}
diff --git a/src/test/java/sevenUnits/utils/ObjectProductTest.java b/src/test/java/sevenUnits/utils/ObjectProductTest.java
index 8c6b353..7c5df88 100644
--- a/src/test/java/sevenUnits/utils/ObjectProductTest.java
+++ b/src/test/java/sevenUnits/utils/ObjectProductTest.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 Adrien Hopkins
+ * Copyright (C) 2018, 2021, 2024, 2025 Adrien Hopkins
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -34,7 +34,7 @@ import sevenUnits.unit.Metric;
/**
* Tests for {@link ObjectProduct} using BaseDimension as a test object. This is
* NOT part of this program's public API.
- *
+ *
* @author Adrien Hopkins
* @since 2018-12-12
* @since v0.1.0
@@ -42,7 +42,7 @@ import sevenUnits.unit.Metric;
class ObjectProductTest {
/**
* Tests {@link UnitDimension#equals}
- *
+ *
* @since 2018-12-12
* @since v0.1.0
*/
@@ -54,7 +54,7 @@ class ObjectProductTest {
/**
* Tests {@code UnitDimension}'s exponentiation
- *
+ *
* @since 2019-01-15
* @since v0.1.0
*/
@@ -66,7 +66,7 @@ class ObjectProductTest {
/**
* Tests {@code UnitDimension}'s multiplication and division.
- *
+ *
* @since 2018-12-12
* @since v0.1.0
*/
diff --git a/src/test/java/sevenUnits/utils/SemanticVersionTest.java b/src/test/java/sevenUnits/utils/SemanticVersionTest.java
index 1e59ae3..5b74812 100644
--- a/src/test/java/sevenUnits/utils/SemanticVersionTest.java
+++ b/src/test/java/sevenUnits/utils/SemanticVersionTest.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2022 Adrien Hopkins
+ * Copyright (C) 2022, 2024, 2025 Adrien Hopkins
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -35,12 +35,14 @@ import org.junit.jupiter.api.Test;
* Tests for {@link SemanticVersionNumber}
*
* @since 2022-02-19
+ * @since v0.4.0
*/
public final class SemanticVersionTest {
/**
* Test for {@link SemanticVersionNumber#compatible}
- *
+ *
* @since 2022-02-20
+ * @since v0.4.0
*/
@Test
public void testCompatibility() {
@@ -64,38 +66,37 @@ public final class SemanticVersionTest {
/**
* Tests {@link SemanticVersionNumber#toString} for complex version numbers
- *
+ *
* @since 2022-02-19
+ * @since v0.4.0
*/
@Test
public void testComplexToString() {
- final SemanticVersionNumber v1 = builder(1, 2, 3).preRelease(1, 2, 3)
- .build();
+ final var v1 = builder(1, 2, 3).preRelease(1, 2, 3).build();
assertEquals("1.2.3-1.2.3", v1.toString());
- final SemanticVersionNumber v2 = builder(4, 5, 6).preRelease("abc", 123)
+ final var v2 = builder(4, 5, 6).preRelease("abc", 123)
.buildMetadata("2022-02-19").build();
assertEquals("4.5.6-abc.123+2022-02-19", v2.toString());
- final SemanticVersionNumber v3 = builder(1, 0, 0)
- .preRelease("x-y-z", "--").build();
+ final var v3 = builder(1, 0, 0).preRelease("x-y-z", "--").build();
assertEquals("1.0.0-x-y-z.--", v3.toString());
}
/**
* Tests that complex version can be created and their parts read
- *
+ *
* @since 2022-02-19
+ * @since v0.4.0
*/
@Test
public void testComplexVersions() {
- final SemanticVersionNumber v1 = builder(1, 2, 3).preRelease(1, 2, 3)
- .build();
+ final var v1 = builder(1, 2, 3).preRelease(1, 2, 3).build();
assertEquals(1, v1.majorVersion());
assertEquals(2, v1.minorVersion());
assertEquals(3, v1.patchVersion());
assertEquals(List.of("1", "2", "3"), v1.preReleaseIdentifiers());
assertEquals(List.of(), v1.buildMetadata());
- final SemanticVersionNumber v2 = builder(4, 5, 6).preRelease("abc", 123)
+ final var v2 = builder(4, 5, 6).preRelease("abc", 123)
.buildMetadata("2022-02-19").build();
assertEquals(4, v2.majorVersion());
assertEquals(5, v2.minorVersion());
@@ -103,8 +104,7 @@ public final class SemanticVersionTest {
assertEquals(List.of("abc", "123"), v2.preReleaseIdentifiers());
assertEquals(List.of("2022-02-19"), v2.buildMetadata());
- final SemanticVersionNumber v3 = builder(1, 0, 0)
- .preRelease("x-y-z", "--").build();
+ final var v3 = builder(1, 0, 0).preRelease("x-y-z", "--").build();
assertEquals(1, v3.majorVersion());
assertEquals(0, v3.minorVersion());
assertEquals(0, v3.patchVersion());
@@ -114,8 +114,9 @@ public final class SemanticVersionTest {
/**
* Test that semantic version strings can be parsed correctly
- *
+ *
* @since 2022-02-19
+ * @since v0.4.0
* @see SemanticVersionNumber#fromString
* @see SemanticVersionNumber#isValidVersionString
*/
@@ -153,9 +154,7 @@ public final class SemanticVersionTest {
"Could not parse 1.2.3-abc.56.def+2022abc99");
}
- /**
- * Ensures it is impossible to create invalid version numbers
- */
+ /** Ensures it is impossible to create invalid version numbers */
@Test
public void testInvalidVersionNumbers() {
// stableVersion()
@@ -199,7 +198,7 @@ public final class SemanticVersionTest {
assertThrows(IllegalArgumentException.class, () -> builder(-3, 0, 7),
"Negative major version number tolerated by builder");
- final SemanticVersionNumber.Builder testBuilder = builder(1, 2, 3);
+ final var testBuilder = builder(1, 2, 3);
// note: builder.buildMetadata(null) doesn't even compile lol
// builder.buildMetadata
assertThrows(NullPointerException.class,
@@ -265,8 +264,9 @@ public final class SemanticVersionTest {
/**
* Test for {@link SemanticVersionNumber#isStable}
- *
+ *
* @since 2022-02-19
+ * @since v0.4.0
*/
@Test
public void testIsStable() {
@@ -288,29 +288,27 @@ public final class SemanticVersionTest {
* {@link SemanticVersionNumber#compareTo} according to official rules. Tests
* all of the versions compared in section 11 of the SemVer 2.0.0 document
* and some more.
- *
+ *
* @since 2022-02-19
+ * @since v0.4.0
*/
@Test
public void testOrder() {
- final SemanticVersionNumber v100a = builder(1, 0, 0).preRelease("alpha")
- .build(); // 1.0.0-alpha
- final SemanticVersionNumber v100a1 = preRelease(1, 0, 0, "alpha", 1); // 1.0.0-alpha.1
- final SemanticVersionNumber v100ab = builder(1, 0, 0)
- .preRelease("alpha", "beta").build(); // 1.0.0-alpha.beta
- final SemanticVersionNumber v100b = builder(1, 0, 0).preRelease("beta")
- .build(); // 1.0.0-alpha
- final SemanticVersionNumber v100b2 = preRelease(1, 0, 0, "beta", 2); // 1.0.0-beta.2
- final SemanticVersionNumber v100b11 = preRelease(1, 0, 0, "beta", 11); // 1.0.0-beta.11
- final SemanticVersionNumber v100rc1 = preRelease(1, 0, 0, "rc", 1); // 1.0.0-rc.1
- final SemanticVersionNumber v100 = stableVersion(1, 0, 0);
- final SemanticVersionNumber v100plus = builder(1, 0, 0)
+ final var v100a = builder(1, 0, 0).preRelease("alpha").build(); // 1.0.0-alpha
+ final var v100a1 = preRelease(1, 0, 0, "alpha", 1); // 1.0.0-alpha.1
+ final var v100ab = builder(1, 0, 0).preRelease("alpha", "beta").build(); // 1.0.0-alpha.beta
+ final var v100b = builder(1, 0, 0).preRelease("beta").build(); // 1.0.0-alpha
+ final var v100b2 = preRelease(1, 0, 0, "beta", 2); // 1.0.0-beta.2
+ final var v100b11 = preRelease(1, 0, 0, "beta", 11); // 1.0.0-beta.11
+ final var v100rc1 = preRelease(1, 0, 0, "rc", 1); // 1.0.0-rc.1
+ final var v100 = stableVersion(1, 0, 0);
+ final var v100plus = builder(1, 0, 0)
.buildMetadata("blah", "blah", "blah").build(); // 1.0.0+blah.blah.blah
- final SemanticVersionNumber v200 = stableVersion(2, 0, 0);
- final SemanticVersionNumber v201 = stableVersion(2, 0, 1);
- final SemanticVersionNumber v210 = stableVersion(2, 1, 0);
- final SemanticVersionNumber v211 = stableVersion(2, 1, 1);
- final SemanticVersionNumber v300 = stableVersion(3, 0, 0);
+ final var v200 = stableVersion(2, 0, 0);
+ final var v201 = stableVersion(2, 0, 1);
+ final var v210 = stableVersion(2, 1, 0);
+ final var v211 = stableVersion(2, 1, 1);
+ final var v300 = stableVersion(3, 0, 0);
// test order of version numbers
assertTrue(v100a.compareTo(v100a1) < 0, "1.0.0-alpha >= 1.0.0-alpha.1");
@@ -348,17 +346,18 @@ public final class SemanticVersionTest {
/**
* Tests that simple stable versions can be created and their parts read
- *
+ *
* @since 2022-02-19
+ * @since v0.4.0
*/
@Test
public void testSimpleStableVersions() {
- final SemanticVersionNumber v100 = stableVersion(1, 0, 0);
+ final var v100 = stableVersion(1, 0, 0);
assertEquals(1, v100.majorVersion());
assertEquals(0, v100.minorVersion());
assertEquals(0, v100.patchVersion());
- final SemanticVersionNumber v925 = stableVersion(9, 2, 5);
+ final var v925 = stableVersion(9, 2, 5);
assertEquals(9, v925.majorVersion());
assertEquals(2, v925.minorVersion());
assertEquals(5, v925.patchVersion());
@@ -367,26 +366,28 @@ public final class SemanticVersionTest {
/**
* Tests that {@link SemanticVersionNumber#toString} works for simple version
* numbers
- *
+ *
* @since 2022-02-19
+ * @since v0.4.0
*/
@Test
public void testSimpleToString() {
- final SemanticVersionNumber v100 = stableVersion(1, 0, 0);
+ final var v100 = stableVersion(1, 0, 0);
assertEquals("1.0.0", v100.toString());
- final SemanticVersionNumber v845a1 = preRelease(8, 4, 5, "alpha", 1);
+ final var v845a1 = preRelease(8, 4, 5, "alpha", 1);
assertEquals("8.4.5-alpha.1", v845a1.toString());
}
/**
* Tests that simple unstable versions can be created and their parts read
- *
+ *
* @since 2022-02-19
+ * @since v0.4.0
*/
@Test
public void testSimpleUnstableVersions() {
- final SemanticVersionNumber v350a1 = preRelease(3, 5, 0, "alpha", 1);
+ final var v350a1 = preRelease(3, 5, 0, "alpha", 1);
assertEquals(3, v350a1.majorVersion(),
"Incorrect major version for v3.5.0a1");
assertEquals(5, v350a1.minorVersion(),
diff --git a/src/test/java/sevenUnits/utils/UncertainDoubleTest.java b/src/test/java/sevenUnits/utils/UncertainDoubleTest.java
index 36b373b..733a308 100644
--- a/src/test/java/sevenUnits/utils/UncertainDoubleTest.java
+++ b/src/test/java/sevenUnits/utils/UncertainDoubleTest.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Adrien Hopkins
+ * Copyright (C) 2021, 2022, 2024, 2025 Adrien Hopkins
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -32,11 +32,10 @@ import org.junit.jupiter.api.Test;
*
* @author Adrien Hopkins
* @since 2021-11-29
+ * @since v0.3.2
*/
class UncertainDoubleTest {
- /**
- * Ensures that the compareTo function behaves correctly.
- */
+ /** Ensures that the compareTo function behaves correctly. */
@Test
final void testCompareTo() {
assertTrue(of(2.0, 0.5).compareTo(of(2.0, 0.1)) == 0);
@@ -44,23 +43,18 @@ class UncertainDoubleTest {
assertTrue(of(2.0, 0.5).compareTo(of(3.0, 0.1)) < 0);
}
- /**
- * Tests the ___exact operations
- */
+ /** Tests the ___exact operations */
@Test
final void testExactOperations() {
- final UncertainDouble x = UncertainDouble.of(Math.PI, 0.1);
+ final var x = UncertainDouble.of(Math.PI, 0.1);
// slightly different because roundoff errors
- final UncertainDouble x1 = UncertainDouble.of(Math.PI + Math.E - Math.E,
- 0.1);
- final UncertainDouble x2 = UncertainDouble.of(Math.PI * Math.E / Math.E,
- 0.1);
+ final var x1 = UncertainDouble.of(Math.PI + Math.E - Math.E, 0.1);
+ final var x2 = UncertainDouble.of(Math.PI * Math.E / Math.E, 0.1);
// get results
- final UncertainDouble result1 = x.plusExact(Math.E).minusExact(Math.E);
- final UncertainDouble result2 = x.timesExact(Math.E)
- .dividedByExact(Math.E);
+ final var result1 = x.plusExact(Math.E).minusExact(Math.E);
+ final var result2 = x.timesExact(Math.E).dividedByExact(Math.E);
// test that these operations work & don't change uncertainty
assertEquals(x1, result1);
@@ -75,36 +69,35 @@ class UncertainDoubleTest {
/**
* Test for {@link UncertainDouble#fromRoundedString}
- *
+ *
* @since 2022-04-18
+ * @since v0.4.0
*/
@Test
final void testFromRoundedString() {
assertEquals(of(12345.678, 0.001), fromRoundedString("12345.678"));
}
- /**
- * Test for {@link UncertainDouble#fromString}
- */
+ /** Test for {@link UncertainDouble#fromString} */
@Test
final void testFromString() {
// valid strings
- assertEquals(of(2.0, 0.5), fromString("2.0 � 0.5"));
+ assertEquals(of(2.0, 0.5), fromString("2.0 ± 0.5"));
assertEquals(of(2.0, 0.5), fromString("2.0 +- 0.5"));
assertEquals(of(2.0, 0.0), fromString("2.0"));
// invalid strings
- for (final String s : List.of("2.A", "A", "2.0 � .", "� 3.5")) {
+ for (final String s : List.of("2.A", "A", "2.0 ± ", " ± 3.5")) {
assertThrows(IllegalArgumentException.class, () -> fromString(s));
}
// back and forth
- assertEquals("2.0 � 0.5", of(2.0, 0.5).toString());
+ assertEquals("2.0 ± 0.5", of(2.0, 0.5).toString());
assertEquals("2.0", of(2.0, 0).toString());
}
@Test
final void testHashCode() {
- assertEquals(of(2.0, 0.5).hashCode(), fromString("2.0 � 0.5").hashCode());
+ assertEquals(of(2.0, 0.5).hashCode(), fromString("2.0 ± 0.5").hashCode());
}
}
diff --git a/src/test/java/sevenUnitsGUI/I18nTest.java b/src/test/java/sevenUnitsGUI/I18nTest.java
new file mode 100644
index 0000000..2f90d76
--- /dev/null
+++ b/src/test/java/sevenUnitsGUI/I18nTest.java
@@ -0,0 +1,95 @@
+/**
+ * Copyright (C) 2025 Adrien Hopkins
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+package sevenUnitsGUI;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+import java.util.stream.Stream;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+/**
+ * Tests for the internationalization system.
+ *
+ * @since v1.0.0
+ */
+class I18nTest {
+ private static final Stream<String> testLocaleSupported() {
+ return Stream.of("en", "fr");
+ }
+
+ private static final Stream<Arguments> testLocalization() {
+ return Stream.of(Arguments.of("tv.title", "en", "7Units [v]"),
+ Arguments.of("tv.title", "fr", "7Unités [v]"),
+ Arguments.of("tv.convert_units.title", "en", "Convert Units"),
+ Arguments.of("tv.convert_units.title", "fr", "Convertir Unités"));
+ }
+
+ /**
+ * Tests that the default locale is supported.
+ *
+ * @since v1.0.0
+ * @see Presenter#DEFAULT_LOCALE
+ */
+ @Test
+ void testDefaultLocaleSupported() {
+ final var p = new Presenter(new ViewBot());
+ assertNotNull(p.locales.get(Presenter.DEFAULT_LOCALE),
+ "Default locale is not supported.");
+ }
+
+ /**
+ * Ensures that the system supports the provided locale.
+ *
+ * @param localeName locale to test for support
+ *
+ * @since 2025-06-04
+ * @since v1.0.0
+ */
+ @ParameterizedTest
+ @MethodSource
+ void testLocaleSupported(String localeName) {
+ final var p = new Presenter(new ViewBot());
+ assertNotNull(p.locales.get(localeName),
+ "Locale \"" + localeName + "\" is not supported.");
+ }
+
+ /**
+ * Tests that the system can correctly localize text, using the default
+ * locales.
+ *
+ * @param key key of text to localize
+ * @param locale locale to use
+ * @param expected expected value of output text
+ *
+ * @since 2025-06-04
+ * @since v1.0.0
+ */
+ @ParameterizedTest
+ @MethodSource
+ void testLocalization(String key, String locale, String expected) {
+ final var p = new Presenter(new ViewBot());
+ p.setUserLocale(locale);
+ final var actual = p.getLocalizedText(key);
+ assertEquals(expected, actual);
+ }
+
+}
diff --git a/src/test/java/sevenUnitsGUI/PrefixRepetitionTest.java b/src/test/java/sevenUnitsGUI/PrefixRepetitionTest.java
index 476e407..ead5f4a 100644
--- a/src/test/java/sevenUnitsGUI/PrefixRepetitionTest.java
+++ b/src/test/java/sevenUnitsGUI/PrefixRepetitionTest.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2022 Adrien Hopkins
+ * Copyright (C) 2022, 2024, 2025 Adrien Hopkins
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -31,15 +31,15 @@ import sevenUnits.unit.Metric;
/**
* Tests for the default prefix repetition rules.
*
- * @since v0.4.0
* @since 2022-07-17
+ * @since v0.4.0
*/
class PrefixRepetitionTest {
/**
* Ensures that the complex repetition rule disallows invalid prefix lists.
- *
- * @since v0.4.0
+ *
* @since 2022-07-17
+ * @since v0.4.0
*/
@Test
void testInvalidComplexRepetition() {
@@ -57,9 +57,9 @@ class PrefixRepetitionTest {
/**
* Tests the {@code NO_REPETITION} rule.
- *
- * @since v0.4.0
+ *
* @since 2022-07-17
+ * @since v0.4.0
*/
@Test
void testNoRepetition() {
@@ -71,9 +71,9 @@ class PrefixRepetitionTest {
/**
* Tests the {@code NO_RESTRICTION} rule.
- *
- * @since v0.4.0
+ *
* @since 2022-07-17
+ * @since v0.4.0
*/
@Test
void testNoRestriction() {
@@ -85,9 +85,9 @@ class PrefixRepetitionTest {
/**
* Ensures that the complex repetition rule allows valid prefix lists.
- *
- * @since v0.4.0
+ *
* @since 2022-07-17
+ * @since v0.4.0
*/
@Test
void testValidComplexRepetition() {
diff --git a/src/test/java/sevenUnitsGUI/PrefixSearchTest.java b/src/test/java/sevenUnitsGUI/PrefixSearchTest.java
index 305d0d7..00dd960 100644
--- a/src/test/java/sevenUnitsGUI/PrefixSearchTest.java
+++ b/src/test/java/sevenUnitsGUI/PrefixSearchTest.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2022 Adrien Hopkins
+ * Copyright (C) 2022, 2024, 2025 Adrien Hopkins
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -18,6 +18,7 @@ package sevenUnitsGUI;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import static sevenUnitsGUI.PrefixSearchRule.COMMON_PREFIXES;
import static sevenUnitsGUI.PrefixSearchRule.NO_PREFIXES;
import static sevenUnitsGUI.PrefixSearchRule.getCoherentOnlyRule;
@@ -35,13 +36,11 @@ import sevenUnits.unit.Metric;
/**
* Tests for {@link PrefixSearchRule}
*
- * @since v0.4.0
* @since 2022-07-17
+ * @since v0.4.0
*/
class PrefixSearchTest {
- /**
- * A method that creates duplicate copies of the common prefix rule.
- */
+ /** A method that creates duplicate copies of the common prefix rule. */
private static final PrefixSearchRule getCommonRuleCopy() {
return getCoherentOnlyRule(Set.of(Metric.KILO, Metric.MILLI));
}
@@ -51,8 +50,8 @@ class PrefixSearchTest {
* {@link sevenUnitsGUI.PrefixSearchRule#apply(java.util.Map.Entry)}, for a
* coherent unit and {@link PrefixSearchRule#COMMON_PREFIXES}.
*
- * @since v0.4.0
* @since 2022-07-17
+ * @since v0.4.0
*/
@Test
final void testCoherentPrefixSearch() {
@@ -69,8 +68,8 @@ class PrefixSearchTest {
* Test method for
* {@link sevenUnitsGUI.PrefixSearchRule#equals(java.lang.Object)}.
*
- * @since v0.4.0
* @since 2022-07-17
+ * @since v0.4.0
*/
@Test
final void testEquals() {
@@ -84,8 +83,8 @@ class PrefixSearchTest {
/**
* Test method for {@link sevenUnitsGUI.PrefixSearchRule#getPrefixes()}.
*
- * @since v0.4.0
* @since 2022-07-17
+ * @since v0.4.0
*/
@Test
final void testGetPrefixes() {
@@ -97,8 +96,8 @@ class PrefixSearchTest {
/**
* Test method for {@link sevenUnitsGUI.PrefixSearchRule#hashCode()}.
*
- * @since v0.4.0
* @since 2022-07-17
+ * @since v0.4.0
*/
@Test
final void testHashCode() {
@@ -109,9 +108,9 @@ class PrefixSearchTest {
/**
* Tests prefix searching for a non-coherent unit and
* {@link PrefixSearchRule#COMMON_PREFIXES}.
- *
- * @since v0.4.0
+ *
* @since 2022-07-17
+ * @since v0.4.0
*/
@Test
final void testNonCoherentPrefixSearch() {
@@ -124,9 +123,9 @@ class PrefixSearchTest {
/**
* Tests that {@link PrefixSearchRule#NO_PREFIXES} returns the original unit.
- *
- * @since v0.4.0
+ *
* @since 2022-07-17
+ * @since v0.4.0
*/
@Test
void testNoPrefixes() {
@@ -145,14 +144,17 @@ class PrefixSearchTest {
/**
* Test method for {@link sevenUnitsGUI.PrefixSearchRule#toString()}.
*
- * @since v0.4.0
* @since 2022-07-17
+ * @since v0.4.0
*/
@Test
final void testToString() {
- assertEquals(
- "Apply the following prefixes: [kilo (\u00D7 1000.0), milli (\u00D7 0.001)]",
- COMMON_PREFIXES.toString());
+ final var toString = COMMON_PREFIXES.toString();
+ final var valid1 = "Apply the following prefixes: [kilo (\u00D7 1000.0), milli (\u00D7 0.001)]";
+ final var valid2 = "Apply the following prefixes: [milli (\u00D7 0.001), kilo (\u00D7 1000.0)]";
+
+ assertTrue(valid1.equals(toString) || valid2.equals(toString),
+ "COMMON_PREFIXES.toString invalid (was \"" + toString + "\").");
}
}
diff --git a/src/test/java/sevenUnitsGUI/PresenterTest.java b/src/test/java/sevenUnitsGUI/PresenterTest.java
index 9e25a08..9ac5b84 100644
--- a/src/test/java/sevenUnitsGUI/PresenterTest.java
+++ b/src/test/java/sevenUnitsGUI/PresenterTest.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2022 Adrien Hopkins
+ * Copyright (C) 2022-2025 Adrien Hopkins
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -17,13 +17,12 @@
package sevenUnitsGUI;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
-import java.math.RoundingMode;
import java.nio.file.Path;
import java.util.HashSet;
-import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
@@ -32,12 +31,12 @@ import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import sevenUnits.unit.BaseDimension;
import sevenUnits.unit.BritishImperial;
import sevenUnits.unit.LinearUnit;
-import sevenUnits.unit.LinearUnitValue;
import sevenUnits.unit.Metric;
import sevenUnits.unit.Unit;
import sevenUnits.unit.UnitDatabase;
@@ -53,11 +52,11 @@ import sevenUnits.utils.UncertainDouble;
* <em>Note: this test outputs a lot to the standard output, because creating a
* {@link UnitDatabase} and converting with a {@link ViewBot} both trigger
* println statements.</em>
- *
+ *
* @author Adrien Hopkins
*
- * @since v0.4.0
* @since 2022-02-10
+ * @since v0.4.0
*/
public final class PresenterTest {
private static final Path TEST_SETTINGS = Path.of("src", "test", "resources",
@@ -74,10 +73,10 @@ public final class PresenterTest {
/**
* @return rounding rules used by {@link #testRoundingRules}
- * @since v0.4.0
* @since 2022-04-16
+ * @since v0.4.0
*/
- private static final Stream<Function<UncertainDouble, String>> getRoundingRules() {
+ private static Stream<Function<UncertainDouble, String>> getRoundingRules() {
final var SCIENTIFIC_ROUNDING = StandardDisplayRules.uncertaintyBased();
final var INTEGER_ROUNDING = StandardDisplayRules.fixedDecimals(0);
final var SIG_FIG_ROUNDING = StandardDisplayRules.fixedPrecision(4);
@@ -85,81 +84,99 @@ public final class PresenterTest {
return Stream.of(SCIENTIFIC_ROUNDING, INTEGER_ROUNDING, SIG_FIG_ROUNDING);
}
- private static final Stream<Function<Map.Entry<String, LinearUnit>, Map<String, LinearUnit>>> getSearchRules() {
+ private static Stream<Function<Map.Entry<String, LinearUnit>, Map<String, LinearUnit>>> getSearchRules() {
return SEARCH_RULES;
}
- private static final Set<String> names(Set<? extends Nameable> units) {
+ private static Set<String> names(Set<? extends Nameable> units) {
return units.stream().map(Nameable::getName).collect(Collectors.toSet());
}
+ private static Stream<Arguments> testConvertExpressions() {
+ return Stream.of(
+ Arguments.of("10000.0 m", "km", "10000.0 m = 10.00000 km"),
+ Arguments.of("1.0 m", "ft; in", "1.0 m = 3 ft + 3 in"),
+ Arguments.of("1.0 m", "ftin", "1.0 m = 3 ft + 3 in"));
+ }
+
+ private static Stream<Arguments> testConvertUnits() {
+ return Stream.of(
+ Arguments.of("m", "km", 10000.0, "10000.0 m = 10.00000 km"),
+ Arguments.of("m", "ftin", 1.0, "1.0 m = 3 ft + 3 in"));
+ }
+
/**
* Test method for {@link Presenter#convertExpressions}
- *
- * @since v0.4.0
+ *
* @since 2022-02-12
+ * @since v0.4.0
*/
- @Test
- void testConvertExpressions() {
+ @ParameterizedTest
+ @MethodSource
+ void testConvertExpressions(String from, String to, String expectedOutput) {
// setup
- final ViewBot viewBot = new ViewBot();
- final Presenter presenter = new Presenter(viewBot);
+ final var viewBot = new ViewBot();
+ final var presenter = new Presenter(viewBot);
- viewBot.setFromExpression("10000.0 m");
- viewBot.setToExpression("km");
+ viewBot.setFromExpression(from);
+ viewBot.setToExpression(to);
// convert expression
presenter.convertExpressions();
// test result
- final List<UnitConversionRecord> outputs = viewBot
- .expressionConversionList();
- assertEquals("10000.0 m = 10.00000 km",
- outputs.get(outputs.size() - 1).toString());
+ final var outputs = viewBot.expressionConversionList();
+ assertEquals(expectedOutput, outputs.get(outputs.size() - 1).toString());
}
/**
- * Tests that unit-conversion Views can correctly convert units
- *
- * @since v0.4.0
+ * Test method for {@link Presenter#convertUnits}
+ *
* @since 2022-02-12
+ * @since v0.4.0
*/
- @Test
- void testConvertUnits() {
+ @ParameterizedTest
+ @MethodSource
+ void testConvertUnits(String from, String to, double value,
+ String expectedOutput) {
// setup
- final ViewBot viewBot = new ViewBot();
- final Presenter presenter = new Presenter(viewBot);
+ final var viewBot = new ViewBot();
+ final var presenter = new Presenter(viewBot);
- viewBot.setFromUnitNames(names(testUnits));
- viewBot.setToUnitNames(names(testUnits));
- viewBot.setFromSelection("metre");
- viewBot.setToSelection("kilometre");
- viewBot.setInputValue("10000.0");
+ viewBot.setFromSelection(from);
+ viewBot.setToSelection(to);
+ viewBot.setInputValue(Double.toString(value));
- // convert units
+ // convert expression
presenter.convertUnits();
- /*
- * use result from system as expected - I'm not testing unit conversion
- * here (that's for the backend tests), I'm just testing that it correctly
- * calls the unit conversion system
- */
- final LinearUnitValue expectedInput = LinearUnitValue.of(Metric.METRE,
- UncertainDouble.fromRoundedString("10000.0"));
- final LinearUnitValue expectedOutput = expectedInput
- .convertTo(Metric.KILOMETRE);
- final UnitConversionRecord expectedUC = UnitConversionRecord.valueOf(
- expectedInput.getUnit().getName(),
- expectedOutput.getUnit().getName(), "10000.0",
- expectedOutput.getValue().toString(false, RoundingMode.HALF_EVEN));
- assertEquals(List.of(expectedUC), viewBot.unitConversionList());
+ // test result
+ final var outputs = viewBot.unitConversionList();
+ assertEquals(expectedOutput, outputs.get(outputs.size() - 1).toString());
+ }
+
+ /**
+ * Ensures that the default unitfile can be disabled.
+ *
+ * @since 2025-02-23
+ * @since v1.0.0
+ */
+ @Test
+ void testDisableDefault() {
+ final var viewBot = new ViewBot();
+ final var presenter = new Presenter(viewBot);
+ assumeTrue(presenter.database.containsUnitName("joule"),
+ "Attempted to test disabling default on unit not in default file.");
+ presenter.setUseDefaultDatafiles(false);
+ assertFalse(presenter.database.containsUnitName("joule"),
+ "Presenter disabled default datafiles, but still contains the joule.");
}
/**
* Tests that duplicate units are successfully removed, if that is asked for
- *
- * @since v0.4.0
+ *
* @since 2022-04-16
+ * @since v0.4.0
*/
@Test
void testDuplicateUnits() {
@@ -190,9 +207,9 @@ public final class PresenterTest {
/**
* Tests that one-way conversion correctly filters From and To units
- *
- * @since v0.4.0
+ *
* @since 2022-04-16
+ * @since v0.4.0
*/
@Test
void testOneWayConversion() {
@@ -224,9 +241,9 @@ public final class PresenterTest {
/**
* Tests the prefix-viewing functionality.
- *
- * @since v0.4.0
+ *
* @since 2022-04-16
+ * @since v0.4.0
*/
@Test
void testPrefixViewing() {
@@ -254,9 +271,9 @@ public final class PresenterTest {
/**
* Tests that rounding rules are used correctly.
- *
- * @since v0.4.0
+ *
* @since 2022-04-16
+ * @since v0.4.0
*/
@ParameterizedTest
@MethodSource("getRoundingRules")
@@ -273,9 +290,9 @@ public final class PresenterTest {
presenter.convertUnits();
// test the result of the rounding
- final String expectedOutputString = roundingRule
+ final var expectedOutputString = roundingRule
.apply(UncertainDouble.fromRoundedString("12.3456789"));
- final String actualOutputString = viewBot.unitConversionList().get(0)
+ final var actualOutputString = viewBot.unitConversionList().get(0)
.outputValueString();
assertEquals(expectedOutputString, actualOutputString);
}
@@ -284,8 +301,8 @@ public final class PresenterTest {
* Tests that the Presenter correctly applies search rules.
*
* @param searchRule search rule to test
- * @since v0.4.0
* @since 2022-07-08
+ * @since v0.4.0
*/
@ParameterizedTest
@MethodSource("getSearchRules")
@@ -309,7 +326,7 @@ public final class PresenterTest {
.apply(Map.entry("inch", BritishImperial.Length.INCH)).keySet());
expectedOutput.addAll(
searchRule.apply(Map.entry("metre", Metric.METRE)).keySet());
- final Set<String> actualOutput = viewBot.getFromUnitNames();
+ final var actualOutput = viewBot.getFromUnitNames();
// test output
assertEquals(expectedOutput, actualOutput);
@@ -317,9 +334,9 @@ public final class PresenterTest {
/**
* Tests that settings can be saved to and loaded from a file.
- *
- * @since v0.4.0
+ *
* @since 2022-04-16
+ * @since v0.4.0
*/
@Test
void testSettingsSaving() {
@@ -351,9 +368,9 @@ public final class PresenterTest {
/**
* Ensures the Presenter generates the correct data upon a unit-viewing.
- *
- * @since v0.4.0
+ *
* @since 2022-04-16
+ * @since v0.4.0
*/
@Test
void testUnitViewing() {
@@ -385,15 +402,15 @@ public final class PresenterTest {
/**
* Test for {@link Presenter#updateView()}
- *
- * @since v0.4.0
+ *
* @since 2022-02-12
+ * @since v0.4.0
*/
@Test
void testUpdateView() {
// setup
- final ViewBot viewBot = new ViewBot();
- final Presenter presenter = new Presenter(viewBot);
+ final var viewBot = new ViewBot();
+ final var presenter = new Presenter(viewBot);
presenter.setOneWayConversionEnabled(false);
presenter.setSearchRule(PrefixSearchRule.NO_PREFIXES);
@@ -415,8 +432,8 @@ public final class PresenterTest {
// filter to length units only, then get the filtered sets of units
presenter.updateView();
- final Set<String> fromUnits = viewBot.getFromUnitNames();
- final Set<String> toUnits = viewBot.getToUnitNames();
+ final var fromUnits = viewBot.getFromUnitNames();
+ final var toUnits = viewBot.getToUnitNames();
// test that fromUnits/toUnits is [METRE, KILOMETRE]
assertEquals(Set.of("metre", "kilometre"), fromUnits);
diff --git a/src/test/java/sevenUnitsGUI/RoundingTest.java b/src/test/java/sevenUnitsGUI/RoundingTest.java
index f749f85..589b8d0 100644
--- a/src/test/java/sevenUnitsGUI/RoundingTest.java
+++ b/src/test/java/sevenUnitsGUI/RoundingTest.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2022 Adrien Hopkins
+ * Copyright (C) 2022, 2024, 2025 Adrien Hopkins
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -41,8 +41,8 @@ import sevenUnitsGUI.StandardDisplayRules.UncertaintyBased;
/**
* Tests that ensure the rounding rules work as intended.
*
- * @since v0.4.0
* @since 2022-07-17
+ * @since v0.4.0
*/
class RoundingTest {
// rounding rules to test
@@ -69,8 +69,8 @@ class RoundingTest {
/**
* @return arguments for
* {@link #testFixedDecimalRounding(UncertainDouble, String, String, String)}
- * @since v0.4.0
* @since 2022-07-17
+ * @since v0.4.0
*/
private static final Stream<Arguments> fixedDecimalRoundingExamples() {
// input, zero decimal string, two decimal string, six decimal string
@@ -83,8 +83,8 @@ class RoundingTest {
/**
* @return arguments for
* {@link #testFixedPrecisionRounding(UncertainDouble, String, String, String)}
- * @since v0.4.0
* @since 2022-07-17
+ * @since v0.4.0
*/
private static final Stream<Arguments> fixedPrecisionRoundingExamples() {
// input, one sig fig string, three s.f. string, six s.f. string
@@ -97,8 +97,8 @@ class RoundingTest {
/**
* @return arguments for
* {@link #testUncertaintyRounding(UncertainDouble, String)}
- * @since v0.4.0
* @since 2022-07-17
+ * @since v0.4.0
*/
private static final Stream<Arguments> uncertaintyRoundingExamples() {
// input, uncertainty rounding string
@@ -112,8 +112,8 @@ class RoundingTest {
* Test for {@link FixedDecimals#decimalPlaces()} and
* {@link FixedPrecision#significantFigures()}.
*
- * @since v0.4.0
* @since 2022-07-17
+ * @since v0.4.0
*/
@Test
void testDataMethods() {
@@ -137,9 +137,9 @@ class RoundingTest {
/**
* Tests that the rounding methods' equals() methods work.
- *
- * @since v0.4.0
+ *
* @since 2022-07-17
+ * @since v0.4.0
*/
@Test
void testEquals() {
@@ -161,7 +161,7 @@ class RoundingTest {
// test that FixedDecimals is never equal to FixedPrecision
// this unlikely argument is the test - the equals should return false!
@SuppressWarnings("unlikely-arg-type")
- final boolean differentRulesEqual = Objects.equals(fixedDecimals(4),
+ final var differentRulesEqual = Objects.equals(fixedDecimals(4),
fixedPrecision(4));
assertFalse(differentRulesEqual, "fixedDecimals(4) == fixedPrecision(4)");
}
@@ -174,6 +174,7 @@ class RoundingTest {
* @param twoDecimalString expected string for two decimal places
* @param sixDecimalString expected string for six decimal places
* @since 2022-07-17
+ * @since v0.4.0
*/
@ParameterizedTest
@MethodSource("fixedDecimalRoundingExamples")
@@ -200,8 +201,8 @@ class RoundingTest {
* @param oneSigFigString expected string for one significant figure
* @param threeSigFigString expected string for three significant figures
* @param twelveSigFigString expected string for twelve significant figures
- * @since v0.4.0
* @since 2022-07-17
+ * @since v0.4.0
*/
@ParameterizedTest
@MethodSource("fixedPrecisionRoundingExamples")
@@ -225,9 +226,9 @@ class RoundingTest {
/**
* Tests that {@link StandardDisplayRules#getStandardRule} gets rounding
* rules as intended.
- *
- * @since v0.4.0
+ *
* @since 2022-07-17
+ * @since v0.4.0
*/
@Test
void testGetStandardRule() {
@@ -243,9 +244,9 @@ class RoundingTest {
/**
* Tests that the rounding methods' equals() methods work.
- *
- * @since v0.4.0
+ *
* @since 2022-07-17
+ * @since v0.4.0
*/
@Test
void testHashCode() {
@@ -257,9 +258,9 @@ class RoundingTest {
/**
* Tests that the {@code toString()} methods of the three rounding rule
* classes work correctly.
- *
- * @since v0.4.0
+ *
* @since 2022-07-17
+ * @since v0.4.0
*/
@Test
void testToString() {
@@ -273,8 +274,8 @@ class RoundingTest {
*
* @param input input number
* @param output expected output string
- * @since v0.4.0
* @since 2022-07-17
+ * @since v0.4.0
*/
@ParameterizedTest
@MethodSource("uncertaintyRoundingExamples")
diff --git a/src/test/java/sevenUnitsGUI/TabbedViewTest.java b/src/test/java/sevenUnitsGUI/TabbedViewTest.java
index 165718f..b32579c 100644
--- a/src/test/java/sevenUnitsGUI/TabbedViewTest.java
+++ b/src/test/java/sevenUnitsGUI/TabbedViewTest.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2022 Adrien Hopkins
+ * Copyright (C) 2022, 2024, 2025 Adrien Hopkins
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -18,20 +18,24 @@ package sevenUnitsGUI;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import java.util.concurrent.TimeUnit;
+
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Timeout;
/**
- * Test for the TabbedView
+ * Test for the TabbedView.
*
- * @since v0.4.0
* @since 2022-07-17
+ * @since v0.4.0
*/
+@Timeout(value = 10, unit = TimeUnit.SECONDS)
class TabbedViewTest {
/**
* @return a view with all settings set to standard values
- *
- * @since v0.4.0
+ *
* @since 2022-07-17
+ * @since v0.4.0
*/
private static final TabbedView setupView() {
final var view = new TabbedView();
@@ -50,9 +54,9 @@ class TabbedViewTest {
/**
* Simulates an expression conversion operation, and ensures it works
* properly.
- *
- * @since v0.4.0
+ *
* @since 2022-07-17
+ * @since v0.4.0
*/
@Test
void testExpressionConversion() {
@@ -71,9 +75,9 @@ class TabbedViewTest {
/**
* Simulates a unit conversion operation, and ensures it works properly.
- *
- * @since v0.4.0
+ *
* @since 2022-07-17
+ * @since v0.4.0
*/
@Test
void testUnitConversion() {