Calculator display changes

This commit is contained in:
Sergey Solovyev 2012-09-20 22:49:39 +04:00
parent 1d2aaa9d47
commit 79e85ea255
36 changed files with 3595 additions and 2859 deletions

View File

@ -1,9 +1,25 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.jscl.JsclOperation;
import org.solovyev.common.msg.MessageRegistry;
/** /**
* User: Solovyev_S * User: Solovyev_S
* Date: 20.09.12 * Date: 20.09.12
* Time: 16:38 * Time: 16:38
*/ */
public interface Calculator extends CalculatorEventContainer { public interface Calculator extends CalculatorEventContainer {
@NotNull
CalculatorEventDataId createFirstEventDataId();
void evaluate(@NotNull JsclOperation operation,
@NotNull String expression);
@NotNull
CalculatorEventDataId evaluate(@NotNull JsclOperation operation,
@NotNull String expression,
@Nullable MessageRegistry mr);
} }

View File

@ -0,0 +1,28 @@
/*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com
* or visit http://se.solovyev.org
*/
package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* User: serso
* Date: 12/17/11
* Time: 9:45 PM
*/
public interface CalculatorDisplay extends CalculatorEventListener {
void setView(@Nullable CalculatorDisplayView view);
@NotNull
CalculatorDisplayViewState getViewState();
void setViewState(@NotNull CalculatorDisplayViewState viewState);
@NotNull
CalculatorEventData getLastEventData();
}

View File

@ -0,0 +1,147 @@
package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import static org.solovyev.android.calculator.CalculatorEventType.*;
/**
* User: serso
* Date: 9/20/12
* Time: 8:24 PM
*/
public class CalculatorDisplayImpl implements CalculatorDisplay {
@NotNull
private CalculatorEventData lastCalculatorEventData = CalculatorEventDataImpl.newInstance(CalculatorLocatorImpl.getInstance().getCalculator().createFirstEventDataId());
@Nullable
private CalculatorDisplayView view;
@NotNull
private final Object viewLock = new Object();
@NotNull
private CalculatorDisplayViewState lastViewState = CalculatorDisplayViewStateImpl.newDefaultInstance();
@Override
public void setView(@Nullable CalculatorDisplayView view) {
synchronized (viewLock) {
this.view = view;
if (view != null) {
this.view.setState(lastViewState);
}
}
}
@NotNull
@Override
public CalculatorDisplayViewState getViewState() {
return this.lastViewState;
}
@Override
public void setViewState(@NotNull CalculatorDisplayViewState viewState) {
synchronized (viewLock) {
this.lastViewState = viewState;
if (this.view != null) {
this.view.setState(viewState);
}
}
}
/* @Override
@Nullable
public CharSequence getText() {
synchronized (viewLock) {
return view != null ? view.getText() : null;
}
}
@Override
public void setText(@Nullable CharSequence text) {
synchronized (viewLock) {
if (view != null) {
view.setText(text);
}
}
}
@Override
public int getSelection() {
synchronized (viewLock) {
return view != null ? view.getSelection() : 0;
}
}
@Override
public void setSelection(int selection) {
synchronized (viewLock) {
if (view != null) {
view.setSelection(selection);
}
}
}*/
@Override
@NotNull
public CalculatorEventData getLastEventData() {
return lastCalculatorEventData;
}
@Override
public void onCalculatorEvent(@NotNull CalculatorEventData calculatorEventData,
@NotNull CalculatorEventType calculatorEventType,
@Nullable Object data) {
if (calculatorEventType.isOfType(calculation_result, calculation_failed, calculation_cancelled)) {
if (calculatorEventData.isAfter(lastCalculatorEventData)) {
lastCalculatorEventData = calculatorEventData;
}
switch (calculatorEventType) {
case calculation_result:
processCalculationResult((CalculatorEvaluationEventData)calculatorEventData, (CalculatorOutput) data);
break;
case calculation_cancelled:
processCalculationCancelled((CalculatorEvaluationEventData)calculatorEventData);
break;
case calculation_failed:
processCalculationFailed((CalculatorEvaluationEventData)calculatorEventData, (CalculatorFailure) data);
break;
}
}
}
private void processCalculationFailed(@NotNull CalculatorEvaluationEventData calculatorEventData, @NotNull CalculatorFailure data) {
final CalculatorEvalException calculatorEvalException = data.getCalculationEvalException();
final String errorMessage;
if (calculatorEvalException != null) {
errorMessage = CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error);
} else {
final CalculatorParseException calculationParseException = data.getCalculationParseException();
if (calculationParseException != null) {
errorMessage = calculationParseException.getLocalizedMessage();
} else {
errorMessage = CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error);
}
}
this.setViewState(CalculatorDisplayViewStateImpl.newErrorState(calculatorEventData.getOperation(), errorMessage));
}
private void processCalculationCancelled(@NotNull CalculatorEvaluationEventData calculatorEventData) {
final String errorMessage = CalculatorMessages.getBundle().getString(CalculatorMessages.syntax_error);
this.setViewState(CalculatorDisplayViewStateImpl.newErrorState(calculatorEventData.getOperation(), errorMessage));
}
private void processCalculationResult(@NotNull CalculatorEvaluationEventData calculatorEventData, @NotNull CalculatorOutput data) {
final String stringResult = data.getStringResult();
this.setViewState(CalculatorDisplayViewStateImpl.newValidState(calculatorEventData.getOperation(), data.getResult(), stringResult, 0));
}
}

View File

@ -0,0 +1,16 @@
package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
/**
* User: serso
* Date: 9/20/12
* Time: 8:25 PM
*/
public interface CalculatorDisplayView {
void setState(@NotNull CalculatorDisplayViewState state);
@NotNull
CalculatorDisplayViewState getState();
}

View File

@ -0,0 +1,33 @@
package org.solovyev.android.calculator;
import jscl.math.Generic;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.jscl.JsclOperation;
/**
* User: serso
* Date: 9/20/12
* Time: 9:50 PM
*/
public interface CalculatorDisplayViewState {
@NotNull
String getText();
int getSelection();
@Nullable
Generic getResult();
boolean isValid();
@Nullable
String getErrorMessage();
@NotNull
JsclOperation getOperation();
@Nullable
String getStringResult();
}

View File

@ -0,0 +1,104 @@
package org.solovyev.android.calculator;
import jscl.math.Generic;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.jscl.JsclOperation;
import org.solovyev.common.text.StringUtils;
/**
* User: serso
* Date: 9/20/12
* Time: 9:50 PM
*/
public class CalculatorDisplayViewStateImpl implements CalculatorDisplayViewState {
@NotNull
private JsclOperation operation = JsclOperation.numeric;
@Nullable
private Generic result;
@Nullable
private String stringResult = "";
private boolean valid = true;
@Nullable
private String errorMessage;
private int selection = 0;
private CalculatorDisplayViewStateImpl() {
}
@NotNull
public static CalculatorDisplayViewState newDefaultInstance() {
return new CalculatorDisplayViewStateImpl();
}
@NotNull
public static CalculatorDisplayViewState newErrorState(@NotNull JsclOperation operation,
@NotNull String errorMessage) {
final CalculatorDisplayViewStateImpl calculatorDisplayState = new CalculatorDisplayViewStateImpl();
calculatorDisplayState.valid = false;
calculatorDisplayState.errorMessage = errorMessage;
calculatorDisplayState.operation = operation;
return calculatorDisplayState;
}
@NotNull
public static CalculatorDisplayViewState newValidState(@NotNull JsclOperation operation,
@Nullable Generic result,
@NotNull String stringResult,
int selection) {
final CalculatorDisplayViewStateImpl calculatorDisplayState = new CalculatorDisplayViewStateImpl();
calculatorDisplayState.valid = true;
calculatorDisplayState.result = result;
calculatorDisplayState.stringResult = stringResult;
calculatorDisplayState.operation = operation;
calculatorDisplayState.selection = selection;
return calculatorDisplayState;
}
@NotNull
@Override
public String getText() {
return StringUtils.getNotEmpty(isValid() ? stringResult : errorMessage, "");
}
@Override
public int getSelection() {
return selection;
}
@Nullable
@Override
public Generic getResult() {
return this.result;
}
@Override
public boolean isValid() {
return this.valid;
}
@Nullable
@Override
public String getErrorMessage() {
return this.errorMessage;
}
@Override
@Nullable
public String getStringResult() {
return stringResult;
}
@NotNull
@Override
public JsclOperation getOperation() {
return this.operation;
}
}

View File

@ -0,0 +1,18 @@
package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.jscl.JsclOperation;
/**
* User: serso
* Date: 9/20/12
* Time: 10:00 PM
*/
public interface CalculatorEvaluationEventData extends CalculatorEventData{
@NotNull
JsclOperation getOperation();
@NotNull
String getExpression();
}

View File

@ -0,0 +1,58 @@
package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.jscl.JsclOperation;
/**
* User: serso
* Date: 9/20/12
* Time: 10:01 PM
*/
public class CalculatorEvaluationEventDataImpl implements CalculatorEvaluationEventData {
@NotNull
private final CalculatorEventData calculatorEventData;
@NotNull
private final JsclOperation operation;
@NotNull
private final String expression;
public CalculatorEvaluationEventDataImpl(@NotNull CalculatorEventData calculatorEventData,
@NotNull JsclOperation operation,
@NotNull String expression) {
this.calculatorEventData = calculatorEventData;
this.operation = operation;
this.expression = expression;
}
@NotNull
@Override
public JsclOperation getOperation() {
return this.operation;
}
@NotNull
@Override
public String getExpression() {
return this.expression;
}
@Override
public long getEventId() {
return calculatorEventData.getEventId();
}
@Override
@Nullable
public Long getCalculationId() {
return calculatorEventData.getCalculationId();
}
@Override
public boolean isAfter(@NotNull CalculatorEventDataId calculatorEventDataId) {
return calculatorEventData.isAfter(calculatorEventDataId);
}
}

View File

@ -1,11 +1,10 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import org.jetbrains.annotations.Nullable;
/** /**
* User: Solovyev_S * User: Solovyev_S
* Date: 20.09.12 * Date: 20.09.12
* Time: 16:51 * Time: 16:51
*/ */
public interface CalculatorEventData extends CalculatorEventDataId { public interface CalculatorEventData extends CalculatorEventDataId {
} }

View File

@ -1,5 +1,6 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
/** /**
@ -14,4 +15,6 @@ public interface CalculatorEventDataId {
@Nullable @Nullable
Long getCalculationId(); Long getCalculationId();
boolean isAfter(@NotNull CalculatorEventDataId calculatorEventDataId);
} }

View File

@ -8,7 +8,7 @@ import org.jetbrains.annotations.Nullable;
* Date: 20.09.12 * Date: 20.09.12
* Time: 18:18 * Time: 18:18
*/ */
public class CalculatorEventDataIdImpl implements CalculatorEventDataId { class CalculatorEventDataIdImpl implements CalculatorEventDataId {
private final long eventId; private final long eventId;
@ -22,7 +22,7 @@ public class CalculatorEventDataIdImpl implements CalculatorEventDataId {
} }
@NotNull @NotNull
public static CalculatorEventDataId newInstance(long id, static CalculatorEventDataId newInstance(long id,
@Nullable Long calculationId) { @Nullable Long calculationId) {
return new CalculatorEventDataIdImpl(id, calculationId); return new CalculatorEventDataIdImpl(id, calculationId);
} }
@ -38,6 +38,11 @@ public class CalculatorEventDataIdImpl implements CalculatorEventDataId {
return this.calculationId; return this.calculationId;
} }
@Override
public boolean isAfter(@NotNull CalculatorEventDataId calculatorEventDataId) {
return this.eventId > calculatorEventDataId.getEventId();
}
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) return true;

View File

