summaryrefslogtreecommitdiff
path: root/src/test/java/sevenUnitsGUI
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/java/sevenUnitsGUI')
-rw-r--r--src/test/java/sevenUnitsGUI/PresenterTest.java356
1 files changed, 356 insertions, 0 deletions
diff --git a/src/test/java/sevenUnitsGUI/PresenterTest.java b/src/test/java/sevenUnitsGUI/PresenterTest.java
new file mode 100644
index 0000000..3364e83
--- /dev/null
+++ b/src/test/java/sevenUnitsGUI/PresenterTest.java
@@ -0,0 +1,356 @@
+/**
+ * Copyright (C) 2022 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.assertTrue;
+
+import java.math.RoundingMode;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import sevenUnits.unit.BaseDimension;
+import sevenUnits.unit.BritishImperial;
+import sevenUnits.unit.LinearUnitValue;
+import sevenUnits.unit.Metric;
+import sevenUnits.unit.Unit;
+import sevenUnits.unit.UnitType;
+import sevenUnits.utils.NameSymbol;
+import sevenUnits.utils.Nameable;
+import sevenUnits.utils.ObjectProduct;
+import sevenUnits.utils.UncertainDouble;
+
+/**
+ * @author Adrien Hopkins
+ *
+ * @since 2022-02-10
+ */
+public final class PresenterTest {
+ private static final Path TEST_SETTINGS = Path.of("src", "test", "resources",
+ "test-settings.txt");
+ static final Set<Unit> testUnits = Set.of(Metric.METRE, Metric.KILOMETRE,
+ Metric.METRE_PER_SECOND, Metric.KILOMETRE_PER_HOUR);
+
+ static final Set<ObjectProduct<BaseDimension>> testDimensions = Set
+ .of(Metric.Dimensions.LENGTH, Metric.Dimensions.VELOCITY);
+
+ /**
+ * @return rounding rules used by {@link #testRoundingRules}
+ * @since 2022-04-16
+ */
+ private static final 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);
+
+ return Stream.of(SCIENTIFIC_ROUNDING, INTEGER_ROUNDING, SIG_FIG_ROUNDING);
+ }
+
+ private static final Set<String> names(Set<? extends Nameable> units) {
+ return units.stream().map(Nameable::getName).collect(Collectors.toSet());
+ }
+
+ /**
+ * Test method for {@link Presenter#convertExpressions}
+ *
+ * @since 2022-02-12
+ */
+ @Test
+ void testConvertExpressions() {
+ // setup
+ final ViewBot viewBot = new ViewBot();
+ final Presenter presenter = new Presenter(viewBot);
+
+ viewBot.setFromExpression("10000.0 m");
+ viewBot.setToExpression("km");
+
+ // 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());
+ }
+
+ /**
+ * Tests that unit-conversion Views can correctly convert units
+ *
+ * @since 2022-02-12
+ */
+ @Test
+ void testConvertUnits() {
+ // setup
+ final ViewBot viewBot = new ViewBot();
+ final Presenter presenter = new Presenter(viewBot);
+
+ viewBot.setFromUnitNames(names(testUnits));
+ viewBot.setToUnitNames(names(testUnits));
+ viewBot.setFromSelection("metre");
+ viewBot.setToSelection("kilometre");
+ viewBot.setInputValue("10000.0");
+
+ // convert units
+ 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());
+ }
+
+ /**
+ * Tests that duplicate units are successfully removed, if that is asked for
+ *
+ * @since 2022-04-16
+ */
+ @Test
+ void testDuplicateUnits() {
+ final var metre = Metric.METRE;
+ final var meter = Metric.METRE.withName(NameSymbol.of("meter", "m"));
+
+ // load 2 duplicate units
+ final var viewBot = new ViewBot();
+ final var presenter = new Presenter(viewBot);
+ presenter.database.clear();
+ presenter.database.addUnit("metre", metre);
+ presenter.database.addUnit("meter", meter);
+ presenter.setOneWayConversionEnabled(false);
+
+ // test that only one of them is included if duplicate units disabled
+ presenter.setShowDuplicates(false);
+ presenter.updateView();
+ assertEquals(1, viewBot.getFromUnitNames().size());
+ assertEquals(1, viewBot.getToUnitNames().size());
+
+ // test that both of them is included if duplicate units enabled
+ presenter.setShowDuplicates(true);
+ presenter.updateView();
+ assertEquals(2, viewBot.getFromUnitNames().size());
+ assertEquals(2, viewBot.getToUnitNames().size());
+ }
+
+ /**
+ * Tests that one-way conversion correctly filters From and To units
+ *
+ * @since 2022-04-16
+ */
+ @Test
+ void testOneWayConversion() {
+ // metre is metric, inch is non-metric, tempC is semi-metric
+ final var allNames = Set.of("metre", "inch", "tempC");
+ final var metricNames = Set.of("metre", "tempC");
+ final var nonMetricNames = Set.of("inch", "tempC");
+
+ // load view with one metric and one non-metric unit
+ final var viewBot = new ViewBot();
+ final var presenter = new Presenter(viewBot);
+ presenter.database.clear();
+ presenter.database.addUnit("metre", Metric.METRE);
+ presenter.database.addUnit("inch", BritishImperial.Length.INCH);
+ presenter.database.addUnit("tempC", Metric.CELSIUS);
+
+ // test that units are removed from each side when one-way conversion is
+ // enabled
+ presenter.setOneWayConversionEnabled(true);
+ assertEquals(nonMetricNames, viewBot.getFromUnitNames());
+ assertEquals(metricNames, viewBot.getToUnitNames());
+
+ // test that units are kept when one-way conversion is disabled
+ presenter.setOneWayConversionEnabled(false);
+ assertEquals(allNames, viewBot.getFromUnitNames());
+ assertEquals(allNames, viewBot.getToUnitNames());
+ }
+
+ /**
+ * Tests the prefix-viewing functionality.
+ *
+ * @since 2022-04-16
+ */
+ @Test
+ void testPrefixViewing() {
+ // setup
+ final var viewBot = new ViewBot();
+ final var presenter = new Presenter(viewBot);
+ viewBot.setViewablePrefixNames(Set.of("kilo", "milli"));
+ presenter.setNumberDisplayRule(UncertainDouble::toString);
+
+ // view prefix
+ viewBot.setViewedPrefixName("kilo");
+ presenter.prefixSelected(); // just in case
+
+ // get correct values
+ final var expectedNameSymbol = presenter.database.getPrefix("kilo")
+ .getNameSymbol();
+ final var expectedMultiplierString = String
+ .valueOf(Metric.KILO.getMultiplier());
+
+ // test that presenter's values are correct
+ final var prefixRecord = viewBot.prefixViewList().get(0);
+ assertEquals(expectedNameSymbol, prefixRecord.getNameSymbol());
+ assertEquals(expectedMultiplierString, prefixRecord.multiplierString());
+ }
+
+ /**
+ * Tests that rounding rules are used correctly.
+ *
+ * @since 2022-04-16
+ */
+ @ParameterizedTest
+ @MethodSource("getRoundingRules")
+ void testRoundingRules(Function<UncertainDouble, String> roundingRule) {
+ // setup
+ final var viewBot = new ViewBot();
+ final var presenter = new Presenter(viewBot);
+ presenter.setNumberDisplayRule(roundingRule);
+
+ // convert and round
+ viewBot.setInputValue("12345.6789");
+ viewBot.setFromSelection("metre");
+ viewBot.setToSelection("kilometre");
+ presenter.convertUnits();
+
+ // test the result of the rounding
+ final String expectedOutputString = roundingRule
+ .apply(UncertainDouble.fromRoundedString("12.3456789"));
+ final String actualOutputString = viewBot.unitConversionList().get(0)
+ .outputValueString();
+ assertEquals(expectedOutputString, actualOutputString);
+ }
+
+ /**
+ * Tests that settings can be saved to and loaded from a file.
+ *
+ * @since 2022-04-16
+ */
+ @Test
+ void testSettingsSaving() {
+ // setup
+ final var viewBot = new ViewBot();
+ final var presenter = new Presenter(viewBot);
+
+ // set and save custom settings
+ presenter.setOneWayConversionEnabled(true);
+ presenter.setShowDuplicates(true);
+ presenter.setNumberDisplayRule(StandardDisplayRules.fixedPrecision(11));
+ presenter.setPrefixRepetitionRule(
+ DefaultPrefixRepetitionRule.COMPLEX_REPETITION);
+ presenter.saveSettings(TEST_SETTINGS);
+
+ // overwrite custom settings
+ presenter.setOneWayConversionEnabled(false);
+ presenter.setShowDuplicates(false);
+ presenter.setNumberDisplayRule(StandardDisplayRules.uncertaintyBased());
+
+ // load settings & test that they're the same
+ presenter.loadSettings(TEST_SETTINGS);
+ assertTrue(presenter.oneWayConversionEnabled());
+ assertTrue(presenter.duplicatesShown());
+ assertEquals(StandardDisplayRules.fixedPrecision(11),
+ presenter.getNumberDisplayRule());
+ }
+
+ /**
+ * Ensures the Presenter generates the correct data upon a unit-viewing.
+ *
+ * @since 2022-04-16
+ */
+ @Test
+ void testUnitViewing() {
+ // setup
+ final var viewBot = new ViewBot();
+ final var presenter = new Presenter(viewBot);
+ viewBot.setViewableUnitNames(names(testUnits));
+
+ // view unit
+ viewBot.setViewedUnitName("metre");
+ presenter.unitNameSelected(); // just in case this isn't triggered
+ // automatically
+
+ // get correct values
+ final var expectedNameSymbol = presenter.database.getUnit("metre")
+ .getNameSymbol();
+ final var expectedDefinition = "(Base unit)";
+ final var expectedDimensionName = presenter
+ .getDimensionName(Metric.METRE.getDimension());
+ final var expectedUnitType = UnitType.METRIC;
+
+ // test for correctness
+ final var viewRecord = viewBot.unitViewList().get(0);
+ assertEquals(expectedNameSymbol, viewRecord.getNameSymbol());
+ assertEquals(expectedDefinition, viewRecord.definition());
+ assertEquals(expectedDimensionName, viewRecord.dimensionName());
+ assertEquals(expectedUnitType, viewRecord.unitType());
+ }
+
+ /**
+ * Test for {@link Presenter#updateView()}
+ *
+ * @since 2022-02-12
+ */
+ @Test
+ void testUpdateView() {
+ // setup
+ final ViewBot viewBot = new ViewBot();
+ final Presenter presenter = new Presenter(viewBot);
+ presenter.setOneWayConversionEnabled(false);
+
+ // override default database units
+ presenter.database.clear();
+ for (final Unit unit : testUnits) {
+ presenter.database.addUnit(unit.getPrimaryName().orElseThrow(), unit);
+ }
+ for (final var dimension : testDimensions) {
+ presenter.database.addDimension(
+ dimension.getPrimaryName().orElseThrow(), dimension);
+ }
+
+ // set from and to units
+ viewBot.setFromUnitNames(names(testUnits));
+ viewBot.setToUnitNames(names(testUnits));
+ viewBot.setDimensionNames(names(testDimensions));
+ viewBot.setSelectedDimensionName(Metric.Dimensions.LENGTH.getName());
+
+ // 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();
+
+ // test that fromUnits/toUnits is [METRE, KILOMETRE]
+ assertEquals(Set.of("metre", "kilometre"), fromUnits);
+ assertEquals(Set.of("metre", "kilometre"), toUnits);
+ }
+}