diff --git a/app/src/main/java/org/solovyev/android/calculator/Engine.java b/app/src/main/java/org/solovyev/android/calculator/Engine.java index 5163b492..378c73ce 100644 --- a/app/src/main/java/org/solovyev/android/calculator/Engine.java +++ b/app/src/main/java/org/solovyev/android/calculator/Engine.java @@ -26,6 +26,7 @@ import android.content.Context; import android.content.SharedPreferences; import android.support.annotation.NonNull; import android.support.annotation.StringRes; +import android.support.annotation.VisibleForTesting; import android.text.TextUtils; import com.squareup.otto.Bus; @@ -251,7 +252,8 @@ public class Engine implements SharedPreferences.OnSharedPreferenceChangeListene editor.apply(); } - private void initAsync() { + @VisibleForTesting + void initAsync() { init(variablesRegistry); init(functionsRegistry); init(operatorsRegistry); diff --git a/app/src/main/java/org/solovyev/android/calculator/ToJsclTextProcessor.java b/app/src/main/java/org/solovyev/android/calculator/ToJsclTextProcessor.java index f11c23f7..4ab0fe64 100644 --- a/app/src/main/java/org/solovyev/android/calculator/ToJsclTextProcessor.java +++ b/app/src/main/java/org/solovyev/android/calculator/ToJsclTextProcessor.java @@ -22,17 +22,19 @@ package org.solovyev.android.calculator; -import jscl.math.function.Function; -import jscl.math.function.IConstant; import org.solovyev.android.calculator.math.MathType; import org.solovyev.android.calculator.text.TextProcessor; import org.solovyev.common.msg.MessageType; +import java.util.ArrayList; +import java.util.List; + import javax.annotation.Nonnull; import javax.inject.Inject; import javax.inject.Singleton; -import java.util.ArrayList; -import java.util.List; + +import jscl.math.function.Function; +import jscl.math.function.IConstant; @Singleton public class ToJsclTextProcessor implements TextProcessor { diff --git a/app/src/test/java/org/solovyev/android/calculator/CalculatorMessagesTest.java b/app/src/test/java/org/solovyev/android/calculator/CalculatorMessagesTest.java index e0e87077..7fad927c 100644 --- a/app/src/test/java/org/solovyev/android/calculator/CalculatorMessagesTest.java +++ b/app/src/test/java/org/solovyev/android/calculator/CalculatorMessagesTest.java @@ -1,6 +1,12 @@ package org.solovyev.android.calculator; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; import org.solovyev.common.msg.MessageType; import java.util.Arrays; @@ -10,9 +16,8 @@ import java.util.Locale; import javax.annotation.Nonnull; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - +@Config(constants = BuildConfig.class) +@RunWith(value = RobolectricTestRunner.class) public class CalculatorMessagesTest { private static final Locale[] LOCALES = new Locale[]{ diff --git a/app/src/test/java/org/solovyev/android/calculator/FromJsclSimplifyTextProcessorTest.java b/app/src/test/java/org/solovyev/android/calculator/FromJsclSimplifyTextProcessorTest.java index b175daf3..b74257e7 100644 --- a/app/src/test/java/org/solovyev/android/calculator/FromJsclSimplifyTextProcessorTest.java +++ b/app/src/test/java/org/solovyev/android/calculator/FromJsclSimplifyTextProcessorTest.java @@ -22,32 +22,27 @@ package org.solovyev.android.calculator; +import static org.junit.Assert.assertEquals; + import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; import org.solovyev.android.calculator.text.FromJsclSimplifyTextProcessor; import org.solovyev.android.calculator.variables.CppVariable; -import static org.junit.Assert.assertEquals; - +@Config(constants = BuildConfig.class, manifest = Config.NONE) +@RunWith(RobolectricTestRunner.class) public class FromJsclSimplifyTextProcessorTest { @Test public void testProcess() throws Exception { final Engine engine = Tests.makeEngine(); FromJsclSimplifyTextProcessor tp = new FromJsclSimplifyTextProcessor(engine); - //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))")); engine.getMathEngine().setGroupingSeparator(' '); - //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")); engine.getVariablesRegistry().addOrUpdate(CppVariable.builder("t2.718281828459045", 2).build().toJsclConstant()); engine.getVariablesRegistry().addOrUpdate(CppVariable.builder("t").build().toJsclConstant()); - //Assert.assertEquals("t2.718281828459045e", tp.process("t2.718281828459045*2.718281828459045")); - //Assert.assertEquals("ee", tp.process("2.718281828459045*2.718281828459045")); assertEquals("t×", tp.process("t*")); assertEquals("×t", tp.process("*t")); assertEquals("t2", tp.process("t*2")); diff --git a/app/src/test/java/org/solovyev/android/calculator/Tests.java b/app/src/test/java/org/solovyev/android/calculator/Tests.java index 574534e5..9c0cc4f8 100644 --- a/app/src/test/java/org/solovyev/android/calculator/Tests.java +++ b/app/src/test/java/org/solovyev/android/calculator/Tests.java @@ -1,13 +1,25 @@ package org.solovyev.android.calculator; +import android.content.SharedPreferences; +import android.os.Handler; import android.support.annotation.NonNull; -import jscl.JsclMathEngine; + +import org.mockito.Mockito; +import org.robolectric.RuntimeEnvironment; +import org.solovyev.android.calculator.entities.BaseEntitiesRegistry; import org.solovyev.android.calculator.functions.FunctionsRegistry; import org.solovyev.android.calculator.operators.OperatorsRegistry; import org.solovyev.android.calculator.operators.PostfixFunctionsRegistry; +import org.solovyev.android.io.FileSystem; +import java.io.File; import java.util.concurrent.Executor; +import javax.annotation.Nonnull; + +import dagger.Lazy; +import jscl.JsclMathEngine; + public class Tests { @NonNull @@ -25,10 +37,36 @@ public class Tests { final JsclMathEngine mathEngine = JsclMathEngine.getInstance(); mathEngine.setGroupingSeparator(' '); final Engine engine = new Engine(mathEngine); - engine.postfixFunctionsRegistry = new PostfixFunctionsRegistry(mathEngine); - engine.functionsRegistry = new FunctionsRegistry(mathEngine); - engine.variablesRegistry = new VariablesRegistry(mathEngine); - engine.operatorsRegistry = new OperatorsRegistry(mathEngine); + engine.postfixFunctionsRegistry = init(new PostfixFunctionsRegistry(mathEngine)); + engine.functionsRegistry = init(new FunctionsRegistry(mathEngine)); + engine.variablesRegistry = init(new VariablesRegistry(mathEngine)); + engine.operatorsRegistry = init(new OperatorsRegistry(mathEngine)); + engine.errorReporter = new ErrorReporter() { + @Override + public void onException(@Nonnull Throwable e) { + throw new AssertionError(e); + } + + @Override + public void onError(@Nonnull String message) { + throw new AssertionError(message); + } + }; + engine.initAsync(); return engine; } + + @NonNull + private static > T init(@NonNull T registry) { + registry.preferences = Mockito.mock(SharedPreferences.class); + registry.filesDir = new Lazy() { + @Override + public File get() { + return RuntimeEnvironment.application.getFilesDir(); + } + }; + registry.fileSystem = Mockito.mock(FileSystem.class); + registry.handler = new Handler(); + return registry; + } } diff --git a/app/src/test/java/org/solovyev/android/calculator/ToJsclTextProcessorTest.java b/app/src/test/java/org/solovyev/android/calculator/ToJsclTextProcessorTest.java index 38acd2e5..0285c41c 100644 --- a/app/src/test/java/org/solovyev/android/calculator/ToJsclTextProcessorTest.java +++ b/app/src/test/java/org/solovyev/android/calculator/ToJsclTextProcessorTest.java @@ -22,14 +22,20 @@ package org.solovyev.android.calculator; -import jscl.JsclMathEngine; -import jscl.NumeralBase; -import org.junit.Before; -import org.junit.Test; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; + +import jscl.JsclMathEngine; +import jscl.NumeralBase; + +@Config(constants = BuildConfig.class) +@RunWith(value = RobolectricTestRunner.class) public class ToJsclTextProcessorTest { private ToJsclTextProcessor preprocessor; diff --git a/app/src/test/java/org/solovyev/android/calculator/jscl/FromJsclNumericTextProcessorTest.java b/app/src/test/java/org/solovyev/android/calculator/jscl/FromJsclNumericTextProcessorTest.java index 4484edf5..0f52c1e0 100644 --- a/app/src/test/java/org/solovyev/android/calculator/jscl/FromJsclNumericTextProcessorTest.java +++ b/app/src/test/java/org/solovyev/android/calculator/jscl/FromJsclNumericTextProcessorTest.java @@ -22,14 +22,21 @@ package org.solovyev.android.calculator.jscl; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; +import org.solovyev.android.calculator.BuildConfig; + import jscl.AngleUnit; import jscl.JsclMathEngine; import jscl.math.Expression; import jscl.math.Generic; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; +@Config(constants = BuildConfig.class) +@RunWith(value = RobolectricTestRunner.class) public class FromJsclNumericTextProcessorTest { @Test diff --git a/app/src/test/java/org/solovyev/android/calculator/math/MathTypeTest.java b/app/src/test/java/org/solovyev/android/calculator/math/MathTypeTest.java index b2868fe1..36140bfd 100644 --- a/app/src/test/java/org/solovyev/android/calculator/math/MathTypeTest.java +++ b/app/src/test/java/org/solovyev/android/calculator/math/MathTypeTest.java @@ -22,15 +22,21 @@ package org.solovyev.android.calculator.math; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.solovyev.android.calculator.Engine; -import org.solovyev.android.calculator.Tests; - import static org.junit.Assert.assertEquals; import static org.solovyev.android.calculator.math.MathType.postfix_function; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; +import org.solovyev.android.calculator.BuildConfig; +import org.solovyev.android.calculator.Engine; +import org.solovyev.android.calculator.Tests; + +@Config(constants = BuildConfig.class) +@RunWith(value = RobolectricTestRunner.class) public class MathTypeTest { Engine engine; diff --git a/app/src/test/java/org/solovyev/android/calculator/model/AndroidEngineTest.java b/app/src/test/java/org/solovyev/android/calculator/model/AndroidEngineTest.java index 1ec4fd4e..32324938 100644 --- a/app/src/test/java/org/solovyev/android/calculator/model/AndroidEngineTest.java +++ b/app/src/test/java/org/solovyev/android/calculator/model/AndroidEngineTest.java @@ -162,7 +162,7 @@ public class AndroidEngineTest extends BaseCalculatorTest { assertEval("e", "e*0x:ABCDEF/0x:ABCDEF"); assertEval("30 606 154.462", "0x:ABCDEF*e*0x:ABCDEF/0x:ABCDEF"); assertEval("30 606 154.462", "c+0x:ABCDEF*e*0x:ABCDEF/0x:ABCDEF-c+0x:C-0x:C"); - assertEval("1 446 257 064 651.832", "28*28 * sin(28) - 0b:1101 + √(28) + exp (28)"); + assertEval("1 446 257 064 651.832", "28*28 * sin(28) - 0b:1101 + √(28) + exp(28)"); assertEval("13", "0b:1101"); assertError("0b:π"); @@ -189,7 +189,7 @@ public class AndroidEngineTest extends BaseCalculatorTest { assertEval("∞", Expression.valueOf("ln(10)/ln(1)").numeric().toString()); // logarithm - assertEval("ln(x)/ln(base)", ((CustomFunction) me.getFunctionsRegistry().get("log")).getContent()); + assertEval("ln(x)/ln(base)", ((CustomFunction) me.getFunctionsRegistry().get("log")).getContent(), JsclOperation.simplify); assertEval("∞", "log(1, 10)"); assertEval("3.322", "log(2, 10)"); assertEval("1.431", "log(5, 10)"); diff --git a/app/src/test/java/org/solovyev/android/calculator/model/EvaluateTest.java b/app/src/test/java/org/solovyev/android/calculator/model/EvaluateTest.java index fdc3494f..5b1a2bf3 100644 --- a/app/src/test/java/org/solovyev/android/calculator/model/EvaluateTest.java +++ b/app/src/test/java/org/solovyev/android/calculator/model/EvaluateTest.java @@ -136,12 +136,12 @@ public class EvaluateTest extends BaseCalculatorTest { assertEval("4", "k11"); engine.getVariablesRegistry().addOrUpdate(CppVariable.builder("t").build().toJsclConstant()); - assertEval("11t", "t11"); - assertEval("11et", "t11e"); + assertEval("11t", "t11", JsclOperation.simplify); + assertEval("11et", "t11e", JsclOperation.simplify); assertEval("∞", "∞"); assertEval("∞", "Infinity"); - assertEval("11∞t", "t11∞"); - assertEval("-t+t^3", "t(t-1)(t+1)"); + assertEval("11∞t", "t11∞", JsclOperation.simplify); + assertEval("-t+t^3", "t(t-1)(t+1)", JsclOperation.simplify); assertEval("100", "0.1E3"); assertEval("3.957", "ln(8)lg(8)+ln(8)"); diff --git a/app/src/test/java/org/solovyev/android/calculator/model/NumeralBaseTest.java b/app/src/test/java/org/solovyev/android/calculator/model/NumeralBaseTest.java index 689067c7..859e702a 100644 --- a/app/src/test/java/org/solovyev/android/calculator/model/NumeralBaseTest.java +++ b/app/src/test/java/org/solovyev/android/calculator/model/NumeralBaseTest.java @@ -22,23 +22,32 @@ package org.solovyev.android.calculator.model; -import au.com.bytecode.opencsv.CSVReader; import com.google.common.base.Function; -import jscl.JsclMathEngine; -import jscl.MathEngine; -import jscl.math.Expression; -import jscl.util.ExpressionGeneratorWithInput; + import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; import org.solovyev.android.calculator.BaseCalculatorTest; +import org.solovyev.android.calculator.BuildConfig; import org.solovyev.android.calculator.ParseException; -import javax.annotation.Nonnull; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; +import javax.annotation.Nonnull; + +import au.com.bytecode.opencsv.CSVReader; +import jscl.JsclMathEngine; +import jscl.MathEngine; +import jscl.math.Expression; +import jscl.util.ExpressionGeneratorWithInput; + +@Config(constants = BuildConfig.class) +@RunWith(value = RobolectricTestRunner.class) public class NumeralBaseTest extends BaseCalculatorTest { @Before diff --git a/jscl/src/main/java/org/solovyev/common/msg/Messages.java b/jscl/src/main/java/org/solovyev/common/msg/Messages.java index 27f08506..af6481d0 100644 --- a/jscl/src/main/java/org/solovyev/common/msg/Messages.java +++ b/jscl/src/main/java/org/solovyev/common/msg/Messages.java @@ -22,12 +22,13 @@ package org.solovyev.common.msg; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; import java.text.MessageFormat; import java.util.List; import java.util.Locale; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + public final class Messages { private Messages() { @@ -40,24 +41,22 @@ public final class Messages { } /** - * @param locale locale for which default formatting will be applied - * @param messagePattern message pattern which will be used for {@link MessageFormat} - * @param parameters message parameters which will be used for {@link MessageFormat} - * @return formatted message string according to default locale formatting, nested messages are processed properly - * (for each message from parameter method {@link Message#getLocalizedMessage(Locale)} is called) + * @param locale locale for which default formatting will be applied + * @param pattern message pattern which will be used for {@link MessageFormat} + * @param parameters message parameters which will be used for {@link MessageFormat} + * @return formatted message string according to default locale formatting, nested messages are + * processed properly + * (for each message from parameter method {@link Message#getLocalizedMessage(Locale)} is + * called) */ @Nonnull - public static String prepareMessage(@Nonnull Locale locale, @Nonnull String messagePattern, @Nonnull List parameters) { + public static String prepareMessage(@Nonnull Locale locale, @Nonnull String pattern, @Nonnull List parameters) { String result; if (parameters.isEmpty()) { - result = messagePattern; + result = pattern; } else { - final MessageFormat format = new MessageFormat(messagePattern); - - format.setLocale(locale); - format.applyPattern(messagePattern); - + final MessageFormat format = new MessageFormat(pattern, locale); result = format.format(prepareParameters(parameters, locale)); }