@ -13,10 +13,15 @@ class CalculatorEventDataImpl implements CalculatorEventData {
@NotNull @NotNull
private CalculatorEventDataId calculatorEventDataId; private CalculatorEventDataId calculatorEventDataId;
CalculatorEventDataImpl(@NotNull CalculatorEventDataId calculatorEventDataId) { private CalculatorEventDataImpl(@NotNull CalculatorEventDataId calculatorEventDataId) {
this.calculatorEventDataId = calculatorEventDataId; this.calculatorEventDataId = calculatorEventDataId;
} }
@NotNull
public static CalculatorEventData newInstance(@NotNull CalculatorEventDataId calculatorEventDataId) {
return new CalculatorEventDataImpl(calculatorEventDataId);
}
@Override @Override
public long getEventId() { public long getEventId() {
return calculatorEventDataId.getEventId(); return calculatorEventDataId.getEventId();
@ -28,6 +33,11 @@ class CalculatorEventDataImpl implements CalculatorEventData {
return calculatorEventDataId.getCalculationId(); return calculatorEventDataId.getCalculationId();
} }
@Override
public boolean isAfter(@NotNull CalculatorEventDataId calculatorEventDataId) {
return this.calculatorEventDataId.isAfter(calculatorEventDataId);
}
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) return true;

View File

@ -1,9 +1,43 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
/** /**
* User: Solovyev_S * User: Solovyev_S
* Date: 20.09.12 * Date: 20.09.12
* Time: 16:40 * Time: 16:40
*/ */
public enum CalculatorEventType { public enum CalculatorEventType {
/*
**********************************************************************
*
* org.solovyev.android.calculator.CalculatorEvaluationEventData
*
**********************************************************************
*/
// @NotNull org.solovyev.android.calculator.CalculatorInput
calculation_started,
// @NotNull org.solovyev.android.calculator.CalculatorOutput
calculation_result,
calculation_cancelled,
calculation_finished,
// @NotNull org.solovyev.android.calculator.CalculatorFailure
calculation_failed;
public boolean isOfType(@NotNull CalculatorEventType... types) {
for (CalculatorEventType type : types) {
if ( this == type ) {
return true;
}
}
return false;
}
} }

View File

@ -0,0 +1,21 @@
package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* User: serso
* Date: 9/20/12
* Time: 7:33 PM
*/
public interface CalculatorFailure {
@NotNull
Exception getException();
@Nullable
CalculatorParseException getCalculationParseException();
@Nullable
CalculatorEvalException getCalculationEvalException();
}

View File

@ -0,0 +1,34 @@
package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
/**
* User: serso
* Date: 9/20/12
* Time: 7:34 PM
*/
public class CalculatorFailureImpl implements CalculatorFailure {
@NotNull
private Exception exception;
public CalculatorFailureImpl(@NotNull Exception exception) {
this.exception = exception;
}
@NotNull
@Override
public Exception getException() {
return this.exception;
}
@Override
public CalculatorParseException getCalculationParseException() {
return exception instanceof CalculatorParseException ? (CalculatorParseException)exception : null;
}
@Override
public CalculatorEvalException getCalculationEvalException() {
return exception instanceof CalculatorEvalException ? (CalculatorEvalException)exception : null;
}
}

View File

@ -9,9 +9,11 @@ import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.jscl.JsclOperation; import org.solovyev.android.calculator.jscl.JsclOperation;
import org.solovyev.android.calculator.text.TextProcessor; import org.solovyev.android.calculator.text.TextProcessor;
import org.solovyev.common.msg.MessageRegistry; import org.solovyev.common.msg.MessageRegistry;
import org.solovyev.common.msg.MessageType;
import java.util.List; import java.util.List;
import java.util.concurrent.*; import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
/** /**
@ -21,14 +23,13 @@ import java.util.concurrent.atomic.AtomicLong;
*/ */
public class CalculatorImpl implements Calculator { public class CalculatorImpl implements Calculator {
private static final long FIRST_ID = 0;
@NotNull @NotNull
private final CalculatorEventContainer calculatorEventContainer = new ListCalculatorEventContainer(); private final CalculatorEventContainer calculatorEventContainer = new ListCalculatorEventContainer();
@NotNull @NotNull
private static final Calculator instance = new CalculatorImpl(); private final AtomicLong counter = new AtomicLong(FIRST_ID);
@NotNull
private final AtomicLong counter = new AtomicLong(0);
@NotNull @NotNull
private final Object lock = new Object(); private final Object lock = new Object();
@ -39,12 +40,7 @@ public class CalculatorImpl implements Calculator {
@NotNull @NotNull
private final Executor threadPoolExecutor = Executors.newFixedThreadPool(10); private final Executor threadPoolExecutor = Executors.newFixedThreadPool(10);
private CalculatorImpl() { public CalculatorImpl() {
}
@NotNull
public static Calculator getInstance() {
return instance;
} }
@NotNull @NotNull
@ -53,6 +49,12 @@ public class CalculatorImpl implements Calculator {
return CalculatorEventDataIdImpl.newInstance(eventId, eventId); return CalculatorEventDataIdImpl.newInstance(eventId, eventId);
} }
@NotNull
private CalculatorEventDataId nextEventDataId(@NotNull Long calculationId) {
long eventId = counter.incrementAndGet();
return CalculatorEventDataIdImpl.newInstance(eventId, calculationId);
}
/* /*
********************************************************************** **********************************************************************
* *
@ -61,81 +63,120 @@ public class CalculatorImpl implements Calculator {
********************************************************************** **********************************************************************
*/ */
@NotNull
@Override
public CalculatorEventDataId createFirstEventDataId() {
return CalculatorEventDataIdImpl.newInstance(FIRST_ID, FIRST_ID);
}
@Override
public void evaluate(@NotNull JsclOperation operation, public void evaluate(@NotNull JsclOperation operation,
@NotNull String expression) { @NotNull String expression) {
evaluate(operation, expression, null); evaluate(operation, expression, null);
} }
public void evaluate(@NotNull final JsclOperation operation, @Override
@NotNull final String expression, @NotNull
@Nullable final MessageRegistry mr) { public CalculatorEventDataId evaluate(@NotNull final JsclOperation operation,
@NotNull final String expression,
@Nullable final MessageRegistry mr) {
final CalculatorEventDataId eventDataId = nextCalculatorEventDataId(); final CalculatorEventDataId eventDataId = nextCalculatorEventDataId();
threadPoolExecutor.execute(new Runnable() { threadPoolExecutor.execute(new Runnable() {
@Override @Override
public void run() { public void run() {
CalculatorImpl.this.evaluate(eventDataId, operation, expression, mr); CalculatorImpl.this.evaluate(eventDataId.getCalculationId(), operation, expression, mr);
} }
}); });
return eventDataId;
} }
private void evaluate(@NotNull CalculatorEventDataId eventDataId, private void evaluate(@NotNull Long calculationId,
@NotNull JsclOperation operation, @NotNull JsclOperation operation,
@NotNull String expression, @NotNull String expression,
@Nullable MessageRegistry mr) { @Nullable MessageRegistry mr) {
synchronized (lock) { synchronized (lock) {
PreparedExpression preparedExpression = null; PreparedExpression preparedExpression = null;
fireCalculatorEvent(newCalculationEventData(operation, expression, calculationId), CalculatorEventType.calculation_started, new CalculatorInputImpl(expression, operation));
try { try {
preparedExpression = preprocessor.process(expression); preparedExpression = preprocessor.process(expression);
final String jsclExpression = preparedExpression.toString(); final String jsclExpression = preparedExpression.toString();
try { try {
final Generic genericResult = operation.evaluateGeneric(jsclExpression); final Generic result = operation.evaluateGeneric(jsclExpression);
// NOTE: toString() method must be called here as ArithmeticOperationException may occur in it (just to avoid later check!) // NOTE: toString() method must be called here as ArithmeticOperationException may occur in it (just to avoid later check!)
genericResult.toString(); result.toString();
final CalculatorOutputImpl data = new CalculatorOutputImpl(operation.getFromProcessor().process(result), operation, result);
fireCalculatorEvent(newCalculationEventData(operation, expression, calculationId), CalculatorEventType.calculation_result, data);
//return new Result(operation.getFromProcessor().process(genericResult), operation, genericResult);
} catch (AbstractJsclArithmeticException e) { } catch (AbstractJsclArithmeticException e) {
handleException(eventDataId, operation, expression, mr, preparedExpression, null, new CalculatorEvalException(e, e, jsclExpression)); handleException(calculationId, operation, expression, mr, new CalculatorEvalException(e, e, jsclExpression));
} }
} catch (ArithmeticException e) { } catch (ArithmeticException e) {
//final AndroidMessage androidMessage = new AndroidMessage(R.string.msg_1, MessageType.error, CalculatorApplication.getInstance(), e.getMessage()); handleException(calculationId, operation, expression, mr, preparedExpression, new CalculatorParseException(expression, new CalculatorMessage(CalculatorMessages.msg_001, MessageType.error, e.getMessage())));
handleException(operation, expression, mr, preparedExpression, new CalculatorParseException(jsclExpression, androidMessage));
} catch (StackOverflowError e) { } catch (StackOverflowError e) {
//final AndroidMessage androidMessage = new AndroidMessage(R.string.msg_2, MessageType.error, CalculatorApplication.getInstance()); handleException(calculationId, operation, expression, mr, preparedExpression, new CalculatorParseException(expression, new CalculatorMessage(CalculatorMessages.msg_002, MessageType.error)));
handleException(eventDataId, operation, expression, mr, preparedExpression, new CalculatorParseException(e), null);
} catch (jscl.text.ParseException e) { } catch (jscl.text.ParseException e) {
//System.out.println(e.getMessage()); handleException(calculationId, operation, expression, mr, preparedExpression, new CalculatorParseException(e));
handleException(eventDataId, operation, expression, mr, preparedExpression, new CalculatorParseException(e), null);
} catch (ParseInterruptedException e) { } catch (ParseInterruptedException e) {
// do nothing - we ourselves interrupt the calculations // do nothing - we ourselves interrupt the calculations
fireCalculatorEvent(newCalculationEventData(operation, expression, calculationId), CalculatorEventType.calculation_cancelled, null);
} catch (CalculatorParseException e) { } catch (CalculatorParseException e) {
handleException(eventDataId, operation, expression, mr, preparedExpression, e, null); handleException(calculationId, operation, expression, mr, preparedExpression, e);
} finally {
fireCalculatorEvent(newCalculationEventData(operation, expression, calculationId), CalculatorEventType.calculation_finished, null);
} }
} }
} }
private void handleException(@NotNull CalculatorEventDataId eventDataId, @NotNull
private CalculatorEventData newCalculationEventData(@NotNull JsclOperation operation,
@NotNull String expression,
@NotNull Long calculationId) {
return new CalculatorEvaluationEventDataImpl(CalculatorEventDataImpl.newInstance(nextEventDataId(calculationId)), operation, expression);
}
private void handleException(@NotNull Long calculationId,
@NotNull JsclOperation operation, @NotNull JsclOperation operation,
@NotNull String expression, @NotNull String expression,
@Nullable MessageRegistry mr, @Nullable MessageRegistry mr,
@Nullable PreparedExpression preparedExpression, @Nullable PreparedExpression preparedExpression,
@Nullable CalculatorParseException parseException, @NotNull CalculatorParseException parseException) {
@Nullable CalculatorEvalException evalException) {
if (operation == JsclOperation.numeric && (preparedExpression != null && preparedExpression.isExistsUndefinedVar() || (evalException != null && evalException.getCause() instanceof NumeralBaseException))) { if (operation == JsclOperation.numeric
evaluate(eventDataId, JsclOperation.simplify, expression, mr); && preparedExpression != null
&& preparedExpression.isExistsUndefinedVar()) {
evaluate(calculationId, JsclOperation.simplify, expression, mr);
} }
if (parseException != null) { fireCalculatorEvent(newCalculationEventData(operation, expression, calculationId), CalculatorEventType.calculation_failed, new CalculatorFailureImpl(parseException));
throw parseException; }
} else {
throw evalException; private void handleException(@NotNull Long calculationId,
@NotNull JsclOperation operation,
@NotNull String expression,
@Nullable MessageRegistry mr,
@NotNull CalculatorEvalException evalException) {
if (operation == JsclOperation.numeric && evalException.getCause() instanceof NumeralBaseException) {
evaluate(calculationId, JsclOperation.simplify, expression, mr);
} }
fireCalculatorEvent(newCalculationEventData(operation, expression, calculationId), CalculatorEventType.calculation_failed, new CalculatorFailureImpl(evalException));
} }
/* /*

View File

@ -0,0 +1,18 @@
package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.jscl.JsclOperation;
/**
* User: serso
* Date: 9/20/12
* Time: 7:25 PM
*/
public interface CalculatorInput {
@NotNull
String getExpression();
@NotNull
JsclOperation getOperation();
}

View File

@ -0,0 +1,35 @@
package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.jscl.JsclOperation;
/**
* User: serso
* Date: 9/20/12
* Time: 7:26 PM
*/
public class CalculatorInputImpl implements CalculatorInput {
@NotNull
private String expression;
@NotNull
private JsclOperation operation;
public CalculatorInputImpl(@NotNull String expression, @NotNull JsclOperation operation) {
this.expression = expression;
this.operation = operation;
}
@Override
@NotNull
public String getExpression() {
return expression;
}
@Override
@NotNull
public JsclOperation getOperation() {
return operation;
}
}

View File

@ -12,5 +12,11 @@ public interface CalculatorLocator {
@NotNull @NotNull
JCalculatorEngine getCalculatorEngine(); JCalculatorEngine getCalculatorEngine();
@NotNull
Calculator getCalculator();
@NotNull
CalculatorDisplay getCalculatorDisplay();
void setCalculatorEngine(@NotNull JCalculatorEngine calculatorEngine); void setCalculatorEngine(@NotNull JCalculatorEngine calculatorEngine);
} }

View File

@ -12,6 +12,12 @@ public class CalculatorLocatorImpl implements CalculatorLocator {
@NotNull @NotNull
private JCalculatorEngine calculatorEngine; private JCalculatorEngine calculatorEngine;
@NotNull
private CalculatorDisplay calculatorDisplay = new CalculatorDisplayImpl();
@NotNull
private Calculator calculator = new CalculatorImpl();
@NotNull @NotNull
private static final CalculatorLocator instance = new CalculatorLocatorImpl(); private static final CalculatorLocator instance = new CalculatorLocatorImpl();
@ -29,8 +35,20 @@ public class CalculatorLocatorImpl implements CalculatorLocator {
return calculatorEngine; return calculatorEngine;
} }
@NotNull
@Override
public Calculator getCalculator() {
return this.calculator;
}
@Override @Override
public void setCalculatorEngine(@NotNull JCalculatorEngine calculatorEngine) { public void setCalculatorEngine(@NotNull JCalculatorEngine calculatorEngine) {
this.calculatorEngine = calculatorEngine; this.calculatorEngine = calculatorEngine;
} }
@Override
@NotNull
public CalculatorDisplay getCalculatorDisplay() {
return calculatorDisplay;
}
} }

