Commit ccc6a983 authored by Hallvard Trætteberg's avatar Hallvard Trætteberg
Browse files

Some more tests and improved API

parent b57fd9aa
......@@ -100,6 +100,11 @@ public class AppController {
// TODO clear operand
}
@FXML
void handleSwap() {
// TODO clear operand
}
private void performOperation(UnaryOperator<Double> op) {
// TODO
}
......
......@@ -7,10 +7,13 @@ import java.util.function.UnaryOperator;
public class Calc {
private List<Double> operandStack = new ArrayList<>();
private final List<Double> operandStack;
public Calc(Double... operands) {
operandStack.addAll(List.of(operands));
public Calc(double... operands) {
operandStack = new ArrayList<>(operands.length + 2);
for (var d : operands) {
operandStack.add(d);
}
}
/**
......@@ -20,29 +23,24 @@ public class Calc {
return operandStack.size();
}
/**
* Pushes a new operand into the n'th place from the top.
* @param n the place to push
* @param d the new operand
*/
public void pushOperand(int n, double d) {
operandStack.add(operandStack.size() - n, d);
}
/**
* Pushes a new operand onto top of the stack.
* @param d the new operand
*/
public void pushOperand(double d) {
pushOperand(0, d);
operandStack.add(d);
}
/**
* @param n the place (from the top) to peek
* @return the n'th operand from the top
* @throws IllegalArgumentException if n is larger than the operand count
*/
public double peekOperand(int n) {
return operandStack.get(operandStack.size() - n - 1);
if (n > getOperandCount()) {
throw new IllegalArgumentException("Cannot peek at position " + n + " when the operand count is " + getOperandCount());
}
return operandStack.get(getOperandCount() - n - 1);
}
/**
......@@ -52,30 +50,26 @@ public class Calc {
return peekOperand(0);
}
/**
* Removes and returns the n'th operand from the top.
* @param n the place from the top to remove
* @return the n'th operand from the top
*/
public double popOperand(int n) {
return operandStack.remove(operandStack.size() - n - 1);
}
/**
* Removes and returns the top operand.
* @return the top operand
* @throws IllegalStateException if the stack is empty
*/
public double popOperand() {
return popOperand(0);
if (getOperandCount() == 0) {
throw new IllegalStateException("Cannot pop from an empty stack");
}
return operandStack.remove(operandStack.size() - 1);
}
/**
* Performs the provided operation in the top operand, and
* replaces it with the result.
* @param op the operation to perform
* @return the result of performing the operation
* @throws IllegalStateException if the operand stack is empty
*/
public double performOperation(UnaryOperator<Double> op) {
public double performOperation(UnaryOperator<Double> op) throws IllegalStateException {
// TODO
return 0.0;
}
......@@ -85,8 +79,12 @@ public class Calc {
* replaces them with the result.
* @param op the operation to perform
* @return the result of performing the operation
* @throws IllegalStateException if the operand count is less than two
*/
public double performOperation(BinaryOperator<Double> op) {
public double performOperation(BinaryOperator<Double> op) throws IllegalStateException {
if (getOperandCount() < 2) {
throw new IllegalStateException("Too few operands (" + getOperandCount() + ") on the stack");
}
var op1 = popOperand();
var op2 = popOperand();
var result = op.apply(op1, op2);
......
......@@ -15,7 +15,7 @@
<!-- multi-line button label with XML entity for newline -->
<Button text="E&#10;n&#10;t&#10;e&#10;r" onAction="#handleEnter"
GridPane.rowIndex="2" GridPane.columnIndex="3" GridPane.rowSpan="4"/>
GridPane.rowIndex="2" GridPane.columnIndex="3" GridPane.rowSpan="3"/>
<Button text="7" onAction="#handleDigit"
GridPane.rowIndex="2" GridPane.columnIndex="0"/>
......@@ -23,24 +23,29 @@
GridPane.rowIndex="2" GridPane.columnIndex="1"/>
<Button text="9" onAction="#handleDigit"
GridPane.rowIndex="2" GridPane.columnIndex="2"/>
<Button text="4" onAction="#handleDigit"
GridPane.rowIndex="3" GridPane.columnIndex="0"/>
<Button text="5" onAction="#handleDigit"
GridPane.rowIndex="3" GridPane.columnIndex="1"/>
<Button text="6" onAction="#handleDigit"
GridPane.rowIndex="3" GridPane.columnIndex="2"/>
<Button text="1" onAction="#handleDigit"
GridPane.rowIndex="4" GridPane.columnIndex="0"/>
<Button text="2" onAction="#handleDigit"
GridPane.rowIndex="4" GridPane.columnIndex="1"/>
<Button text="3" onAction="#handleDigit"
GridPane.rowIndex="4" GridPane.columnIndex="2"/>
<Button text="0" onAction="#handleDigit"
GridPane.rowIndex="5" GridPane.columnIndex="0"/>
<Button text="." onAction="#handlePoint"
GridPane.rowIndex="5" GridPane.columnIndex="1"/>
<Button text="C" onAction="#handleClear"
GridPane.rowIndex="5" GridPane.columnIndex="2"/>
<Button text="~" onAction="#handleSwap"
GridPane.rowIndex="5" GridPane.columnIndex="3"/>
<Button text="+" onAction="#handleOpAdd"
GridPane.rowIndex="6" GridPane.columnIndex="0"/>
......
package app;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class CalcTest {
private static void checkCalc(Calc calc, double... operands) {
Assertions.assertEquals(operands.length, calc.getOperandCount(), "Wrong operand count");
for (int i = 0; i < operands.length; i++) {
Assertions.assertEquals(operands[i], calc.peekOperand(i), "Wrong value at #" + i + " of operand stack");
}
}
@Test
public void testCalc() {
checkCalc(new Calc());
checkCalc(new Calc(1.0), 1.0);
checkCalc(new Calc(3.14, 1.0), 1.0, 3.14);
}
@Test
public void testPushOperand() {
Calc calc = new Calc();
calc.pushOperand(1.0);
checkCalc(calc, 1.0);
calc.pushOperand(3.14);
checkCalc(calc, 3.14, 1.0);
}
@Test
public void testPopOperand() {
Calc calc = new Calc(1.0, 3.14);
Assertions.assertEquals(3.14, calc.popOperand());
checkCalc(calc, 1.0);
Assertions.assertEquals(1.0, calc.popOperand());
checkCalc(calc);
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment