summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdrien Hopkins <ahopk127@my.yorku.ca>2022-04-09 11:32:43 -0500
committerAdrien Hopkins <ahopk127@my.yorku.ca>2022-04-09 11:32:43 -0500
commitc421e474a7b0d0d453e4a527907f327f2ddef320 (patch)
tree1edf5930488ad18f318a05dcfa3aa4824f5e22ca /src
parent91f87da88f98de996e167f0ff6809356f6d57e11 (diff)
View now sends and recieves Strings instead of data
Diffstat (limited to 'src')
-rw-r--r--src/main/java/sevenUnitsGUI/ExpressionConversionView.java7
-rw-r--r--src/main/java/sevenUnitsGUI/Presenter.java153
-rw-r--r--src/main/java/sevenUnitsGUI/SearchBoxList.java10
-rw-r--r--src/main/java/sevenUnitsGUI/TabbedView.java76
-rw-r--r--src/main/java/sevenUnitsGUI/UnitConversionRecord.java180
-rw-r--r--src/main/java/sevenUnitsGUI/UnitConversionView.java47
-rw-r--r--src/main/java/sevenUnitsGUI/View.java2
-rw-r--r--src/main/java/sevenUnitsGUI/ViewBot.java141
-rw-r--r--src/test/java/sevenUnitsGUI/PresenterTest.java85
9 files changed, 460 insertions, 241 deletions
diff --git a/src/main/java/sevenUnitsGUI/ExpressionConversionView.java b/src/main/java/sevenUnitsGUI/ExpressionConversionView.java
index 5a587d4..872ca10 100644
--- a/src/main/java/sevenUnitsGUI/ExpressionConversionView.java
+++ b/src/main/java/sevenUnitsGUI/ExpressionConversionView.java
@@ -38,11 +38,8 @@ public interface ExpressionConversionView extends View {
/**
* Shows the output of an expression conversion to the user.
*
- * @param fromExpression expression converted from
- * @param toExpression expression converted to
- * @param value conversion factor between two expressions
+ * @param uc unit conversion to show
* @since 2021-12-15
*/
- void showExpressionConversionOutput(String fromExpression,
- String toExpression, double value);
+ void showExpressionConversionOutput(UnitConversionRecord uc);
}
diff --git a/src/main/java/sevenUnitsGUI/Presenter.java b/src/main/java/sevenUnitsGUI/Presenter.java
index 57d353d..9f8fe69 100644
--- a/src/main/java/sevenUnitsGUI/Presenter.java
+++ b/src/main/java/sevenUnitsGUI/Presenter.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Adrien Hopkins
+ * Copyright (C) 2021-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
@@ -19,13 +19,11 @@ package sevenUnitsGUI;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Optional;
-import java.util.OptionalDouble;
import java.util.Scanner;
import java.util.Set;
import java.util.function.Function;
@@ -135,25 +133,6 @@ public final class Presenter {
}
/**
- * Accepts a collection and returns a set with the unique elements in that
- * collection
- *
- * @param <E> type of element in collection
- * @param collection collection to uniquify
- * @return unique collection
- * @since 2022-02-26
- */
- private static <E> Set<E> unique(Collection<E> collection) {
- final Set<E> uniqueSet = new HashSet<>();
- for (final E e : collection) {
- if (!uniqueSet.contains(e)) {
- uniqueSet.add(e);
- }
- }
- return uniqueSet;
- }
-
- /**
* @return {@code line} with any comments removed.
* @since 2021-03-13
*/
@@ -206,7 +185,7 @@ public final class Presenter {
* removed from the From unit list and imperial/USC units removed from the To
* unit list.
*/
- private boolean oneWayConversion;
+ private boolean oneWayConversionEnabled;
/**
* If this is false, duplicate units will be removed from the unit view in
@@ -260,13 +239,6 @@ public final class Presenter {
}
/**
- * Gets settings from the view and applies them to both view and presenter.
- *
- * @since 2021-12-15
- */
- public void applySettings() {}
-
- /**
* Converts from the view's input expression to its output expression.
* Displays an error message if any of the required fields are invalid.
*
@@ -316,8 +288,9 @@ public final class Presenter {
// convert and show output
if (from.getUnit().canConvertTo(to)) {
final double value = from.asUnitValue().convertTo(to).getValue();
- xcview.showExpressionConversionOutput(fromExpression, toExpression,
- value);
+ final UnitConversionRecord uc = UnitConversionRecord.valueOf(
+ fromExpression, toExpression, "", String.valueOf(value));
+ xcview.showExpressionConversionOutput(uc);
} else {
this.view.showErrorMessage("Conversion Error",
"Cannot convert between \"" + fromExpression + "\" and \""
@@ -343,49 +316,82 @@ public final class Presenter {
if (this.view instanceof UnitConversionView) {
final UnitConversionView ucview = (UnitConversionView) this.view;
- final Optional<Unit> fromUnitOptional = ucview.getFromSelection();
- final Optional<Unit> toUnitOptional = ucview.getToSelection();
- final OptionalDouble valueOptional = ucview.getInputValue();
+ final Optional<String> fromUnitOptional = ucview.getFromSelection();
+ final Optional<String> toUnitOptional = ucview.getToSelection();
+ final String valueString = ucview.getInputValue();
- // ensure everything is obtained
- final Unit fromUnit, toUnit;
- final double value;
+ // extract values from optionals
+ final String fromUnitString, toUnitString;
if (fromUnitOptional.isPresent()) {
- fromUnit = fromUnitOptional.orElseThrow();
+ fromUnitString = fromUnitOptional.orElseThrow();
} else {
- this.view.showErrorMessage("Unit Conversion Error",
+ this.view.showErrorMessage("Unit Selection Error",
"Please specify a From unit");
return;
}
if (toUnitOptional.isPresent()) {
- toUnit = toUnitOptional.orElseThrow();
+ toUnitString = toUnitOptional.orElseThrow();
} else {
- this.view.showErrorMessage("Unit Conversion Error",
+ this.view.showErrorMessage("Unit Selection Error",
"Please specify a To unit");
return;
}
- if (valueOptional.isPresent()) {
- value = valueOptional.orElseThrow();
- } else {
- this.view.showErrorMessage("Unit Conversion Error",
- "Please specify a valid value");
+
+ // convert strings to data, checking if anything is invalid
+ final Unit fromUnit, toUnit;
+ final double value;
+
+ if (this.database.containsUnitName(fromUnitString)) {
+ fromUnit = this.database.getUnit(fromUnitString);
+ } else
+ throw this.viewError("Nonexistent From unit: %s", fromUnitString);
+ if (this.database.containsUnitName(toUnitString)) {
+ toUnit = this.database.getUnit(toUnitString);
+ } else
+ throw this.viewError("Nonexistent To unit: %s", toUnitString);
+ try {
+ value = Double.parseDouble(valueString);
+ } catch (final NumberFormatException e) {
+ this.view.showErrorMessage("Value Error",
+ "Invalid value " + valueString);
return;
}
if (!fromUnit.canConvertTo(toUnit))
- throw new AssertionError(
- "From and To units incompatible (should be impossible)");
+ throw this.viewError("Could not convert between %s and %s",
+ fromUnit, toUnit);
// convert!
final UnitValue initialValue = UnitValue.of(fromUnit, value);
final UnitValue converted = initialValue.convertTo(toUnit);
- ucview.showUnitConversionOutput(initialValue, converted);
+
+ ucview.showUnitConversionOutput(
+ UnitConversionRecord.fromValues(initialValue, converted));
} else
throw new UnsupportedOperationException(
"This function can only be called when the view is a UnitConversionView.");
}
/**
+ * @return true iff duplicate units are shown in unit lists
+ * @since 2022-03-30
+ */
+ public boolean duplicateUnitsShown() {
+ return this.showDuplicateUnits;
+ }
+
+ /**
+ * @return true iff the One-Way Conversion feature is available (views that
+ * show units as a list will have metric units removed from the From
+ * unit list and imperial/USC units removed from the To unit list)
+ *
+ * @since 2022-03-30
+ */
+ public boolean isOneWayConversionEnabled() {
+ return this.oneWayConversionEnabled;
+ }
+
+ /**
* Loads settings from the user's settings file and applies them to the view.
*
* @since 2021-12-15
@@ -403,7 +409,7 @@ public final class Presenter {
// unit conversion specific stuff
if (this.view instanceof UnitConversionView) {
final UnitConversionView ucview = (UnitConversionView) this.view;
- ucview.setDimensions(unique(this.database.dimensionMap().values()));
+ ucview.setDimensionNames(this.database.dimensionMap().keySet());
}
}
@@ -417,6 +423,26 @@ public final class Presenter {
*/
public void saveSettings() {}
+ /**
+ * @param oneWayConversionEnabled whether not one-way conversion should be
+ * enabled
+ * @since 2022-03-30
+ * @see {@link #isOneWayConversionEnabled}
+ */
+ public void setOneWayConversionEnabled(boolean oneWayConversionEnabled) {
+ this.oneWayConversionEnabled = oneWayConversionEnabled;
+ this.updateView();
+ }
+
+ /**
+ * @param showDuplicateUnits whether or not duplicate units should be shown
+ * @since 2022-03-30
+ */
+ public void setShowDuplicateUnits(boolean showDuplicateUnits) {
+ this.showDuplicateUnits = showDuplicateUnits;
+ this.updateView();
+ }
+
void unitNameSelected() {}
/**
@@ -427,17 +453,30 @@ public final class Presenter {
public void updateView() {
if (this.view instanceof UnitConversionView) {
final UnitConversionView ucview = (UnitConversionView) this.view;
- final ObjectProduct<BaseDimension> viewDimension = ucview
- .getSelectedDimension().orElseThrow();
+ final ObjectProduct<BaseDimension> viewDimension = this.database
+ .getDimension(((UnitConversionView) this.view)
+ .getSelectedDimensionName().orElseThrow());
- final Set<Unit> units = this.database
+ final Set<String> units = this.database
.unitMapPrefixless(this.showDuplicateUnits).entrySet().stream()
.map(Map.Entry::getValue)
.filter(u -> viewDimension.equals(u.getDimension()))
- .collect(Collectors.toSet());
+ .map(Unit::getName).collect(Collectors.toSet());
- ucview.setFromUnits(units);
- ucview.setToUnits(units);
+ ucview.setFromUnitNames(units);
+ ucview.setToUnitNames(units);
}
}
+
+ /**
+ * @param message message to add
+ * @param args string formatting arguments for message
+ * @return AssertionError stating that an error has happened in the view's
+ * code
+ * @since 2022-04-09
+ */
+ private AssertionError viewError(String message, Object... args) {
+ return new AssertionError("View Programming Error (from " + this.view
+ + "): " + String.format(message, args));
+ }
}
diff --git a/src/main/java/sevenUnitsGUI/SearchBoxList.java b/src/main/java/sevenUnitsGUI/SearchBoxList.java
index 2b935d0..9b41601 100644
--- a/src/main/java/sevenUnitsGUI/SearchBoxList.java
+++ b/src/main/java/sevenUnitsGUI/SearchBoxList.java
@@ -22,6 +22,7 @@ import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
@@ -166,6 +167,15 @@ final class SearchBoxList<E> extends JPanel {
}
/**
+ * @return items available in search list, including items that are hidden by
+ * the search filter
+ * @since 2022-03-30
+ */
+ public Collection<E> getItems() {
+ return Collections.unmodifiableCollection(this.itemsToFilter);
+ }
+
+ /**
* @return this component's search box component
* @since 2019-04-14
* @since v0.2.0
diff --git a/src/main/java/sevenUnitsGUI/TabbedView.java b/src/main/java/sevenUnitsGUI/TabbedView.java
index 0461cb6..ed45011 100644
--- a/src/main/java/sevenUnitsGUI/TabbedView.java
+++ b/src/main/java/sevenUnitsGUI/TabbedView.java
@@ -23,13 +23,12 @@ import java.awt.GridLayout;
import java.awt.event.KeyEvent;
import java.text.DecimalFormat;
import java.text.NumberFormat;
-import java.text.ParseException;
import java.util.AbstractSet;
import java.util.Collections;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Optional;
-import java.util.OptionalDouble;
import java.util.Set;
import javax.swing.BorderFactory;
@@ -57,12 +56,6 @@ import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;
import sevenUnits.ProgramInfo;
-import sevenUnits.unit.BaseDimension;
-import sevenUnits.unit.Unit;
-import sevenUnits.unit.UnitPrefix;
-import sevenUnits.unit.UnitValue;
-import sevenUnits.utils.NamedObjectProduct;
-import sevenUnits.utils.ObjectProduct;
/**
* A View that separates its functions into multiple tabs
@@ -140,13 +133,13 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView {
// DIMENSION-BASED CONVERTER
/** The combo box that selects dimensions */
- private final JComboBox<NamedObjectProduct<BaseDimension>> dimensionSelector;
+ private final JComboBox<String> dimensionSelector;
/** The panel for inputting values in the dimension-based converter */
private final JFormattedTextField valueInput;
/** The panel for "From" in the dimension-based converter */
- private final SearchBoxList<Unit> fromSearch;
+ private final SearchBoxList<String> fromSearch;
/** The panel for "To" in the dimension-based converter */
- private final SearchBoxList<Unit> toSearch;
+ private final SearchBoxList<String> toSearch;
/** The output area in the dimension-based converter */
private final JTextArea unitOutput;
@@ -160,9 +153,9 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView {
// UNIT AND PREFIX VIEWERS
/** The searchable list of unit names in the unit viewer */
- private final SearchBoxList<Unit> unitNameList;
+ private final SearchBoxList<String> unitNameList;
/** The searchable list of prefix names in the prefix viewer */
- private final SearchBoxList<UnitPrefix> prefixNameList;
+ private final SearchBoxList<String> prefixNameList;
/** The text box for unit data in the unit viewer */
private final JTextArea unitTextBox;
/** The text box for prefix data in the prefix viewer */
@@ -528,7 +521,7 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView {
}
@Override
- public Set<NamedObjectProduct<BaseDimension>> getDimensions() {
+ public Set<String> getDimensionNames() {
return Collections
.unmodifiableSet(new JComboBoxItemSet<>(this.dimensionSelector));
}
@@ -539,27 +532,25 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView {
}
@Override
- public Optional<Unit> getFromSelection() {
+ public Optional<String> getFromSelection() {
return this.fromSearch.getSelectedValue();
}
@Override
- public OptionalDouble getInputValue() {
- try {
- this.valueInput.commitEdit();
- } catch (final ParseException e) {
- return OptionalDouble.empty();
- }
- return OptionalDouble
- .of(((Number) this.valueInput.getValue()).doubleValue());
+ public Set<String> getFromUnitNames() {
+ // this should work because the only way I can mutate the item list is
+ // with setFromUnits which only accepts a Set
+ return new HashSet<>(this.fromSearch.getItems());
+ }
+
+ @Override
+ public String getInputValue() {
+ return this.valueInput.getText();
}
@Override
- public Optional<? extends ObjectProduct<BaseDimension>> getSelectedDimension() {
- // this must work because this function can only return items that are in
- // the selector, which are all of type ObjectProduct<BaseDimension>
- @SuppressWarnings("unchecked")
- final ObjectProduct<BaseDimension> selectedItem = (ObjectProduct<BaseDimension>) this.dimensionSelector
+ public Optional<String> getSelectedDimensionName() {
+ final String selectedItem = (String) this.dimensionSelector
.getSelectedItem();
return Optional.ofNullable(selectedItem);
}
@@ -570,26 +561,32 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView {
}
@Override
- public Optional<Unit> getToSelection() {
+ public Optional<String> getToSelection() {
return this.toSearch.getSelectedValue();
}
@Override
- public void setDimensions(
- Set<NamedObjectProduct<BaseDimension>> dimensions) {
+ public Set<String> getToUnitNames() {
+ // this should work because the only way I can mutate the item list is
+ // with setToUnits which only accepts a Set
+ return new HashSet<>(this.toSearch.getItems());
+ }
+
+ @Override
+ public void setDimensionNames(Set<String> dimensionNames) {
this.dimensionSelector.removeAllItems();
- for (final NamedObjectProduct<BaseDimension> d : dimensions) {
+ for (final String d : dimensionNames) {
this.dimensionSelector.addItem(d);
}
}
@Override
- public void setFromUnits(Set<? extends Unit> units) {
+ public void setFromUnitNames(Set<String> units) {
this.fromSearch.setItems(units);
}
@Override
- public void setToUnits(Set<? extends Unit> units) {
+ public void setToUnitNames(Set<String> units) {
this.toSearch.setItems(units);
}
@@ -600,15 +597,14 @@ final class TabbedView implements ExpressionConversionView, UnitConversionView {
}
@Override
- public void showExpressionConversionOutput(String fromExpression,
- String toExpression, double value) {
- this.expressionOutput.setText(
- String.format("%s = %s %s", fromExpression, value, toExpression));
+ public void showExpressionConversionOutput(UnitConversionRecord uc) {
+ this.expressionOutput.setText(String.format("%s = %s %s", uc.fromName(),
+ uc.outputValueString(), uc.toName()));
}
@Override
- public void showUnitConversionOutput(UnitValue input, UnitValue output) {
- this.unitOutput.setText(input + " = " + output);
+ public void showUnitConversionOutput(UnitConversionRecord uc) {
+ this.unitOutput.setText(uc.toString());
}
}
diff --git a/src/main/java/sevenUnitsGUI/UnitConversionRecord.java b/src/main/java/sevenUnitsGUI/UnitConversionRecord.java
new file mode 100644
index 0000000..60675e2
--- /dev/null
+++ b/src/main/java/sevenUnitsGUI/UnitConversionRecord.java
@@ -0,0 +1,180 @@
+/**
+ * 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 sevenUnits.unit.UnitValue;
+
+/**
+ * A record of a conversion between units or expressions
+ *
+ * @since 2022-04-09
+ */
+public final class UnitConversionRecord {
+ /**
+ * Gets a {@code UnitConversionRecord} from two unit values
+ *
+ * @param input input unit & value
+ * @param output output unit & value
+ * @return unit conversion record
+ * @since 2022-04-09
+ */
+ public static UnitConversionRecord fromValues(UnitValue input,
+ UnitValue output) {
+ return UnitConversionRecord.valueOf(input.getUnit().getName(),
+ output.getUnit().getName(), String.valueOf(input.getValue()),
+ String.valueOf(output.getValue()));
+ }
+
+ /**
+ * Gets a {@code UnitConversionRecord}
+ *
+ * @param fromName name of unit or expression that was converted
+ * from
+ * @param toName name of unit or expression that was converted to
+ * @param inputValueString string representing input value
+ * @param outputValueString string representing output value
+ * @return unit conversion record
+ * @since 2022-04-09
+ */
+ public static UnitConversionRecord valueOf(String fromName, String toName,
+ String inputValueString, String outputValueString) {
+ return new UnitConversionRecord(fromName, toName, inputValueString,
+ outputValueString);
+ }
+
+ /**
+ * The name of the unit or expression that was converted from
+ */
+ private final String fromName;
+ /**
+ * The name of the unit or expression that was converted to
+ */
+ private final String toName;
+
+ /**
+ * A string representing the input value. It doesn't need to be the same as
+ * the input value's string representation; it could be rounded, for example.
+ */
+ private final String inputValueString;
+ /**
+ * A string representing the input value. It doesn't need to be the same as
+ * the input value's string representation; it could be rounded, for example.
+ */
+ private final String outputValueString;
+
+ /**
+ * @param fromName name of unit or expression that was converted
+ * from
+ * @param toName name of unit or expression that was converted to
+ * @param inputValueString string representing input value
+ * @param outputValueString string representing output value
+ * @since 2022-04-09
+ */
+ private UnitConversionRecord(String fromName, String toName,
+ String inputValueString, String outputValueString) {
+ this.fromName = fromName;
+ this.toName = toName;
+ this.inputValueString = inputValueString;
+ this.outputValueString = outputValueString;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (!(obj instanceof UnitConversionRecord))
+ return false;
+ final UnitConversionRecord other = (UnitConversionRecord) obj;
+ if (this.fromName == null) {
+ if (other.fromName != null)
+ return false;
+ } else if (!this.fromName.equals(other.fromName))
+ return false;
+ if (this.inputValueString == null) {
+ if (other.inputValueString != null)
+ return false;
+ } else if (!this.inputValueString.equals(other.inputValueString))
+ return false;
+ if (this.outputValueString == null) {
+ if (other.outputValueString != null)
+ return false;
+ } else if (!this.outputValueString.equals(other.outputValueString))
+ return false;
+ if (this.toName == null) {
+ if (other.toName != null)
+ return false;
+ } else if (!this.toName.equals(other.toName))
+ return false;
+ return true;
+ }
+
+ /**
+ * @return name of unit or expression that was converted from
+ * @since 2022-04-09
+ */
+ public String fromName() {
+ return this.fromName;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result
+ + (this.fromName == null ? 0 : this.fromName.hashCode());
+ result = prime * result + (this.inputValueString == null ? 0
+ : this.inputValueString.hashCode());
+ result = prime * result + (this.outputValueString == null ? 0
+ : this.outputValueString.hashCode());
+ result = prime * result
+ + (this.toName == null ? 0 : this.toName.hashCode());
+ return result;
+ }
+
+ /**
+ * @return string representing input value
+ * @since 2022-04-09
+ */
+ public String inputValueString() {
+ return this.inputValueString;
+ }
+
+ /**
+ * @return string representing output value
+ * @since 2022-04-09
+ */
+ public String outputValueString() {
+ return this.outputValueString;
+ }
+
+ /**
+ * @return name of unit or expression that was converted to
+ * @since 2022-04-09
+ */
+ public String toName() {
+ return this.toName;
+ }
+
+ @Override
+ public String toString() {
+ final String inputString = this.inputValueString.isBlank() ? this.fromName
+ : this.inputValueString + " " + this.fromName;
+ final String outputString = this.outputValueString.isBlank() ? this.toName
+ : this.outputValueString + " " + this.toName;
+ return inputString + " = " + outputString;
+ }
+}
diff --git a/src/main/java/sevenUnitsGUI/UnitConversionView.java b/src/main/java/sevenUnitsGUI/UnitConversionView.java
index 67d3ddc..9d3a67b 100644
--- a/src/main/java/sevenUnitsGUI/UnitConversionView.java
+++ b/src/main/java/sevenUnitsGUI/UnitConversionView.java
@@ -17,15 +17,8 @@
package sevenUnitsGUI;
import java.util.Optional;
-import java.util.OptionalDouble;
import java.util.Set;
-import sevenUnits.unit.BaseDimension;
-import sevenUnits.unit.Unit;
-import sevenUnits.unit.UnitValue;
-import sevenUnits.utils.NamedObjectProduct;
-import sevenUnits.utils.ObjectProduct;
-
/**
* A View that supports single unit-based conversion
*
@@ -37,60 +30,72 @@ public interface UnitConversionView extends View {
* @return dimensions available for filtering
* @since 2022-01-29
*/
- Set<NamedObjectProduct<BaseDimension>> getDimensions();
+ Set<String> getDimensionNames();
/**
- * @return unit to convert <em>from</em>
+ * @return name of unit to convert <em>from</em>
* @since 2021-12-15
*/
- Optional<Unit> getFromSelection();
+ Optional<String> getFromSelection();
+
+ /**
+ * @return list of names of units available to convert from
+ * @since 2022-03-30
+ */
+ Set<String> getFromUnitNames();
/**
* @return value to convert between the units (specifically, the numeric
* string provided by the user)
* @since 2021-12-15
*/
- OptionalDouble getInputValue();
+ String getInputValue();
/**
* @return selected dimension
* @since 2021-12-15
*/
- Optional<? extends ObjectProduct<BaseDimension>> getSelectedDimension();
+ Optional<String> getSelectedDimensionName();
/**
- * @return unit to convert <em>to</em>
+ * @return name of unit to convert <em>to</em>
* @since 2021-12-15
*/
- Optional<Unit> getToSelection();
+ Optional<String> getToSelection();
+
+ /**
+ * @return list of names of units available to convert to
+ * @since 2022-03-30
+ */
+ Set<String> getToUnitNames();
/**
* Sets the available dimensions for filtering.
*
- * @param dimensions dimensions to use
+ * @param dimensionNames names of dimensions to use
* @since 2021-12-15
*/
- void setDimensions(Set<NamedObjectProduct<BaseDimension>> dimensions);
+ void setDimensionNames(Set<String> dimensionNames);
/**
* Sets the available units to convert from. {@link #getFromSelection} is not
* required to use one of these units; this method is to be used for views
* that allow the user to select units from a list.
*
- * @param units units to convert from
+ * @param unitNames names of units to convert from
* @since 2021-12-15
*/
- void setFromUnits(Set<? extends Unit> units);
+ void setFromUnitNames(Set<String> unitNames);
/**
* Sets the available units to convert to. {@link #getToSelection} is not
* required to use one of these units; this method is to be used for views
* that allow the user to select units from a list.
*
- * @param units units to convert to
+ * @param unitNames names of units to convert to
* @since 2021-12-15
*/
- void setToUnits(Set<? extends Unit> units);
+ void setToUnitNames(Set<String> unitNames);
/**
* Shows the output of a unit conversion.
@@ -99,5 +104,5 @@ public interface UnitConversionView extends View {
* @param output output unit & value
* @since 2021-12-24
*/
- void showUnitConversionOutput(UnitValue input, UnitValue output);
+ void showUnitConversionOutput(UnitConversionRecord uc);
}
diff --git a/src/main/java/sevenUnitsGUI/View.java b/src/main/java/sevenUnitsGUI/View.java
index a93c76a..e78c9cc 100644
--- a/src/main/java/sevenUnitsGUI/View.java
+++ b/src/main/java/sevenUnitsGUI/View.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2021 Adrien Hopkins
+ * Copyright (C) 2021-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
diff --git a/src/main/java/sevenUnitsGUI/ViewBot.java b/src/main/java/sevenUnitsGUI/ViewBot.java
index 43d73bb..0195dd6 100644
--- a/src/main/java/sevenUnitsGUI/ViewBot.java
+++ b/src/main/java/sevenUnitsGUI/ViewBot.java
@@ -21,15 +21,8 @@ import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
-import java.util.OptionalDouble;
import java.util.Set;
-import sevenUnits.unit.BaseDimension;
-import sevenUnits.unit.Unit;
-import sevenUnits.unit.UnitValue;
-import sevenUnits.utils.NamedObjectProduct;
-import sevenUnits.utils.ObjectProduct;
-
/**
* A class that simulates a View (supports both unit and expression conversion)
* for testing. Getters and setters work as expected.
@@ -42,7 +35,7 @@ final class ViewBot implements UnitConversionView, ExpressionConversionView {
private final Presenter presenter;
/** The dimensions available to select from */
- private Set<NamedObjectProduct<BaseDimension>> dimensions;
+ private Set<String> dimensionNames;
/** The expression in the From field */
private String fromExpression;
/** The expression in the To field */
@@ -50,23 +43,22 @@ final class ViewBot implements UnitConversionView, ExpressionConversionView {
/**
* The user-provided string representing the value in {@code fromSelection}
*/
- private OptionalDouble inputValue;
+ private String inputValue;
/** The unit selected in the From selection */
- private Optional<Unit> fromSelection;
+ private Optional<String> fromSelection;
/** The unit selected in the To selection */
- private Optional<Unit> toSelection;
+ private Optional<String> toSelection;
/** The currently selected dimension */
- private Optional<? extends ObjectProduct<BaseDimension>> selectedDimension;
+ private Optional<String> selectedDimensionName;
/** The units available in the From selection */
- private Set<? extends Unit> fromUnits;
+ private Set<String> fromUnits;
/** The units available in the To selection */
- private Set<? extends Unit> toUnits;
- /** Saved input values of all unit conversions */
- private final List<UnitValue> unitConversionInputValues;
- /** Saved output values of all unit conversions */
- private final List<UnitValue> unitConversionOutputValues;
+ private Set<String> toUnits;
+
+ /** Saved outputs of all unit conversions */
+ private final List<UnitConversionRecord> unitConversions;
/** Saved outputs of all unit expressions */
- private final List<String> expressionConversionOutputs;
+ private final List<UnitConversionRecord> expressionConversions;
/**
* Creates a new {@code ViewBot} with a new presenter.
@@ -76,9 +68,16 @@ final class ViewBot implements UnitConversionView, ExpressionConversionView {
public ViewBot() {
this.presenter = new Presenter(this);
- this.unitConversionInputValues = new ArrayList<>();
- this.unitConversionOutputValues = new ArrayList<>();
- this.expressionConversionOutputs = new ArrayList<>();
+ this.unitConversions = new ArrayList<>();
+ this.expressionConversions = new ArrayList<>();
+ }
+
+ /**
+ * @return list of records of expression conversions done by this bot
+ * @since 2022-04-09
+ */
+ public List<UnitConversionRecord> expressionConversionList() {
+ return this.expressionConversions;
}
/**
@@ -86,12 +85,8 @@ final class ViewBot implements UnitConversionView, ExpressionConversionView {
* @since 2022-01-29
*/
@Override
- public Set<NamedObjectProduct<BaseDimension>> getDimensions() {
- return this.dimensions;
- }
-
- public List<String> getExpressionConversionOutputs() {
- return this.expressionConversionOutputs;
+ public Set<String> getDimensionNames() {
+ return this.dimensionNames;
}
@Override
@@ -100,7 +95,7 @@ final class ViewBot implements UnitConversionView, ExpressionConversionView {
}
@Override
- public Optional<Unit> getFromSelection() {
+ public Optional<String> getFromSelection() {
return this.fromSelection;
}
@@ -108,12 +103,13 @@ final class ViewBot implements UnitConversionView, ExpressionConversionView {
* @return the units available for selection in From
* @since 2022-01-29
*/
- public Set<Unit> getFromUnits() {
+ @Override
+ public Set<String> getFromUnitNames() {
return Collections.unmodifiableSet(this.fromUnits);
}
@Override
- public OptionalDouble getInputValue() {
+ public String getInputValue() {
return this.inputValue;
}
@@ -126,8 +122,8 @@ final class ViewBot implements UnitConversionView, ExpressionConversionView {
}
@Override
- public Optional<ObjectProduct<BaseDimension>> getSelectedDimension() {
- return this.selectedDimension.map(x -> x);
+ public Optional<String> getSelectedDimensionName() {
+ return this.selectedDimensionName;
}
@Override
@@ -136,7 +132,7 @@ final class ViewBot implements UnitConversionView, ExpressionConversionView {
}
@Override
- public Optional<Unit> getToSelection() {
+ public Optional<String> getToSelection() {
return this.toSelection;
}
@@ -144,30 +140,14 @@ final class ViewBot implements UnitConversionView, ExpressionConversionView {
* @return the units available for selection in To
* @since 2022-01-29
*/
- public Set<Unit> getToUnits() {
+ @Override
+ public Set<String> getToUnitNames() {
return Collections.unmodifiableSet(this.toUnits);
}
- /**
- * @return the unitConversionInputValues
- * @since 2022-02-26
- */
- public List<UnitValue> getUnitConversionInputValues() {
- return this.unitConversionInputValues;
- }
-
- /**
- * @return the unitConversionOutputValues
- * @since 2022-02-10
- */
- public List<UnitValue> getUnitConversionOutputValues() {
- return this.unitConversionOutputValues;
- }
-
@Override
- public void setDimensions(
- Set<NamedObjectProduct<BaseDimension>> dimensions) {
- this.dimensions = Objects.requireNonNull(dimensions,
+ public void setDimensionNames(Set<String> dimensionNames) {
+ this.dimensionNames = Objects.requireNonNull(dimensionNames,
"dimensions may not be null");
}
@@ -187,7 +167,7 @@ final class ViewBot implements UnitConversionView, ExpressionConversionView {
* @param fromSelection the fromSelection to set
* @since 2022-01-29
*/
- public void setFromSelection(Optional<Unit> fromSelection) {
+ public void setFromSelection(Optional<String> fromSelection) {
this.fromSelection = Objects.requireNonNull(fromSelection,
"fromSelection cannot be null");
}
@@ -196,12 +176,12 @@ final class ViewBot implements UnitConversionView, ExpressionConversionView {
* @param fromSelection the fromSelection to set
* @since 2022-02-10
*/
- public void setFromSelection(Unit fromSelection) {
+ public void setFromSelection(String fromSelection) {
this.setFromSelection(Optional.of(fromSelection));
}
@Override
- public void setFromUnits(Set<? extends Unit> units) {
+ public void setFromUnitNames(Set<String> units) {
this.fromUnits = Objects.requireNonNull(units, "units may not be null");
}
@@ -209,22 +189,21 @@ final class ViewBot implements UnitConversionView, ExpressionConversionView {
* @param inputValue the inputValue to set
* @since 2022-01-29
*/
- public void setInputValue(OptionalDouble inputValue) {
+ public void setInputValue(String inputValue) {
this.inputValue = inputValue;
}
- public void setSelectedDimension(
- ObjectProduct<BaseDimension> selectedDimension) {
- this.setSelectedDimension(Optional.of(selectedDimension));
- }
-
/**
* @param selectedDimension the selectedDimension to set
* @since 2022-01-29
*/
- public void setSelectedDimension(
- Optional<? extends ObjectProduct<BaseDimension>> selectedDimension) {
- this.selectedDimension = selectedDimension;
+ public void setSelectedDimensionName(
+ Optional<String> selectedDimensionName) {
+ this.selectedDimensionName = selectedDimensionName;
+ }
+
+ public void setSelectedDimensionName(String selectedDimensionName) {
+ this.setSelectedDimensionName(Optional.of(selectedDimensionName));
}
/**
@@ -243,17 +222,17 @@ final class ViewBot implements UnitConversionView, ExpressionConversionView {
* @param toSelection the toSelection to set
* @since 2022-01-29
*/
- public void setToSelection(Optional<Unit> toSelection) {
+ public void setToSelection(Optional<String> toSelection) {
this.toSelection = Objects.requireNonNull(toSelection,
"toSelection cannot be null.");
}
- public void setToSelection(Unit toSelection) {
+ public void setToSelection(String toSelection) {
this.setToSelection(Optional.of(toSelection));
}
@Override
- public void setToUnits(Set<? extends Unit> units) {
+ public void setToUnitNames(Set<String> units) {
this.toUnits = Objects.requireNonNull(units, "units may not be null");
}
@@ -263,19 +242,15 @@ final class ViewBot implements UnitConversionView, ExpressionConversionView {
}
@Override
- public void showExpressionConversionOutput(String fromExpression,
- String toExpression, double value) {
- final String output = String.format("%s = %s %s", fromExpression, value,
- toExpression);
- this.expressionConversionOutputs.add(output);
- System.out.println("Expression Conversion: " + output);
+ public void showExpressionConversionOutput(UnitConversionRecord uc) {
+ this.expressionConversions.add(uc);
+ System.out.println("Expression Conversion: " + uc);
}
@Override
- public void showUnitConversionOutput(UnitValue input, UnitValue output) {
- this.unitConversionInputValues.add(input);
- this.unitConversionOutputValues.add(output);
- System.out.println("Unit conversion: " + input + " = " + output);
+ public void showUnitConversionOutput(UnitConversionRecord uc) {
+ this.unitConversions.add(uc);
+ System.out.println("Unit Conversion: " + uc);
}
@Override
@@ -283,4 +258,12 @@ final class ViewBot implements UnitConversionView, ExpressionConversionView {
return super.toString() + String.format("[presenter=%s]", this.presenter);
}
+ /**
+ * @return list of records of every unit conversion made by this bot
+ * @since 2022-04-09
+ */
+ public List<UnitConversionRecord> unitConversionList() {
+ return Collections.unmodifiableList(this.unitConversions);
+ }
+
}
diff --git a/src/test/java/sevenUnitsGUI/PresenterTest.java b/src/test/java/sevenUnitsGUI/PresenterTest.java
index 82842d8..dc2fb57 100644
--- a/src/test/java/sevenUnitsGUI/PresenterTest.java
+++ b/src/test/java/sevenUnitsGUI/PresenterTest.java
@@ -17,12 +17,9 @@
package sevenUnitsGUI;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assumptions.assumeTrue;
-import java.util.Collection;
import java.util.List;
-import java.util.Optional;
-import java.util.OptionalDouble;
import java.util.Set;
import java.util.stream.Collectors;
@@ -32,6 +29,7 @@ import sevenUnits.unit.BaseDimension;
import sevenUnits.unit.Metric;
import sevenUnits.unit.Unit;
import sevenUnits.unit.UnitValue;
+import sevenUnits.utils.Nameable;
import sevenUnits.utils.NamedObjectProduct;
/**
@@ -46,10 +44,8 @@ public final class PresenterTest {
static final Set<NamedObjectProduct<BaseDimension>> testDimensions = Set
.of(Metric.Dimensions.LENGTH, Metric.Dimensions.VELOCITY);
- private static final List<String> unitNames(
- Collection<? extends Unit> units) {
- return units.stream().map(Unit::getShortName)
- .collect(Collectors.toList());
+ private static final Set<String> names(Set<? extends Nameable> units) {
+ return units.stream().map(Nameable::getName).collect(Collectors.toSet());
}
/**
@@ -70,8 +66,10 @@ public final class PresenterTest {
presenter.convertExpressions();
// test result
- final List<String> outputs = viewBot.getExpressionConversionOutputs();
- assertEquals("10000.0 m = 10.0 km", outputs.get(outputs.size() - 1));
+ final List<UnitConversionRecord> outputs = viewBot
+ .expressionConversionList();
+ assertEquals("10000.0 m = 10.0 km",
+ outputs.get(outputs.size() - 1).toString());
}
/**
@@ -85,11 +83,11 @@ public final class PresenterTest {
final ViewBot viewBot = new ViewBot();
final Presenter presenter = new Presenter(viewBot);
- viewBot.setFromUnits(testUnits);
- viewBot.setToUnits(testUnits);
- viewBot.setFromSelection(Optional.of(Metric.METRE));
- viewBot.setToSelection(Optional.of(Metric.KILOMETRE));
- viewBot.setInputValue(OptionalDouble.of(10000.0));
+ viewBot.setFromUnitNames(names(testUnits));
+ viewBot.setToUnitNames(names(testUnits));
+ viewBot.setFromSelection("metre");
+ viewBot.setToSelection("kilometre");
+ viewBot.setInputValue("10000.0");
// convert units
presenter.convertUnits();
@@ -102,11 +100,29 @@ public final class PresenterTest {
final UnitValue expectedInput = UnitValue.of(Metric.METRE, 10000.0);
final UnitValue expectedOutput = expectedInput
.convertTo(Metric.KILOMETRE);
+ final UnitConversionRecord expectedUC = UnitConversionRecord
+ .fromValues(expectedInput, expectedOutput);
- final List<UnitValue> inputs = viewBot.getUnitConversionInputValues();
- final List<UnitValue> outputs = viewBot.getUnitConversionOutputValues();
- assertEquals(expectedInput, inputs.get(inputs.size() - 1));
- assertEquals(expectedOutput, outputs.get(outputs.size() - 1));
+ assertEquals(List.of(expectedUC), viewBot.unitConversionList());
+ }
+
+ @Test
+ void testDuplicateUnits() {
+ assumeTrue(false, "Not yet implemented");
+ /*
+ * enable and disable duplicate units and check for those in From and To,
+ * include duplicate units in the input set
+ */
+ }
+
+ @Test
+ void testOneWayConversion() {
+ assumeTrue(false, "Not yet implemented");
+ /*
+ * enable and disable one-way conversion, testing the units in From and To
+ * on each setting to ensure they match the rule. Include at least one
+ * metric exception.
+ */
}
/**
@@ -125,31 +141,24 @@ public final class PresenterTest {
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.setFromUnits(testUnits);
- viewBot.setToUnits(testUnits);
- viewBot.setDimensions(testDimensions);
- viewBot.setSelectedDimension(Optional.of(Metric.Dimensions.LENGTH));
+ 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<Unit> fromUnits = viewBot.getFromUnits();
- final Set<Unit> toUnits = viewBot.getToUnits();
+ final Set<String> fromUnits = viewBot.getFromUnitNames();
+ final Set<String> toUnits = viewBot.getToUnitNames();
// test that fromUnits/toUnits is [METRE, KILOMETRE]
- // HOWEVER I don't care about the order so I'm testing it this way
- assertEquals(2, fromUnits.size(),
- "Invalid fromUnits (length != 2): " + unitNames(fromUnits));
- assertEquals(2, toUnits.size(),
- "Invalid toUnits (length != 2): " + unitNames(toUnits));
- assertTrue(fromUnits.contains(Metric.METRE),
- "Invaild fromUnits (METRE missing): " + unitNames(fromUnits));
- assertTrue(toUnits.contains(Metric.METRE),
- "Invaild toUnits (METRE missing): " + unitNames(toUnits));
- assertTrue(fromUnits.contains(Metric.KILOMETRE),
- "Invaild fromUnits (KILOMETRE missing): " + unitNames(fromUnits));
- assertTrue(toUnits.contains(Metric.KILOMETRE),
- "Invaild toUnits (KILOMETRE missing): " + unitNames(toUnits));
+ assertEquals(Set.of("metre", "kilometre"), fromUnits);
+ assertEquals(Set.of("metre", "kilometre"), toUnits);
}
}