/** * 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 . */ package sevenUnitsGUI; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.Set; import sevenUnits.unit.UnitType; import sevenUnits.utils.NameSymbol; import sevenUnits.utils.Nameable; /** * A class that simulates a View (supports both unit and expression conversion) * for testing. Getters and setters work as expected. * * @author Adrien Hopkins * @since 2022-01-29 */ final class ViewBot implements UnitConversionView, ExpressionConversionView { /** * A record of the parameters given to * {@link View#showPrefix(NameSymbol, String)}, for testing. * * @since 2022-04-16 */ public static final class PrefixViewingRecord implements Nameable { private final NameSymbol nameSymbol; private final String multiplierString; /** * @param nameSymbol * @param multiplierString * @since 2022-04-16 */ public PrefixViewingRecord(NameSymbol nameSymbol, String multiplierString) { this.nameSymbol = nameSymbol; this.multiplierString = multiplierString; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof PrefixViewingRecord)) return false; final PrefixViewingRecord other = (PrefixViewingRecord) obj; return Objects.equals(this.multiplierString, other.multiplierString) && Objects.equals(this.nameSymbol, other.nameSymbol); } @Override public NameSymbol getNameSymbol() { return this.nameSymbol; } @Override public int hashCode() { return Objects.hash(this.multiplierString, this.nameSymbol); } public String multiplierString() { return this.multiplierString; } public NameSymbol nameSymbol() { return this.nameSymbol; } @Override public String toString() { final StringBuilder builder = new StringBuilder(); builder.append("PrefixViewingRecord [nameSymbol="); builder.append(this.nameSymbol); builder.append(", multiplierString="); builder.append(this.multiplierString); builder.append("]"); return builder.toString(); } } /** * A record of the parameters given to * {@link View#showUnit(NameSymbol, String, String, UnitType)}, for testing. * * @since 2022-04-16 */ public static final class UnitViewingRecord implements Nameable { private final NameSymbol nameSymbol; private final String definition; private final String dimensionName; private final UnitType unitType; /** * @since 2022-04-16 */ public UnitViewingRecord(NameSymbol nameSymbol, String definition, String dimensionName, UnitType unitType) { this.nameSymbol = nameSymbol; this.definition = definition; this.dimensionName = dimensionName; this.unitType = unitType; } /** * @return the definition * @since 2022-04-16 */ public String definition() { return this.definition; } /** * @return the dimensionName * @since 2022-04-16 */ public String dimensionName() { return this.dimensionName; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof UnitViewingRecord)) return false; final UnitViewingRecord other = (UnitViewingRecord) obj; return Objects.equals(this.definition, other.definition) && Objects.equals(this.dimensionName, other.dimensionName) && Objects.equals(this.nameSymbol, other.nameSymbol) && this.unitType == other.unitType; } /** * @return the nameSymbol * @since 2022-04-16 */ @Override public NameSymbol getNameSymbol() { return this.nameSymbol; } @Override public int hashCode() { return Objects.hash(this.definition, this.dimensionName, this.nameSymbol, this.unitType); } public NameSymbol nameSymbol() { return this.nameSymbol; } @Override public String toString() { final StringBuilder builder = new StringBuilder(); builder.append("UnitViewingRecord [nameSymbol="); builder.append(this.nameSymbol); builder.append(", definition="); builder.append(this.definition); builder.append(", dimensionName="); builder.append(this.dimensionName); builder.append(", unitType="); builder.append(this.unitType); builder.append("]"); return builder.toString(); } /** * @return the unitType * @since 2022-04-16 */ public UnitType unitType() { return this.unitType; } } /** The presenter that works with this ViewBot */ private final Presenter presenter; /** The dimensions available to select from */ private Set dimensionNames; /** The expression in the From field */ private String fromExpression; /** The expression in the To field */ private String toExpression; /** * The user-provided string representing the value in {@code fromSelection} */ private String inputValue; /** The unit selected in the From selection */ private Optional fromSelection; /** The unit selected in the To selection */ private Optional toSelection; /** The currently selected dimension */ private Optional selectedDimensionName; /** The units available in the From selection */ private Set fromUnits; /** The units available in the To selection */ private Set toUnits; /** Saved outputs of all unit conversions */ private final List unitConversions; /** Saved outputs of all unit expressions */ private final List expressionConversions; /** Saved outputs of all unit viewings */ private final List unitViewingRecords; /** Saved outputs of all prefix viewings */ private final List prefixViewingRecords; /** * Creates a new {@code ViewBot} with a new presenter. * * @since 2022-01-29 */ public ViewBot() { this.presenter = new Presenter(this); this.unitConversions = new ArrayList<>(); this.expressionConversions = new ArrayList<>(); this.unitViewingRecords = new ArrayList<>(); this.prefixViewingRecords = new ArrayList<>(); } /** * @return list of records of expression conversions done by this bot * @since 2022-04-09 */ public List expressionConversionList() { return Collections.unmodifiableList(this.expressionConversions); } /** * @return the available dimensions * @since 2022-01-29 */ @Override public Set getDimensionNames() { return this.dimensionNames; } @Override public String getFromExpression() { return this.fromExpression; } @Override public Optional getFromSelection() { return this.fromSelection; } /** * @return the units available for selection in From * @since 2022-01-29 */ @Override public Set getFromUnitNames() { return Collections.unmodifiableSet(this.fromUnits); } @Override public String getInputValue() { return this.inputValue; } /** * @return the presenter associated with tihs view * @since 2022-01-29 */ public Presenter getPresenter() { return this.presenter; } @Override public Optional getSelectedDimensionName() { return this.selectedDimensionName; } @Override public String getToExpression() { return this.toExpression; } @Override public Optional getToSelection() { return this.toSelection; } /** * @return the units available for selection in To * @since 2022-01-29 */ @Override public Set getToUnitNames() { return Collections.unmodifiableSet(this.toUnits); } @Override public Optional getViewedPrefixName() { throw new UnsupportedOperationException("Not implemented yet"); } @Override public Optional getViewedUnitName() { throw new UnsupportedOperationException("Not implemented yet"); } /** * @return list of records of this viewBot's prefix views * @since 2022-04-16 */ public List prefixViewList() { return Collections.unmodifiableList(this.prefixViewingRecords); } @Override public void setDimensionNames(Set dimensionNames) { this.dimensionNames = Objects.requireNonNull(dimensionNames, "dimensions may not be null"); } /** * Sets the From expression (as in {@link #getFromExpression}). * * @param fromExpression the expression to convert from * @throws NullPointerException if {@code fromExpression} is null * @since 2022-01-29 */ public void setFromExpression(String fromExpression) { this.fromExpression = Objects.requireNonNull(fromExpression, "fromExpression cannot be null."); } /** * @param fromSelection the fromSelection to set * @since 2022-01-29 */ public void setFromSelection(Optional fromSelection) { this.fromSelection = Objects.requireNonNull(fromSelection, "fromSelection cannot be null"); } /** * @param fromSelection the fromSelection to set * @since 2022-02-10 */ public void setFromSelection(String fromSelection) { this.setFromSelection(Optional.of(fromSelection)); } @Override public void setFromUnitNames(Set units) { this.fromUnits = Objects.requireNonNull(units, "units may not be null"); } /** * @param inputValue the inputValue to set * @since 2022-01-29 */ public void setInputValue(String inputValue) { this.inputValue = inputValue; } /** * @param selectedDimension the selectedDimension to set * @since 2022-01-29 */ public void setSelectedDimensionName( Optional selectedDimensionName) { this.selectedDimensionName = selectedDimensionName; } public void setSelectedDimensionName(String selectedDimensionName) { this.setSelectedDimensionName(Optional.of(selectedDimensionName)); } /** * Sets the To expression (as in {@link #getToExpression}). * * @param toExpression the expression to convert to * @throws NullPointerException if {@code toExpression} is null * @since 2022-01-29 */ public void setToExpression(String toExpression) { this.toExpression = Objects.requireNonNull(toExpression, "toExpression cannot be null."); } /** * @param toSelection the toSelection to set * @since 2022-01-29 */ public void setToSelection(Optional toSelection) { this.toSelection = Objects.requireNonNull(toSelection, "toSelection cannot be null."); } public void setToSelection(String toSelection) { this.setToSelection(Optional.of(toSelection)); } @Override public void setToUnitNames(Set units) { this.toUnits = Objects.requireNonNull(units, "units may not be null"); } @Override public void setViewablePrefixNames(Set prefixNames) { throw new UnsupportedOperationException("Not implemented yet"); } @Override public void setViewableUnitNames(Set unitNames) { throw new UnsupportedOperationException("Not implemented yet"); } public void setViewedPrefixName( @SuppressWarnings("unused") Optional viewedPrefixName) { throw new UnsupportedOperationException("Not implemented yet"); } public void setViewedPrefixName(String viewedPrefixName) { this.setViewedPrefixName(Optional.of(viewedPrefixName)); } public void setViewedUnitName( @SuppressWarnings("unused") Optional viewedUnitName) { throw new UnsupportedOperationException("Not implemented yet"); } public void setViewedUnitName(String viewedUnitName) { this.setViewedUnitName(Optional.of(viewedUnitName)); } @Override public void showErrorMessage(String title, String message) { System.err.printf("%s: %s%n", title, message); } @Override public void showExpressionConversionOutput(UnitConversionRecord uc) { this.expressionConversions.add(uc); System.out.println("Expression Conversion: " + uc); } @Override public void showPrefix(NameSymbol name, String multiplierString) { throw new UnsupportedOperationException("Not implemented yet"); } @Override public void showUnit(NameSymbol name, String definition, String dimensionName, UnitType type) { throw new UnsupportedOperationException("Not implemented yet"); } @Override public void showUnitConversionOutput(UnitConversionRecord uc) { this.unitConversions.add(uc); System.out.println("Unit Conversion: " + uc); } @Override public String toString() { 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 unitConversionList() { return Collections.unmodifiableList(this.unitConversions); } /** * @return list of records of unit viewings made by this bot * @since 2022-04-16 */ public List unitViewList() { return Collections.unmodifiableList(this.unitViewingRecords); } }