View File

@ -0,0 +1,31 @@
package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
import org.solovyev.common.msg.AbstractMessage;
import org.solovyev.common.msg.MessageType;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
/**
* User: serso
* Date: 9/20/12
* Time: 8:06 PM
*/
public class CalculatorMessage extends AbstractMessage {
protected CalculatorMessage(@NotNull String messageCode, @NotNull MessageType messageType, @org.jetbrains.annotations.Nullable Object... parameters) {
super(messageCode, messageType, parameters);
}
protected CalculatorMessage(@NotNull String messageCode, @NotNull MessageType messageType, @NotNull List<?> parameters) {
super(messageCode, messageType, parameters);
}
@Override
protected String getMessagePattern(@NotNull Locale locale) {
final ResourceBundle rb = CalculatorMessages.getBundle(locale);
return rb.getString(getMessageCode());
}
}

View File

@ -0,0 +1,69 @@
package org.solovyev.android.calculator;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
/**
* User: serso
* Date: 9/20/12
* Time: 8:10 PM
*/
public final class CalculatorMessages {
@NotNull
private static final Map<Locale, ResourceBundle> bundlesByLocale = new HashMap<Locale, ResourceBundle>();
private CalculatorMessages() {
throw new AssertionError();
}
@NotNull
public static ResourceBundle getBundle() {
return getBundle(Locale.getDefault());
}
@NotNull
public static ResourceBundle getBundle(@NotNull Locale locale) {
synchronized (bundlesByLocale) {
ResourceBundle result = bundlesByLocale.get(locale);
if (result == null) {
result = ResourceBundle.getBundle("org/solovyev/android/calculator/messages", locale);
bundlesByLocale.put(locale, result);
}
return result;
}
}
/* Arithmetic error occurred: {0} */
@NotNull
public static final String msg_001 = "msg_1";
/* Too complex expression*/
@NotNull
public static final String msg_002 = "msg_2";
/* Too long execution time - check the expression*/
@NotNull
public static final String msg_003 = "msg_3";
/* Evaluation was cancelled*/
@NotNull
public static final String msg_004 = "msg_4";
/* No parameters are specified for function: {0}*/
@NotNull
public static final String msg_005 = "msg_5";
/* Infinite loop is detected in expression*/
@NotNull
public static final String msg_006 = "msg_6";
/* Error */
@NotNull
public static final String syntax_error = "syntax_error";
}

View File

@ -0,0 +1,22 @@
package org.solovyev.android.calculator;
import jscl.math.Generic;
import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.jscl.JsclOperation;
/**
* User: serso
* Date: 9/20/12
* Time: 7:29 PM
*/
public interface CalculatorOutput {
@NotNull
String getStringResult();
@NotNull
JsclOperation getOperation();
@NotNull
Generic getResult();
}

View File

@ -0,0 +1,46 @@
package org.solovyev.android.calculator;
import jscl.math.Generic;
import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.jscl.JsclOperation;
/**
* User: serso
* Date: 9/20/12
* Time: 7:28 PM
*/
public class CalculatorOutputImpl implements CalculatorOutput {
@NotNull
private Generic result;
@NotNull
private String stringResult;
@NotNull
private JsclOperation operation;
public CalculatorOutputImpl(@NotNull String stringResult, @NotNull JsclOperation operation, @NotNull Generic result) {
this.stringResult = stringResult;
this.operation = operation;
this.result = result;
}
@Override
@NotNull
public String getStringResult() {
return stringResult;
}
@Override
@NotNull
public JsclOperation getOperation() {
return operation;
}
@Override
@NotNull
public Generic getResult() {
return result;
}
}

View File

@ -1,40 +0,0 @@
/*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com
* or visit http://se.solovyev.org
*/
package org.solovyev.android.calculator;
import jscl.math.Generic;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.Editor;
import org.solovyev.android.calculator.jscl.JsclOperation;
/**
* User: serso
* Date: 12/17/11
* Time: 9:45 PM
*/
public interface JCalculatorDisplay extends Editor{
boolean isValid();
void setValid(boolean valid);
@Nullable
String getErrorMessage();
void setErrorMessage(@Nullable String errorMessage);
void setJsclOperation(@NotNull JsclOperation jsclOperation);
@NotNull
JsclOperation getJsclOperation();
void setGenericResult(@Nullable Generic genericResult);
@Nullable
Generic getGenericResult();
}

View File

@ -11,8 +11,11 @@ import org.jetbrains.annotations.Nullable;
import org.simpleframework.xml.Element; import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root; import org.simpleframework.xml.Root;
import org.simpleframework.xml.Transient; import org.simpleframework.xml.Transient;
import org.solovyev.android.calculator.JCalculatorDisplay; import org.solovyev.android.calculator.CalculatorDisplay;
import org.solovyev.android.calculator.CalculatorDisplayViewState;
import org.solovyev.android.calculator.CalculatorDisplayViewStateImpl;
import org.solovyev.android.calculator.jscl.JsclOperation; import org.solovyev.android.calculator.jscl.JsclOperation;
import org.solovyev.common.text.StringUtils;
/** /**
* User: serso * User: serso
@ -47,24 +50,27 @@ public class CalculatorDisplayHistoryState implements Cloneable {
} }
@NotNull @NotNull
public static CalculatorDisplayHistoryState newInstance(@NotNull JCalculatorDisplay display) { public static CalculatorDisplayHistoryState newInstance(@NotNull CalculatorDisplay display) {
final CalculatorDisplayHistoryState result = new CalculatorDisplayHistoryState(); final CalculatorDisplayHistoryState result = new CalculatorDisplayHistoryState();
result.editorState = EditorHistoryState.newInstance(display); result.editorState = EditorHistoryState.newInstance(display.getViewState());
result.valid = display.isValid();
result.jsclOperation = display.getJsclOperation(); final CalculatorDisplayViewState displayViewState = display.getViewState();
result.genericResult = display.getGenericResult();
result.errorMessage = display.getErrorMessage(); result.valid = displayViewState.isValid();
result.jsclOperation = displayViewState.getOperation();
result.genericResult = displayViewState.getResult();
result.errorMessage = displayViewState.getErrorMessage();
return result; return result;
} }
public void setValuesFromHistory(@NotNull JCalculatorDisplay display) { public void setValuesFromHistory(@NotNull CalculatorDisplay display) {
this.getEditorState().setValuesFromHistory(display); if ( this.isValid() ) {
display.setValid(this.isValid()); display.setViewState(CalculatorDisplayViewStateImpl.newValidState(this.getJsclOperation(), this.getGenericResult(), StringUtils.getNotEmpty(this.getEditorState().getText(), ""), this.getEditorState().getCursorPosition()));
display.setErrorMessage(this.getErrorMessage()); } else {
display.setJsclOperation(this.getJsclOperation()); display.setViewState(CalculatorDisplayViewStateImpl.newErrorState(this.getJsclOperation(), StringUtils.getNotEmpty(this.getErrorMessage(), "")));
display.setGenericResult(this.getGenericResult()); }
} }

View File

@ -8,8 +8,8 @@ package org.solovyev.android.calculator.history;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.simpleframework.xml.Element; import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root; import org.simpleframework.xml.Root;
import org.solovyev.android.calculator.CalculatorDisplay;
import org.solovyev.android.calculator.Editor; import org.solovyev.android.calculator.Editor;
import org.solovyev.android.calculator.JCalculatorDisplay;
/** /**
* User: serso * User: serso
@ -38,7 +38,7 @@ public class CalculatorHistoryState extends AbstractHistoryState {
this.displayState = displayState; this.displayState = displayState;
} }
public static CalculatorHistoryState newInstance(@NotNull Editor editor, @NotNull JCalculatorDisplay display) { public static CalculatorHistoryState newInstance(@NotNull Editor editor, @NotNull CalculatorDisplay display) {
final EditorHistoryState editorHistoryState = EditorHistoryState.newInstance(editor); final EditorHistoryState editorHistoryState = EditorHistoryState.newInstance(editor);
final CalculatorDisplayHistoryState displayHistoryState = CalculatorDisplayHistoryState.newInstance(display); final CalculatorDisplayHistoryState displayHistoryState = CalculatorDisplayHistoryState.newInstance(display);
return new CalculatorHistoryState(editorHistoryState, displayHistoryState); return new CalculatorHistoryState(editorHistoryState, displayHistoryState);
@ -94,7 +94,7 @@ public class CalculatorHistoryState extends AbstractHistoryState {
return result; return result;
} }
public void setValuesFromHistory(@NotNull Editor editor, @NotNull JCalculatorDisplay display) { public void setValuesFromHistory(@NotNull Editor editor, @NotNull CalculatorDisplay display) {
this.getEditorState().setValuesFromHistory(editor); this.getEditorState().setValuesFromHistory(editor);
this.getDisplayState().setValuesFromHistory(display); this.getDisplayState().setValuesFromHistory(display);
} }

View File

@ -9,6 +9,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.simpleframework.xml.Element; import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root; import org.simpleframework.xml.Root;
import org.solovyev.android.calculator.CalculatorDisplayViewState;
import org.solovyev.android.calculator.Editor; import org.solovyev.android.calculator.Editor;
@Root @Root
@ -35,6 +36,16 @@ public class EditorHistoryState implements Cloneable{
return result; return result;
} }
@NotNull
public static EditorHistoryState newInstance(@NotNull CalculatorDisplayViewState viewState) {
final EditorHistoryState result = new EditorHistoryState();
result.text = viewState.getText();
result.cursorPosition = viewState.getSelection();
return result;
}
public void setValuesFromHistory(@NotNull Editor editor) { public void setValuesFromHistory(@NotNull Editor editor) {
editor.setText(this.getText()); editor.setText(this.getText());
editor.setSelection(this.getCursorPosition()); editor.setSelection(this.getCursorPosition());

View File

@ -0,0 +1,8 @@
msg_1=Arithmetic error occurred: {0}
msg_2=Too complex expression
msg_3=Too long execution time - check the expression
msg_4=Evaluation was cancelled
msg_5=No parameters are specified for function: {0}
msg_6=Infinite loop is detected in expression
syntax_error=Error

View File

@ -6,7 +6,7 @@
~ or visit http://se.solovyev.org ~ or visit http://se.solovyev.org
--> -->
<org.solovyev.android.calculator.CalculatorDisplay <org.solovyev.android.calculator.AndroidCalculatorDisplayView
xmlns:a="http://schemas.android.com/apk/res/android" xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/calculatorDisplay" a:id="@+id/calculatorDisplay"
style="@style/display_style" style="@style/display_style"

View File

@ -15,11 +15,9 @@ import jscl.math.Generic;
import jscl.math.function.Constant; import jscl.math.function.Constant;
import jscl.math.function.IConstant; import jscl.math.function.IConstant;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.jscl.JsclOperation; import org.solovyev.android.calculator.jscl.JsclOperation;
import org.solovyev.android.calculator.model.CalculatorEngine; import org.solovyev.android.calculator.model.CalculatorEngine;
import org.solovyev.android.calculator.text.TextProcessor; import org.solovyev.android.calculator.text.TextProcessor;
import org.solovyev.android.calculator.ToJsclTextProcessor;
import org.solovyev.android.calculator.view.NumeralBaseConverterDialog; import org.solovyev.android.calculator.view.NumeralBaseConverterDialog;
import org.solovyev.android.calculator.view.TextHighlighter; import org.solovyev.android.calculator.view.TextHighlighter;
import org.solovyev.android.calculator.view.UnitConverterViewBuilder; import org.solovyev.android.calculator.view.UnitConverterViewBuilder;
@ -37,9 +35,9 @@ import java.util.Set;
* Date: 9/17/11 * Date: 9/17/11
* Time: 10:58 PM * Time: 10:58 PM
*/ */
public class CalculatorDisplay extends AutoResizeTextView implements JCalculatorDisplay { public class AndroidCalculatorDisplayView extends AutoResizeTextView implements CalculatorDisplayView {
private static enum ConversionMenuItem implements AMenuItem<CalculatorDisplay> { private static enum ConversionMenuItem implements AMenuItem<CalculatorDisplayView> {
convert_to_bin(NumeralBase.bin), convert_to_bin(NumeralBase.bin),
convert_to_dec(NumeralBase.dec), convert_to_dec(NumeralBase.dec),
convert_to_hex(NumeralBase.hex); convert_to_hex(NumeralBase.hex);
@ -72,23 +70,27 @@ public class CalculatorDisplay extends AutoResizeTextView implements JCalculator
} }
@Override @Override
public void onClick(@NotNull CalculatorDisplay data, @NotNull Context context) { public void onClick(@NotNull CalculatorDisplayView data, @NotNull Context context) {
final NumeralBase fromNumeralBase = CalculatorEngine.instance.getEngine().getNumeralBase(); final NumeralBase fromNumeralBase = CalculatorEngine.instance.getEngine().getNumeralBase();
String to; final Generic lastResult = CalculatorLocatorImpl.getInstance().getCalculatorDisplay().getViewState().getResult();
try {
to = convert(data.getGenericResult());
// add prefix if (lastResult != null) {
if (fromNumeralBase != toNumeralBase) { String to;
to = toNumeralBase.getJsclPrefix() + to; try {
to = convert(lastResult);
// add prefix
if (fromNumeralBase != toNumeralBase) {
to = toNumeralBase.getJsclPrefix() + to;
}
} catch (UnitConverterViewBuilder.ConversionException e) {
to = context.getString(R.string.c_error);
} }
} catch (UnitConverterViewBuilder.ConversionException e) {
to = context.getString(R.string.c_error);
}
data.setText(to); data.setText(to);
data.redraw(); //data.redraw();
}
} }
@NotNull @NotNull
@ -112,18 +114,18 @@ public class CalculatorDisplay extends AutoResizeTextView implements JCalculator
} }
} }
public static enum MenuItem implements LabeledMenuItem<CalculatorDisplay> { public static enum MenuItem implements LabeledMenuItem<CalculatorDisplayView> {
copy(R.string.c_copy) { copy(R.string.c_copy) {
@Override @Override
public void onClick(@NotNull CalculatorDisplay data, @NotNull Context context) { public void onClick(@NotNull CalculatorDisplayView data, @NotNull Context context) {
CalculatorModel.copyResult(context, data); CalculatorModel.copyResult(context, data);
} }
}, },
convert_to_bin(R.string.convert_to_bin) { convert_to_bin(R.string.convert_to_bin) {
@Override @Override
public void onClick(@NotNull CalculatorDisplay data, @NotNull Context context) { public void onClick(@NotNull CalculatorDisplayView data, @NotNull Context context) {
ConversionMenuItem.convert_to_bin.onClick(data, context); ConversionMenuItem.convert_to_bin.onClick(data, context);
} }
@ -135,7 +137,7 @@ public class CalculatorDisplay extends AutoResizeTextView implements JCalculator
convert_to_dec(R.string.convert_to_dec) { convert_to_dec(R.string.convert_to_dec) {
@Override @Override
public void onClick(@NotNull CalculatorDisplay data, @NotNull Context context) { public void onClick(@NotNull CalculatorDisplayView data, @NotNull Context context) {
ConversionMenuItem.convert_to_dec.onClick(data, context); ConversionMenuItem.convert_to_dec.onClick(data, context);
} }
@ -147,7 +149,7 @@ public class CalculatorDisplay extends AutoResizeTextView implements JCalculator
convert_to_hex(R.string.convert_to_hex) { convert_to_hex(R.string.convert_to_hex) {
@Override @Override
public void onClick(@NotNull CalculatorDisplay data, @NotNull Context context) { public void onClick(@NotNull CalculatorDisplayView data, @NotNull Context context) {
ConversionMenuItem.convert_to_hex.onClick(data, context); ConversionMenuItem.convert_to_hex.onClick(data, context);
} }
@ -159,8 +161,11 @@ public class CalculatorDisplay extends AutoResizeTextView implements JCalculator
convert(R.string.c_convert) { convert(R.string.c_convert) {
@Override @Override
public void onClick(@NotNull CalculatorDisplay data, @NotNull Context context) { public void onClick(@NotNull CalculatorDisplayView data, @NotNull Context context) {
new NumeralBaseConverterDialog(data.getGenericResult().toString()).show(context); final Generic result = data.getState().getResult();
if (result != null) {
new NumeralBaseConverterDialog(result.toString()).show(context);
}
} }
@Override @Override
@ -169,10 +174,10 @@ public class CalculatorDisplay extends AutoResizeTextView implements JCalculator
} }
}, },
plot(R.string.c_plot) { plot(R.string.c_plot) {
@Override @Override
public void onClick(@NotNull CalculatorDisplay data, @NotNull Context context) { public void onClick(@NotNull CalculatorDisplayView data, @NotNull Context context) {
final Generic generic = data.getGenericResult(); final Generic generic = data.getState().getResult();
assert generic != null; assert generic != null;
final Constant constant = CollectionsUtils.getFirstCollectionElement(getNotSystemConstants(generic)); final Constant constant = CollectionsUtils.getFirstCollectionElement(getNotSystemConstants(generic));
@ -180,18 +185,18 @@ public class CalculatorDisplay extends AutoResizeTextView implements JCalculator
CalculatorActivityLauncher.plotGraph(context, generic, constant); CalculatorActivityLauncher.plotGraph(context, generic, constant);
} }
@Override @Override
protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) { protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) {
boolean result = false; boolean result = false;
if (operation == JsclOperation.simplify) { if (operation == JsclOperation.simplify) {
if (getNotSystemConstants(generic).size() == 1) { if (getNotSystemConstants(generic).size() == 1) {
result = true; result = true;
} }
} }
return result; return result;
} }
@NotNull @NotNull
private Set<Constant> getNotSystemConstants(@NotNull Generic generic) { private Set<Constant> getNotSystemConstants(@NotNull Generic generic) {
@ -208,140 +213,104 @@ public class CalculatorDisplay extends AutoResizeTextView implements JCalculator
} }
}; };
private final int captionId; private final int captionId;
MenuItem(int captionId) { MenuItem(int captionId) {
this.captionId = captionId; this.captionId = captionId;
} }
public final boolean isItemVisible(@NotNull CalculatorDisplay display) { public final boolean isItemVisible(@NotNull CalculatorDisplayViewState displayViewState) {
//noinspection ConstantConditions //noinspection ConstantConditions
return display.isValid() && display.getGenericResult() != null && isItemVisibleFor(display.getGenericResult(), display.getJsclOperation()); return displayViewState.isValid() && displayViewState.getResult() != null && isItemVisibleFor(displayViewState.getResult(), displayViewState.getOperation());
} }
protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) { protected boolean isItemVisibleFor(@NotNull Generic generic, @NotNull JsclOperation operation) {
return true; return true;
} }
@NotNull @NotNull
@Override @Override
public String getCaption(@NotNull Context context) { public String getCaption(@NotNull Context context) {
return context.getString(captionId); return context.getString(captionId);
} }
} }
private boolean valid = true; @NotNull
private CalculatorDisplayViewState state = CalculatorDisplayViewStateImpl.newDefaultInstance();
@Nullable @NotNull
private String errorMessage; private final static TextProcessor<TextHighlighter.Result, String> textHighlighter = new TextHighlighter(Color.WHITE, false, CalculatorEngine.instance.getEngine());
@NotNull public AndroidCalculatorDisplayView(Context context) {
private JsclOperation jsclOperation = JsclOperation.numeric; super(context);
}
@NotNull public AndroidCalculatorDisplayView(Context context, AttributeSet attrs) {
private final static TextProcessor<TextHighlighter.Result, String> textHighlighter = new TextHighlighter(Color.WHITE, false, CalculatorEngine.instance.getEngine()); super(context, attrs);
}
@Nullable public AndroidCalculatorDisplayView(Context context, AttributeSet attrs, int defStyle) {
private Generic genericResult; super(context, attrs, defStyle);
}
public CalculatorDisplay(Context context) { public boolean isValid() {
super(context); return this.state.isValid();
} }
public CalculatorDisplay(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CalculatorDisplay(Context context, AttributeSet attrs, int defStyle) { @Override
super(context, attrs, defStyle); public void setState(@NotNull CalculatorDisplayViewState state) {
} this.state = state;
if ( state.isValid() ) {
setTextColor(getResources().getColor(R.color.default_text_color));
setText(state.getStringResult());
} else {
setTextColor(getResources().getColor(R.color.display_error_text_color));
setText(state.getErrorMessage());
}
}
@Override @NotNull
public boolean isValid() { @Override
return valid; public CalculatorDisplayViewState getState() {
} return this.state;
}
@Override @Override
public void setValid(boolean valid) { public void setText(CharSequence text, BufferType type) {
this.valid = valid; super.setText(text, type);
if (valid) { }
errorMessage = null;
setTextColor(getResources().getColor(R.color.default_text_color));
} else {
setTextColor(getResources().getColor(R.color.display_error_text_color));
}
}
@Override public synchronized void redraw() {
@Nullable if (isValid()) {
public String getErrorMessage() { String text = getText().toString();
return errorMessage;
}
@Override Log.d(this.getClass().getName(), text);
public void setErrorMessage(@Nullable String errorMessage) {
this.errorMessage = errorMessage;
}
@Override try {
public void setJsclOperation(@NotNull JsclOperation jsclOperation) { TextHighlighter.Result result = textHighlighter.process(text);
this.jsclOperation = jsclOperation; text = result.toString();
} } catch (CalculatorParseException e) {
Log.e(this.getClass().getName(), e.getMessage(), e);
}
@Override Log.d(this.getClass().getName(), text);
@NotNull super.setText(Html.fromHtml(text), BufferType.EDITABLE);
public JsclOperation getJsclOperation() { }
return jsclOperation;
}
@Override // todo serso: think where to move it (keep in mind org.solovyev.android.view.AutoResizeTextView.resetTextSize())
public void setText(CharSequence text, BufferType type) { setAddEllipsis(false);
super.setText(text, type); setMinTextSize(10);
resizeText();
}
setValid(true); @Override
} public int getSelection() {
return this.getSelectionStart();
}
public synchronized void redraw() { @Override
if (isValid()) { public void setSelection(int selection) {
String text = getText().toString(); // not supported by TextView
}
Log.d(this.getClass().getName(), text);
try {
TextHighlighter.Result result = textHighlighter.process(text);
text = result.toString();
} catch (CalculatorParseException e) {
Log.e(this.getClass().getName(), e.getMessage(), e);
}
Log.d(this.getClass().getName(), text);
super.setText(Html.fromHtml(text), BufferType.EDITABLE);
}
// todo serso: think where to move it (keep in mind org.solovyev.android.view.AutoResizeTextView.resetTextSize())
setAddEllipsis(false);
setMinTextSize(10);
resizeText();
}
@Override
public void setGenericResult(@Nullable Generic genericResult) {
this.genericResult = genericResult;
}
@Override
@Nullable
public Generic getGenericResult() {
return genericResult;
}
@Override
public int getSelection() {
return this.getSelectionStart();
}
@Override
public void setSelection(int selection) {
// not supported by TextView
}
} }

