From 2c27a105409a943ce1c73620a76fcbe3b981bc64 Mon Sep 17 00:00:00 2001 From: serso Date: Sun, 9 Oct 2011 20:22:44 +0400 Subject: [PATCH] changes --- AndroidManifest.xml | 38 +++++---- res/drawable/copy.png | Bin 0 -> 3138 bytes res/drawable/heart.png | Bin 0 -> 4778 bytes res/drawable/heart_original.png | Bin 0 -> 20217 bytes res/drawable/paste.png | Bin 1446 -> 3201 bytes res/layout-land/main.xml | 57 +++++++------- res/layout-port/main.xml | 25 +++--- res/layout/calc_copy_button.xml | 15 ++++ res/layout/calc_display.xml | 2 +- res/layout/calc_donate_button.xml | 15 ++++ res/layout/calc_editor.xml | 2 +- res/values-ru/strings.xml | 1 + res/values/strings.xml | 3 +- .../calculator/CalculatorActivity.java | 20 ++++- .../CalculatorDisplayHistoryState.java | 35 ++++++++- .../android/calculator/CalculatorHistory.java | 72 ++++++++++++++++++ .../android/calculator/CalculatorView.java | 66 +++++++++------- .../calculator/EditorHistoryState.java | 18 +++++ .../android/calculator/math/Functions.java | 4 +- .../calculator/model/ToJsclTextProcessor.java | 12 +-- .../view/widgets/DirectionDragButton.java | 18 ++--- .../view/widgets/SoftKeyboardDisabler.java | 50 ++++++++++++ .../model/ToJsclPreprocessorTest.java | 22 ++++-- 23 files changed, 354 insertions(+), 121 deletions(-) create mode 100644 res/drawable/copy.png create mode 100644 res/drawable/heart.png create mode 100644 res/drawable/heart_original.png create mode 100644 res/layout/calc_copy_button.xml create mode 100644 res/layout/calc_donate_button.xml create mode 100644 src/main/java/org/solovyev/android/calculator/CalculatorHistory.java create mode 100644 src/main/java/org/solovyev/android/view/widgets/SoftKeyboardDisabler.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 187f8c57..cf708767 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,27 +1,33 @@ + package="org.solovyev.android.calculator" + versionCode="1" + versionName="1.0"> - + - - - - + + + + - - + + - - - + - + + + + + \ No newline at end of file diff --git a/res/drawable/copy.png b/res/drawable/copy.png new file mode 100644 index 0000000000000000000000000000000000000000..eb5e59c307098c3b7ce8b8ac011336aa64427a6f GIT binary patch literal 3138 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 literal 0 HcmV?d00001 diff --git a/res/drawable/heart.png b/res/drawable/heart.png new file mode 100644 index 0000000000000000000000000000000000000000..7ab281ecdaf74dc48df49b7fd4c7fed3b95ec10a GIT binary patch literal 4778 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 nBIVqlqh7CnpG=DWJ^va2{l4``&)irO ziV&40T%|~nCIw9-LSe*WkRU8VQ&1({G&5-ci2`d$D9OV2Y^aSS4>S!y*@oX9hMg=Dk^>nhr>VepQivaH#Zl{ z^pg4cd0PNf8_#0)Ju@>iKV4p44*UK7_n}be`#>P@{_gH>cy@O74ZmJO_c_+=0)Xob z*45Rqgu7MZF#$+__tLED)O#@Vjg5`0y1JT0qfz$o@W5Oy z7dt#WWOTnmgpN{w1yDSE#~u>^?(+@~4*nU7#k!KH_-vPzl`%z8glL*3dYspFopByS z&d<-;{r&w%pVPFx)z#InU-1|Bn1t zwLrRr3;iv`qI+U*L!<= zK^~oY8X6jeTRENwVCuHEHg<4u(6h6%)3dd;Wxagm+`;>rnwmuZ;5mg+f=f68ARdnk z!Jvri-~$91H#Ka+Ql+J(Lb3snWCo9T1-eWY`3#Q~D&}t$TSA7t*x!SFjTUR0uZx`^#Qn0h$wS&bHfbFRc6bDOaKt! z64}}i=WR7A4)siYDzpWXga_G;MW5A%h-W(rF9&lgP|U>T|s2vFth<8ymuXjPHGP3xErwqoWZ-5?CXj z(i^UqF5^2Lh5mKS%Wt`q%nN|1v3U?MGq!FIa#G9L&vfO@J5)Tax2@>Z@NRE)$E`a9d<|id_+-?*C ziDfp|URYQ#MdEA#Zv1}#54^5_W2UOa zwmL03+=U`>dwaVr0N0^V=x5&lYGUukxIEO2Bn}3Hk=xtbyh#kp+aYn>uwQv?V&_b* zUEQ=i6a!=T0pvwxX_drw!f2c%>&V9I3yeakYZ->iM6w{Q{(_Uil+$6|{ A3;+NC diff --git a/res/layout-land/main.xml b/res/layout-land/main.xml index 114fbc00..72a3b525 100644 --- a/res/layout-land/main.xml +++ b/res/layout-land/main.xml @@ -17,73 +17,68 @@ - + - - - + - + - + + + + - - - + + - - + + - - diff --git a/res/layout-port/main.xml b/res/layout-port/main.xml index de58d175..63210bfb 100644 --- a/res/layout-port/main.xml +++ b/res/layout-port/main.xml @@ -17,15 +17,15 @@ - + - + @@ -65,7 +65,7 @@ - + @@ -75,11 +75,8 @@ - - - - - + + diff --git a/res/layout/calc_copy_button.xml b/res/layout/calc_copy_button.xml new file mode 100644 index 00000000..4ed715d9 --- /dev/null +++ b/res/layout/calc_copy_button.xml @@ -0,0 +1,15 @@ + + + + + \ No newline at end of file diff --git a/res/layout/calc_display.xml b/res/layout/calc_display.xml index 4cd8b0ed..220bc7fc 100644 --- a/res/layout/calc_display.xml +++ b/res/layout/calc_display.xml @@ -8,7 +8,7 @@ + + + + \ No newline at end of file diff --git a/res/layout/calc_editor.xml b/res/layout/calc_editor.xml index 96b36dea..ff0122f2 100644 --- a/res/layout/calc_editor.xml +++ b/res/layout/calc_editor.xml @@ -12,7 +12,7 @@ a:layout_height="0dp"> Отношение длины окружности к диаметру Вещесвтенное число, такое что производная функции f(x) = e^x в точке x = 0 равно 1 Мнимая единица, определённая как i^2 = −1 + Введите новое выражение diff --git a/res/values/strings.xml b/res/values/strings.xml index e531f851..33bb44c2 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -58,5 +58,6 @@ Ratio of any circle\'s circumference to its diameter Unique real number such that the value of the derivative (slope of the tangent line) of the function f(x) = e^x at the point x = 0 is equal to 1 Imaginary unit, defined such that i^2 = −1 - + Enter new expression + Press to copy diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java b/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java index d38b3849..d6651d25 100644 --- a/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java +++ b/src/main/java/org/solovyev/android/calculator/CalculatorActivity.java @@ -7,6 +7,7 @@ package org.solovyev.android.calculator; import android.app.Activity; import android.content.*; +import android.net.Uri; import android.os.Bundle; import android.preference.PreferenceManager; import android.text.ClipboardManager; @@ -100,6 +101,9 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh } private void init() { + + calculatorView = new CalculatorView(this, CalculatorModel.instance); + insertTextReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -128,9 +132,6 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh // todo serso: create serso runtime exception throw new RuntimeException("Could not initialize interpreter!"); } - - this.calculatorView = new CalculatorView(this, CalculatorModel.instance); - initialized = true; } } @@ -191,6 +192,11 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh }); } + @SuppressWarnings({"UnusedDeclaration"}) + public void copyButtonClickHandler(@NotNull View v) { + calculatorView.copyResult(this); + } + @SuppressWarnings({"UnusedDeclaration"}) public void clearButtonClickHandler(@NotNull View v) { calculatorView.clear(); @@ -207,6 +213,14 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh startActivity(new Intent(this, CalculatorVarsActivity.class)); } + @SuppressWarnings({"UnusedDeclaration"}) + public void donateButtonClickHandler(@NotNull View v) { + final String paypalDonateUrl = "https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=se%2esolovyev%40gmail%2ecom&lc=RU&item_name=android%2ecalculator%40se%2esolovyev¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted"; + final Intent i = new Intent(Intent.ACTION_VIEW); + i.setData(Uri.parse(paypalDonateUrl)); + startActivity(i); + } + @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorDisplayHistoryState.java b/src/main/java/org/solovyev/android/calculator/CalculatorDisplayHistoryState.java index e1c05a1c..83106328 100644 --- a/src/main/java/org/solovyev/android/calculator/CalculatorDisplayHistoryState.java +++ b/src/main/java/org/solovyev/android/calculator/CalculatorDisplayHistoryState.java @@ -5,6 +5,7 @@ package org.solovyev.android.calculator; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** @@ -12,19 +13,24 @@ import org.jetbrains.annotations.Nullable; * Date: 9/17/11 * Time: 11:05 PM */ -public class CalculatorDisplayHistoryState extends EditorHistoryState { +public class CalculatorDisplayHistoryState { private boolean valid = true; + @NotNull + private final EditorHistoryState editorHistoryState; + public CalculatorDisplayHistoryState() { + this.editorHistoryState = new EditorHistoryState(); } public CalculatorDisplayHistoryState(boolean valid) { + this.editorHistoryState = new EditorHistoryState(); this.valid = valid; } public CalculatorDisplayHistoryState(int cursorPosition, @Nullable String text, boolean valid) { - super(cursorPosition, text); + this.editorHistoryState = new EditorHistoryState(cursorPosition, text); this.valid = valid; } @@ -35,4 +41,29 @@ public class CalculatorDisplayHistoryState extends EditorHistoryState { public void setValid(boolean valid) { this.valid = valid; } + + public EditorHistoryState getEditorHistoryState() { + return editorHistoryState; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof CalculatorDisplayHistoryState)) return false; + + CalculatorDisplayHistoryState that = (CalculatorDisplayHistoryState) o; + + if (valid != that.valid) return false; + if (editorHistoryState != null ? !editorHistoryState.equals(that.editorHistoryState) : that.editorHistoryState != null) + return false; + + return true; + } + + @Override + public int hashCode() { + int result = (valid ? 1 : 0); + result = 31 * result + (editorHistoryState != null ? editorHistoryState.hashCode() : 0); + return result; + } } diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorHistory.java b/src/main/java/org/solovyev/android/calculator/CalculatorHistory.java new file mode 100644 index 00000000..b0deb3b0 --- /dev/null +++ b/src/main/java/org/solovyev/android/calculator/CalculatorHistory.java @@ -0,0 +1,72 @@ +/* + * 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; +import org.solovyev.common.utils.history.HistoryAction; +import org.solovyev.common.utils.history.HistoryHelper; +import org.solovyev.common.utils.history.SimpleHistoryHelper; + +/** + * User: serso + * Date: 10/9/11 + * Time: 6:35 PM + */ +public enum CalculatorHistory implements HistoryHelper { + + instance; + + private final HistoryHelper historyHelper = new SimpleHistoryHelper(); + + @Override + public boolean isEmpty() { + return this.historyHelper.isEmpty(); + } + + @Override + public CalculatorHistoryState getLastHistoryState() { + return this.historyHelper.getLastHistoryState(); + } + + @Override + public boolean isUndoAvailable() { + return historyHelper.isUndoAvailable(); + } + + @Override + public CalculatorHistoryState undo(@Nullable CalculatorHistoryState currentState) { + return historyHelper.undo(currentState); + } + + @Override + public boolean isRedoAvailable() { + return historyHelper.isRedoAvailable(); + } + + @Override + public CalculatorHistoryState redo(@Nullable CalculatorHistoryState currentState) { + return historyHelper.redo(currentState); + } + + @Override + public boolean isActionAvailable(@NotNull HistoryAction historyAction) { + return historyHelper.isActionAvailable(historyAction); + } + + @Override + public CalculatorHistoryState doAction(@NotNull HistoryAction historyAction, @Nullable CalculatorHistoryState currentState) { + return historyHelper.doAction(historyAction, currentState); + } + + @Override + public void addState(@Nullable CalculatorHistoryState currentState) { + historyHelper.addState(currentState); + } + + +} diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorView.java b/src/main/java/org/solovyev/android/calculator/CalculatorView.java index 8bb34d08..fd597233 100644 --- a/src/main/java/org/solovyev/android/calculator/CalculatorView.java +++ b/src/main/java/org/solovyev/android/calculator/CalculatorView.java @@ -6,6 +6,7 @@ package org.solovyev.android.calculator; import android.app.Activity; +import android.content.Context; import android.os.Handler; import android.text.ClipboardManager; import android.util.Log; @@ -21,11 +22,10 @@ import org.solovyev.android.calculator.model.CalculatorModel; import org.solovyev.android.calculator.model.ParseException; import org.solovyev.android.view.CursorControl; import org.solovyev.android.view.HistoryControl; +import org.solovyev.android.view.widgets.SoftKeyboardDisabler; import org.solovyev.common.utils.MutableObject; import org.solovyev.common.utils.StringUtils; import org.solovyev.common.utils.history.HistoryAction; -import org.solovyev.common.utils.history.HistoryHelper; -import org.solovyev.common.utils.history.SimpleHistoryHelper; /** * User: serso @@ -46,35 +46,43 @@ public class CalculatorView implements CursorControl, HistoryControl history; - public CalculatorView(@NotNull final Activity activity, @NotNull CalculatorModel calculator) { this.calculatorModel = calculator; - this.editor = (CalculatorEditor) activity.findViewById(R.id.editText); + this.editor = (CalculatorEditor) activity.findViewById(R.id.calculatorEditor); + this.editor.setOnTouchListener(new SoftKeyboardDisabler()); - this.display = (CalculatorDisplay) activity.findViewById(R.id.resultEditText); + this.display = (CalculatorDisplay) activity.findViewById(R.id.calculatorDisplay); this.display.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - if (((CalculatorDisplay) v).isValid()) { - final CharSequence text = ((TextView) v).getText(); - if (!StringUtils.isEmpty(text)) { - final ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(Activity.CLIPBOARD_SERVICE); - clipboard.setText(text); - Toast.makeText(activity, activity.getText(R.string.c_result_copied), Toast.LENGTH_SHORT).show(); - } - } + copyResult(activity); } }); - this.history = new SimpleHistoryHelper(); - saveHistoryState(); + + final CalculatorHistoryState lastState = CalculatorHistory.instance.getLastHistoryState(); + if ( lastState == null ) { + saveHistoryState(); + } else { + setCurrentHistoryState(lastState); + } + + } + + public void copyResult(@NotNull Context context) { + if (display.isValid()) { + final CharSequence text = display.getText(); + if (!StringUtils.isEmpty(text)) { + final ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Activity.CLIPBOARD_SERVICE); + clipboard.setText(text); + Toast.makeText(context, context.getText(R.string.c_result_copied), Toast.LENGTH_SHORT).show(); + } + } } private void saveHistoryState() { - history.addState(getCurrentHistoryState()); + CalculatorHistory.instance.addState(getCurrentHistoryState()); } @@ -117,14 +125,14 @@ public class CalculatorView implements CursorControl, HistoryControl allPrefix; static { - final List functions = new ArrayList(Arrays.asList(SIN, SINH, ASIN, ASINH, COS, COSH, ACOS, ACOSH, TAN, TANH, ATAN, ATANH, LOG, LN, MOD, SQRT, SQRT_SIGN, EXP)); + final List functions = new ArrayList(Arrays.asList(SIN, SINH, ASIN, ASINH, COS, COSH, ACOS, ACOSH, TAN, TANH, ATAN, ATANH, LOG, LN, MOD, SQRT, SQRT_SIGN, EXP, E)); Collections.sort(functions, new MathEntityComparator()); allPrefix = functions; } diff --git a/src/main/java/org/solovyev/android/calculator/model/ToJsclTextProcessor.java b/src/main/java/org/solovyev/android/calculator/model/ToJsclTextProcessor.java index 14d49cfe..12b37c9f 100644 --- a/src/main/java/org/solovyev/android/calculator/model/ToJsclTextProcessor.java +++ b/src/main/java/org/solovyev/android/calculator/model/ToJsclTextProcessor.java @@ -39,10 +39,10 @@ class ToJsclTextProcessor implements TextProcessor { sb.append(')'); } else if (ch == '×' || ch == '∙') { sb.append("*"); - } else if ( mathType == MathType.function ){ + } else if (mathType == MathType.function) { sb.append(toJsclFunction(mathTypeResult.getMatch())); i += mathTypeResult.getMatch().length() - 1; - } else if ( mathType == MathType.constant ) { + } else if (mathType == MathType.constant) { sb.append(mathTypeResult.getMatch()); i += mathTypeResult.getMatch().length() - 1; } else { @@ -148,6 +148,8 @@ class ToJsclTextProcessor implements TextProcessor { result = Functions.LOG; } else if (function.equals(Functions.SQRT_SIGN)) { result = Functions.SQRT; + } else if (function.equals(Functions.E)) { + result = Functions.E_POWER; } else { result = function; } @@ -178,9 +180,9 @@ class ToJsclTextProcessor implements TextProcessor { @NotNull private static MathType.Result checkMultiplicationSignBeforeFunction(@NotNull StringBuilder sb, - @NotNull String s, - int i, - @Nullable MathType.Result mathTypeBeforeResult) { + @NotNull String s, + int i, + @Nullable MathType.Result mathTypeBeforeResult) { MathType.Result result = MathType.getType(s, i); if (i > 0) { diff --git a/src/main/java/org/solovyev/android/view/widgets/DirectionDragButton.java b/src/main/java/org/solovyev/android/view/widgets/DirectionDragButton.java index a5ad49ab..1a41e425 100644 --- a/src/main/java/org/solovyev/android/view/widgets/DirectionDragButton.java +++ b/src/main/java/org/solovyev/android/view/widgets/DirectionDragButton.java @@ -13,8 +13,6 @@ import android.text.TextPaint; import android.util.AttributeSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.solovyev.android.view.widgets.DragButton; -import org.solovyev.android.view.widgets.DragDirection; import org.solovyev.common.utils.Point2d; import org.solovyev.common.utils.StringUtils; @@ -101,11 +99,11 @@ public class DirectionDragButton extends DragButton { initUpDownTextPaint(basePaint); if (textUp != null) { - textUpPosition = getTextPosition(upDownTextPaint, basePaint, textUp, 1); + textUpPosition = getTextPosition(upDownTextPaint, basePaint, textUp, getText(), 1, getWidth(), getHeight()); } if (textDown != null) { - textDownPosition = getTextPosition(upDownTextPaint, basePaint, textDown, -1); + textDownPosition = getTextPosition(upDownTextPaint, basePaint, textDown, getText(), -1, getWidth(), getHeight()); } if ( textDownPosition != null && textUpPosition != null ) { @@ -118,21 +116,21 @@ public class DirectionDragButton extends DragButton { } - private Point2d getTextPosition(@NotNull Paint paint, @NotNull Paint basePaint, @NotNull CharSequence text, float direction) { + public static Point2d getTextPosition(@NotNull Paint paint, @NotNull Paint basePaint, @NotNull CharSequence text, CharSequence baseText, float direction, int w, int h) { final Point2d result = new Point2d(); float width = paint.measureText(text.toString() + " "); - result.setX(getWidth() - width); + result.setX(w - width); float selfHeight = paint.ascent() + paint.descent(); - basePaint.measureText(StringUtils.getNotEmpty(getText(), "|")); + basePaint.measureText(StringUtils.getNotEmpty(baseText, "|")); - float height = getHeight() - basePaint.ascent() - basePaint.descent(); + float height = h - basePaint.ascent() - basePaint.descent(); if (direction < 0) { - result.setY(height / 2 - direction * height / 3 + selfHeight); + result.setY(height / 2 + height / 3 + selfHeight); } else { - result.setY(height / 2 - direction * height / 3); + result.setY(height / 2 - height / 3); } return result; diff --git a/src/main/java/org/solovyev/android/view/widgets/SoftKeyboardDisabler.java b/src/main/java/org/solovyev/android/view/widgets/SoftKeyboardDisabler.java new file mode 100644 index 00000000..b0f04776 --- /dev/null +++ b/src/main/java/org/solovyev/android/view/widgets/SoftKeyboardDisabler.java @@ -0,0 +1,50 @@ +/* + * 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.view.widgets; + +import android.text.InputType; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.EditText; + +/** + * User: serso + * Date: 10/9/11 + * Time: 4:27 PM + */ +public class SoftKeyboardDisabler implements View.OnTouchListener { + + @Override + public boolean onTouch(View v, MotionEvent event) { + boolean result; + Log.d(this.getClass().getName(), "org.solovyev.android.view.widgets.SoftKeyboardDisabler.onTouch(): action=" + event.getAction() + ", event=" + event); + + if (v instanceof EditText) { + final EditText editText = (EditText) v; + int inputType = editText.getInputType(); + int selectionStart = editText.getSelectionStart(); + int selectionEnd = editText.getSelectionEnd(); + + // disable soft input + editText.setInputType(InputType.TYPE_NULL); + editText.onTouchEvent(event); + + // restore input type + editText.setInputType(inputType); + editText.setSelection(selectionStart, selectionEnd); + + result = true; + } else { + result = false; + } + + return result; + } + + +} diff --git a/src/test/java/org/solovyev/android/calculator/model/ToJsclPreprocessorTest.java b/src/test/java/org/solovyev/android/calculator/model/ToJsclPreprocessorTest.java index 977841dd..9be3b77f 100644 --- a/src/test/java/org/solovyev/android/calculator/model/ToJsclPreprocessorTest.java +++ b/src/test/java/org/solovyev/android/calculator/model/ToJsclPreprocessorTest.java @@ -7,6 +7,7 @@ package org.solovyev.android.calculator.model; import org.junit.Assert; +import org.junit.BeforeClass; import org.junit.Test; /** @@ -16,16 +17,23 @@ import org.junit.Test; */ public class ToJsclPreprocessorTest { + @BeforeClass + public static void setUp() throws Exception { + CalculatorModel.instance.init(null); + } + @Test public void testProcess() throws Exception { final ToJsclTextProcessor preprocessor = new ToJsclTextProcessor(); Assert.assertEquals( "sin(4)*cos(5)", preprocessor.process("sin(4)cos(5)")); - Assert.assertEquals( "pi*sin(4)*pi*cos(sqrt(5))", preprocessor.process("πsin(4)πcos(√(5))")); - Assert.assertEquals( "pi*sin(4)+pi*cos(sqrt(5))", preprocessor.process("πsin(4)+πcos(√(5))")); - Assert.assertEquals( "pi*sin(4)+pi*cos(sqrt(5+sqrt(-1)))", preprocessor.process("πsin(4)+πcos(√(5+i))")); - Assert.assertEquals( "pi*sin(4.01)+pi*cos(sqrt(5+sqrt(-1)))", preprocessor.process("πsin(4.01)+πcos(√(5+i))")); - Assert.assertEquals( "exp(1)^pi*sin(4.01)+pi*cos(sqrt(5+sqrt(-1)))", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))")); + Assert.assertEquals( "3.141592653589793*sin(4)*3.141592653589793*cos(sqrt(5))", preprocessor.process("πsin(4)πcos(√(5))")); + Assert.assertEquals( "3.141592653589793*sin(4)+3.141592653589793*cos(sqrt(5))", preprocessor.process("πsin(4)+πcos(√(5))")); + Assert.assertEquals( "3.141592653589793*sin(4)+3.141592653589793*cos(sqrt(5+sqrt(-1)))", preprocessor.process("πsin(4)+πcos(√(5+i))")); + Assert.assertEquals( "3.141592653589793*sin(4.01)+3.141592653589793*cos(sqrt(5+sqrt(-1)))", preprocessor.process("πsin(4.01)+πcos(√(5+i))")); + Assert.assertEquals( "2.718281828459045^3.141592653589793*sin(4.01)+3.141592653589793*cos(sqrt(5+sqrt(-1)))", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))")); + Assert.assertEquals( "2.718281828459045^3.141592653589793*sin(4.01)+3.141592653589793*cos(sqrt(5+sqrt(-1)))*10^2", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))E2")); + Assert.assertEquals( "2.718281828459045^3.141592653589793*sin(4.01)+3.141592653589793*cos(sqrt(5+sqrt(-1)))*10^-2", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))E-2")); } @Test @@ -44,7 +52,7 @@ public class ToJsclPreprocessorTest { Assert.assertEquals(4, preprocessor.getPostfixFunctionStart("2.23+(5.4434234*sin(5.1+1))!", 26)); Assert.assertEquals(0, preprocessor.getPostfixFunctionStart("sin(5)!", 5)); Assert.assertEquals(0, preprocessor.getPostfixFunctionStart("sin(5sin(5sin(5)))!", 17)); - Assert.assertEquals(1, preprocessor.getPostfixFunctionStart("2+sin(5sin(5sin(5)))!", 19)); - Assert.assertEquals(4, preprocessor.getPostfixFunctionStart("2.23+sin(5.4434234*sin(5.1+1))!", 29)); + Assert.assertEquals(2, preprocessor.getPostfixFunctionStart("2+sin(5sin(5sin(5)))!", 19)); + Assert.assertEquals(5, preprocessor.getPostfixFunctionStart("2.23+sin(5.4434234*sin(5.1+1))!", 29)); } }