From 78af49e0e5b2ab2eaab87e62c33089c5caa834f8 Mon Sep 17 00:00:00 2001 From: Adrien Hopkins Date: Mon, 28 Jun 2021 17:16:12 -0500 Subject: Renamed project to 7Units --- .../math/ConditionalExistenceCollectionsTest.java | 159 ----------- .../unitConverter/math/ExpressionParserTest.java | 52 ---- .../org/unitConverter/math/ObjectProductTest.java | 78 ----- .../java/org/unitConverter/unit/MultiUnitTest.java | 106 ------- .../org/unitConverter/unit/UnitDatabaseTest.java | 310 -------------------- src/test/java/org/unitConverter/unit/UnitTest.java | 146 ---------- .../math/ConditionalExistenceCollectionsTest.java | 161 +++++++++++ .../java/sevenUnits/math/ExpressionParserTest.java | 54 ++++ .../java/sevenUnits/math/ObjectProductTest.java | 80 ++++++ src/test/java/sevenUnits/unit/MultiUnitTest.java | 110 +++++++ .../java/sevenUnits/unit/UnitDatabaseTest.java | 317 +++++++++++++++++++++ src/test/java/sevenUnits/unit/UnitTest.java | 153 ++++++++++ 12 files changed, 875 insertions(+), 851 deletions(-) delete mode 100644 src/test/java/org/unitConverter/math/ConditionalExistenceCollectionsTest.java delete mode 100644 src/test/java/org/unitConverter/math/ExpressionParserTest.java delete mode 100644 src/test/java/org/unitConverter/math/ObjectProductTest.java delete mode 100644 src/test/java/org/unitConverter/unit/MultiUnitTest.java delete mode 100644 src/test/java/org/unitConverter/unit/UnitDatabaseTest.java delete mode 100644 src/test/java/org/unitConverter/unit/UnitTest.java create mode 100644 src/test/java/sevenUnits/math/ConditionalExistenceCollectionsTest.java create mode 100644 src/test/java/sevenUnits/math/ExpressionParserTest.java create mode 100644 src/test/java/sevenUnits/math/ObjectProductTest.java create mode 100644 src/test/java/sevenUnits/unit/MultiUnitTest.java create mode 100644 src/test/java/sevenUnits/unit/UnitDatabaseTest.java create mode 100644 src/test/java/sevenUnits/unit/UnitTest.java (limited to 'src/test') diff --git a/src/test/java/org/unitConverter/math/ConditionalExistenceCollectionsTest.java b/src/test/java/org/unitConverter/math/ConditionalExistenceCollectionsTest.java deleted file mode 100644 index 311ace5..0000000 --- a/src/test/java/org/unitConverter/math/ConditionalExistenceCollectionsTest.java +++ /dev/null @@ -1,159 +0,0 @@ -/** - * Copyright (C) 2019 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 . - */ -package org.unitConverter.math; - -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.util.Arrays; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.NoSuchElementException; - -import org.junit.jupiter.api.Test; -import org.unitConverter.math.ConditionalExistenceCollections.ConditionalExistenceIterator; - -/** - * Tests the {@link #ConditionalExistenceCollections}. - * - * @author Adrien Hopkins - * @since 2019-10-16 - */ -class ConditionalExistenceCollectionsTest { - - /** - * The returned iterator ignores elements that don't start with "a". - * - * @return test iterator - * @since 2019-10-17 - */ - ConditionalExistenceIterator getTestIterator() { - final List items = Arrays.asList("aa", "ab", "ba"); - final Iterator it = items.iterator(); - final ConditionalExistenceIterator cit = (ConditionalExistenceIterator) 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 - */ - Map getTestMap() { - final Map map = new HashMap<>(); - map.put("one", 1); - map.put("two", 2); - map.put("zero", 0); - map.put("ten", 10); - final Map conditionalMap = ConditionalExistenceCollections.conditionalExistenceMap(map, - e -> !Integer.valueOf(0).equals(e.getValue())); - return conditionalMap; - } - - /** - * Test method for {@link org.unitConverter.math.ZeroIsNullMap#containsKey(java.lang.Object)}. - */ - @Test - void testContainsKeyObject() { - final Map map = this.getTestMap(); - assertTrue(map.containsKey("one")); - assertTrue(map.containsKey("ten")); - assertFalse(map.containsKey("five")); - assertFalse(map.containsKey("zero")); - } - - /** - * Test method for {@link org.unitConverter.math.ZeroIsNullMap#containsValue(java.lang.Object)}. - */ - @Test - void testContainsValueObject() { - final Map map = this.getTestMap(); - assertTrue(map.containsValue(1)); - assertTrue(map.containsValue(10)); - assertFalse(map.containsValue(5)); - assertFalse(map.containsValue(0)); - } - - /** - * Test method for {@link org.unitConverter.math.ZeroIsNullMap#entrySet()}. - */ - @Test - void testEntrySet() { - final Map map = this.getTestMap(); - for (final Entry e : map.entrySet()) { - assertTrue(e.getValue() != 0); - } - } - - /** - * Test method for {@link org.unitConverter.math.ZeroIsNullMap#get(java.lang.Object)}. - */ - @Test - void testGetObject() { - final Map map = this.getTestMap(); - assertEquals(1, map.get("one")); - assertEquals(10, map.get("ten")); - assertEquals(null, map.get("five")); - assertEquals(null, map.get("zero")); - } - - @Test - void testIterator() { - final ConditionalExistenceIterator testIterator = this.getTestIterator(); - - assertTrue(testIterator.hasNext); - assertTrue(testIterator.hasNext()); - assertEquals("aa", testIterator.nextElement); - assertEquals("aa", testIterator.next()); - - assertTrue(testIterator.hasNext); - assertTrue(testIterator.hasNext()); - assertEquals("ab", testIterator.nextElement); - assertEquals("ab", testIterator.next()); - - assertFalse(testIterator.hasNext); - assertFalse(testIterator.hasNext()); - assertEquals(null, testIterator.nextElement); - assertThrows(NoSuchElementException.class, testIterator::next); - } - - /** - * Test method for {@link org.unitConverter.math.ZeroIsNullMap#keySet()}. - */ - @Test - void testKeySet() { - final Map map = this.getTestMap(); - assertFalse(map.keySet().contains("zero")); - } - - /** - * Test method for {@link org.unitConverter.math.ZeroIsNullMap#values()}. - */ - @Test - void testValues() { - final Map map = this.getTestMap(); - assertFalse(map.values().contains(0)); - } - -} diff --git a/src/test/java/org/unitConverter/math/ExpressionParserTest.java b/src/test/java/org/unitConverter/math/ExpressionParserTest.java deleted file mode 100644 index f3180c1..0000000 --- a/src/test/java/org/unitConverter/math/ExpressionParserTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright (C) 2019 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 . - */ -package org.unitConverter.math; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import org.junit.jupiter.api.Test; - -/** - * 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 - */ -class ExpressionParserTest { - private static final ExpressionParser 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(); - - /** - * Test method for {@link org.unitConverter.math.ExpressionParser#parseExpression(java.lang.String)}. - */ - @Test - public void testParseExpression() { - // test parsing of expressions - assertEquals((int) numberParser.parseExpression("1 + 2 ^ 5 * 3"), 97); - assertEquals((int) numberParser.parseExpression("(1 + 2) ^ 5 * 3"), 729); - - // ensure it normally goes left to right - assertEquals((int) numberParser.parseExpression("1 + 2 + 3 + 4"), 10); - assertEquals((int) numberParser.parseExpression("12 - 4 - 3"), 5); - assertEquals((int) numberParser.parseExpression("12 - (4 - 3)"), 11); - assertEquals((int) numberParser.parseExpression("1 / 2 + 3"), 3); - } - -} diff --git a/src/test/java/org/unitConverter/math/ObjectProductTest.java b/src/test/java/org/unitConverter/math/ObjectProductTest.java deleted file mode 100644 index afd18b7..0000000 --- a/src/test/java/org/unitConverter/math/ObjectProductTest.java +++ /dev/null @@ -1,78 +0,0 @@ -/** - * Copyright (C) 2018 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 . - */ -package org.unitConverter.math; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.unitConverter.unit.SI.Dimensions.AREA; -import static org.unitConverter.unit.SI.Dimensions.ENERGY; -import static org.unitConverter.unit.SI.Dimensions.LENGTH; -import static org.unitConverter.unit.SI.Dimensions.MASS; -import static org.unitConverter.unit.SI.Dimensions.MASS_DENSITY; -import static org.unitConverter.unit.SI.Dimensions.QUANTITY; -import static org.unitConverter.unit.SI.Dimensions.TIME; -import static org.unitConverter.unit.SI.Dimensions.VOLUME; - -import org.junit.jupiter.api.Test; -import org.unitConverter.unit.SI; - -/** - * 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 - */ -class ObjectProductTest { - /** - * Tests {@link UnitDimension#equals} - * - * @since 2018-12-12 - * @since v0.1.0 - */ - @Test - public void testEquals() { - assertEquals(LENGTH, LENGTH); - assertFalse(LENGTH.equals(QUANTITY)); - } - - /** - * Tests {@code UnitDimension}'s exponentiation - * - * @since 2019-01-15 - * @since v0.1.0 - */ - @Test - public void testExponents() { - assertEquals(1, LENGTH.getExponent(SI.BaseDimensions.LENGTH)); - assertEquals(3, VOLUME.getExponent(SI.BaseDimensions.LENGTH)); - } - - /** - * Tests {@code UnitDimension}'s multiplication and division. - * - * @since 2018-12-12 - * @since v0.1.0 - */ - @Test - public void testMultiplicationAndDivision() { - assertEquals(AREA, LENGTH.times(LENGTH)); - assertEquals(MASS_DENSITY, MASS.dividedBy(VOLUME)); - assertEquals(ENERGY, AREA.times(MASS).dividedBy(TIME).dividedBy(TIME)); - assertEquals(LENGTH, LENGTH.times(TIME).dividedBy(TIME)); - } -} diff --git a/src/test/java/org/unitConverter/unit/MultiUnitTest.java b/src/test/java/org/unitConverter/unit/MultiUnitTest.java deleted file mode 100644 index 5ea9d07..0000000 --- a/src/test/java/org/unitConverter/unit/MultiUnitTest.java +++ /dev/null @@ -1,106 +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 . - */ -package org.unitConverter.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 { - - @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(SI.METRE.withPrefix(SI.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 feetAndInches = SI.METRE.withPrefix(SI.MILLI) - .convertTo(footInch, millimetres); - assertEquals(feet, feetAndInches.get(0), 1e-10); - assertEquals(inches, feetAndInches.get(1), 1e-10); - } - } - - /** - * Test method for - * {@link org.unitConverter.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 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 feetAndInches = footInch.convertFromBase(metres); - assertEquals(feet, feetAndInches.get(0), 1e-10); - assertEquals(inches, feetAndInches.get(1), 1e-10); - } - } - - /** - * Test method for - * {@link org.unitConverter.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/org/unitConverter/unit/UnitDatabaseTest.java b/src/test/java/org/unitConverter/unit/UnitDatabaseTest.java deleted file mode 100644 index 7f957f3..0000000 --- a/src/test/java/org/unitConverter/unit/UnitDatabaseTest.java +++ /dev/null @@ -1,310 +0,0 @@ -/** - * Copyright (C) 2019 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 . - */ -package org.unitConverter.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.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.NoSuchElementException; -import java.util.Set; - -import org.junit.jupiter.api.Test; - -/** - * 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 - */ -class UnitDatabaseTest { - // some linear units and one nonlinear - private static final Unit U = SI.METRE; - private static final Unit V = SI.KILOGRAM; - private static final Unit W = SI.SECOND; - - // used for testing expressions - // J = U^2 * V / W^2 - private static final LinearUnit J = SI.KILOGRAM.times(SI.METRE.toExponent(2)) - .dividedBy(SI.SECOND.toExponent(2)); - private static final LinearUnit K = SI.KELVIN; - - private static final Unit NONLINEAR = Unit - .fromConversionFunctions(SI.METRE.getBase(), o -> o + 1, o -> o - 1); - - // make the prefix values prime so I can tell which multiplications were made - private static final UnitPrefix A = UnitPrefix.valueOf(2) - .withName(NameSymbol.ofName("A")); - private static final UnitPrefix B = UnitPrefix.valueOf(3) - .withName(NameSymbol.ofName("B")); - private static final UnitPrefix C = UnitPrefix.valueOf(5) - .withName(NameSymbol.ofName("C")); - private static final UnitPrefix AB = UnitPrefix.valueOf(7); - private static final UnitPrefix BC = UnitPrefix.valueOf(11); - - /** - * Confirms that operations that shouldn't function for infinite databases - * throw an {@code IllegalStateException}. - * - * @since 2019-05-03 - */ -// @Test -// @Timeout(value = 1, unit = TimeUnit.SECONDS) - public void testInfiniteSetExceptions() { - // load units - final UnitDatabase infiniteDatabase = new UnitDatabase(); - - infiniteDatabase.addUnit("J", J); - infiniteDatabase.addUnit("K", K); - - infiniteDatabase.addPrefix("A", A); - infiniteDatabase.addPrefix("B", B); - infiniteDatabase.addPrefix("C", C); - - final Set> entrySet = infiniteDatabase.unitMap() - .entrySet(); - final Set keySet = infiniteDatabase.unitMap().keySet(); - assertThrows(IllegalStateException.class, () -> entrySet.toArray()); - assertThrows(IllegalStateException.class, () -> keySet.toArray()); - } - - /** - * Test that prefixes correctly apply to units. - * - * @since 2019-04-14 - * @since v0.2.0 - */ - @Test - public void testPrefixes() { - final UnitDatabase database = new UnitDatabase(); - - database.addUnit("U", U); - database.addUnit("V", V); - database.addUnit("W", W); - - database.addPrefix("A", A); - database.addPrefix("B", B); - database.addPrefix("C", C); - - // test the getPrefixesFromName method - final List expected = Arrays.asList(C, B, A); - assertEquals(expected, database.getPrefixesFromName("ABCU")); - - // get the product - final Unit abcuNonlinear = database.getUnit("ABCU"); - assert abcuNonlinear instanceof LinearUnit; - - final LinearUnit abcu = (LinearUnit) abcuNonlinear; - assertEquals(A.getMultiplier() * B.getMultiplier() * C.getMultiplier(), - abcu.getConversionFactor(), 1e-15); - } - - /** - * Tests the functionnalites of the prefixless unit map. - * - *

- * The map should be an auto-updating view of the units in the database. - *

- * - * @since 2019-04-14 - * @since v0.2.0 - */ - @Test - public void testPrefixlessUnitMap() { - final UnitDatabase database = new UnitDatabase(); - final Map prefixlessUnits = database - .unitMapPrefixless(true); - - database.addUnit("U", U); - database.addUnit("V", V); - database.addUnit("W", W); - - // this should work because the map should be an auto-updating view - assertTrue(prefixlessUnits.containsKey("U")); - assertFalse(prefixlessUnits.containsKey("Z")); - - assertTrue(prefixlessUnits.containsValue(U)); - assertFalse(prefixlessUnits.containsValue(NONLINEAR)); - } - - /** - * 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(); - - database.addUnit("U", U); - database.addUnit("V", V); - database.addUnit("W", W); - - assertTrue(database.containsUnitName("U")); - assertFalse(database.containsUnitName("Z")); - - assertEquals(U, database.getUnit("U")); - assertThrows(NoSuchElementException.class, () -> database.getUnit("Z")); - } - - /** - * 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(); - - database.addUnit("U", U); - database.addUnit("V", V); - database.addUnit("W", W); - database.addUnit("fj", J.times(5)); - database.addUnit("ej", J.times(8)); - - database.addPrefix("A", A); - database.addPrefix("B", B); - database.addPrefix("C", C); - - // 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"); - - assertEquals(expected1, actual1); - - // second test - test addition and subtraction - final Unit expected2 = J.times(58); - final Unit actual2 = database.getUnitFromExpression("2 fj + 6 ej"); - - assertEquals(expected2, actual2); - } - - /** - * 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(); - - database.addUnit("J", J); - database.addUnit("K", K); - - database.addPrefix("A", A); - database.addPrefix("B", B); - database.addPrefix("C", C); - - final int NUM_UNITS = database.unitMapPrefixless(true).size(); - final int NUM_PREFIXES = database.prefixMap().size(); - - final Iterator nameIterator = database.unitMap().keySet() - .iterator(); - final Iterator> entryIterator = database.unitMap() - .entrySet().iterator(); - - int expectedLength = 1; - int unitsWithThisLengthSoFar = 0; - - // loop 1000 times - for (int i = 0; i < 1000; i++) { - // expected length of next - if (unitsWithThisLengthSoFar >= NUM_UNITS - * (int) Math.pow(NUM_PREFIXES, expectedLength - 1)) { - expectedLength++; - unitsWithThisLengthSoFar = 0; - } - - // test that stuff is valid - final String nextName = nameIterator.next(); - final Unit nextUnit = database.getUnit(nextName); - final Entry nextEntry = entryIterator.next(); - - assertEquals(expectedLength, nextName.length()); - assertEquals(nextName, nextEntry.getKey()); - assertEquals(nextUnit, nextEntry.getValue()); - - unitsWithThisLengthSoFar++; - } - - // test toString for consistency - final String entryIteratorString = entryIterator.toString(); - for (int i = 0; i < 3; i++) { - assertEquals(entryIteratorString, entryIterator.toString()); - } - - final String nameIteratorString = nameIterator.toString(); - for (int i = 0; i < 3; i++) { - assertEquals(nameIteratorString, nameIterator.toString()); - } - } - - /** - * Determine, given a unit name that could mean multiple things, which - * meaning is chosen. - *

- * 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. - *

- * - * @since 2019-04-14 - * @since v0.2.0 - */ - @Test - public void testUnitPrefixCombinations() { - // load units - final UnitDatabase database = new UnitDatabase(); - - database.addUnit("J", J); - - database.addPrefix("A", A); - database.addPrefix("B", B); - database.addPrefix("C", C); - database.addPrefix("AB", AB); - database.addPrefix("BC", BC); - - // 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"); - - assertEquals(expected1, actual1); - - // test 2 - ABC-J vs AB-CJ vs AB-C-J - database.addUnit("CJ", J.times(13)); - database.addPrefix("ABC", UnitPrefix.valueOf(17)); - - final Unit expected2 = J.times(17); - final Unit actual2 = database.getUnit("ABCJ"); - - assertEquals(expected2, actual2); - } -} diff --git a/src/test/java/org/unitConverter/unit/UnitTest.java b/src/test/java/org/unitConverter/unit/UnitTest.java deleted file mode 100644 index 3b594f2..0000000 --- a/src/test/java/org/unitConverter/unit/UnitTest.java +++ /dev/null @@ -1,146 +0,0 @@ -/** - * Copyright (C) 2018 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 . - */ -package org.unitConverter.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.util.Random; -import java.util.concurrent.ThreadLocalRandom; - -import org.junit.jupiter.api.Test; -import org.unitConverter.math.DecimalComparison; - -/** - * 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 - */ -class UnitTest { - /** A random number generator */ - private static final Random rng = ThreadLocalRandom.current(); - - @Test - public void testAdditionAndSubtraction() { - final LinearUnit inch = SI.METRE.times(0.0254) - .withName(NameSymbol.of("inch", "in")); - final LinearUnit foot = SI.METRE.times(0.3048) - .withName(NameSymbol.of("foot", "ft")); - - assertEquals(inch.plus(foot), SI.METRE.times(0.3302)); - assertEquals(foot.minus(inch), SI.METRE.times(0.2794)); - - // test with LinearUnitValue - final LinearUnitValue value1 = LinearUnitValue.getExact(SI.METRE, 15); - final LinearUnitValue value2 = LinearUnitValue.getExact(foot, 120); - final LinearUnitValue value3 = LinearUnitValue.getExact(SI.METRE, 0.5); - final LinearUnitValue value4 = LinearUnitValue.getExact(SI.KILOGRAM, 60); - - // make sure addition is done correctly - assertEquals(51.576, value1.plus(value2).getValueExact(), 0.001); - assertEquals(15.5, value1.plus(value3).getValueExact()); - assertEquals(52.076, value1.plus(value2).plus(value3).getValueExact(), - 0.001); - - // make sure addition uses the correct unit, and is still associative - // (ignoring floating-point rounding errors) - assertEquals(SI.METRE, value1.plus(value2).getUnit()); - assertEquals(SI.METRE, value1.plus(value2).plus(value3).getUnit()); - assertEquals(foot, value2.plus(value1).getUnit()); - assertTrue(value1.plus(value2).equals(value2.plus(value1), true)); - - // make sure errors happen when they should - assertThrows(IllegalArgumentException.class, () -> value1.plus(value4)); - } - - @Test - public void testConversion() { - final LinearUnit metre = SI.METRE; - final Unit inch = metre.times(0.0254); - - final UnitValue 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++) { - // initiate random values - final double conversionFactor = UnitTest.rng.nextDouble() * 1000000; - final double testValue = UnitTest.rng.nextDouble() * 1000000; - final double expected = testValue * conversionFactor; - - // test - final Unit unit = SI.METRE.times(conversionFactor); - final double actual = unit.convertToBase(testValue); - - assertEquals(actual, expected, - expected * DecimalComparison.DOUBLE_EPSILON); - } - } - - @Test - public void testEquals() { - final LinearUnit metre = SI.METRE; - final Unit meter = SI.BaseUnits.METRE.asLinearUnit(); - - assertEquals(metre, meter); - } - - @Test - public void testIsMetric() { - final Unit metre = SI.METRE; - final Unit megasecond = SI.SECOND.withPrefix(SI.MEGA); - final Unit hour = SI.HOUR; - - assertTrue(metre.isMetric()); - assertTrue(megasecond.isMetric()); - assertFalse(hour.isMetric()); - } - - @Test - public void testMultiplicationAndDivision() { - // test unit-times-unit multiplication - final LinearUnit generatedJoule = SI.KILOGRAM - .times(SI.METRE.toExponent(2)).dividedBy(SI.SECOND.toExponent(2)); - final LinearUnit actualJoule = SI.JOULE; - - assertEquals(generatedJoule, actualJoule); - - // test multiplication by conversion factors - final LinearUnit kilometre = SI.METRE.times(1000); - final LinearUnit hour = SI.SECOND.times(3600); - final LinearUnit generatedKPH = kilometre.dividedBy(hour); - - final LinearUnit actualKPH = SI.METRE.dividedBy(SI.SECOND).dividedBy(3.6); - - assertEquals(generatedKPH, actualKPH); - } - - @Test - public void testPrefixes() { - final LinearUnit generatedKilometre = SI.METRE.withPrefix(SI.KILO); - final LinearUnit actualKilometre = SI.METRE.times(1000); - - assertEquals(generatedKilometre, actualKilometre); - } -} diff --git a/src/test/java/sevenUnits/math/ConditionalExistenceCollectionsTest.java b/src/test/java/sevenUnits/math/ConditionalExistenceCollectionsTest.java new file mode 100644 index 0000000..a35dc5a --- /dev/null +++ b/src/test/java/sevenUnits/math/ConditionalExistenceCollectionsTest.java @@ -0,0 +1,161 @@ +/** + * Copyright (C) 2019 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 . + */ +package sevenUnits.math; + +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.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.NoSuchElementException; + +import org.junit.jupiter.api.Test; + +import sevenUnits.math.ConditionalExistenceCollections; +import sevenUnits.math.ConditionalExistenceCollections.ConditionalExistenceIterator; + +/** + * Tests the {@link #ConditionalExistenceCollections}. + * + * @author Adrien Hopkins + * @since 2019-10-16 + */ +class ConditionalExistenceCollectionsTest { + + /** + * The returned iterator ignores elements that don't start with "a". + * + * @return test iterator + * @since 2019-10-17 + */ + ConditionalExistenceIterator getTestIterator() { + final List items = Arrays.asList("aa", "ab", "ba"); + final Iterator it = items.iterator(); + final ConditionalExistenceIterator cit = (ConditionalExistenceIterator) 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 + */ + Map getTestMap() { + final Map map = new HashMap<>(); + map.put("one", 1); + map.put("two", 2); + map.put("zero", 0); + map.put("ten", 10); + final Map conditionalMap = ConditionalExistenceCollections.conditionalExistenceMap(map, + e -> !Integer.valueOf(0).equals(e.getValue())); + return conditionalMap; + } + + /** + * Test method for {@link org.unitConverter.math.ZeroIsNullMap#containsKey(java.lang.Object)}. + */ + @Test + void testContainsKeyObject() { + final Map map = this.getTestMap(); + assertTrue(map.containsKey("one")); + assertTrue(map.containsKey("ten")); + assertFalse(map.containsKey("five")); + assertFalse(map.containsKey("zero")); + } + + /** + * Test method for {@link org.unitConverter.math.ZeroIsNullMap#containsValue(java.lang.Object)}. + */ + @Test + void testContainsValueObject() { + final Map map = this.getTestMap(); + assertTrue(map.containsValue(1)); + assertTrue(map.containsValue(10)); + assertFalse(map.containsValue(5)); + assertFalse(map.containsValue(0)); + } + + /** + * Test method for {@link org.unitConverter.math.ZeroIsNullMap#entrySet()}. + */ + @Test + void testEntrySet() { + final Map map = this.getTestMap(); + for (final Entry e : map.entrySet()) { + assertTrue(e.getValue() != 0); + } + } + + /** + * Test method for {@link org.unitConverter.math.ZeroIsNullMap#get(java.lang.Object)}. + */ + @Test + void testGetObject() { + final Map map = this.getTestMap(); + assertEquals(1, map.get("one")); + assertEquals(10, map.get("ten")); + assertEquals(null, map.get("five")); + assertEquals(null, map.get("zero")); + } + + @Test + void testIterator() { + final ConditionalExistenceIterator testIterator = this.getTestIterator(); + + assertTrue(testIterator.hasNext); + assertTrue(testIterator.hasNext()); + assertEquals("aa", testIterator.nextElement); + assertEquals("aa", testIterator.next()); + + assertTrue(testIterator.hasNext); + assertTrue(testIterator.hasNext()); + assertEquals("ab", testIterator.nextElement); + assertEquals("ab", testIterator.next()); + + assertFalse(testIterator.hasNext); + assertFalse(testIterator.hasNext()); + assertEquals(null, testIterator.nextElement); + assertThrows(NoSuchElementException.class, testIterator::next); + } + + /** + * Test method for {@link org.unitConverter.math.ZeroIsNullMap#keySet()}. + */ + @Test + void testKeySet() { + final Map map = this.getTestMap(); + assertFalse(map.keySet().contains("zero")); + } + + /** + * Test method for {@link org.unitConverter.math.ZeroIsNullMap#values()}. + */ + @Test + void testValues() { + final Map map = this.getTestMap(); + assertFalse(map.values().contains(0)); + } + +} diff --git a/src/test/java/sevenUnits/math/ExpressionParserTest.java b/src/test/java/sevenUnits/math/ExpressionParserTest.java new file mode 100644 index 0000000..4801233 --- /dev/null +++ b/src/test/java/sevenUnits/math/ExpressionParserTest.java @@ -0,0 +1,54 @@ +/** + * Copyright (C) 2019 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 . + */ +package sevenUnits.math; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +import sevenUnits.math.ExpressionParser; + +/** + * 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 + */ +class ExpressionParserTest { + private static final ExpressionParser 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(); + + /** + * Test method for {@link sevenUnits.math.ExpressionParser#parseExpression(java.lang.String)}. + */ + @Test + public void testParseExpression() { + // test parsing of expressions + assertEquals((int) numberParser.parseExpression("1 + 2 ^ 5 * 3"), 97); + assertEquals((int) numberParser.parseExpression("(1 + 2) ^ 5 * 3"), 729); + + // ensure it normally goes left to right + assertEquals((int) numberParser.parseExpression("1 + 2 + 3 + 4"), 10); + assertEquals((int) numberParser.parseExpression("12 - 4 - 3"), 5); + assertEquals((int) numberParser.parseExpression("12 - (4 - 3)"), 11); + assertEquals((int) numberParser.parseExpression("1 / 2 + 3"), 3); + } + +} diff --git a/src/test/java/sevenUnits/math/ObjectProductTest.java b/src/test/java/sevenUnits/math/ObjectProductTest.java new file mode 100644 index 0000000..1734f26 --- /dev/null +++ b/src/test/java/sevenUnits/math/ObjectProductTest.java @@ -0,0 +1,80 @@ +/** + * Copyright (C) 2018 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 . + */ +package sevenUnits.math; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static sevenUnits.unit.SI.Dimensions.AREA; +import static sevenUnits.unit.SI.Dimensions.ENERGY; +import static sevenUnits.unit.SI.Dimensions.LENGTH; +import static sevenUnits.unit.SI.Dimensions.MASS; +import static sevenUnits.unit.SI.Dimensions.MASS_DENSITY; +import static sevenUnits.unit.SI.Dimensions.QUANTITY; +import static sevenUnits.unit.SI.Dimensions.TIME; +import static sevenUnits.unit.SI.Dimensions.VOLUME; + +import org.junit.jupiter.api.Test; + +import sevenUnits.math.ObjectProduct; +import sevenUnits.unit.SI; + +/** + * 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 + */ +class ObjectProductTest { + /** + * Tests {@link UnitDimension#equals} + * + * @since 2018-12-12 + * @since v0.1.0 + */ + @Test + public void testEquals() { + assertEquals(LENGTH, LENGTH); + assertFalse(LENGTH.equals(QUANTITY)); + } + + /** + * Tests {@code UnitDimension}'s exponentiation + * + * @since 2019-01-15 + * @since v0.1.0 + */ + @Test + public void testExponents() { + assertEquals(1, LENGTH.getExponent(SI.BaseDimensions.LENGTH)); + assertEquals(3, VOLUME.getExponent(SI.BaseDimensions.LENGTH)); + } + + /** + * Tests {@code UnitDimension}'s multiplication and division. + * + * @since 2018-12-12 + * @since v0.1.0 + */ + @Test + public void testMultiplicationAndDivision() { + assertEquals(AREA, LENGTH.times(LENGTH)); + assertEquals(MASS_DENSITY, MASS.dividedBy(VOLUME)); + assertEquals(ENERGY, AREA.times(MASS).dividedBy(TIME).dividedBy(TIME)); + assertEquals(LENGTH, LENGTH.times(TIME).dividedBy(TIME)); + } +} diff --git a/src/test/java/sevenUnits/unit/MultiUnitTest.java b/src/test/java/sevenUnits/unit/MultiUnitTest.java new file mode 100644 index 0000000..82722af --- /dev/null +++ b/src/test/java/sevenUnits/unit/MultiUnitTest.java @@ -0,0 +1,110 @@ +/** + * 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 . + */ +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; + +import sevenUnits.unit.BritishImperial; +import sevenUnits.unit.MultiUnit; +import sevenUnits.unit.SI; + +/** + * Tests related to the {@code MultiUnit}. + * + * @since 2020-10-03 + */ +class MultiUnitTest { + + @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(SI.METRE.withPrefix(SI.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 feetAndInches = SI.METRE.withPrefix(SI.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 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 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 new file mode 100644 index 0000000..c706b5c --- /dev/null +++ b/src/test/java/sevenUnits/unit/UnitDatabaseTest.java @@ -0,0 +1,317 @@ +/** + * Copyright (C) 2019 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 . + */ +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.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.NoSuchElementException; +import java.util.Set; + +import org.junit.jupiter.api.Test; + +import sevenUnits.unit.LinearUnit; +import sevenUnits.unit.NameSymbol; +import sevenUnits.unit.SI; +import sevenUnits.unit.Unit; +import sevenUnits.unit.UnitDatabase; +import sevenUnits.unit.UnitPrefix; + +/** + * 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 + */ +class UnitDatabaseTest { + // some linear units and one nonlinear + private static final Unit U = SI.METRE; + private static final Unit V = SI.KILOGRAM; + private static final Unit W = SI.SECOND; + + // used for testing expressions + // J = U^2 * V / W^2 + private static final LinearUnit J = SI.KILOGRAM.times(SI.METRE.toExponent(2)) + .dividedBy(SI.SECOND.toExponent(2)); + private static final LinearUnit K = SI.KELVIN; + + private static final Unit NONLINEAR = Unit + .fromConversionFunctions(SI.METRE.getBase(), o -> o + 1, o -> o - 1); + + // make the prefix values prime so I can tell which multiplications were made + private static final UnitPrefix A = UnitPrefix.valueOf(2) + .withName(NameSymbol.ofName("A")); + private static final UnitPrefix B = UnitPrefix.valueOf(3) + .withName(NameSymbol.ofName("B")); + private static final UnitPrefix C = UnitPrefix.valueOf(5) + .withName(NameSymbol.ofName("C")); + private static final UnitPrefix AB = UnitPrefix.valueOf(7); + private static final UnitPrefix BC = UnitPrefix.valueOf(11); + + /** + * Confirms that operations that shouldn't function for infinite databases + * throw an {@code IllegalStateException}. + * + * @since 2019-05-03 + */ +// @Test +// @Timeout(value = 1, unit = TimeUnit.SECONDS) + public void testInfiniteSetExceptions() { + // load units + final UnitDatabase infiniteDatabase = new UnitDatabase(); + + infiniteDatabase.addUnit("J", J); + infiniteDatabase.addUnit("K", K); + + infiniteDatabase.addPrefix("A", A); + infiniteDatabase.addPrefix("B", B); + infiniteDatabase.addPrefix("C", C); + + final Set> entrySet = infiniteDatabase.unitMap() + .entrySet(); + final Set keySet = infiniteDatabase.unitMap().keySet(); + assertThrows(IllegalStateException.class, () -> entrySet.toArray()); + assertThrows(IllegalStateException.class, () -> keySet.toArray()); + } + + /** + * Test that prefixes correctly apply to units. + * + * @since 2019-04-14 + * @since v0.2.0 + */ + @Test + public void testPrefixes() { + final UnitDatabase database = new UnitDatabase(); + + database.addUnit("U", U); + database.addUnit("V", V); + database.addUnit("W", W); + + database.addPrefix("A", A); + database.addPrefix("B", B); + database.addPrefix("C", C); + + // test the getPrefixesFromName method + final List expected = Arrays.asList(C, B, A); + assertEquals(expected, database.getPrefixesFromName("ABCU")); + + // get the product + final Unit abcuNonlinear = database.getUnit("ABCU"); + assert abcuNonlinear instanceof LinearUnit; + + final LinearUnit abcu = (LinearUnit) abcuNonlinear; + assertEquals(A.getMultiplier() * B.getMultiplier() * C.getMultiplier(), + abcu.getConversionFactor(), 1e-15); + } + + /** + * Tests the functionnalites of the prefixless unit map. + * + *

+ * The map should be an auto-updating view of the units in the database. + *

+ * + * @since 2019-04-14 + * @since v0.2.0 + */ + @Test + public void testPrefixlessUnitMap() { + final UnitDatabase database = new UnitDatabase(); + final Map prefixlessUnits = database + .unitMapPrefixless(true); + + database.addUnit("U", U); + database.addUnit("V", V); + database.addUnit("W", W); + + // this should work because the map should be an auto-updating view + assertTrue(prefixlessUnits.containsKey("U")); + assertFalse(prefixlessUnits.containsKey("Z")); + + assertTrue(prefixlessUnits.containsValue(U)); + assertFalse(prefixlessUnits.containsValue(NONLINEAR)); + } + + /** + * 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(); + + database.addUnit("U", U); + database.addUnit("V", V); + database.addUnit("W", W); + + assertTrue(database.containsUnitName("U")); + assertFalse(database.containsUnitName("Z")); + + assertEquals(U, database.getUnit("U")); + assertThrows(NoSuchElementException.class, () -> database.getUnit("Z")); + } + + /** + * 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(); + + database.addUnit("U", U); + database.addUnit("V", V); + database.addUnit("W", W); + database.addUnit("fj", J.times(5)); + database.addUnit("ej", J.times(8)); + + database.addPrefix("A", A); + database.addPrefix("B", B); + database.addPrefix("C", C); + + // 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"); + + assertEquals(expected1, actual1); + + // second test - test addition and subtraction + final Unit expected2 = J.times(58); + final Unit actual2 = database.getUnitFromExpression("2 fj + 6 ej"); + + assertEquals(expected2, actual2); + } + + /** + * 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(); + + database.addUnit("J", J); + database.addUnit("K", K); + + database.addPrefix("A", A); + database.addPrefix("B", B); + database.addPrefix("C", C); + + final int NUM_UNITS = database.unitMapPrefixless(true).size(); + final int NUM_PREFIXES = database.prefixMap().size(); + + final Iterator nameIterator = database.unitMap().keySet() + .iterator(); + final Iterator> entryIterator = database.unitMap() + .entrySet().iterator(); + + int expectedLength = 1; + int unitsWithThisLengthSoFar = 0; + + // loop 1000 times + for (int i = 0; i < 1000; i++) { + // expected length of next + if (unitsWithThisLengthSoFar >= NUM_UNITS + * (int) Math.pow(NUM_PREFIXES, expectedLength - 1)) { + expectedLength++; + unitsWithThisLengthSoFar = 0; + } + + // test that stuff is valid + final String nextName = nameIterator.next(); + final Unit nextUnit = database.getUnit(nextName); + final Entry nextEntry = entryIterator.next(); + + assertEquals(expectedLength, nextName.length()); + assertEquals(nextName, nextEntry.getKey()); + assertEquals(nextUnit, nextEntry.getValue()); + + unitsWithThisLengthSoFar++; + } + + // test toString for consistency + final String entryIteratorString = entryIterator.toString(); + for (int i = 0; i < 3; i++) { + assertEquals(entryIteratorString, entryIterator.toString()); + } + + final String nameIteratorString = nameIterator.toString(); + for (int i = 0; i < 3; i++) { + assertEquals(nameIteratorString, nameIterator.toString()); + } + } + + /** + * Determine, given a unit name that could mean multiple things, which + * meaning is chosen. + *

+ * 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. + *

+ * + * @since 2019-04-14 + * @since v0.2.0 + */ + @Test + public void testUnitPrefixCombinations() { + // load units + final UnitDatabase database = new UnitDatabase(); + + database.addUnit("J", J); + + database.addPrefix("A", A); + database.addPrefix("B", B); + database.addPrefix("C", C); + database.addPrefix("AB", AB); + database.addPrefix("BC", BC); + + // 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"); + + assertEquals(expected1, actual1); + + // test 2 - ABC-J vs AB-CJ vs AB-C-J + database.addUnit("CJ", J.times(13)); + database.addPrefix("ABC", UnitPrefix.valueOf(17)); + + final Unit expected2 = J.times(17); + final Unit actual2 = database.getUnit("ABCJ"); + + assertEquals(expected2, actual2); + } +} diff --git a/src/test/java/sevenUnits/unit/UnitTest.java b/src/test/java/sevenUnits/unit/UnitTest.java new file mode 100644 index 0000000..d216ae8 --- /dev/null +++ b/src/test/java/sevenUnits/unit/UnitTest.java @@ -0,0 +1,153 @@ +/** + * Copyright (C) 2018 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 . + */ +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.util.Random; +import java.util.concurrent.ThreadLocalRandom; + +import org.junit.jupiter.api.Test; + +import sevenUnits.math.DecimalComparison; +import sevenUnits.unit.LinearUnit; +import sevenUnits.unit.LinearUnitValue; +import sevenUnits.unit.NameSymbol; +import sevenUnits.unit.SI; +import sevenUnits.unit.Unit; +import sevenUnits.unit.UnitValue; + +/** + * 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 + */ +class UnitTest { + /** A random number generator */ + private static final Random rng = ThreadLocalRandom.current(); + + @Test + public void testAdditionAndSubtraction() { + final LinearUnit inch = SI.METRE.times(0.0254) + .withName(NameSymbol.of("inch", "in")); + final LinearUnit foot = SI.METRE.times(0.3048) + .withName(NameSymbol.of("foot", "ft")); + + assertEquals(inch.plus(foot), SI.METRE.times(0.3302)); + assertEquals(foot.minus(inch), SI.METRE.times(0.2794)); + + // test with LinearUnitValue + final LinearUnitValue value1 = LinearUnitValue.getExact(SI.METRE, 15); + final LinearUnitValue value2 = LinearUnitValue.getExact(foot, 120); + final LinearUnitValue value3 = LinearUnitValue.getExact(SI.METRE, 0.5); + final LinearUnitValue value4 = LinearUnitValue.getExact(SI.KILOGRAM, 60); + + // make sure addition is done correctly + assertEquals(51.576, value1.plus(value2).getValueExact(), 0.001); + assertEquals(15.5, value1.plus(value3).getValueExact()); + assertEquals(52.076, value1.plus(value2).plus(value3).getValueExact(), + 0.001); + + // make sure addition uses the correct unit, and is still associative + // (ignoring floating-point rounding errors) + assertEquals(SI.METRE, value1.plus(value2).getUnit()); + assertEquals(SI.METRE, value1.plus(value2).plus(value3).getUnit()); + assertEquals(foot, value2.plus(value1).getUnit()); + assertTrue(value1.plus(value2).equals(value2.plus(value1), true)); + + // make sure errors happen when they should + assertThrows(IllegalArgumentException.class, () -> value1.plus(value4)); + } + + @Test + public void testConversion() { + final LinearUnit metre = SI.METRE; + final Unit inch = metre.times(0.0254); + + final UnitValue 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++) { + // initiate random values + final double conversionFactor = UnitTest.rng.nextDouble() * 1000000; + final double testValue = UnitTest.rng.nextDouble() * 1000000; + final double expected = testValue * conversionFactor; + + // test + final Unit unit = SI.METRE.times(conversionFactor); + final double actual = unit.convertToBase(testValue); + + assertEquals(actual, expected, + expected * DecimalComparison.DOUBLE_EPSILON); + } + } + + @Test + public void testEquals() { + final LinearUnit metre = SI.METRE; + final Unit meter = SI.BaseUnits.METRE.asLinearUnit(); + + assertEquals(metre, meter); + } + + @Test + public void testIsMetric() { + final Unit metre = SI.METRE; + final Unit megasecond = SI.SECOND.withPrefix(SI.MEGA); + final Unit hour = SI.HOUR; + + assertTrue(metre.isMetric()); + assertTrue(megasecond.isMetric()); + assertFalse(hour.isMetric()); + } + + @Test + public void testMultiplicationAndDivision() { + // test unit-times-unit multiplication + final LinearUnit generatedJoule = SI.KILOGRAM + .times(SI.METRE.toExponent(2)).dividedBy(SI.SECOND.toExponent(2)); + final LinearUnit actualJoule = SI.JOULE; + + assertEquals(generatedJoule, actualJoule); + + // test multiplication by conversion factors + final LinearUnit kilometre = SI.METRE.times(1000); + final LinearUnit hour = SI.SECOND.times(3600); + final LinearUnit generatedKPH = kilometre.dividedBy(hour); + + final LinearUnit actualKPH = SI.METRE.dividedBy(SI.SECOND).dividedBy(3.6); + + assertEquals(generatedKPH, actualKPH); + } + + @Test + public void testPrefixes() { + final LinearUnit generatedKilometre = SI.METRE.withPrefix(SI.KILO); + final LinearUnit actualKilometre = SI.METRE.times(1000); + + assertEquals(generatedKilometre, actualKilometre); + } +} -- cgit v1.2.3