View File

@ -53,7 +53,7 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
private CalculatorEditor editor; private CalculatorEditor editor;
@NotNull @NotNull
private CalculatorDisplay display; private AndroidCalculatorDisplayView display;
@NotNull @NotNull
private CalculatorEngine calculatorEngine; private CalculatorEngine calculatorEngine;
@ -66,7 +66,7 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
this.editor.init(preferences); this.editor.init(preferences);
preferences.registerOnSharedPreferenceChangeListener(editor); preferences.registerOnSharedPreferenceChangeListener(editor);
this.display = (CalculatorDisplay) activity.findViewById(R.id.calculatorDisplay); this.display = (AndroidCalculatorDisplayView) activity.findViewById(R.id.calculatorDisplay);
this.display.setOnClickListener(new CalculatorDisplayOnClickListener(activity)); this.display.setOnClickListener(new CalculatorDisplayOnClickListener(activity));
final CalculatorHistoryState lastState = AndroidCalculatorHistoryImpl.instance.getLastHistoryState(); final CalculatorHistoryState lastState = AndroidCalculatorHistoryImpl.instance.getLastHistoryState();
@ -97,8 +97,9 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
copyResult(context, display); copyResult(context, display);
} }
public static void copyResult(@NotNull Context context, @NotNull final CalculatorDisplay display) { public static void copyResult(@NotNull Context context, @NotNull final CalculatorDisplayView display) {
if (display.isValid()) { final CalculatorDisplayViewState displayViewState = display.getState();
if (displayViewState.isValid()) {
final CharSequence text = display.getText(); final CharSequence text = display.getText();
if (!StringUtils.isEmpty(text)) { if (!StringUtils.isEmpty(text)) {
final ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Activity.CLIPBOARD_SERVICE); final ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Activity.CLIPBOARD_SERVICE);
@ -228,16 +229,16 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
if (!StringUtils.isEmpty(expression)) { if (!StringUtils.isEmpty(expression)) {
try { try {
Log.d(CalculatorModel.class.getName(), "Trying to evaluate '" + operation + "': " + expression /*+ StringUtils.fromStackTrace(Thread.currentThread().getStackTrace())*/); Log.d(CalculatorModel.class.getName(), "Trying to evaluate '" + operation + "': " + expression /*+ StringUtils.fromStackTrace(Thread.currentThread().getStackTrace())*/);
final CalculatorEngine.Result result = calculatorEngine.evaluate(operation, expression); final CalculatorOutput result = calculatorEngine.evaluate(operation, expression);
// todo serso: second condition might replaced with expression.equals(this.editor.getText().toString()) ONLY if expression will be formatted with text highlighter // todo serso: second condition might replaced with expression.equals(this.editor.getText().toString()) ONLY if expression will be formatted with text highlighter
if (currentRunner == pendingOperation.getObject() && this.editor.getText().length() > 0) { if (currentRunner == pendingOperation.getObject() && this.editor.getText().length() > 0) {
display.setText(result.getResult()); display.setText(result.getStringResult());
} else { } else {
display.setText(""); display.setText("");
} }
display.setJsclOperation(result.getUserOperation()); display.setJsclOperation(result.getOperation());
display.setGenericResult(result.getGenericResult()); display.setGenericResult(result.getResult());
} catch (CalculatorParseException e) { } catch (CalculatorParseException e) {
handleEvaluationException(expression, display, operation, e); handleEvaluationException(expression, display, operation, e);
} catch (CalculatorEvalException e) { } catch (CalculatorEvalException e) {
@ -255,7 +256,7 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
} }
private void handleEvaluationException(@NotNull String expression, private void handleEvaluationException(@NotNull String expression,
@NotNull CalculatorDisplay localDisplay, @NotNull AndroidCalculatorDisplayView localDisplay,
@NotNull JsclOperation operation, @NotNull JsclOperation operation,
@NotNull Message e) { @NotNull Message e) {
Log.d(CalculatorModel.class.getName(), "Evaluation failed for : " + expression + ". Error message: " + e); Log.d(CalculatorModel.class.getName(), "Evaluation failed for : " + expression + ". Error message: " + e);
@ -367,7 +368,7 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
} }
@NotNull @NotNull
public CalculatorDisplay getDisplay() { public AndroidCalculatorDisplayView getDisplay() {
return display; return display;
} }
@ -382,13 +383,15 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if (v instanceof CalculatorDisplay) { if (v instanceof CalculatorDisplayView) {
final CalculatorDisplay cd = (CalculatorDisplay) v; final CalculatorDisplay cd = CalculatorLocatorImpl.getInstance().getCalculatorDisplay();
if (cd.isValid()) { final CalculatorDisplayViewState displayViewState = cd.getViewState();
final List<CalculatorDisplay.MenuItem> filteredMenuItems = new ArrayList<CalculatorDisplay.MenuItem>(CalculatorDisplay.MenuItem.values().length);
for (CalculatorDisplay.MenuItem menuItem : CalculatorDisplay.MenuItem.values()) { if (displayViewState.isValid()) {
if (menuItem.isItemVisible(cd)) { final List<AndroidCalculatorDisplayView.MenuItem> filteredMenuItems = new ArrayList<AndroidCalculatorDisplayView.MenuItem>(AndroidCalculatorDisplayView.MenuItem.values().length);
for (AndroidCalculatorDisplayView.MenuItem menuItem : AndroidCalculatorDisplayView.MenuItem.values()) {
if (menuItem.isItemVisible(displayViewState)) {
filteredMenuItems.add(menuItem); filteredMenuItems.add(menuItem);
} }
} }
@ -398,7 +401,7 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
} }
} else { } else {
final String errorMessage = cd.getErrorMessage(); final String errorMessage = displayViewState.getErrorMessage();
if (errorMessage != null) { if (errorMessage != null) {
showEvaluationError(activity, errorMessage); showEvaluationError(activity, errorMessage);
} }

View File

@ -142,45 +142,12 @@ public enum CalculatorEngine implements JCalculatorEngine {
this.multiplicationSign = multiplicationSign; this.multiplicationSign = multiplicationSign;
} }
public static class Result { public CalculatorOutput evaluate(@NotNull JsclOperation operation,
@NotNull
private Generic genericResult;
@NotNull
private String result;
@NotNull
private JsclOperation userOperation;
public Result(@NotNull String result, @NotNull JsclOperation userOperation, @NotNull Generic genericResult) {
this.result = result;
this.userOperation = userOperation;
this.genericResult = genericResult;
}
@NotNull
public String getResult() {
return result;
}
@NotNull
public JsclOperation getUserOperation() {
return userOperation;
}
@NotNull
public Generic getGenericResult() {
return genericResult;
}
}
public Result evaluate(@NotNull JsclOperation operation,
@NotNull String expression) throws CalculatorParseException, CalculatorEvalException { @NotNull String expression) throws CalculatorParseException, CalculatorEvalException {
return evaluate(operation, expression, null); return evaluate(operation, expression, null);
} }
public Result evaluate(@NotNull final JsclOperation operation, public CalculatorOutput evaluate(@NotNull final JsclOperation operation,
@NotNull String expression, @NotNull String expression,
@Nullable MessageRegistry mr) throws CalculatorParseException, CalculatorEvalException { @Nullable MessageRegistry mr) throws CalculatorParseException, CalculatorEvalException {
synchronized (lock) { synchronized (lock) {
@ -294,7 +261,7 @@ public enum CalculatorEngine implements JCalculatorEngine {
final Generic genericResult = calculationResult.getObject(); final Generic genericResult = calculationResult.getObject();
return new Result(operation.getFromProcessor().process(genericResult), operation, genericResult); return new CalculatorOutputImpl(operation.getFromProcessor().process(genericResult), operation, genericResult);
} }
} }

View File

@ -11,8 +11,8 @@ import junit.framework.Assert;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.junit.Test; import org.junit.Test;
import org.solovyev.android.calculator.CalculatorDisplay;
import org.solovyev.android.calculator.Editor; import org.solovyev.android.calculator.Editor;
import org.solovyev.android.calculator.JCalculatorDisplay;
import org.solovyev.android.calculator.jscl.JsclOperation; import org.solovyev.android.calculator.jscl.JsclOperation;
import org.solovyev.common.equals.CollectionEqualizer; import org.solovyev.common.equals.CollectionEqualizer;
import org.solovyev.common.equals.EqualsTool; import org.solovyev.common.equals.EqualsTool;
@ -125,7 +125,7 @@ public class HistoryUtilsTest {
HistoryHelper<CalculatorHistoryState> history = new SimpleHistoryHelper<CalculatorHistoryState>(); HistoryHelper<CalculatorHistoryState> history = new SimpleHistoryHelper<CalculatorHistoryState>();
JCalculatorDisplay calculatorDisplay = new TestCalculatorDisplay(); CalculatorDisplay calculatorDisplay = new TestCalculatorDisplay();
calculatorDisplay.setErrorMessage("error_msg1"); calculatorDisplay.setErrorMessage("error_msg1");
calculatorDisplay.setText("Error"); calculatorDisplay.setText("Error");
calculatorDisplay.setSelection(1); calculatorDisplay.setSelection(1);
@ -215,7 +215,7 @@ public class HistoryUtilsTest {
} }
private static class TestCalculatorDisplay implements JCalculatorDisplay { private static class TestCalculatorDisplay implements CalculatorDisplay {
@NotNull @NotNull
private final TestEditor testEditor = new TestEditor(); private final TestEditor testEditor = new TestEditor();

View File

@ -54,13 +54,13 @@ public class CalculatorEngineTest {
} }
Assert.assertEquals("0.017", cm.evaluate(JsclOperation.numeric, "").getResult()); Assert.assertEquals("0.017", cm.evaluate(JsclOperation.numeric, "").getStringResult());
Assert.assertEquals("0.349", cm.evaluate(JsclOperation.numeric, "20.0°").getResult()); Assert.assertEquals("0.349", cm.evaluate(JsclOperation.numeric, "20.0°").getStringResult());
Assert.assertEquals("0.5", cm.evaluate(JsclOperation.numeric, "sin(30°)").getResult()); Assert.assertEquals("0.5", cm.evaluate(JsclOperation.numeric, "sin(30°)").getStringResult());
Assert.assertEquals("0.524", cm.evaluate(JsclOperation.numeric, "asin(sin(30°))").getResult()); Assert.assertEquals("0.524", cm.evaluate(JsclOperation.numeric, "asin(sin(30°))").getStringResult());
Assert.assertEquals("∂(cos(t), t, t, 1°)", cm.evaluate(JsclOperation.numeric, "∂(cos(t),t,t,1°)").getResult()); Assert.assertEquals("∂(cos(t), t, t, 1°)", cm.evaluate(JsclOperation.numeric, "∂(cos(t),t,t,1°)").getStringResult());
Assert.assertEquals("∂(cos(t), t, t, 1°)", cm.evaluate(JsclOperation.simplify, "∂(cos(t),t,t,1°)").getResult()); Assert.assertEquals("∂(cos(t), t, t, 1°)", cm.evaluate(JsclOperation.simplify, "∂(cos(t),t,t,1°)").getStringResult());
} finally { } finally {
cm.getEngine().setAngleUnits(defaultAngleUnit); cm.getEngine().setAngleUnits(defaultAngleUnit);
} }
@ -113,120 +113,120 @@ public class CalculatorEngineTest {
public void testEvaluate() throws Exception { public void testEvaluate() throws Exception {
final CalculatorEngine cm = CalculatorEngine.instance; final CalculatorEngine cm = CalculatorEngine.instance;
Assert.assertEquals("cos(t)+10%", cm.evaluate(JsclOperation.simplify, "cos(t)+10%").getResult()); Assert.assertEquals("cos(t)+10%", cm.evaluate(JsclOperation.simplify, "cos(t)+10%").getStringResult());
final Generic expression = cm.getEngine().simplifyGeneric("cos(t)+10%"); final Generic expression = cm.getEngine().simplifyGeneric("cos(t)+10%");
expression.substitute(new Constant("t"), Expression.valueOf(100d)); expression.substitute(new Constant("t"), Expression.valueOf(100d));
Assert.assertEquals("it", cm.evaluate(JsclOperation.simplify, "it").getResult()); Assert.assertEquals("it", cm.evaluate(JsclOperation.simplify, "it").getStringResult());
Assert.assertEquals("10%", cm.evaluate(JsclOperation.simplify, "10%").getResult()); Assert.assertEquals("10%", cm.evaluate(JsclOperation.simplify, "10%").getStringResult());
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "eq(0, 1)").getResult()); Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "eq(0, 1)").getStringResult());
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "eq(1, 1)").getResult()); Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "eq(1, 1)").getStringResult());
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "eq( 1, 1)").getResult()); Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "eq( 1, 1)").getStringResult());
Assert.assertEquals("1", cm.evaluate(JsclOperation.simplify, "eq( 1, 1)").getResult()); Assert.assertEquals("1", cm.evaluate(JsclOperation.simplify, "eq( 1, 1)").getStringResult());
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "lg(10)").getResult()); Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "lg(10)").getStringResult());
Assert.assertEquals("4", cm.evaluate(JsclOperation.numeric, "2+2").getResult()); Assert.assertEquals("4", cm.evaluate(JsclOperation.numeric, "2+2").getStringResult());
final AngleUnit defaultAngleUnit = cm.getEngine().getAngleUnits(); final AngleUnit defaultAngleUnit = cm.getEngine().getAngleUnits();
try { try {
cm.getEngine().setAngleUnits(AngleUnit.rad); cm.getEngine().setAngleUnits(AngleUnit.rad);
Assert.assertEquals("-0.757", cm.evaluate(JsclOperation.numeric, "sin(4)").getResult()); Assert.assertEquals("-0.757", cm.evaluate(JsclOperation.numeric, "sin(4)").getStringResult());
Assert.assertEquals("0.524", cm.evaluate(JsclOperation.numeric, "asin(0.5)").getResult()); Assert.assertEquals("0.524", cm.evaluate(JsclOperation.numeric, "asin(0.5)").getStringResult());
Assert.assertEquals("-0.396", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)").getResult()); Assert.assertEquals("-0.396", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)").getStringResult());
Assert.assertEquals("-0.56", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)√(2)").getResult()); Assert.assertEquals("-0.56", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)√(2)").getStringResult());
Assert.assertEquals("-0.56", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)√(2)").getResult()); Assert.assertEquals("-0.56", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)√(2)").getStringResult());
} finally { } finally {
cm.getEngine().setAngleUnits(defaultAngleUnit); cm.getEngine().setAngleUnits(defaultAngleUnit);
} }
Assert.assertEquals("7.389", cm.evaluate(JsclOperation.numeric, "e^2").getResult()); Assert.assertEquals("7.389", cm.evaluate(JsclOperation.numeric, "e^2").getStringResult());
Assert.assertEquals("7.389", cm.evaluate(JsclOperation.numeric, "exp(1)^2").getResult()); Assert.assertEquals("7.389", cm.evaluate(JsclOperation.numeric, "exp(1)^2").getStringResult());
Assert.assertEquals("7.389", cm.evaluate(JsclOperation.numeric, "exp(2)").getResult()); Assert.assertEquals("7.389", cm.evaluate(JsclOperation.numeric, "exp(2)").getStringResult());
Assert.assertEquals("2+i", cm.evaluate(JsclOperation.numeric, "2*1+√(-1)").getResult()); Assert.assertEquals("2+i", cm.evaluate(JsclOperation.numeric, "2*1+√(-1)").getStringResult());
try { try {
cm.getEngine().setAngleUnits(AngleUnit.rad); cm.getEngine().setAngleUnits(AngleUnit.rad);
Assert.assertEquals("0.921+Πi", cm.evaluate(JsclOperation.numeric, "ln(5cosh(38π√(2cos(2))))").getResult()); Assert.assertEquals("0.921+Πi", cm.evaluate(JsclOperation.numeric, "ln(5cosh(38π√(2cos(2))))").getStringResult());
Assert.assertEquals("-3.41+3.41i", cm.evaluate(JsclOperation.numeric, "(5tan(2i)+2i)/(1-i)").getResult()); Assert.assertEquals("-3.41+3.41i", cm.evaluate(JsclOperation.numeric, "(5tan(2i)+2i)/(1-i)").getStringResult());
} finally { } finally {
cm.getEngine().setAngleUnits(defaultAngleUnit); cm.getEngine().setAngleUnits(defaultAngleUnit);
} }
Assert.assertEquals("7.389i", cm.evaluate(JsclOperation.numeric, "iexp(2)").getResult()); Assert.assertEquals("7.389i", cm.evaluate(JsclOperation.numeric, "iexp(2)").getStringResult());
Assert.assertEquals("2+7.389i", cm.evaluate(JsclOperation.numeric, "2+iexp(2)").getResult()); Assert.assertEquals("2+7.389i", cm.evaluate(JsclOperation.numeric, "2+iexp(2)").getStringResult());
Assert.assertEquals("2+7.389i", cm.evaluate(JsclOperation.numeric, "2+√(-1)exp(2)").getResult()); Assert.assertEquals("2+7.389i", cm.evaluate(JsclOperation.numeric, "2+√(-1)exp(2)").getStringResult());
Assert.assertEquals("2-2.5i", cm.evaluate(JsclOperation.numeric, "2-2.5i").getResult()); Assert.assertEquals("2-2.5i", cm.evaluate(JsclOperation.numeric, "2-2.5i").getStringResult());
Assert.assertEquals("-2-2.5i", cm.evaluate(JsclOperation.numeric, "-2-2.5i").getResult()); Assert.assertEquals("-2-2.5i", cm.evaluate(JsclOperation.numeric, "-2-2.5i").getStringResult());
Assert.assertEquals("-2+2.5i", cm.evaluate(JsclOperation.numeric, "-2+2.5i").getResult()); Assert.assertEquals("-2+2.5i", cm.evaluate(JsclOperation.numeric, "-2+2.5i").getStringResult());
Assert.assertEquals("-2+2.1i", cm.evaluate(JsclOperation.numeric, "-2+2.1i").getResult()); Assert.assertEquals("-2+2.1i", cm.evaluate(JsclOperation.numeric, "-2+2.1i").getStringResult());
Assert.assertEquals("-0.1-0.2i", cm.evaluate(JsclOperation.numeric, "(1-i)/(2+6i)").getResult()); Assert.assertEquals("-0.1-0.2i", cm.evaluate(JsclOperation.numeric, "(1-i)/(2+6i)").getStringResult());
junit.framework.Assert.assertEquals("24", cm.evaluate(JsclOperation.numeric, "4!").getResult()); junit.framework.Assert.assertEquals("24", cm.evaluate(JsclOperation.numeric, "4!").getStringResult());
junit.framework.Assert.assertEquals("24", cm.evaluate(JsclOperation.numeric, "(2+2)!").getResult()); junit.framework.Assert.assertEquals("24", cm.evaluate(JsclOperation.numeric, "(2+2)!").getStringResult());
junit.framework.Assert.assertEquals("120", cm.evaluate(JsclOperation.numeric, "(2+2+1)!").getResult()); junit.framework.Assert.assertEquals("120", cm.evaluate(JsclOperation.numeric, "(2+2+1)!").getStringResult());
junit.framework.Assert.assertEquals("24", cm.evaluate(JsclOperation.numeric, "(2.0+2.0)!").getResult()); junit.framework.Assert.assertEquals("24", cm.evaluate(JsclOperation.numeric, "(2.0+2.0)!").getStringResult());
junit.framework.Assert.assertEquals("24", cm.evaluate(JsclOperation.numeric, "4.0!").getResult()); junit.framework.Assert.assertEquals("24", cm.evaluate(JsclOperation.numeric, "4.0!").getStringResult());
junit.framework.Assert.assertEquals("720", cm.evaluate(JsclOperation.numeric, "(3!)!").getResult()); junit.framework.Assert.assertEquals("720", cm.evaluate(JsclOperation.numeric, "(3!)!").getStringResult());
junit.framework.Assert.assertEquals("36", Expression.valueOf("3!^2").numeric().toString()); junit.framework.Assert.assertEquals("36", Expression.valueOf("3!^2").numeric().toString());
junit.framework.Assert.assertEquals("3", Expression.valueOf("cubic(27)").numeric().toString()); junit.framework.Assert.assertEquals("3", Expression.valueOf("cubic(27)").numeric().toString());
try { try {
junit.framework.Assert.assertEquals("√(-1)!", cm.evaluate(JsclOperation.numeric, "i!").getResult()); junit.framework.Assert.assertEquals("√(-1)!", cm.evaluate(JsclOperation.numeric, "i!").getStringResult());
fail(); fail();
} catch (CalculatorParseException e) { } catch (CalculatorParseException e) {
} }
junit.framework.Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "(π/π)!").getResult()); junit.framework.Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "(π/π)!").getStringResult());
try { try {
junit.framework.Assert.assertEquals("i", cm.evaluate(JsclOperation.numeric, "(-1)i!").getResult()); junit.framework.Assert.assertEquals("i", cm.evaluate(JsclOperation.numeric, "(-1)i!").getStringResult());
fail(); fail();
} catch (CalculatorParseException e) { } catch (CalculatorParseException e) {
} }
junit.framework.Assert.assertEquals("24i", cm.evaluate(JsclOperation.numeric, "4!i").getResult()); junit.framework.Assert.assertEquals("24i", cm.evaluate(JsclOperation.numeric, "4!i").getStringResult());
CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("si", 5d)); CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("si", 5d));
try { try {
cm.getEngine().setAngleUnits(AngleUnit.rad); cm.getEngine().setAngleUnits(AngleUnit.rad);
Assert.assertEquals("0.451", cm.evaluate(JsclOperation.numeric, "acos(0.8999999999999811)").getResult()); Assert.assertEquals("0.451", cm.evaluate(JsclOperation.numeric, "acos(0.8999999999999811)").getStringResult());
Assert.assertEquals("-0.959", cm.evaluate(JsclOperation.numeric, "sin(5)").getResult()); Assert.assertEquals("-0.959", cm.evaluate(JsclOperation.numeric, "sin(5)").getStringResult());
Assert.assertEquals("-4.795", cm.evaluate(JsclOperation.numeric, "sin(5)si").getResult()); Assert.assertEquals("-4.795", cm.evaluate(JsclOperation.numeric, "sin(5)si").getStringResult());
Assert.assertEquals("-23.973", cm.evaluate(JsclOperation.numeric, "sisin(5)si").getResult()); Assert.assertEquals("-23.973", cm.evaluate(JsclOperation.numeric, "sisin(5)si").getStringResult());
Assert.assertEquals("-23.973", cm.evaluate(JsclOperation.numeric, "si*sin(5)si").getResult()); Assert.assertEquals("-23.973", cm.evaluate(JsclOperation.numeric, "si*sin(5)si").getStringResult());
Assert.assertEquals("-3.309", cm.evaluate(JsclOperation.numeric, "sisin(5si)si").getResult()); Assert.assertEquals("-3.309", cm.evaluate(JsclOperation.numeric, "sisin(5si)si").getStringResult());
} finally { } finally {
cm.getEngine().setAngleUnits(defaultAngleUnit); cm.getEngine().setAngleUnits(defaultAngleUnit);
} }
CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("s", 1d)); CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("s", 1d));
Assert.assertEquals("5", cm.evaluate(JsclOperation.numeric, "si").getResult()); Assert.assertEquals("5", cm.evaluate(JsclOperation.numeric, "si").getStringResult());
CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("k", 3.5d)); CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("k", 3.5d));
CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("k1", 4d)); CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("k1", 4d));
Assert.assertEquals("4", cm.evaluate(JsclOperation.numeric, "k11").getResult()); Assert.assertEquals("4", cm.evaluate(JsclOperation.numeric, "k11").getStringResult());
CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("t", (String) null)); CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("t", (String) null));
Assert.assertEquals("11t", cm.evaluate(JsclOperation.numeric, "t11").getResult()); Assert.assertEquals("11t", cm.evaluate(JsclOperation.numeric, "t11").getStringResult());
Assert.assertEquals("11et", cm.evaluate(JsclOperation.numeric, "t11e").getResult()); Assert.assertEquals("11et", cm.evaluate(JsclOperation.numeric, "t11e").getStringResult());
Assert.assertEquals("", cm.evaluate(JsclOperation.numeric, "").getResult()); Assert.assertEquals("", cm.evaluate(JsclOperation.numeric, "").getStringResult());
Assert.assertEquals("", cm.evaluate(JsclOperation.numeric, "Infinity").getResult()); Assert.assertEquals("", cm.evaluate(JsclOperation.numeric, "Infinity").getStringResult());
Assert.assertEquals("11∞t", cm.evaluate(JsclOperation.numeric, "t11∞").getResult()); Assert.assertEquals("11∞t", cm.evaluate(JsclOperation.numeric, "t11∞").getStringResult());
Assert.assertEquals("-t+t^3", cm.evaluate(JsclOperation.numeric, "t(t-1)(t+1)").getResult()); Assert.assertEquals("-t+t^3", cm.evaluate(JsclOperation.numeric, "t(t-1)(t+1)").getStringResult());
Assert.assertEquals("100", cm.evaluate(JsclOperation.numeric, "0.1E3").getResult()); Assert.assertEquals("100", cm.evaluate(JsclOperation.numeric, "0.1E3").getStringResult());
Assert.assertEquals("3.957", cm.evaluate(JsclOperation.numeric, "ln(8)lg(8)+ln(8)").getResult()); Assert.assertEquals("3.957", cm.evaluate(JsclOperation.numeric, "ln(8)lg(8)+ln(8)").getStringResult());
Assert.assertEquals("0.933", cm.evaluate(JsclOperation.numeric, "0x:E/0x:F").getResult()); Assert.assertEquals("0.933", cm.evaluate(JsclOperation.numeric, "0x:E/0x:F").getStringResult());
try { try {
cm.getEngine().setNumeralBase(NumeralBase.hex); cm.getEngine().setNumeralBase(NumeralBase.hex);
Assert.assertEquals("E/F", cm.evaluate(JsclOperation.numeric, "0x:E/0x:F").getResult()); Assert.assertEquals("E/F", cm.evaluate(JsclOperation.numeric, "0x:E/0x:F").getStringResult());
Assert.assertEquals("E/F", cm.evaluate(JsclOperation.simplify, "0x:E/0x:F").getResult()); Assert.assertEquals("E/F", cm.evaluate(JsclOperation.simplify, "0x:E/0x:F").getStringResult());
Assert.assertEquals("E/F", cm.evaluate(JsclOperation.numeric, "E/F").getResult()); Assert.assertEquals("E/F", cm.evaluate(JsclOperation.numeric, "E/F").getStringResult());
Assert.assertEquals("E/F", cm.evaluate(JsclOperation.simplify, "E/F").getResult()); Assert.assertEquals("E/F", cm.evaluate(JsclOperation.simplify, "E/F").getStringResult());
} finally { } finally {
cm.getEngine().setNumeralBase(NumeralBase.dec); cm.getEngine().setNumeralBase(NumeralBase.dec);
} }
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "((((((0))))))").getResult()); Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "((((((0))))))").getStringResult());
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((0))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))").getResult()); Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((0))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))").getStringResult());
/* Assert.assertEquals("0.524", cm.evaluate(JsclOperation.numeric, "30°").getResult()); /* Assert.assertEquals("0.524", cm.evaluate(JsclOperation.numeric, "30°").getResult());
@ -249,11 +249,11 @@ public class CalculatorEngineTest {
}*/ }*/
CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("t", (String) null)); CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("t", (String) null));
Assert.assertEquals("2t", cm.evaluate(JsclOperation.simplify, "∂(t^2,t)").getResult()); Assert.assertEquals("2t", cm.evaluate(JsclOperation.simplify, "∂(t^2,t)").getStringResult());
Assert.assertEquals("2t", cm.evaluate(JsclOperation.numeric, "∂(t^2,t)").getResult()); Assert.assertEquals("2t", cm.evaluate(JsclOperation.numeric, "∂(t^2,t)").getStringResult());
CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("t", "2")); CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("t", "2"));
Assert.assertEquals("2t", cm.evaluate(JsclOperation.simplify, "∂(t^2,t)").getResult()); Assert.assertEquals("2t", cm.evaluate(JsclOperation.simplify, "∂(t^2,t)").getStringResult());
Assert.assertEquals("4", cm.evaluate(JsclOperation.numeric, "∂(t^2,t)").getResult()); Assert.assertEquals("4", cm.evaluate(JsclOperation.numeric, "∂(t^2,t)").getStringResult());
Assert.assertEquals("-x+x*ln(x)", cm.getEngine().simplify("∫(ln(x), x)")); Assert.assertEquals("-x+x*ln(x)", cm.getEngine().simplify("∫(ln(x), x)"));
Assert.assertEquals("-(x-x*ln(x))/(ln(2)+ln(5))", cm.getEngine().simplify("∫(log(10, x), x)")); Assert.assertEquals("-(x-x*ln(x))/(ln(2)+ln(5))", cm.getEngine().simplify("∫(log(10, x), x)"));
@ -267,7 +267,7 @@ public class CalculatorEngineTest {
public void testFormatting() throws Exception { public void testFormatting() throws Exception {
final CalculatorEngine ce = CalculatorEngine.instance; final CalculatorEngine ce = CalculatorEngine.instance;
Assert.assertEquals("12 345", ce.evaluate(JsclOperation.simplify, "12345").getResult()); Assert.assertEquals("12 345", ce.evaluate(JsclOperation.simplify, "12345").getStringResult());
} }
@ -275,7 +275,7 @@ public class CalculatorEngineTest {
public void testI() throws CalculatorParseException, CalculatorEvalException { public void testI() throws CalculatorParseException, CalculatorEvalException {
final CalculatorEngine cm = CalculatorEngine.instance; final CalculatorEngine cm = CalculatorEngine.instance;
Assert.assertEquals("-i", cm.evaluate(JsclOperation.numeric, "i^3").getResult()); Assert.assertEquals("-i", cm.evaluate(JsclOperation.numeric, "i^3").getStringResult());
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
double real = (Math.random()-0.5) * 1000; double real = (Math.random()-0.5) * 1000;
double imag = (Math.random()-0.5) * 1000; double imag = (Math.random()-0.5) * 1000;
@ -289,7 +289,7 @@ public class CalculatorEngineTest {
sb.append(imag); sb.append(imag);
sb.append("^").append(exp); sb.append("^").append(exp);
try { try {
cm.evaluate(JsclOperation.numeric, sb.toString()).getResult(); cm.evaluate(JsclOperation.numeric, sb.toString()).getStringResult();
} catch (Throwable e) { } catch (Throwable e) {
fail(sb.toString()); fail(sb.toString());
} }
@ -304,7 +304,7 @@ public class CalculatorEngineTest {
Assert.fail(); Assert.fail();
} catch (CalculatorParseException e) { } catch (CalculatorParseException e) {
} }
Assert.assertEquals("0.34+1.382i", cm.evaluate(JsclOperation.numeric, "ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(100)))))))))))))))").getResult()); Assert.assertEquals("0.34+1.382i", cm.evaluate(JsclOperation.numeric, "ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(100)))))))))))))))").getStringResult());
try { try {
cm.evaluate(JsclOperation.numeric, "cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos())))))))))))))))))))))))))))))))))))"); cm.evaluate(JsclOperation.numeric, "cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos())))))))))))))))))))))))))))))))))))");
Assert.fail(); Assert.fail();
@ -314,13 +314,13 @@ public class CalculatorEngineTest {
final AngleUnit defaultAngleUnit = cm.getEngine().getAngleUnits(); final AngleUnit defaultAngleUnit = cm.getEngine().getAngleUnits();
try { try {
cm.getEngine().setAngleUnits(AngleUnit.rad); cm.getEngine().setAngleUnits(AngleUnit.rad);
Assert.assertEquals("0.739", cm.evaluate(JsclOperation.numeric, "cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(1))))))))))))))))))))))))))))))))))))").getResult()); Assert.assertEquals("0.739", cm.evaluate(JsclOperation.numeric, "cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(1))))))))))))))))))))))))))))))))))))").getStringResult());
} finally { } finally {
cm.getEngine().setAngleUnits(defaultAngleUnit); cm.getEngine().setAngleUnits(defaultAngleUnit);
} }
CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("si", 5d)); CalculatorEngine.instance.getVarsRegistry().add(new Var.Builder("si", 5d));
Assert.assertEquals("5", cm.evaluate(JsclOperation.numeric, "si").getResult()); Assert.assertEquals("5", cm.evaluate(JsclOperation.numeric, "si").getStringResult());
try { try {
cm.evaluate(JsclOperation.numeric, "sin"); cm.evaluate(JsclOperation.numeric, "sin");
@ -339,11 +339,11 @@ public class CalculatorEngineTest {
decimalGroupSymbols.setGroupingSeparator('\''); decimalGroupSymbols.setGroupingSeparator('\'');
cm.setDecimalGroupSymbols(decimalGroupSymbols); cm.setDecimalGroupSymbols(decimalGroupSymbols);
cm.setPrecision(2); cm.setPrecision(2);
Assert.assertEquals("12'345'678.9", cm.evaluate(JsclOperation.numeric, "1.23456789E7").getResult()); Assert.assertEquals("12'345'678.9", cm.evaluate(JsclOperation.numeric, "1.23456789E7").getStringResult());
cm.setPrecision(10); cm.setPrecision(10);
Assert.assertEquals("12'345'678.9", cm.evaluate(JsclOperation.numeric, "1.23456789E7").getResult()); Assert.assertEquals("12'345'678.9", cm.evaluate(JsclOperation.numeric, "1.23456789E7").getStringResult());
Assert.assertEquals("123'456'789", cm.evaluate(JsclOperation.numeric, "1.234567890E8").getResult()); Assert.assertEquals("123'456'789", cm.evaluate(JsclOperation.numeric, "1.234567890E8").getStringResult());
Assert.assertEquals("1'234'567'890.1", cm.evaluate(JsclOperation.numeric, "1.2345678901E9").getResult()); Assert.assertEquals("1'234'567'890.1", cm.evaluate(JsclOperation.numeric, "1.2345678901E9").getStringResult());
} finally { } finally {
cm.setPrecision(3); cm.setPrecision(3);
DecimalFormatSymbols decimalGroupSymbols = new DecimalFormatSymbols(Locale.getDefault()); DecimalFormatSymbols decimalGroupSymbols = new DecimalFormatSymbols(Locale.getDefault());
@ -357,36 +357,36 @@ public class CalculatorEngineTest {
public void testComparisonFunction() throws Exception { public void testComparisonFunction() throws Exception {
final CalculatorEngine cm = CalculatorEngine.instance; final CalculatorEngine cm = CalculatorEngine.instance;
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "eq(0, 1)").getResult()); Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "eq(0, 1)").getStringResult());
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "eq(1, 1)").getResult()); Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "eq(1, 1)").getStringResult());
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "eq(1, 1.0)").getResult()); Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "eq(1, 1.0)").getStringResult());
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "eq(1, 1.000000000000001)").getResult()); Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "eq(1, 1.000000000000001)").getStringResult());
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "eq(1, 0)").getResult()); Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "eq(1, 0)").getStringResult());
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "lt(0, 1)").getResult()); Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "lt(0, 1)").getStringResult());
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "lt(1, 1)").getResult()); Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "lt(1, 1)").getStringResult());
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "lt(1, 0)").getResult()); Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "lt(1, 0)").getStringResult());
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "gt(0, 1)").getResult()); Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "gt(0, 1)").getStringResult());
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "gt(1, 1)").getResult()); Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "gt(1, 1)").getStringResult());
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "gt(1, 0)").getResult()); Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "gt(1, 0)").getStringResult());
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ne(0, 1)").getResult()); Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ne(0, 1)").getStringResult());
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "ne(1, 1)").getResult()); Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "ne(1, 1)").getStringResult());
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ne(1, 0)").getResult()); Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ne(1, 0)").getStringResult());
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "le(0, 1)").getResult()); Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "le(0, 1)").getStringResult());
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "le(1, 1)").getResult()); Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "le(1, 1)").getStringResult());
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "le(1, 0)").getResult()); Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "le(1, 0)").getStringResult());
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "ge(0, 1)").getResult()); Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "ge(0, 1)").getStringResult());
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ge(1, 1)").getResult()); Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ge(1, 1)").getStringResult());
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ge(1, 0)").getResult()); Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ge(1, 0)").getStringResult());
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "ap(0, 1)").getResult()); Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "ap(0, 1)").getStringResult());
Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ap(1, 1)").getResult()); Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ap(1, 1)").getStringResult());
//Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ap(1, 1.000000000000001)").getResult()); //Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "ap(1, 1.000000000000001)").getResult());
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "ap(1, 0)").getResult()); Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "ap(1, 0)").getStringResult());
} }
@ -395,17 +395,17 @@ public class CalculatorEngineTest {
public void testNumeralSystems() throws Exception { public void testNumeralSystems() throws Exception {
final CalculatorEngine cm = CalculatorEngine.instance; final CalculatorEngine cm = CalculatorEngine.instance;
Assert.assertEquals("11 259 375", cm.evaluate(JsclOperation.numeric, "0x:ABCDEF").getResult()); Assert.assertEquals("11 259 375", cm.evaluate(JsclOperation.numeric, "0x:ABCDEF").getStringResult());
Assert.assertEquals("30 606 154.462", cm.evaluate(JsclOperation.numeric, "0x:ABCDEF*e").getResult()); Assert.assertEquals("30 606 154.462", cm.evaluate(JsclOperation.numeric, "0x:ABCDEF*e").getStringResult());
Assert.assertEquals("30 606 154.462", cm.evaluate(JsclOperation.numeric, "e*0x:ABCDEF").getResult()); Assert.assertEquals("30 606 154.462", cm.evaluate(JsclOperation.numeric, "e*0x:ABCDEF").getStringResult());
Assert.assertEquals("e", cm.evaluate(JsclOperation.numeric, "e*0x:ABCDEF/0x:ABCDEF").getResult()); Assert.assertEquals("e", cm.evaluate(JsclOperation.numeric, "e*0x:ABCDEF/0x:ABCDEF").getStringResult());
Assert.assertEquals("30 606 154.462", cm.evaluate(JsclOperation.numeric, "0x:ABCDEF*e*0x:ABCDEF/0x:ABCDEF").getResult()); Assert.assertEquals("30 606 154.462", cm.evaluate(JsclOperation.numeric, "0x:ABCDEF*e*0x:ABCDEF/0x:ABCDEF").getStringResult());
Assert.assertEquals("30 606 154.462", cm.evaluate(JsclOperation.numeric, "c+0x:ABCDEF*e*0x:ABCDEF/0x:ABCDEF-c+0x:C-0x:C").getResult()); Assert.assertEquals("30 606 154.462", cm.evaluate(JsclOperation.numeric, "c+0x:ABCDEF*e*0x:ABCDEF/0x:ABCDEF-c+0x:C-0x:C").getStringResult());
Assert.assertEquals("1 446 257 064 651.832", cm.evaluate(JsclOperation.numeric, "28*28 * sin(28) - 0b:1101 + √(28) + exp ( 28) ").getResult()); Assert.assertEquals("1 446 257 064 651.832", cm.evaluate(JsclOperation.numeric, "28*28 * sin(28) - 0b:1101 + √(28) + exp ( 28) ").getStringResult());
Assert.assertEquals("13", cm.evaluate(JsclOperation.numeric, "0b:1101").getResult()); Assert.assertEquals("13", cm.evaluate(JsclOperation.numeric, "0b:1101").getStringResult());
try { try {
cm.evaluate(JsclOperation.numeric, "0b:π").getResult(); cm.evaluate(JsclOperation.numeric, "0b:π").getStringResult();
Assert.fail(); Assert.fail();
} catch (CalculatorParseException e) { } catch (CalculatorParseException e) {
// ok // ok
@ -414,12 +414,12 @@ public class CalculatorEngineTest {
final NumeralBase defaultNumeralBase = cm.getEngine().getNumeralBase(); final NumeralBase defaultNumeralBase = cm.getEngine().getNumeralBase();
try{ try{
cm.getEngine().setNumeralBase(NumeralBase.bin); cm.getEngine().setNumeralBase(NumeralBase.bin);
Assert.assertEquals("101", cm.evaluate(JsclOperation.numeric, "10+11").getResult()); Assert.assertEquals("101", cm.evaluate(JsclOperation.numeric, "10+11").getStringResult());
Assert.assertEquals("10/11", cm.evaluate(JsclOperation.numeric, "10/11").getResult()); Assert.assertEquals("10/11", cm.evaluate(JsclOperation.numeric, "10/11").getStringResult());
cm.getEngine().setNumeralBase(NumeralBase.hex); cm.getEngine().setNumeralBase(NumeralBase.hex);
Assert.assertEquals("63 7B", cm.evaluate(JsclOperation.numeric, "56CE+CAD").getResult()); Assert.assertEquals("63 7B", cm.evaluate(JsclOperation.numeric, "56CE+CAD").getStringResult());
Assert.assertEquals("E", cm.evaluate(JsclOperation.numeric, "E").getResult()); Assert.assertEquals("E", cm.evaluate(JsclOperation.numeric, "E").getStringResult());
} finally { } finally {
cm.setNumeralBase(defaultNumeralBase); cm.setNumeralBase(defaultNumeralBase);
} }
@ -434,12 +434,12 @@ public class CalculatorEngineTest {
// logarithm // logarithm
Assert.assertEquals("ln(x)/ln(base)", ((CustomFunction) cm.getFunctionsRegistry().get("log")).getContent()); Assert.assertEquals("ln(x)/ln(base)", ((CustomFunction) cm.getFunctionsRegistry().get("log")).getContent());
Assert.assertEquals("", cm.evaluate(JsclOperation.numeric, "log(1, 10)").getResult()); Assert.assertEquals("", cm.evaluate(JsclOperation.numeric, "log(1, 10)").getStringResult());
Assert.assertEquals("3.322", cm.evaluate(JsclOperation.numeric, "log(2, 10)").getResult()); Assert.assertEquals("3.322", cm.evaluate(JsclOperation.numeric, "log(2, 10)").getStringResult());
Assert.assertEquals("1.431", cm.evaluate(JsclOperation.numeric, "log(5, 10)").getResult()); Assert.assertEquals("1.431", cm.evaluate(JsclOperation.numeric, "log(5, 10)").getStringResult());
Assert.assertEquals("0.96", cm.evaluate(JsclOperation.numeric, "log(11, 10)").getResult()); Assert.assertEquals("0.96", cm.evaluate(JsclOperation.numeric, "log(11, 10)").getStringResult());
Assert.assertEquals("1/(bln(a))", cm.evaluate(JsclOperation.simplify, "∂(log(a, b), b)").getResult()); Assert.assertEquals("1/(bln(a))", cm.evaluate(JsclOperation.simplify, "∂(log(a, b), b)").getStringResult());
Assert.assertEquals("-ln(b)/(aln(a)^2)", cm.evaluate(JsclOperation.simplify, "∂(log(a, b), a)").getResult()); Assert.assertEquals("-ln(b)/(aln(a)^2)", cm.evaluate(JsclOperation.simplify, "∂(log(a, b), a)").getStringResult());
} }
} }

View File

@ -100,11 +100,11 @@ public class NumeralBaseTest {
final String bin = "0b:" + line[2].toUpperCase(); final String bin = "0b:" + line[2].toUpperCase();
final String decExpression = converter.convert(dec); final String decExpression = converter.convert(dec);
final String decResult = CalculatorEngine.instance.evaluate(JsclOperation.numeric, decExpression).getResult(); final String decResult = CalculatorEngine.instance.evaluate(JsclOperation.numeric, decExpression).getStringResult();
final String hexExpression = converter.convert(hex); final String hexExpression = converter.convert(hex);
final String hexResult = CalculatorEngine.instance.evaluate(JsclOperation.numeric, hexExpression).getResult(); final String hexResult = CalculatorEngine.instance.evaluate(JsclOperation.numeric, hexExpression).getStringResult();
final String binExpression = converter.convert(bin); final String binExpression = converter.convert(bin);
final String binResult = CalculatorEngine.instance.evaluate(JsclOperation.numeric, binExpression).getResult(); final String binResult = CalculatorEngine.instance.evaluate(JsclOperation.numeric, binExpression).getStringResult();
Assert.assertEquals("dec-hex: " + decExpression + " : " + hexExpression, decResult, hexResult); Assert.assertEquals("dec-hex: " + decExpression + " : " + hexExpression, decResult, hexResult);
Assert.assertEquals("dec-bin: " + decExpression + " : " + binExpression, decResult, binResult); Assert.assertEquals("dec-bin: " + decExpression + " : " + binExpression, decResult, binResult);