Skip to content

Instantly share code, notes, and snippets.

@michaelkebe
Created November 18, 2009 14:03
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save michaelkebe/237867 to your computer and use it in GitHub Desktop.
package calculator;
public class CalculatorController {
private enum Operation {
NOP, ADDITION, SUBSTRACTION, MULTIPLICATION, DIVISION
}
private static final String INIT_DISPLAY_VALUE = "0.";
private final CalculatorModel model;
private double lastNumber;
private Operation lastOp;
private boolean expectingNewNumber;
public CalculatorController(CalculatorModel model) {
this.model = model;
clear();
}
public void push(char charAt) {
switch (charAt) {
case 'C':
clear();
break;
case '+':
calculateAndDisplayResult();
processOperation(Operation.ADDITION);
break;
case '-':
calculateAndDisplayResult();
processOperation(Operation.SUBSTRACTION);
break;
case '*':
calculateAndDisplayResult();
processOperation(Operation.MULTIPLICATION);
break;
case '/':
calculateAndDisplayResult();
processOperation(Operation.DIVISION);
break;
case '=':
calculateAndDisplayResult();
break;
default:
appendToModel(charAt);
break;
}
}
private void processOperation(Operation op) {
saveLastNumber();
lastOp = op;
}
private void appendToModel(char charAt) {
if (model.getDisplay().equals(INIT_DISPLAY_VALUE) || expectingNewNumber) {
model.setDisplay(String.valueOf(charAt));
expectingNewNumber = false;
} else {
model.setDisplay(model.getDisplay() + charAt);
}
}
private void saveLastNumber() {
lastNumber = parseNumberFromModel();
}
private void calculateAndDisplayResult() {
if (lastOp != Operation.NOP) {
double result = Double.NaN;
double currentNumber = parseNumberFromModel();
switch (lastOp) {
case ADDITION:
result = lastNumber + currentNumber;
break;
case SUBSTRACTION:
result = lastNumber - currentNumber;
break;
case MULTIPLICATION:
result = lastNumber * currentNumber;
break;
case DIVISION:
result = lastNumber / currentNumber;
break;
}
model.setDisplay(String.valueOf(result));
}
expectingNewNumber = true;
}
private double parseNumberFromModel() {
return Double.parseDouble(model.getDisplay());
}
private void clear() {
model.setDisplay(INIT_DISPLAY_VALUE);
lastOp = Operation.NOP;
expectingNewNumber = true;
}
}
package calculator;
import calculator.CalculatorController;
import calculator.CalculatorModel;
import junit.framework.TestCase;
public class CalculatorControllerTest extends TestCase {
private CalculatorController controller;
private CalculatorModel model;
@Override
protected void setUp() throws Exception {
model = new CalculatorModel();
controller = new CalculatorController(model);
}
public void testItShouldInitializeToZero() throws Exception {
pushButtons("C");
assertDisplayShows(0);
}
public void testItShouldInitializeToZeroWithoutPushingC() throws Exception {
assertDisplayShows(0);
}
public void testItShouldDisplayNumberIfPressed() throws Exception {
pushButtons("1");
assertDisplayShows(1);
}
public void testItShouldConcatinateNumberPresses() throws Exception {
pushButtons("12304");
assertDisplayShows(12304);
}
public void testItShouldAddTwoIntegers() throws Exception {
pushButtons("1+2=");
assertDisplayShows(3);
}
public void testItShouldSubstractTwoIntegers() throws Exception {
pushButtons("7-3=");
assertDisplayShows(4);
}
public void testItShouldMultiplicateTwoNumbers() throws Exception {
pushButtons("3*3=");
assertDisplayShows(9);
}
public void testItShouldDivideTwoIntegers() throws Exception {
pushButtons("3/2=");
assertDisplayShows(1.5);
}
public void testItShouldDisplayLastArgumentAfterOp() throws Exception {
pushButtons("1+");
assertDisplayShows(1);
}
public void testItShouldBeChainable() throws Exception {
pushButtons("1+");
assertDisplayShows(1);
pushButtons("2+");
assertDisplayShows(3);
pushButtons("3+");
assertDisplayShows(6);
pushButtons("4=");
assertDisplayShows(10);
}
private void pushButtons(String buttons) {
for (char button : buttons.toCharArray()) {
controller.push(button);
}
}
private void assertDisplayShows(double d) {
assertEquals(d, Double.parseDouble(model.getDisplay()));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment