Application structure changed

This commit is contained in:
Sergey Solovyev
2012-11-30 13:43:41 +04:00
parent a2009599e4
commit 5026597946
668 changed files with 169 additions and 169 deletions

View File

@@ -0,0 +1,19 @@
package org.solovyev.android.calculator;
import org.mockito.Mockito;
import org.solovyev.android.calculator.external.CalculatorExternalListenersContainer;
import org.solovyev.android.calculator.history.CalculatorHistory;
/**
* User: serso
* Date: 10/7/12
* Time: 6:30 PM
*/
public class AbstractCalculatorTest {
protected void setUp() throws Exception {
Locator.getInstance().init(new CalculatorImpl(), CalculatorTestUtils.newCalculatorEngine(), Mockito.mock(CalculatorClipboard.class), Mockito.mock(CalculatorNotifier.class), Mockito.mock(CalculatorHistory.class), new SystemOutCalculatorLogger(), Mockito.mock(CalculatorPreferenceService.class), Mockito.mock(CalculatorKeyboard.class), Mockito.mock(CalculatorExternalListenersContainer.class));
Locator.getInstance().getEngine().init();
}
}

View File

@@ -0,0 +1,23 @@
package org.solovyev.android.calculator;
import jscl.math.Expression;
import org.junit.Test;
import org.solovyev.android.calculator.jscl.JsclOperation;
/**
* User: serso
* Date: 10/20/12
* Time: 12:24 PM
*/
public class CalculatorDisplayViewStateImplTest {
@Test
public void testSerializable() throws Exception {
CalculatorTestUtils.testSerialization(CalculatorDisplayViewStateImpl.newValidState(JsclOperation.numeric, null, "test", 3));
CalculatorTestUtils.testSerialization(CalculatorDisplayViewStateImpl.newValidState(JsclOperation.numeric, Expression.valueOf("3"), "test", 3));
CalculatorTestUtils.testSerialization(CalculatorDisplayViewStateImpl.newValidState(JsclOperation.simplify, Expression.valueOf("3+3"), "test", 3));
CalculatorTestUtils.testSerialization(CalculatorDisplayViewStateImpl.newDefaultInstance());
CalculatorTestUtils.testSerialization(CalculatorDisplayViewStateImpl.newErrorState(JsclOperation.numeric, "ertert"));
}
}

View File

@@ -0,0 +1,208 @@
package org.solovyev.android.calculator;
import junit.framework.Assert;
import org.jetbrains.annotations.NotNull;
import org.junit.Before;
import org.junit.Test;
/**
* User: Solovyev_S
* Date: 21.09.12
* Time: 12:44
*/
public class CalculatorEditorImplTest extends AbstractCalculatorTest {
@NotNull
private CalculatorEditor calculatorEditor;
@Before
public void setUp() throws Exception {
super.setUp();
this.calculatorEditor = new CalculatorEditorImpl(Locator.getInstance().getCalculator());
}
@Test
public void testInsert() throws Exception {
CalculatorEditorViewState viewState = this.calculatorEditor.getViewState();
Assert.assertEquals("", viewState.getText());
Assert.assertEquals(0, viewState.getSelection());
viewState = this.calculatorEditor.insert("");
Assert.assertEquals("", viewState.getText());
Assert.assertEquals(0, viewState.getSelection());
viewState = this.calculatorEditor.insert("test");
Assert.assertEquals("test", viewState.getText());
Assert.assertEquals(4, viewState.getSelection());
viewState = this.calculatorEditor.insert("test");
Assert.assertEquals("testtest", viewState.getText());
Assert.assertEquals(8, viewState.getSelection());
viewState = this.calculatorEditor.insert("");
Assert.assertEquals("testtest", viewState.getText());
Assert.assertEquals(8, viewState.getSelection());
viewState = this.calculatorEditor.insert("1234567890");
Assert.assertEquals("testtest1234567890", viewState.getText());
Assert.assertEquals(18, viewState.getSelection());
viewState = this.calculatorEditor.moveCursorLeft();
viewState = this.calculatorEditor.insert("9");
Assert.assertEquals("testtest12345678990", viewState.getText());
Assert.assertEquals(18, viewState.getSelection());
viewState = this.calculatorEditor.setCursorOnStart();
viewState = this.calculatorEditor.insert("9");
Assert.assertEquals("9testtest12345678990", viewState.getText());
Assert.assertEquals(1, viewState.getSelection());
viewState = this.calculatorEditor.erase();
viewState = this.calculatorEditor.insert("9");
Assert.assertEquals("9testtest12345678990", viewState.getText());
Assert.assertEquals(1, viewState.getSelection());
viewState = this.calculatorEditor.insert("öäü");
Assert.assertEquals("9öäütesttest12345678990", viewState.getText());
this.calculatorEditor.setCursorOnEnd();
viewState = this.calculatorEditor.insert("öäü");
Assert.assertEquals("9öäütesttest12345678990öäü", viewState.getText());
}
@Test
public void testErase() throws Exception {
this.calculatorEditor.setText("");
this.calculatorEditor.erase();
Assert.assertEquals("", this.calculatorEditor.getViewState().getText());
this.calculatorEditor.setText("test");
this.calculatorEditor.erase();
Assert.assertEquals("tes", this.calculatorEditor.getViewState().getText());
this.calculatorEditor.erase();
Assert.assertEquals("te", this.calculatorEditor.getViewState().getText());
this.calculatorEditor.erase();
Assert.assertEquals("t", this.calculatorEditor.getViewState().getText());
this.calculatorEditor.erase();
Assert.assertEquals("", this.calculatorEditor.getViewState().getText());
this.calculatorEditor.erase();
Assert.assertEquals("", this.calculatorEditor.getViewState().getText());
this.calculatorEditor.setText("1234");
this.calculatorEditor.moveCursorLeft();
this.calculatorEditor.erase();
Assert.assertEquals("124", this.calculatorEditor.getViewState().getText());
this.calculatorEditor.erase();
Assert.assertEquals("14", this.calculatorEditor.getViewState().getText());
this.calculatorEditor.erase();
Assert.assertEquals("4", this.calculatorEditor.getViewState().getText());
this.calculatorEditor.setText("1");
this.calculatorEditor.moveCursorLeft();
this.calculatorEditor.erase();
Assert.assertEquals("1", this.calculatorEditor.getViewState().getText());
}
@Test
public void testMoveSelection() throws Exception {
this.calculatorEditor.setText("");
CalculatorEditorViewState viewState = this.calculatorEditor.moveSelection(0);
Assert.assertEquals(0, viewState.getSelection());
viewState = this.calculatorEditor.moveSelection(2);
Assert.assertEquals(0, viewState.getSelection());
viewState = this.calculatorEditor.moveSelection(100);
Assert.assertEquals(0, viewState.getSelection());
viewState = this.calculatorEditor.moveSelection(-3);
Assert.assertEquals(0, viewState.getSelection());
viewState = this.calculatorEditor.moveSelection(-100);
Assert.assertEquals(0, viewState.getSelection());
viewState = this.calculatorEditor.setText("0123456789");
viewState = this.calculatorEditor.moveSelection(0);
Assert.assertEquals(10, viewState.getSelection());
viewState = this.calculatorEditor.moveSelection(1);
Assert.assertEquals(10, viewState.getSelection());
viewState = this.calculatorEditor.moveSelection(-2);
Assert.assertEquals(8, viewState.getSelection());
viewState = this.calculatorEditor.moveSelection(1);
Assert.assertEquals(9, viewState.getSelection());
viewState = this.calculatorEditor.moveSelection(-9);
Assert.assertEquals(0, viewState.getSelection());
viewState = this.calculatorEditor.moveSelection(-10);
Assert.assertEquals(0, viewState.getSelection());
viewState = this.calculatorEditor.moveSelection(2);
Assert.assertEquals(2, viewState.getSelection());
viewState = this.calculatorEditor.moveSelection(2);
Assert.assertEquals(4, viewState.getSelection());
viewState = this.calculatorEditor.moveSelection(-6);
Assert.assertEquals(0, viewState.getSelection());
}
@Test
public void testSetText() throws Exception {
CalculatorEditorViewState viewState = this.calculatorEditor.setText("test");
Assert.assertEquals("test", viewState.getText());
Assert.assertEquals(4, viewState.getSelection());
viewState = this.calculatorEditor.setText("testtest");
Assert.assertEquals("testtest", viewState.getText());
Assert.assertEquals(8, viewState.getSelection());
viewState = this.calculatorEditor.setText("");
Assert.assertEquals("", viewState.getText());
Assert.assertEquals(0, viewState.getSelection());
viewState = this.calculatorEditor.setText("testtest", 0);
Assert.assertEquals("testtest", viewState.getText());
Assert.assertEquals(0, viewState.getSelection());
viewState = this.calculatorEditor.setText("testtest", 2);
Assert.assertEquals("testtest", viewState.getText());
Assert.assertEquals(2, viewState.getSelection());
viewState = this.calculatorEditor.setText("", 0);
Assert.assertEquals("", viewState.getText());
Assert.assertEquals(0, viewState.getSelection());
viewState = this.calculatorEditor.setText("", 3);
Assert.assertEquals("", viewState.getText());
Assert.assertEquals(0, viewState.getSelection());
viewState = this.calculatorEditor.setText("", -3);
Assert.assertEquals("", viewState.getText());
Assert.assertEquals(0, viewState.getSelection());
viewState = this.calculatorEditor.setText("test");
Assert.assertEquals("test", viewState.getText());
Assert.assertEquals(4, viewState.getSelection());
viewState = this.calculatorEditor.setText("", 2);
Assert.assertEquals("", viewState.getText());
Assert.assertEquals(0, viewState.getSelection());
}
}

