diff options
author | Adrien Hopkins <adrien.p.hopkins@gmail.com> | 2019-04-14 17:46:43 -0400 |
---|---|---|
committer | Adrien Hopkins <adrien.p.hopkins@gmail.com> | 2019-04-14 17:46:43 -0400 |
commit | 910b2f1b448ec56e6a66f4aa4f72e71c39de40a1 (patch) | |
tree | 231fcb8f72a467a77efc1e6050de12bd70f7b152 /src/test/java | |
parent | 70273e127b061c69ce4b3d9d6c3881c6b0c2b829 (diff) | |
parent | 2ce65fa76908d77a5e3b045a8eb40c798939b8be (diff) |
Release v0.2.0v0.2.0
Diffstat (limited to 'src/test/java')
-rw-r--r-- | src/test/java/ExpressionParserTest.java | 53 | ||||
-rwxr-xr-x | src/test/java/UnitDimensionTest.java | 79 | ||||
-rwxr-xr-x | src/test/java/UnitTest.java | 116 | ||||
-rw-r--r-- | src/test/java/UnitsDatabaseTest.java | 260 | ||||
-rw-r--r-- | src/test/java/package-info.java | 24 |
5 files changed, 532 insertions, 0 deletions
diff --git a/src/test/java/ExpressionParserTest.java b/src/test/java/ExpressionParserTest.java new file mode 100644 index 0000000..40c91ac --- /dev/null +++ b/src/test/java/ExpressionParserTest.java @@ -0,0 +1,53 @@ +/** + * 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 <https://www.gnu.org/licenses/>. + */ +package test.java; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.unitConverter.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 + */ +public 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(); + + /** + * 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/UnitDimensionTest.java b/src/test/java/UnitDimensionTest.java new file mode 100755 index 0000000..587cf4c --- /dev/null +++ b/src/test/java/UnitDimensionTest.java @@ -0,0 +1,79 @@ +/** + * 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 <https://www.gnu.org/licenses/>. + */ +package test.java; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.unitConverter.dimension.StandardDimensions.AREA; +import static org.unitConverter.dimension.StandardDimensions.ENERGY; +import static org.unitConverter.dimension.StandardDimensions.LENGTH; +import static org.unitConverter.dimension.StandardDimensions.MASS; +import static org.unitConverter.dimension.StandardDimensions.MASS_DENSITY; +import static org.unitConverter.dimension.StandardDimensions.QUANTITY; +import static org.unitConverter.dimension.StandardDimensions.TIME; +import static org.unitConverter.dimension.StandardDimensions.VOLUME; + +import org.junit.Test; +import org.unitConverter.dimension.SIBaseDimension; +import org.unitConverter.dimension.UnitDimension; + +/** + * Tests for {@link UnitDimension}. This is NOT part of this program's public API. + * + * @author Adrien Hopkins + * @since 2018-12-12 + * @since v0.1.0 + */ +public class UnitDimensionTest { + /** + * 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(SIBaseDimension.LENGTH)); + assertEquals(3, VOLUME.getExponent(SIBaseDimension.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/UnitTest.java b/src/test/java/UnitTest.java new file mode 100755 index 0000000..00fcf3c --- /dev/null +++ b/src/test/java/UnitTest.java @@ -0,0 +1,116 @@ +/** + * 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 <https://www.gnu.org/licenses/>. + */ +package test.java; + +import static org.junit.Assert.assertEquals; + +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; + +import org.junit.Test; +import org.unitConverter.dimension.StandardDimensions; +import org.unitConverter.math.DecimalComparison; +import org.unitConverter.unit.BaseUnit; +import org.unitConverter.unit.LinearUnit; +import org.unitConverter.unit.SI; +import org.unitConverter.unit.SIPrefix; +import org.unitConverter.unit.Unit; + +/** + * 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 + */ +public 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); + final LinearUnit foot = SI.METRE.times(0.3048); + + assertEquals(inch.plus(foot), SI.METRE.times(0.3302)); + assertEquals(foot.minus(inch), SI.METRE.times(0.2794)); + } + + @Test + public void testBaseUnitExclusives() { + // this test should have a compile error if I am doing something wrong + final BaseUnit metrePerSecondSquared = SI.METRE.dividedBy(SI.SECOND.toExponent(2)); + + assertEquals(metrePerSecondSquared, SI.SI.getBaseUnit(StandardDimensions.ACCELERATION)); + } + + @Test + public void testConversion() { + final BaseUnit metre = SI.METRE; + final Unit inch = metre.times(0.0254); + + assertEquals(1.9, inch.convertToBase(75), 0.01); + + // try random stuff + for (int i = 0; i < 1000; i++) { + // initiate random values + final double conversionFactor = rng.nextDouble() * 1000000; + final double testValue = 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 BaseUnit metre = SI.METRE; + final Unit meter = SI.SI.getBaseUnit(StandardDimensions.LENGTH); + + assertEquals(metre, meter); + } + + @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.SI.getBaseUnit(StandardDimensions.ENERGY); + + 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.SI.getBaseUnit(StandardDimensions.VELOCITY).dividedBy(3.6); + + assertEquals(generatedKPH, actualKPH); + } + + @Test + public void testPrefixes() { + final LinearUnit generatedKilometre = SI.METRE.withPrefix(SIPrefix.KILO); + final LinearUnit actualKilometre = SI.METRE.times(1000); + + assertEquals(generatedKilometre, actualKilometre); + } +} diff --git a/src/test/java/UnitsDatabaseTest.java b/src/test/java/UnitsDatabaseTest.java new file mode 100644 index 0000000..9222740 --- /dev/null +++ b/src/test/java/UnitsDatabaseTest.java @@ -0,0 +1,260 @@ +/** + * 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 <https://www.gnu.org/licenses/>. + */ +package test.java; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +import org.junit.Test; +import org.unitConverter.UnitsDatabase; +import org.unitConverter.unit.AbstractUnit; +import org.unitConverter.unit.DefaultUnitPrefix; +import org.unitConverter.unit.LinearUnit; +import org.unitConverter.unit.SI; +import org.unitConverter.unit.Unit; +import org.unitConverter.unit.UnitPrefix; + +/** + * A test for the {@link UnitsDatabase} class. This is NOT part of this program's public API. + * + * @author Adrien Hopkins + * @since 2019-04-14 + * @since v0.2.0 + */ +public class UnitsDatabaseTest { + // 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 Unit NONLINEAR = new AbstractUnit(SI.METRE) { + + @Override + public double convertFromBase(final double value) { + return value + 1; + } + + @Override + public double convertToBase(final double value) { + return value - 1; + } + }; + + // make the prefix values prime so I can tell which multiplications were made + private static final UnitPrefix A = new DefaultUnitPrefix(2); + private static final UnitPrefix B = new DefaultUnitPrefix(3); + private static final UnitPrefix C = new DefaultUnitPrefix(5); + private static final UnitPrefix AB = new DefaultUnitPrefix(7); + private static final UnitPrefix BC = new DefaultUnitPrefix(11); + + /** + * Test that prefixes correctly apply to units. + * + * @since 2019-04-14 + * @since v0.2.0 + */ + @Test + public void testPrefixes() { + final UnitsDatabase database = new UnitsDatabase(); + + database.addUnit("U", U); + database.addUnit("V", V); + database.addUnit("W", W); + + database.addPrefix("A", A); + database.addPrefix("B", B); + database.addPrefix("C", C); + + // 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. + * + * <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 UnitsDatabase database = new UnitsDatabase(); + final Map<String, Unit> prefixlessUnits = database.unitMapPrefixless(); + + 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 UnitsDatabase database = new UnitsDatabase(); + + 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")); + assertEquals(null, 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 UnitsDatabase database = new UnitsDatabase(); + + 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 UnitsDatabase database = new UnitsDatabase(); + + database.addUnit("J", J); + + database.addPrefix("A", A); + database.addPrefix("B", B); + database.addPrefix("C", C); + + final Iterator<String> nameIterator = database.unitMap().keySet().iterator(); + final Iterator<Entry<String, Unit>> 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 >= (int) Math.pow(3, expectedLength - 1)) { + expectedLength++; + unitsWithThisLengthSoFar = 0; + } + + final String nextName = nameIterator.next(); + final Unit nextUnit = database.getUnit(nextName); + final Entry<String, Unit> nextEntry = entryIterator.next(); + + assertEquals(expectedLength, nextName.length()); + assertEquals(nextName, nextEntry.getKey()); + assertEquals(nextUnit, nextEntry.getValue()); + + unitsWithThisLengthSoFar++; + } + } + + /** + * Determine, given a unit name that could mean multiple things, which meaning is chosen. + * <p> + * 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 UnitsDatabase database = new UnitsDatabase(); + + 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", new DefaultUnitPrefix(17)); + + final Unit expected2 = J.times(17); + final Unit actual2 = database.getUnit("ABCJ"); + + assertEquals(expected2, actual2); + } +} diff --git a/src/test/java/package-info.java b/src/test/java/package-info.java new file mode 100644 index 0000000..3da7fcb --- /dev/null +++ b/src/test/java/package-info.java @@ -0,0 +1,24 @@ +/** + * 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 <https://www.gnu.org/licenses/>. + */ +/** + * All of the Unit Converter tests. Everything in this package is NOT part of Unit Converter's public API. + * + * @author Adrien Hopkins + * @since 2019-03-16 + * @since v0.2.0 + */ +package test.java;
\ No newline at end of file |