@Test
 public void solveOk() throws Exception {
   String expression = "1+ 2 + 3 * (5 - 4 / (1 + 1 * 3)   )";
   ExpressionSolver target = new ExpressionSolver(expression);
   double actual = target.solve();
   double expected = 15;
   assertEquals(expected, actual, 0d);
 }
 @Test
 public void areNotAllFunctionsDeclared() throws Exception {
   String expression = "1 + Sin(90) + MyFunc(1)";
   ExpressionSolver target = new ExpressionSolver(expression);
   boolean actual = target.areAllFunctionsDeclared();
   boolean expected = false;
   assertThat(actual, is(equalTo(expected)));
 }
 @Test
 public void isSolverNotReady() throws Exception {
   String expression = "1 + myVar + myFunc()";
   ExpressionSolver target = new ExpressionSolver(expression);
   boolean actual = target.isReady();
   boolean expected = false;
   assertThat(actual, is(equalTo(expected)));
 }
 @Test
 public void getAllRequiredDynamicFunctions() throws Exception {
   String expression = "1 + Sin(90) + MyDynamicFunc(1)";
   ExpressionSolver target = new ExpressionSolver(expression);
   Set<FunctionInfo> actual = target.getAllRequiredDynamicFunctions();
   Set<FunctionInfo> expected = new HashSet<>(Arrays.asList(new FunctionInfo("MyDynamicFunc", 1)));
   assertThat(actual, is(equalTo(expected)));
 }
 @Test
 public void getUndefinedFunctions() throws Exception {
   String expression = "1 + myFunc(1)";
   ExpressionSolver target = new ExpressionSolver(expression);
   Set<FunctionInfo> actual = target.getUndefinedFunctions();
   Set<FunctionInfo> expected = new HashSet<>(Arrays.asList(new FunctionInfo("myFunc", 1)));
   assertThat(actual, is(equalTo(expected)));
 }
 @Test
 public void getAllRequiredVariables() throws Exception {
   String expression = "1 + myVar + undefinedVar";
   ExpressionSolver target = new ExpressionSolver(expression);
   target.setVariable("myVar", 1);
   Set<String> actual = target.getAllRequiredVariables();
   Set<String> expected = new HashSet<>(Arrays.asList("myVar", "undefinedVar"));
   assertThat(actual, is(equalTo(expected)));
 }
 @Test
 public void setSeveralVariablesOk() throws Exception {
   String expression = "-10 + myVar * (myVar + myVar2) / -myVar3";
   ExpressionSolver target = new ExpressionSolver(expression);
   target.setVariable("myVar", 1);
   target.setVariable("myVar2", 2);
   target.setVariable("myVar3", 3);
   assertEquals(-11d, target.solve(), 0d);
 }
 @Test
 public void setVariableOk() throws Exception {
   String expression = "myVar";
   ExpressionSolver target = new ExpressionSolver(expression);
   String name = "myVar";
   double value = 1.0;
   target.setVariable(name, value);
   assertEquals(1d, target.solve(), 0d);
 }
 @Test
 public void areAllFunctionsDeclared() throws Exception {
   String expression = "1 + Sin(90) + MyFunc(1)";
   ExpressionSolver target = new ExpressionSolver(expression);
   target.addFunction("MyFunc", Arrays.asList("x"), "1 + x");
   boolean actual = target.areAllFunctionsDeclared();
   boolean expected = true;
   assertThat(actual, is(equalTo(expected)));
 }
 @Test
 public void areAllVariablesBound() throws Exception {
   String expression = "1 + myVar";
   ExpressionSolver target = new ExpressionSolver(expression);
   target.setVariable("myVar", 1);
   boolean actual = target.areAllVariablesBound();
   boolean expected = true;
   assertThat(actual, is(equalTo(expected)));
 }
 @Test
 public void isVariableNotDefined() throws Exception {
   String expression = "1 + myVar + undefinedVar";
   ExpressionSolver target = new ExpressionSolver(expression);
   target.setVariable("myVar", 1);
   boolean actual = target.isVariableDefined("undefinedVar");
   boolean expected = false;
   assertThat(actual, is(equalTo(expected)));
 }
 @Test
 public void functionInFunction() throws Exception {
   String expression = "1 + myFunc(myFunc((x + 9*0)))";
   ExpressionSolver target = new ExpressionSolver(expression);
   target.setVariable("x", 2);
   target.addFunction("myFunc", Arrays.asList("x"), "x*x");
   double actual = target.solve();
   double expected = 17;
   assertEquals(expected, actual, 0d);
 }
 @Test
 public void isSolverReady() throws Exception {
   String expression = "1 + myVar + myFunc()";
   ExpressionSolver target = new ExpressionSolver(expression);
   target.setVariable("myVar", 1);
   target.addFunction("myFunc", Collections.<String>emptyList(), "2");
   boolean actual = target.isReady();
   boolean expected = true;
   assertThat(actual, is(equalTo(expected)));
 }
 @Test
 public void addFunction() throws Exception {
   String expression = "myFunc(1, 2, 3)";
   ExpressionSolver target = new ExpressionSolver(expression);
   String name = "myFunc";
   List<String> variables = Arrays.asList("x", "y", "z");
   String functionExpression = "1 + x + y + z";
   target.addFunction(name, variables, functionExpression);
   assertEquals(7d, target.solve(), 0d);
 }
 @Test
 public void functionInConstructor() throws Exception {
   Function f =
       new Function("myFunc", 1) {
         @Override
         public double apply(double... operands) {
           return operands[0];
         }
       };
   String expression = "1 + myFunc(1)";
   ExpressionSolver target = new ExpressionSolver(expression, Arrays.asList(f));
   double actual = target.solve();
   double expected = 2;
   assertEquals(expected, actual, 0d);
 }
 @Test
 public void functionAndVarInConstructor() throws Exception {
   Function f =
       new Function("myFunc", 1) {
         @Override
         public double apply(double... operands) {
           return operands[0];
         }
       };
   String expression = "1 + myFunc(myVar)";
   Map<String, Double> vars = new HashMap<String, Double>();
   vars.put("myVar", 1d);
   ExpressionSolver target = new ExpressionSolver(expression, vars, Arrays.asList(f));
   double actual = target.solve();
   double expected = 2;
   assertEquals(expected, actual, 0d);
 }