View File

@@ -0,0 +1,21 @@
package org.solovyev.android.calculator;
import junit.framework.Assert;
import org.junit.Test;
/**
* User: serso
* Date: 10/20/12
* Time: 12:31 PM
*/
public class CalculatorEditorViewStateImplTest {
@Test
public void testSerialization() throws Exception {
CalculatorTestUtils.testSerialization(CalculatorEditorViewStateImpl.newDefaultInstance());
CalculatorEditorViewState out = CalculatorTestUtils.testSerialization(CalculatorEditorViewStateImpl.newInstance("treter", 2));
Assert.assertEquals(2, out.getSelection());
Assert.assertEquals("treter", out.getText());
}
}

View File

@@ -0,0 +1,33 @@
package org.solovyev.android.calculator;
import org.junit.Before;
import org.junit.Test;
/**
* User: Solovyev_S
* Date: 15.10.12
* Time: 12:30
*/
public class CalculatorImplTest extends AbstractCalculatorTest {
@Before
public void setUp() throws Exception {
super.setUp();
}
@Test
public void testAnsVariable() throws Exception {
CalculatorTestUtils.assertError("ans");
CalculatorTestUtils.assertError("ans");
CalculatorTestUtils.assertEval("2", "2");
CalculatorTestUtils.assertEval("2", "ans");
CalculatorTestUtils.assertEval("4", "ans^2");
CalculatorTestUtils.assertEval("16", "ans^2");
CalculatorTestUtils.assertEval("0", "0");
CalculatorTestUtils.assertEval("0", "ans");
CalculatorTestUtils.assertEval("3", "3");
CalculatorTestUtils.assertEval("9", "ans*ans");
CalculatorTestUtils.assertError("ans*an");
CalculatorTestUtils.assertEval("81", "ans*ans");
}
}

View File

