Evaluating an expression

Consider the following test class. There is another class in this project, Calculate with a method that has a method signature of public Double run(String expr). What this means is if I create an object of type Calculate called engine, I can then call the run method as in something like double actual = engine.run("( 4 + 5 )"); and I should expect that actual will be equal to 9.0.

How would you write a class and a method to do this? How do you read in the string expression, figure out what it means and then calculate and return the answer?

Take a look at each of the tests below and ponder how you might build such a class. How would you break this problem down into phases that can be called one after another to go from a string argument expr to a double return value.

package rocks.zipcode;

import static org.junit.Assert.*;

public class CalculateTest {

    @org.junit.Before
    public void setUp() throws Exception {
    }

    @org.junit.After
    public void tearDown() throws Exception {
    }

    @org.junit.Test
    public void runSimple() {
        Calculate engine = new Calculate();

        String args2 = "( 4 + 5 )";
        double expected = 9.0;
        double actual = engine.run(args2);
        assertEquals(expected, actual, 0.0001);
    }
    @org.junit.Test
    public void runAlexTest() {
        Calculate engine = new Calculate();

        String args2 = "( -4 + 5 )";
        double expected = 1.0;
        double actual = engine.run(args2);
        assertEquals(expected, actual, 0.0001);
    }

    @org.junit.Test
    public void runSimpleRPN() {
        Calculate engine = new Calculate();

        String args2 = "( 4 5 + 7 3.0 / * )";
        double expected = 21.0;
        double actual = engine.run(args2);
        assertEquals(expected, actual, 0.0001);
    }

    @org.junit.Test
    public void runFailedTestNoParens() {
        Calculate engine = new Calculate();

        String args2 = "4 + 5";
        double expected = 9.0;
        double actual = engine.run(args2);
        assertNotEquals(expected, actual, 0.0001);
    }

    @org.junit.Test
    public void runSimple2() {
        Calculate engine = new Calculate();

        String args2 = "( ( 4 + 5 ) * ( 7 / 3.0 ) )";
        double expected = 21.0;
        double actual = engine.run(args2);
        assertEquals(expected, actual, 0.0001);
    }

    @org.junit.Test
    public void runSimple3() {
        Calculate engine = new Calculate();

        String args2 = "( sqrt ( 2.0 ) * sqrt ( 5.0 ) )";
        double expected = 3.162277660;
        double actual = engine.run(args2);
        assertEquals(expected, actual, 0.0001);
    }

    @org.junit.Test
    public void runLongerDemo() {
        Calculate engine = new Calculate();

        String args2 = "( ( ( 4 + 5 ) * ( 7 / 3.0 ) ) - ( 13 / 6.0 ) )";
        double expected = 18.833333333;
        double actual = engine.run(args2);
        assertEquals(expected, actual, 0.0001);
    }

    //( ( 5 + ( 3 * 8 ) ) – ( 2 * 7 ) )

    @org.junit.Test
    public void runFromReadme() {
        Calculate engine = new Calculate();

        String args2 = "( ( 5 + ( 3 * 8 ) ) - ( 2 * 7 ) )";
        double expected = 15;
        double actual = engine.run(args2);
        assertEquals(expected, actual, 0.0001);
    }


}