@@ -0,0 +1,172 @@
package org.solovyev.android.calculator;
import jscl.JsclMathEngine;
import junit.framework.Assert;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.mockito.Mockito;
import org.solovyev.android.calculator.external.CalculatorExternalListenersContainer;
import org.solovyev.android.calculator.history.CalculatorHistory;
import org.solovyev.android.calculator.jscl.JsclOperation;
import java.io.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* User: serso
* Date: 10/7/12
* Time: 8:40 PM
*/
public class CalculatorTestUtils {
// in seconds
public static final int TIMEOUT = 3;
public static void staticSetUp() throws Exception {
Locator.getInstance().init(new CalculatorImpl(), newCalculatorEngine(), Mockito.mock(CalculatorClipboard.class), Mockito.mock(CalculatorNotifier.class), Mockito.mock(CalculatorHistory.class), new SystemOutCalculatorLogger(), Mockito.mock(CalculatorPreferenceService.class), Mockito.mock(CalculatorKeyboard.class), Mockito.mock(CalculatorExternalListenersContainer.class));
Locator.getInstance().getEngine().init();
}
@NotNull
static CalculatorEngineImpl newCalculatorEngine() {
final MathEntityDao mathEntityDao = Mockito.mock(MathEntityDao.class);
final JsclMathEngine jsclEngine = JsclMathEngine.getInstance();
final CalculatorVarsRegistry varsRegistry = new CalculatorVarsRegistry(jsclEngine.getConstantsRegistry(), mathEntityDao);
final CalculatorFunctionsMathRegistry functionsRegistry = new CalculatorFunctionsMathRegistry(jsclEngine.getFunctionsRegistry(), mathEntityDao);
final CalculatorOperatorsMathRegistry operatorsRegistry = new CalculatorOperatorsMathRegistry(jsclEngine.getOperatorsRegistry(), mathEntityDao);
final CalculatorPostfixFunctionsRegistry postfixFunctionsRegistry = new CalculatorPostfixFunctionsRegistry(jsclEngine.getPostfixFunctionsRegistry(), mathEntityDao);
return new CalculatorEngineImpl(jsclEngine, varsRegistry, functionsRegistry, operatorsRegistry, postfixFunctionsRegistry, null);
}
public static void assertEval(@NotNull String expected, @NotNull String expression) {
assertEval(expected, expression, JsclOperation.numeric);
}
public static void assertEval(@NotNull String expected, @NotNull String expression, @NotNull JsclOperation operation) {
final Calculator calculator = Locator.getInstance().getCalculator();
Locator.getInstance().getDisplay().setViewState(CalculatorDisplayViewStateImpl.newDefaultInstance());
final CountDownLatch latch = new CountDownLatch(1);
final TestCalculatorEventListener calculatorEventListener = new TestCalculatorEventListener(latch);
try {
calculator.addCalculatorEventListener(calculatorEventListener);
calculatorEventListener.setCalculatorEventData(calculator.evaluate(operation, expression));
if (latch.await(TIMEOUT, TimeUnit.SECONDS)) {
Assert.assertNotNull(calculatorEventListener.getResult());
Assert.assertEquals(expected, calculatorEventListener.getResult().getText());
} else {
Assert.fail("Too long wait for: " + expression);
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
calculator.removeCalculatorEventListener(calculatorEventListener);
}
}
public static void assertError(@NotNull String expression) {
assertError(expression, JsclOperation.numeric);
}
public static <S extends Serializable> S testSerialization(@NotNull S serializable) throws IOException, ClassNotFoundException {
final ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(out);
oos.writeObject(serializable);
} finally {
if (oos != null) {
oos.close();
}
}
byte[] serialized = out.toByteArray();
Assert.assertTrue(serialized.length > 0);
final ObjectInputStream resultStream = new ObjectInputStream(new ByteArrayInputStream(out.toByteArray()));
final S result = (S) resultStream.readObject();
Assert.assertNotNull(result);
return result;
}
private static final class TestCalculatorEventListener implements CalculatorEventListener {
@Nullable
private CalculatorEventData calculatorEventData;
@NotNull
private final CountDownLatch latch;
@Nullable
private volatile CalculatorDisplayViewState result = null;
public TestCalculatorEventListener(@NotNull CountDownLatch latch) {
this.latch = latch;
}
public void setCalculatorEventData(@Nullable CalculatorEventData calculatorEventData) {
this.calculatorEventData = calculatorEventData;
}
@Override
public void onCalculatorEvent(@NotNull CalculatorEventData calculatorEventData, @NotNull CalculatorEventType calculatorEventType, @Nullable Object data) {
if (this.calculatorEventData != null && calculatorEventData.isSameSequence(this.calculatorEventData)) {
if (calculatorEventType == CalculatorEventType.display_state_changed) {
final CalculatorDisplayChangeEventData displayChange = (CalculatorDisplayChangeEventData) data;
result = displayChange.getNewValue();
try {
// need to sleep a little bit as await
new CountDownLatch(1).await(100, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
}
latch.countDown();
}
}
}
@Nullable
public CalculatorDisplayViewState getResult() {
return result;
}
}
public static void assertError(@NotNull String expression, @NotNull JsclOperation operation) {
final Calculator calculator = Locator.getInstance().getCalculator();
Locator.getInstance().getDisplay().setViewState(CalculatorDisplayViewStateImpl.newDefaultInstance());
final CountDownLatch latch = new CountDownLatch(1);
final TestCalculatorEventListener calculatorEventListener = new TestCalculatorEventListener(latch);
try {
calculator.addCalculatorEventListener(calculatorEventListener);
calculatorEventListener.setCalculatorEventData(calculator.evaluate(operation, expression));
if (latch.await(TIMEOUT, TimeUnit.SECONDS)) {
Assert.assertNotNull(calculatorEventListener.getResult());
Assert.assertFalse(calculatorEventListener.getResult().isValid());
} else {
Assert.fail("Too long wait for: " + expression);
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
calculator.removeCalculatorEventListener(calculatorEventListener);
}
}
}

View File

@@ -0,0 +1,71 @@
package org.solovyev.android.calculator;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.solovyev.android.calculator.model.Var;
import org.solovyev.android.calculator.text.FromJsclSimplifyTextProcessor;
import java.text.DecimalFormatSymbols;
/**
* User: serso
* Date: 10/20/11
* Time: 3:43 PM
*/
public class FromJsclSimplifyTextProcessorTest extends AbstractCalculatorTest {
@BeforeClass
public static void staticSetUp() throws Exception {
CalculatorTestUtils.staticSetUp();
}
@Test
public void testProcess() throws Exception {
FromJsclSimplifyTextProcessor tp = new FromJsclSimplifyTextProcessor();
//Assert.assertEquals("(e)", tp.process("(2.718281828459045)"));
//Assert.assertEquals("ee", tp.process("2.718281828459045*2.718281828459045"));
//Assert.assertEquals("((e)(e))", tp.process("((2.718281828459045)*(2.718281828459045))"));
DecimalFormatSymbols decimalGroupSymbols = new DecimalFormatSymbols();
decimalGroupSymbols.setGroupingSeparator(' ');
Locator.getInstance().getEngine().setDecimalGroupSymbols(decimalGroupSymbols);
//Assert.assertEquals("123 456 789e", tp.process("123456789*2.718281828459045"));
//Assert.assertEquals("123 456 789e", tp.process("123 456 789 * 2.718281828459045"));
//Assert.assertEquals("t11e", tp.process("t11*2.718281828459045"));
//Assert.assertEquals("e", tp.process("2.718281828459045"));
//Assert.assertEquals("tee", tp.process("t2.718281828459045*2.718281828459045"));
Locator.getInstance().getEngine().getVarsRegistry().add(new Var.Builder("t2.718281828459045", "2"));
Locator.getInstance().getEngine().getVarsRegistry().add(new Var.Builder("t", (String)null));
//Assert.assertEquals("t2.718281828459045e", tp.process("t2.718281828459045*2.718281828459045"));
//Assert.assertEquals("ee", tp.process("2.718281828459045*2.718281828459045"));
Assert.assertEquals("t×", tp.process("t*"));
Assert.assertEquals("×t", tp.process("*t"));
Assert.assertEquals("t2", tp.process("t*2"));
Assert.assertEquals("2t", tp.process("2*t"));
Locator.getInstance().getEngine().getVarsRegistry().add(new Var.Builder("t", (String) null));
Assert.assertEquals("t×", tp.process("t*"));
Assert.assertEquals("×t", tp.process("*t"));
Assert.assertEquals("t2", tp.process("t*2"));
Assert.assertEquals("2t", tp.process("2*t"));
Assert.assertEquals("t^2×2", tp.process("t^2*2"));
Assert.assertEquals("2t^2", tp.process("2*t^2"));
Assert.assertEquals("t^[2×2t]", tp.process("t^[2*2*t]"));
Assert.assertEquals("2t^2[2t]", tp.process("2*t^2[2*t]"));
Locator.getInstance().getEngine().getVarsRegistry().add(new Var.Builder("k", (String) null));
Assert.assertEquals("(t+2k)[k+2t]", tp.process("(t+2*k)*[k+2*t]"));
Assert.assertEquals("(te+2k)e[k+2te]", tp.process("(t*e+2*k)*e*[k+2*t*e]"));
Assert.assertEquals("tlog(3)", tp.process("t*log(3)"));
Assert.assertEquals("t√(3)", tp.process("t*√(3)"));
Assert.assertEquals("20x", tp.process("20*x"));
Assert.assertEquals("20x", tp.process("20x"));
Assert.assertEquals("2×0x3", tp.process("2*0x3"));
Assert.assertEquals("2×0x:3", tp.process("2*0x:3"));
}
}

View File

@@ -0,0 +1,53 @@
package org.solovyev.android.calculator.history;
import junit.framework.Assert;
import org.jetbrains.annotations.NotNull;
import org.junit.BeforeClass;
import org.junit.Test;
import org.solovyev.android.calculator.CalculatorDisplayViewStateImpl;
import org.solovyev.android.calculator.CalculatorEditorViewStateImpl;
import org.solovyev.android.calculator.Locator;
import org.solovyev.android.calculator.CalculatorTestUtils;
import java.util.List;
/**
* User: Solovyev_S
* Date: 10.10.12
* Time: 15:07
*/
public class CalculatorHistoryImplTest {
@BeforeClass
public static void setUp() throws Exception {
CalculatorTestUtils.staticSetUp();
}
@Test
public void testGetStates() throws Exception {
CalculatorHistory calculatorHistory = new CalculatorHistoryImpl(Locator.getInstance().getCalculator());
addState(calculatorHistory, "1");
addState(calculatorHistory, "12");
addState(calculatorHistory, "123");
addState(calculatorHistory, "123+");
addState(calculatorHistory, "123+3");
addState(calculatorHistory, "");
addState(calculatorHistory, "2");
addState(calculatorHistory, "23");
addState(calculatorHistory, "235");
addState(calculatorHistory, "2355");
addState(calculatorHistory, "235");
addState(calculatorHistory, "2354");
addState(calculatorHistory, "23547");
final List<CalculatorHistoryState> states = calculatorHistory.getStates(false);
Assert.assertEquals(2, states.size());
Assert.assertEquals("23547", states.get(1).getEditorState().getText());
Assert.assertEquals("123+3", states.get(0).getEditorState().getText());
}
private void addState(@NotNull CalculatorHistory calculatorHistory, @NotNull String text) {
calculatorHistory.addState(CalculatorHistoryState.newInstance(CalculatorEditorViewStateImpl.newInstance(text, 3), CalculatorDisplayViewStateImpl.newDefaultInstance()));
}
}

View File

@@ -0,0 +1,52 @@
/*
* 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.jscl;
import jscl.AngleUnit;
import jscl.JsclMathEngine;
import jscl.math.Expression;
import jscl.math.Generic;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.solovyev.android.calculator.AbstractCalculatorTest;
import org.solovyev.android.calculator.CalculatorTestUtils;
/**
* User: serso
* Date: 10/18/11
* Time: 10:42 PM
*/
public class FromJsclNumericTextProcessorTest extends AbstractCalculatorTest {
@BeforeClass
public static void staticSetUp() throws Exception {
CalculatorTestUtils.staticSetUp();
}
@Test
public void testCreateResultForComplexNumber() throws Exception {
final FromJsclNumericTextProcessor cm = new FromJsclNumericTextProcessor();
final JsclMathEngine me = JsclMathEngine.getInstance();
final AngleUnit defaultAngleUnits = me.getAngleUnits();
Assert.assertEquals("1.22133+23 123i", cm.process(Expression.valueOf("1.22133232+23123*i").numeric()));
Assert.assertEquals("1.22133+1.2i", cm.process(Expression.valueOf("1.22133232+1.2*i").numeric()));
Assert.assertEquals("1.22133+0i", cm.process(Expression.valueOf("1.22133232+0.000000001*i").numeric()));
try {
me.setAngleUnits(AngleUnit.rad);
Assert.assertEquals("1-0i", cm.process(Expression.valueOf("-(e^(i*π))").numeric()));
} finally {
me.setAngleUnits(defaultAngleUnits);
}
Assert.assertEquals("1.22i", cm.process(Expression.valueOf("1.22*i").numeric()));
Assert.assertEquals("i", cm.process(Expression.valueOf("i").numeric()));
Generic numeric = Expression.valueOf("e^(Π*i)+1").numeric();
junit.framework.Assert.assertEquals("0i", cm.process(numeric));
}
}

View File

@@ -0,0 +1,71 @@
/*
* 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.math;
import junit.framework.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.solovyev.android.calculator.AbstractCalculatorTest;
import org.solovyev.android.calculator.CalculatorTestUtils;
/**
* User: serso
* Date: 10/5/11
* Time: 1:25 AM
*/
public class MathTypeTest extends AbstractCalculatorTest {
@BeforeClass
public static void staticSetUp() throws Exception {
CalculatorTestUtils.staticSetUp();
}
@Test
public void testGetType() throws Exception {
Assert.assertEquals(MathType.function, MathType.getType("sin", 0, false).getMathType());
Assert.assertEquals(MathType.text, MathType.getType("sn", 0, false).getMathType());
Assert.assertEquals(MathType.text, MathType.getType("s", 0, false).getMathType());
Assert.assertEquals(MathType.text, MathType.getType("", 0, false).getMathType());
try {
Assert.assertEquals(MathType.text, MathType.getType("22", -1, false).getMathType());
Assert.fail();
} catch (IllegalArgumentException e) {
}
try {
Assert.assertEquals(MathType.text, MathType.getType("22", 2, false).getMathType());
Assert.fail();
} catch (IllegalArgumentException e) {
}
Assert.assertEquals("atanh", MathType.getType("atanh", 0, false).getMatch());
}
/* @Test
public void testPostfixFunctionsProcessing() throws Exception {
org.junit.Assert.assertEquals(-1, MathType.getPostfixFunctionStart("5!", 1));
org.junit.Assert.assertEquals(0, MathType.getPostfixFunctionStart("!", 1));
org.junit.Assert.assertEquals(-1, MathType.getPostfixFunctionStart("5.4434234!", 9));
org.junit.Assert.assertEquals(1, MathType.getPostfixFunctionStart("2+5!", 3));
org.junit.Assert.assertEquals(4, MathType.getPostfixFunctionStart("2.23+5.4434234!", 14));
org.junit.Assert.assertEquals(14, MathType.getPostfixFunctionStart("2.23+5.4434234*5!", 16));
org.junit.Assert.assertEquals(14, MathType.getPostfixFunctionStart("2.23+5.4434234*5.1!", 18));
org.junit.Assert.assertEquals(4, MathType.getPostfixFunctionStart("2.23+(5.4434234*5.1)!", 20));
org.junit.Assert.assertEquals(4, MathType.getPostfixFunctionStart("2.23+(5.4434234*(5.1+1))!", 24));
org.junit.Assert.assertEquals(4, MathType.getPostfixFunctionStart("2.23+(5.4434234*sin(5.1+1))!", 27));
org.junit.Assert.assertEquals(0, MathType.getPostfixFunctionStart("sin(5)!", 6));
org.junit.Assert.assertEquals(-1, MathType.getPostfixFunctionStart(")!", ")!".indexOf("!")));
org.junit.Assert.assertEquals(0, MathType.getPostfixFunctionStart("sin(5sin(5sin(5)))!", 18));
org.junit.Assert.assertEquals(2, MathType.getPostfixFunctionStart("2+sin(5sin(5sin(5)))!", 20));
org.junit.Assert.assertEquals(5, MathType.getPostfixFunctionStart("2.23+sin(5.4434234*sin(5.1+1))!", 30));
org.junit.Assert.assertEquals(5, MathType.getPostfixFunctionStart("2.23+sin(5.4434234*sin(5.1E2+e))!", "2.23+sin(5.4434234*sin(5.1E2+e))!".indexOf("!")));
org.junit.Assert.assertEquals(5, MathType.getPostfixFunctionStart("2.23+sin(5.4434234*sin(5.1E2+5 555 555))!", "2.23+sin(5.4434234*sin(5.1E2+5 555 555))!".indexOf("!")));
org.junit.Assert.assertEquals(5, MathType.getPostfixFunctionStart("2.23+sin(5.4434234^sin(5.1E2!+5'555'555))!", "2.23+sin(5.4434234^sin(5.1E2!+5'555'555))!".lastIndexOf("!")));
}*/
}

View File

@@ -0,0 +1,426 @@
/*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com
*/
package org.solovyev.android.calculator.model;
import jscl.AngleUnit;
import jscl.JsclMathEngine;
import jscl.MathEngine;
import jscl.NumeralBase;
import jscl.math.Expression;
import jscl.math.Generic;
import jscl.math.function.Constant;
import jscl.math.function.CustomFunction;
import jscl.text.ParseException;
import junit.framework.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.solovyev.android.calculator.AbstractCalculatorTest;
import org.solovyev.android.calculator.Locator;
import org.solovyev.android.calculator.CalculatorEvalException;
import org.solovyev.android.calculator.CalculatorTestUtils;
import org.solovyev.android.calculator.jscl.JsclOperation;
import java.text.DecimalFormatSymbols;
import java.util.Locale;
import static junit.framework.Assert.fail;
/**
* User: serso
* Date: 9/17/11
* Time: 9:47 PM
*/
@SuppressWarnings("deprecation")
public class AndroidCalculatorEngineTest extends AbstractCalculatorTest {
@BeforeClass
public static void staticSetUp() throws Exception {
CalculatorTestUtils.staticSetUp();
Locator.getInstance().getEngine().setPrecision(3);
}
@Test
public void testDegrees() throws Exception {
final MathEngine cm = Locator.getInstance().getEngine().getMathEngine0();
final AngleUnit defaultAngleUnit = cm.getAngleUnits();
try {
cm.setAngleUnits(AngleUnit.rad);
cm.setPrecision(3);
CalculatorTestUtils.assertError("°");
CalculatorTestUtils.assertEval("0.017", "");
CalculatorTestUtils.assertEval("0.349", "20.0°");
CalculatorTestUtils.assertEval("0.5", "sin(30°)");
CalculatorTestUtils.assertEval("0.524", "asin(sin(30°))");
CalculatorTestUtils.assertEval("∂(cos(t), t, t, 1°)", "∂(cos(t),t,t,1°)");
CalculatorTestUtils.assertEval("∂(cos(t), t, t, 1°)", "∂(cos(t),t,t,1°)", JsclOperation.simplify);
} finally {
cm.setAngleUnits(defaultAngleUnit);
}
}
/* @Test
public void testLongExecution() throws Exception {
final MathEngine cm = Locator.getInstance().getEngine().getMathEngine0();
try {
cm.evaluate( "3^10^10^10");
fail();
} catch (ParseException e) {
if (e.getMessageCode().equals(Messages.msg_3)) {
} else {
System.out.print(e.getCause().getMessage());
fail();
}
}
try {
cm.evaluate("9999999!");
fail();
} catch (ParseException e) {
if (e.getMessageCode().equals(Messages.msg_3)) {
} else {
System.out.print(e.getCause().getMessage());
fail();
}
}
final long start = System.currentTimeMillis();
try {
cm.evaluate( "3^10^10^10");
fail();
} catch (ParseException e) {
if (e.getMessage().startsWith("Too long calculation")) {
final long end = System.currentTimeMillis();
Assert.assertTrue(end - start < 1000);
} else {
fail();
}
}
}*/
@Test
public void testEvaluate() throws Exception {
final MathEngine cm = Locator.getInstance().getEngine().getMathEngine0();
CalculatorTestUtils.assertEval("cos(t)+10%", "cos(t)+10%", JsclOperation.simplify);
final Generic expression = cm.simplifyGeneric("cos(t)+10%");
expression.substitute(new Constant("t"), Expression.valueOf(100d));
CalculatorTestUtils.assertEval("it", "it", JsclOperation.simplify);
CalculatorTestUtils.assertEval("10%", "10%", JsclOperation.simplify);
CalculatorTestUtils.assertEval("0", "eq(0, 1)");
CalculatorTestUtils.assertEval("1", "eq(1, 1)");
CalculatorTestUtils.assertEval("1", "eq( 1, 1)");
CalculatorTestUtils.assertEval("1", "eq( 1, 1)", JsclOperation.simplify);
CalculatorTestUtils.assertEval("1", "lg(10)");
CalculatorTestUtils.assertEval("4", "2+2");
final AngleUnit defaultAngleUnit = cm.getAngleUnits();
try {
cm.setAngleUnits(AngleUnit.rad);
CalculatorTestUtils.assertEval("-0.757", "sin(4)");
CalculatorTestUtils.assertEval("0.524", "asin(0.5)");
CalculatorTestUtils.assertEval("-0.396", "sin(4)asin(0.5)");
CalculatorTestUtils.assertEval("-0.56", "sin(4)asin(0.5)√(2)");
CalculatorTestUtils.assertEval("-0.56", "sin(4)asin(0.5)√(2)");
} finally {
cm.setAngleUnits(defaultAngleUnit);
}
CalculatorTestUtils.assertEval("7.389", "e^2");
CalculatorTestUtils.assertEval("7.389", "exp(1)^2");
CalculatorTestUtils.assertEval("7.389", "exp(2)");
CalculatorTestUtils.assertEval("2+i", "2*1+√(-1)");
try {
cm.setAngleUnits(AngleUnit.rad);
CalculatorTestUtils.assertEval("0.921+Πi", "ln(5cosh(38π√(2cos(2))))");
CalculatorTestUtils.assertEval("-3.41+3.41i", "(5tan(2i)+2i)/(1-i)");
} finally {
cm.setAngleUnits(defaultAngleUnit);
}
CalculatorTestUtils.assertEval("7.389i", "iexp(2)");
CalculatorTestUtils.assertEval("2+7.389i", "2+iexp(2)");
CalculatorTestUtils.assertEval("2+7.389i", "2+√(-1)exp(2)");
CalculatorTestUtils.assertEval("2-2.5i", "2-2.5i");
CalculatorTestUtils.assertEval("-2-2.5i", "-2-2.5i");
CalculatorTestUtils.assertEval("-2+2.5i", "-2+2.5i");
CalculatorTestUtils.assertEval("-2+2.1i", "-2+2.1i");
CalculatorTestUtils.assertEval("-0.1-0.2i", "(1-i)/(2+6i)");
CalculatorTestUtils.assertEval("24", "4!");
CalculatorTestUtils.assertEval("24", "(2+2)!");
CalculatorTestUtils.assertEval("120", "(2+2+1)!");
CalculatorTestUtils.assertEval("24", "(2.0+2.0)!");
CalculatorTestUtils.assertEval("24", "4.0!");
CalculatorTestUtils.assertEval("720", "(3!)!");
CalculatorTestUtils.assertEval("36", Expression.valueOf("3!^2").numeric().toString());
CalculatorTestUtils.assertEval("3", Expression.valueOf("cubic(27)").numeric().toString());
CalculatorTestUtils.assertError("i!");
CalculatorTestUtils.assertEval("1", cm.evaluate( "(π/π)!"));
CalculatorTestUtils.assertError("(-1)i!");
CalculatorTestUtils.assertEval("24i", "4!i");
Locator.getInstance().getEngine().getVarsRegistry().add(new Var.Builder("si", 5d));
try {
cm.setAngleUnits(AngleUnit.rad);
CalculatorTestUtils.assertEval("0.451", "acos(0.8999999999999811)");
CalculatorTestUtils.assertEval("-0.959", "sin(5)");
CalculatorTestUtils.assertEval("-4.795", "sin(5)si");
CalculatorTestUtils.assertEval("-23.973", "sisin(5)si");
CalculatorTestUtils.assertEval("-23.973", "si*sin(5)si");
CalculatorTestUtils.assertEval("-3.309", "sisin(5si)si");
} finally {
cm.setAngleUnits(defaultAngleUnit);
}
Locator.getInstance().getEngine().getVarsRegistry().add(new Var.Builder("s", 1d));
CalculatorTestUtils.assertEval("5", cm.evaluate( "si"));
Locator.getInstance().getEngine().getVarsRegistry().add(new Var.Builder("k", 3.5d));
Locator.getInstance().getEngine().getVarsRegistry().add(new Var.Builder("k1", 4d));
CalculatorTestUtils.assertEval("4", "k11");
Locator.getInstance().getEngine().getVarsRegistry().add(new Var.Builder("t", (String) null));
CalculatorTestUtils.assertEval("11t", "t11");
CalculatorTestUtils.assertEval("11et", "t11e");
CalculatorTestUtils.assertEval("", "");
CalculatorTestUtils.assertEval("", "Infinity");
CalculatorTestUtils.assertEval("11∞t", "t11∞");
CalculatorTestUtils.assertEval("-t+t^3", "t(t-1)(t+1)");
CalculatorTestUtils.assertEval("100", "0.1E3");
CalculatorTestUtils.assertEval("3.957", "ln(8)lg(8)+ln(8)");
CalculatorTestUtils.assertEval("0.933", "0x:E/0x:F");
try {
cm.setNumeralBase(NumeralBase.hex);
CalculatorTestUtils.assertEval("0.EE E", "0x:E/0x:F");
CalculatorTestUtils.assertEval("0.EE E", cm.simplify( "0x:E/0x:F"));
CalculatorTestUtils.assertEval("0.EE E", "E/F");
CalculatorTestUtils.assertEval("0.EE E", cm.simplify( "E/F"));
} finally {
cm.setNumeralBase(NumeralBase.dec);
}
CalculatorTestUtils.assertEval("0", "((((((0))))))");
CalculatorTestUtils.assertEval("0", "((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((0))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))");
/* CalculatorTestUtils.assertEval("0.524", cm.evaluate( "30°").getResult());
CalculatorTestUtils.assertEval("0.524", cm.evaluate( "(10+20)°").getResult());
CalculatorTestUtils.assertEval("1.047", cm.evaluate( "(10+20)°*2").getResult());
try {
CalculatorTestUtils.assertEval("0.278", cm.evaluate( "30°^2").getResult());
fail();
} catch (ParseException e) {
if ( !e.getMessage().equals("Power operation after postfix function is currently unsupported!") ) {
fail();
}
}*//*
*//* try {
cm.setTimeout(5000);
CalculatorTestUtils.assertEval("2", cm.evaluate( "2!").getResult());
} finally {
cm.setTimeout(3000);
}*/
Locator.getInstance().getEngine().getVarsRegistry().add(new Var.Builder("t", (String) null));
CalculatorTestUtils.assertEval("2t", "∂(t^2,t)", JsclOperation.simplify);
CalculatorTestUtils.assertEval("2t", "∂(t^2,t)");
Locator.getInstance().getEngine().getVarsRegistry().add(new Var.Builder("t", "2"));
CalculatorTestUtils.assertEval("2t", "∂(t^2,t)", JsclOperation.simplify);
CalculatorTestUtils.assertEval("4", "∂(t^2,t)");
CalculatorTestUtils.assertEval("-x+xln(x)", "∫(ln(x), x)", JsclOperation.simplify);
CalculatorTestUtils.assertEval("-(x-xln(x))/(ln(2)+ln(5))", "∫(log(10, x), x)", JsclOperation.simplify);
CalculatorTestUtils.assertEval("∫((ln(2)+ln(5))/ln(x), x)", "∫(ln(10)/ln(x), x)", JsclOperation.simplify);
//CalculatorTestUtils.assertEval("∫(ln(10)/ln(x), x)", Expression.valueOf("∫(log(x, 10), x)").expand().toString());
CalculatorTestUtils.assertEval("∫((ln(2)+ln(5))/ln(x), x)", "∫(log(x, 10), x)");
CalculatorTestUtils.assertEval("∫((ln(2)+ln(5))/ln(x), x)", "∫(log(x, 10), x)", JsclOperation.simplify);
}
@Test
public void testFormatting() throws Exception {
final MathEngine ce = Locator.getInstance().getEngine().getMathEngine0();
CalculatorTestUtils.assertEval("12 345", ce.simplify( "12345"));
}
@Test
public void testI() throws ParseException, CalculatorEvalException {
final MathEngine cm = Locator.getInstance().getEngine().getMathEngine0();
CalculatorTestUtils.assertEval("-i", cm.evaluate( "i^3"));
for (int i = 0; i < 1000; i++) {
double real = (Math.random()-0.5) * 1000;
double imag = (Math.random()-0.5) * 1000;
int exp = (int)(Math.random() * 10);
final StringBuilder sb = new StringBuilder();
sb.append(real);
if ( imag > 0 ) {
sb.append("+");
}
sb.append(imag);
sb.append("^").append(exp);
try {
cm.evaluate( sb.toString());
} catch (Throwable e) {
fail(sb.toString());
}
}
}
@Test
public void testEmptyFunction() throws Exception {
final MathEngine cm = Locator.getInstance().getEngine().getMathEngine0();
try {
cm.evaluate( "cos(cos(cos(cos(acos(acos(acos(acos(acos(acos(acos(acos(cos(cos(cos(cos(cosh(acos(cos(cos(cos(cos(cos(acos(acos(acos(acos(acos(acos(acos(acos(cos(cos(cos(cos(cosh(acos(cos())))))))))))))))))))))))))))))))))))))");
Assert.fail();
} catch (ParseException e) {
}
CalculatorTestUtils.assertEval("0.34+1.382i", "ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(100)))))))))))))))");
try {
cm.evaluate( "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();
} catch (ParseException e) {
}
final AngleUnit defaultAngleUnit = cm.getAngleUnits();
try {
cm.setAngleUnits(AngleUnit.rad);
CalculatorTestUtils.assertEval("0.739", cm.evaluate( "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))))))))))))))))))))))))))))))))))))"));
} finally {
cm.setAngleUnits(defaultAngleUnit);
}
Locator.getInstance().getEngine().getVarsRegistry().add(new Var.Builder("si", 5d));
CalculatorTestUtils.assertEval("5", cm.evaluate( "si"));
CalculatorTestUtils.assertError("sin");
}
@Test
public void testRounding() throws Exception {
final MathEngine cm = Locator.getInstance().getEngine().getMathEngine0();
try {
DecimalFormatSymbols decimalGroupSymbols = new DecimalFormatSymbols(Locale.getDefault());
decimalGroupSymbols.setDecimalSeparator('.');
decimalGroupSymbols.setGroupingSeparator('\'');
cm.setDecimalGroupSymbols(decimalGroupSymbols);
cm.setPrecision(2);
CalculatorTestUtils.assertEval("12'345'678.9", cm.evaluate( "1.23456789E7"));
cm.setPrecision(10);
CalculatorTestUtils.assertEval("12'345'678.9", cm.evaluate( "1.23456789E7"));
CalculatorTestUtils.assertEval("123'456'789", cm.evaluate( "1.234567890E8"));
CalculatorTestUtils.assertEval("1'234'567'890.1", cm.evaluate( "1.2345678901E9"));
} finally {
cm.setPrecision(3);
DecimalFormatSymbols decimalGroupSymbols = new DecimalFormatSymbols(Locale.getDefault());
decimalGroupSymbols.setDecimalSeparator('.');
decimalGroupSymbols.setGroupingSeparator(JsclMathEngine.GROUPING_SEPARATOR_DEFAULT.charAt(0));
cm.setDecimalGroupSymbols(decimalGroupSymbols);
}
}
@Test
public void testComparisonFunction() throws Exception {
final MathEngine cm = Locator.getInstance().getEngine().getMathEngine0();
CalculatorTestUtils.assertEval("0", "eq(0, 1)");
CalculatorTestUtils.assertEval("1", "eq(1, 1)");
CalculatorTestUtils.assertEval("1", "eq(1, 1.0)");
CalculatorTestUtils.assertEval("0", "eq(1, 1.000000000000001)");
CalculatorTestUtils.assertEval("0", "eq(1, 0)");
CalculatorTestUtils.assertEval("1", "lt(0, 1)");
CalculatorTestUtils.assertEval("0", "lt(1, 1)");
CalculatorTestUtils.assertEval("0", "lt(1, 0)");
CalculatorTestUtils.assertEval("0", "gt(0, 1)");
CalculatorTestUtils.assertEval("0", "gt(1, 1)");
CalculatorTestUtils.assertEval("1", "gt(1, 0)");
CalculatorTestUtils.assertEval("1", "ne(0, 1)");
CalculatorTestUtils.assertEval("0", "ne(1, 1)");
CalculatorTestUtils.assertEval("1", "ne(1, 0)");
CalculatorTestUtils.assertEval("1", "le(0, 1)");
CalculatorTestUtils.assertEval("1", "le(1, 1)");
CalculatorTestUtils.assertEval("0", "le(1, 0)");
CalculatorTestUtils.assertEval("0", "ge(0, 1)");
CalculatorTestUtils.assertEval("1", "ge(1, 1)");
CalculatorTestUtils.assertEval("1", "ge(1, 0)");
CalculatorTestUtils.assertEval("0", "ap(0, 1)");
CalculatorTestUtils.assertEval("1", "ap(1, 1)");
CalculatorTestUtils.assertEval("0", "ap(1, 0)");
}
@Test
public void testNumeralSystems() throws Exception {
final MathEngine cm = Locator.getInstance().getEngine().getMathEngine0();
CalculatorTestUtils.assertEval("11 259 375", "0x:ABCDEF");
CalculatorTestUtils.assertEval("30 606 154.462", "0x:ABCDEF*e");
CalculatorTestUtils.assertEval("30 606 154.462", "e*0x:ABCDEF");
CalculatorTestUtils.assertEval("e", "e*0x:ABCDEF/0x:ABCDEF");
CalculatorTestUtils.assertEval("30 606 154.462", "0x:ABCDEF*e*0x:ABCDEF/0x:ABCDEF");
CalculatorTestUtils.assertEval("30 606 154.462", "c+0x:ABCDEF*e*0x:ABCDEF/0x:ABCDEF-c+0x:C-0x:C");
CalculatorTestUtils.assertEval("1 446 257 064 651.832", "28*28 * sin(28) - 0b:1101 + √(28) + exp ( 28) ");
CalculatorTestUtils.assertEval("13", "0b:1101");
CalculatorTestUtils.assertError("0b:π");
final NumeralBase defaultNumeralBase = cm.getNumeralBase();
try{
cm.setNumeralBase(NumeralBase.bin);
CalculatorTestUtils.assertEval("101", "10+11");
CalculatorTestUtils.assertEval("0.101", "10/11");
cm.setNumeralBase(NumeralBase.hex);
CalculatorTestUtils.assertEval("63 7B", "56CE+CAD");
CalculatorTestUtils.assertEval("E", "E");
} finally {
cm.setNumeralBase(defaultNumeralBase);
}
}
@Test
public void testLog() throws Exception {
final MathEngine cm = Locator.getInstance().getEngine().getMathEngine0();
CalculatorTestUtils.assertEval("", Expression.valueOf("1/0").numeric().toString());
CalculatorTestUtils.assertEval("", Expression.valueOf("ln(10)/ln(1)").numeric().toString());
// logarithm
CalculatorTestUtils.assertEval("ln(x)/ln(base)", ((CustomFunction) cm.getFunctionsRegistry().get("log")).getContent());
CalculatorTestUtils.assertEval("", "log(1, 10)");
CalculatorTestUtils.assertEval("3.322", "log(2, 10)");
CalculatorTestUtils.assertEval("1.431", "log(5, 10)");
CalculatorTestUtils.assertEval("0.96", "log(11, 10)");
CalculatorTestUtils.assertEval("1/(bln(a))", "∂(log(a, b), b)", JsclOperation.simplify);
CalculatorTestUtils.assertEval("-ln(b)/(aln(a)^2)", "∂(log(a, b), a)", JsclOperation.simplify);
}
}

View File

@@ -0,0 +1,162 @@
package org.solovyev.android.calculator.model;
import jscl.util.ExpressionGenerator;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;
import org.solovyev.android.calculator.CalculatorTestUtils;
import org.solovyev.common.equals.CollectionEqualizer;
import org.solovyev.common.equals.EqualsUtils;
import org.solovyev.common.text.StringUtils;
import java.io.StringWriter;
import java.util.*;
/**
* User: serso
* Date: 11/14/12
* Time: 8:06 PM
*/
public class FunctionsTest {
private static final String xml = "<functions>\n" +
" <functions class=\"java.util.ArrayList\">\n" +
" <function>\n" +
" <name>test</name>\n" +
" <body>x+y</body>\n" +
" <parameterNames class=\"java.util.ArrayList\">\n" +
" <string>x</string>\n" +
" <string>y</string>\n" +
" </parameterNames>\n" +
" <system>false</system>\n" +
" <description>description</description>\n" +
" </function>\n" +
" <function>\n" +
" <name>z_2</name>\n" +
" <body>e^(z_1^2+z_2^2)</body>\n" +
" <parameterNames class=\"java.util.ArrayList\">\n" +
" <string>z_1</string>\n" +
" <string>z_2</string>\n" +
" </parameterNames>\n" +
" <system>true</system>\n" +
" <description></description>\n" +
" </function>\n" +
" <function>\n" +
" <name>z_2</name>\n" +
" <body>e^(z_1^2+z_2^2)</body>\n" +
" <parameterNames class=\"java.util.ArrayList\">\n" +
" <string>z_1</string>\n" +
" <string>z_2</string>\n" +
" </parameterNames>\n" +
" <system>true</system>\n" +
" <description></description>\n" +
" </function>\n" +
" </functions>\n" +
"</functions>";
@Before
public void setUp() throws Exception {
CalculatorTestUtils.staticSetUp();
}
@Test
public void testXml() throws Exception {
final Functions in = new Functions();
AFunction first = new AFunction.Builder("test", "x+y", Arrays.asList("x", "y")).setDescription("description").setSystem(false).create();
in.getEntities().add(first);
AFunction second = new AFunction.Builder("z_2", "e^(z_1^2+z_2^2)", Arrays.asList("z_1", "z_2")).setSystem(true).create();
in.getEntities().add(second);
AFunction third = new AFunction.Builder("z_2", "e^(z_1^2+z_2^2)", Arrays.asList("z_1", "z_2")).setSystem(true).setDescription("").create();
in.getEntities().add(third);
final Functions out = testXml(in, xml);
Assert.assertTrue(!out.getEntities().isEmpty());
final AFunction firstOut = out.getEntities().get(0);
final AFunction secondOut = out.getEntities().get(1);
assertEquals(first, firstOut);
assertEquals(second, secondOut);
}
@NotNull
private Functions testXml(@NotNull Functions in, @Nullable String expectedXml) throws Exception {
final String actualXml = toXml(in);
if (expectedXml != null) {
Assert.assertEquals(expectedXml, actualXml);
}
final Serializer serializer = new Persister();
final Functions out = serializer.read(Functions.class, actualXml);
final String actualXml2 = toXml(out);
Assert.assertEquals(actualXml, actualXml2);
return out;
}
private String toXml(Functions in) throws Exception {
final StringWriter sw = new StringWriter();
final Serializer serializer = new Persister();
serializer.write(in, sw);
return sw.toString();
}
@Test
public void testRandomXml() throws Exception {
final Functions in = new Functions();
final Random random = new Random(new Date().getTime());
ExpressionGenerator generator = new ExpressionGenerator(10);
for ( int i = 0; i < 1000; i++ ) {
final String content = generator.generate();
final String paramsString = StringUtils.generateRandomString(random.nextInt(10));
final List<String> parameterNames = new ArrayList<String>();
for (int j = 0; j < paramsString.length(); j++) {
parameterNames.add(String.valueOf(paramsString.charAt(j)));
}
final AFunction.Builder builder = new AFunction.Builder("test_" + i, content, parameterNames);
if ( random.nextBoolean() ) {
builder.setDescription(StringUtils.generateRandomString(random.nextInt(100)));
}
builder.setSystem(random.nextBoolean());
in.getEntities().add(builder.create());
}
testXml(in, null);
}
private void assertEquals(@NotNull final AFunction expected,
@NotNull AFunction actual) {
//Assert.assertEquals(expected.getId(), actual.getId());
Assert.assertEquals(expected.getContent(), actual.getContent());
Assert.assertEquals(expected.getDescription(), actual.getDescription());
Assert.assertEquals(expected.getName(), actual.getName());
Assert.assertThat(actual.getParameterNames(), new BaseMatcher<List<String>>() {
@Override
public boolean matches(Object item) {
return EqualsUtils.areEqual(expected.getParameterNames(), (List<String>)item, new CollectionEqualizer<String>(null));
}
@Override
public void describeTo(Description description) {
}
});
}
}

View File

@@ -0,0 +1,145 @@
package org.solovyev.android.calculator.model;
import au.com.bytecode.opencsv.CSVReader;
import jscl.JsclMathEngine;
import jscl.MathEngine;
import jscl.math.Expression;
import jscl.text.ParseException;
import jscl.util.ExpressionGeneratorWithInput;
import org.jetbrains.annotations.NotNull;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.solovyev.android.calculator.*;
import org.solovyev.common.Converter;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
/**
* User: serso
* Date: 12/14/11
* Time: 4:16 PM
*/
public class NumeralBaseTest extends AbstractCalculatorTest {
@BeforeClass
public static void staticSetUp() throws Exception {
CalculatorTestUtils.staticSetUp();
Locator.getInstance().getEngine().setPrecision(3);
}
@Test
public void testConversion() throws Exception {
CSVReader reader = null;
try {
final MathEngine me = JsclMathEngine.getInstance();
reader = new CSVReader(new InputStreamReader(NumeralBaseTest.class.getResourceAsStream("/org/solovyev/android/calculator/model/nb_table.csv")), '\t');
// skip first line
reader.readNext();
String[] line = reader.readNext();
for (; line != null; line = reader.readNext()) {
testExpression(line, new DummyExpression());
testExpression(line, new Expression1());
testExpression(line, new Expression2());
testExpression(line, new Expression3());
final String dec = line[0].toUpperCase();
final String hex = "0x:" + line[1].toUpperCase();
final String bin = "0b:" + line[2].toUpperCase();
final List<String> input = new ArrayList<String>();
input.add(dec);
input.add(hex);
input.add(bin);
//System.out.println("Dec: " + dec);
//System.out.println("Hex: " + hex);
//System.out.println("Bin: " + bin);
final ExpressionGeneratorWithInput eg = new ExpressionGeneratorWithInput(input, 20);
final List<String> expressions = eg.generate();
final String decExpression = expressions.get(0);
final String hexExpression = expressions.get(1);
final String binExpression = expressions.get(2);
//System.out.println("Dec expression: " + decExpression);
//System.out.println("Hex expression: " + hexExpression);
//System.out.println("Bin expression: " + binExpression);
final String decResult = Expression.valueOf(decExpression).numeric().toString();
//System.out.println("Dec result: " + decResult);
final String hexResult = Expression.valueOf(hexExpression).numeric().toString();
//System.out.println("Hex result: " + hexResult);
final String binResult = Expression.valueOf(binExpression).numeric().toString();
//System.out.println("Bin result: " + binResult);
Assert.assertEquals("dec-hex: " + decExpression + " : " + hexExpression, decResult, hexResult);
Assert.assertEquals("dec-bin: " + decExpression + " : " + binExpression, decResult, binResult);
}
} finally {
if (reader != null) {
reader.close();
}
}
}
public static void testExpression(@NotNull String[] line, @NotNull Converter<String, String> converter) throws ParseException, CalculatorEvalException, CalculatorParseException {
final String dec = line[0].toUpperCase();
final String hex = "0x:" + line[1].toUpperCase();
final String bin = "0b:" + line[2].toUpperCase();
final String decExpression = converter.convert(dec);
final String decResult = Locator.getInstance().getEngine().getMathEngine().evaluate(decExpression);
final String hexExpression = converter.convert(hex);
final String hexResult = Locator.getInstance().getEngine().getMathEngine().evaluate(hexExpression);
final String binExpression = converter.convert(bin);
final String binResult = Locator.getInstance().getEngine().getMathEngine().evaluate(binExpression);
Assert.assertEquals("dec-hex: " + decExpression + " : " + hexExpression, decResult, hexResult);
Assert.assertEquals("dec-bin: " + decExpression + " : " + binExpression, decResult, binResult);
}
private static class DummyExpression implements Converter<String, String> {
@NotNull
@Override
public String convert(@NotNull String s) {
return s;
}
}
private static class Expression1 implements Converter<String, String> {
@NotNull
@Override
public String convert(@NotNull String s) {
return s + "*" + s;
}
}
private static class Expression2 implements Converter<String, String> {
@NotNull
@Override
public String convert(@NotNull String s) {
return s + "*" + s + " * sin(" + s + ") - 0b:1101";
}
}
private static class Expression3 implements Converter<String, String> {
@NotNull
@Override
public String convert(@NotNull String s) {
return s + "*" + s + " * sin(" + s + ") - 0b:1101 + √(" + s + ") + exp ( " + s + ")";
}
}
}

View File

@@ -0,0 +1,163 @@
/*
* 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.model;
import jscl.JsclMathEngine;
import jscl.NumeralBase;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.solovyev.android.calculator.*;
import org.solovyev.android.calculator.text.TextProcessor;
/**
* User: serso
* Date: 9/26/11
* Time: 12:13 PM
*/
public class ToJsclTextProcessorTest extends AbstractCalculatorTest {
@BeforeClass
public static void staticSetUp() throws Exception {
CalculatorTestUtils.staticSetUp();
}
@Test
public void testSpecialCases() throws CalculatorParseException {
final TextProcessor<PreparedExpression, String> preprocessor = ToJsclTextProcessor.getInstance();
Assert.assertEquals( "3^E10", preprocessor.process("3^E10").toString());
}
@Test
public void testProcess() throws Exception {
final TextProcessor<PreparedExpression, String> preprocessor = ToJsclTextProcessor.getInstance();
Assert.assertEquals( "", preprocessor.process("").toString());
Assert.assertEquals( "()", preprocessor.process("[]").toString());
Assert.assertEquals( "()*()", preprocessor.process("[][]").toString());
Assert.assertEquals( "()*(1)", preprocessor.process("[][1]").toString());
Assert.assertEquals( "(0)*(1)", preprocessor.process("[0][1]").toString());
Assert.assertEquals( "(0)*(1E)", preprocessor.process("[0][1E]").toString());
Assert.assertEquals( "(0)*(1E1)", preprocessor.process("[0][1E1]").toString());
Assert.assertEquals( "(0)*(1E-1)", preprocessor.process("[0][1E-1]").toString());
Assert.assertEquals( "(0)*(1.E-1)", preprocessor.process("[0][1.E-1]").toString());
Assert.assertEquals( "(0)*(2*E-1)", preprocessor.process("[0][2*E-1]").toString());
Assert.assertEquals( "(0)*ln(1)*(2*E-1)", preprocessor.process("[0]ln(1)[2*E-1]").toString());
Assert.assertEquals( "sin(4)*asin(0.5)*√(2)", preprocessor.process("sin(4)asin(0.5)√(2)").toString());
Assert.assertEquals( "sin(4)*cos(5)", preprocessor.process("sin(4)cos(5)").toString());
Assert.assertEquals( "π*sin(4)*π*cos(√(5))", preprocessor.process("πsin(4)πcos(√(5))").toString());
Assert.assertEquals( "π*sin(4)+π*cos(√(5))", preprocessor.process("πsin(4)+πcos(√(5))").toString());
Assert.assertEquals( "π*sin(4)+π*cos(√(5+(√(-1))))", preprocessor.process("πsin(4)+πcos(√(5+i))").toString());
Assert.assertEquals( "π*sin(4.01)+π*cos(√(5+(√(-1))))", preprocessor.process("πsin(4.01)+πcos(√(5+i))").toString());
Assert.assertEquals( "e^π*sin(4.01)+π*cos(√(5+(√(-1))))", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))").toString());
Assert.assertEquals( "e^π*sin(4.01)+π*cos(√(5+(√(-1))))E2", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))E2").toString());
Assert.assertEquals( "e^π*sin(4.01)+π*cos(√(5+(√(-1))))E-2", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))E-2").toString());
Assert.assertEquals( "E2", preprocessor.process("E2").toString());
Assert.assertEquals( "E-2", preprocessor.process("E-2").toString());
Assert.assertEquals( "E-1/2", preprocessor.process("E-1/2").toString());
Assert.assertEquals( "E-1.2", preprocessor.process("E-1.2").toString());
Assert.assertEquals( "E+1.2", preprocessor.process("E+1.2").toString());
Assert.assertEquals( "E(-1.2)", preprocessor.process("E(-1.2)").toString());
Assert.assertEquals( "EE", preprocessor.process("EE").toString());
try {
Locator.getInstance().getEngine().setNumeralBase(NumeralBase.hex);
Assert.assertEquals( "22F*exp(F)", preprocessor.process("22Fexp(F)").toString());
} finally {
Locator.getInstance().getEngine().setNumeralBase(NumeralBase.dec);
}
Assert.assertEquals( "0x:ABCDEF", preprocessor.process("0x:ABCDEF").toString());
Assert.assertEquals( "0x:ABCDEF", preprocessor.process("0x:A BC DEF").toString());
Assert.assertEquals( "0x:ABCDEF", preprocessor.process("0x:A BC DEF").toString());
Assert.assertEquals( "0x:ABCDEF*0*x", preprocessor.process("0x:A BC DEF*0x").toString());
Assert.assertEquals( "0x:ABCDEF001*0*x", preprocessor.process("0x:A BC DEF001*0x").toString());
Assert.assertEquals( "0x:ABCDEF001*0*c", preprocessor.process("0x:A BC DEF001*0c").toString());
Assert.assertEquals( "0x:ABCDEF001*c", preprocessor.process("0x:A BC DEF001*c").toString());
Assert.assertEquals( "0b:1101", preprocessor.process("0b:1101").toString());
Assert.assertEquals( "0x:1C", preprocessor.process("0x:1C").toString());
Assert.assertEquals( "0x:1C", preprocessor.process(" 0x:1C").toString());
Assert.assertEquals( "0x:1C*0x:1C*sin(0x:1C)-0b:1101+√(0x:1C)+exp(0x:1C)", preprocessor.process("0x:1C*0x:1C * sin(0x:1C) - 0b:1101 + √(0x:1C) + exp ( 0x:1C)").toString());
Assert.assertEquals( "0x:1C*0x:1C*sin(0x:1C)-0b:1101+√(0x:1C)+exp(0x:1C)", preprocessor.process("0x:1C*0x:1C * sin(0x:1C) - 0b:1101 + √(0x:1C) + exp ( 0x:1C)").toString());
try {
preprocessor.process("ln()");
Assert.fail();
} catch (CalculatorParseException e) {
}
try {
preprocessor.process("ln()ln()");
Assert.fail();
} catch (CalculatorParseException e) {
}
try {
preprocessor.process("eln()eln()ln()ln()ln()e");
Assert.fail();
} catch (CalculatorParseException e) {
}
try {
preprocessor.process("ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln(ln()))))))))))))))");
Assert.fail();
} catch (CalculatorParseException e) {
}
try {
preprocessor.process("cos(cos(cos(cos(acos(acos(acos(acos(acos(acos(acos(acos(cos(cos(cos(cos(cosh(acos(cos(cos(cos(cos(cos(acos(acos(acos(acos(acos(acos(acos(acos(cos(cos(cos(cos(cosh(acos(cos())))))))))))))))))))))))))))))))))))))");
Assert.fail();
} catch (CalculatorParseException e) {
}
}
@Test
public void testDegrees() throws Exception {
final TextProcessor<PreparedExpression, String> preprocessor = ToJsclTextProcessor.getInstance();
Assert.assertEquals( "", preprocessor.process("").toString());
/* try {
Assert.assertEquals( "π/180", preprocessor.process("°").toString());
} catch (ParseException e) {
if ( !e.getMessage().startsWith("Could not find start of prefix") ){
junit.framework.Assert.fail();
}
}
Assert.assertEquals( "1*π/180", preprocessor.process("1°").toString());
Assert.assertEquals( "20.0*π/180", preprocessor.process("20.0°").toString());
Assert.assertEquals( "sin(30*π/180)", preprocessor.process("sin(30°)").toString());
Assert.assertEquals( "asin(sin(π/6))*π/180", preprocessor.process("asin(sin(π/6))°").toString());
Assert.assertEquals( "1*π/180*sin(1)", preprocessor.process("1°sin(1)").toString());
try {
Assert.assertEquals( "1*π/180^sin(1)", preprocessor.process("1°^sin(1)").toString());
junit.framework.Assert.fail();
} catch (ParseException e) {
if ( !e.getMessage().equals("Power operation after postfix function is currently unsupported!") ) {
junit.framework.Assert.fail();
}
}*/
}
@Test
public void testPostfixFunction() throws Exception {
}
@Test
public void testNumeralBases() throws Exception {
final TextProcessor<PreparedExpression, String> processor = ToJsclTextProcessor.getInstance();
final NumeralBase defaultNumeralBase = JsclMathEngine.getInstance().getNumeralBase();
try{
JsclMathEngine.getInstance().setNumeralBase(NumeralBase.bin);
Assert.assertEquals("101", JsclMathEngine.getInstance().evaluate("10+11"));
JsclMathEngine.getInstance().setNumeralBase(NumeralBase.hex);
Assert.assertEquals("56CE+CAD", processor.process("56CE+CAD").getExpression());
} finally {
JsclMathEngine.getInstance().setNumeralBase(defaultNumeralBase);
}
}
}