From 10e05d88b05d971ddd58124e59f18cd26b62c50f Mon Sep 17 00:00:00 2001 From: Sergey Solovyev Date: Sat, 13 Oct 2012 14:02:44 +0400 Subject: [PATCH] Tests --- .../calculator/CalculatorEditorImplTest.java | 7 ++ .../AndroidCalculatorEditorView.java | 38 +++++---- .../AndroidCalculatorEditorViewTest.java | 83 +++++++++++++++++++ .../calculator/CalculatorTestUtils.java | 23 ++++- 4 files changed, 132 insertions(+), 19 deletions(-) create mode 100644 calculatorpp/src/test/java/org/solovyev/android/calculator/AndroidCalculatorEditorViewTest.java diff --git a/calculatorpp-core/src/test/java/org/solovyev/android/calculator/CalculatorEditorImplTest.java b/calculatorpp-core/src/test/java/org/solovyev/android/calculator/CalculatorEditorImplTest.java index ae3fcbaf..26b82557 100644 --- a/calculatorpp-core/src/test/java/org/solovyev/android/calculator/CalculatorEditorImplTest.java +++ b/calculatorpp-core/src/test/java/org/solovyev/android/calculator/CalculatorEditorImplTest.java @@ -64,6 +64,13 @@ public class CalculatorEditorImplTest extends AbstractCalculatorTest { 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 diff --git a/calculatorpp/src/main/java/org/solovyev/android/calculator/AndroidCalculatorEditorView.java b/calculatorpp/src/main/java/org/solovyev/android/calculator/AndroidCalculatorEditorView.java index b3d7ba2e..5e4bb32a 100644 --- a/calculatorpp/src/main/java/org/solovyev/android/calculator/AndroidCalculatorEditorView.java +++ b/calculatorpp/src/main/java/org/solovyev/android/calculator/AndroidCalculatorEditorView.java @@ -49,7 +49,7 @@ public class AndroidCalculatorEditorView extends EditText implements SharedPrefe // NOTE: static because super constructor calls some overridden methods (like onSelectionChanged and current lock is not yet created) @NotNull - private static final Object lock = new Object(); + private static final Object viewLock = new Object(); @NotNull private final Handler uiHandler = new Handler(); @@ -154,30 +154,32 @@ public class AndroidCalculatorEditorView extends EditText implements SharedPrefe @Override public void setState(@NotNull final CalculatorEditorViewState viewState) { + synchronized (viewLock) { - final CharSequence text = prepareText(viewState.getText(), highlightText); + final CharSequence text = prepareText(viewState.getText(), highlightText); - uiHandler.post(new Runnable() { - @Override - public void run() { - final AndroidCalculatorEditorView editorView = AndroidCalculatorEditorView.this; - synchronized (lock) { - try { - editorView.viewStateChange = true; - editorView.viewState = viewState; - editorView.setText(text, BufferType.EDITABLE); - editorView.setSelection(viewState.getSelection()); - } finally { - editorView.viewStateChange = false; + uiHandler.post(new Runnable() { + @Override + public void run() { + final AndroidCalculatorEditorView editorView = AndroidCalculatorEditorView.this; + synchronized (viewLock) { + try { + editorView.viewStateChange = true; + editorView.viewState = viewState; + editorView.setText(text, BufferType.EDITABLE); + editorView.setSelection(viewState.getSelection()); + } finally { + editorView.viewStateChange = false; + } } } - } - }); + }); + } } @Override protected void onSelectionChanged(int selStart, int selEnd) { - synchronized (lock) { + synchronized (viewLock) { if (!viewStateChange) { // external text change => need to notify editor super.onSelectionChanged(selStart, selEnd); @@ -187,7 +189,7 @@ public class AndroidCalculatorEditorView extends EditText implements SharedPrefe } public void handleTextChange(Editable s) { - synchronized (lock) { + synchronized (viewLock) { if (!viewStateChange) { // external text change => need to notify editor CalculatorLocatorImpl.getInstance().getEditor().setText(String.valueOf(s)); diff --git a/calculatorpp/src/test/java/org/solovyev/android/calculator/AndroidCalculatorEditorViewTest.java b/calculatorpp/src/test/java/org/solovyev/android/calculator/AndroidCalculatorEditorViewTest.java new file mode 100644 index 00000000..3cdb278c --- /dev/null +++ b/calculatorpp/src/test/java/org/solovyev/android/calculator/AndroidCalculatorEditorViewTest.java @@ -0,0 +1,83 @@ +package org.solovyev.android.calculator; + +import junit.framework.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.solovyev.common.text.StringUtils; + +import java.util.Date; +import java.util.Random; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * User: serso + * Date: 10/13/12 + * Time: 1:11 PM + */ +@RunWith(value = CalculatorppTestRunner.class) +public class AndroidCalculatorEditorViewTest { + + @BeforeClass + public static void staticSetUp() throws Exception { + CalculatorTestUtils.staticSetUp(null); + } + + @Before + public void setUp() throws Exception { + CalculatorActivity context = new CalculatorActivity(); + CalculatorTestUtils.initViews(context); + } + + @Test + public void testAsyncWork() throws Exception { + final int threadNum = 10; + final int count = 10; + final int maxTextLength = 100; + + final Random random = new Random(new Date().getTime()); + final CountDownLatch startLatchLatch = new CountDownLatch(threadNum); + final CountDownLatch finishLatch = new CountDownLatch(threadNum * count); + final AtomicBoolean error = new AtomicBoolean(false); + + for ( int i = 0; i < threadNum; i++ ) { + new Thread(new Runnable() { + @Override + public void run() { + try { + startLatchLatch.await(); + } catch (InterruptedException e) { + System.out.println(e); + error.set(true); + for ( int j = 0; j < count; j++ ) { + finishLatch.countDown(); + } + return; + } + + for ( int j = 0; j < count; j++ ) { + try { + int textLength = random.nextInt(maxTextLength); + CalculatorLocatorImpl.getInstance().getEditor().insert(StringUtils.generateRandomString(textLength), textLength); + } catch (Throwable e) { + System.out.println(e); + error.set(true); + } finally { + finishLatch.countDown(); + } + } + } + }).start(); + startLatchLatch.countDown(); + } + + if ( finishLatch.await(60, TimeUnit.SECONDS) ) { + Assert.assertFalse(error.get()); + } else { + Assert.fail("Too long execution!"); + } + } +} diff --git a/calculatorpp/src/test/java/org/solovyev/android/calculator/CalculatorTestUtils.java b/calculatorpp/src/test/java/org/solovyev/android/calculator/CalculatorTestUtils.java index 5c2fc6bd..32898fb2 100644 --- a/calculatorpp/src/test/java/org/solovyev/android/calculator/CalculatorTestUtils.java +++ b/calculatorpp/src/test/java/org/solovyev/android/calculator/CalculatorTestUtils.java @@ -1,7 +1,9 @@ package org.solovyev.android.calculator; +import android.content.Context; import jscl.JsclMathEngine; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.mockito.Mockito; import org.solovyev.android.calculator.history.CalculatorHistory; @@ -12,11 +14,30 @@ import org.solovyev.android.calculator.history.CalculatorHistory; */ public class CalculatorTestUtils { - public static void staticSetUp() throws Exception { + public static void staticSetUp(@Nullable Context context) throws Exception { CalculatorLocatorImpl.getInstance().init(new CalculatorImpl(), newCalculatorEngine(), Mockito.mock(CalculatorClipboard.class), Mockito.mock(CalculatorNotifier.class), Mockito.mock(CalculatorHistory.class), new SystemOutCalculatorLogger()); CalculatorLocatorImpl.getInstance().getEngine().init(); + + if ( context != null ) { + initViews(context); + } } + public static void initViews(@NotNull Context context) { + final AndroidCalculatorEditorView editor = new AndroidCalculatorEditorView(context); + editor.init(context); + CalculatorLocatorImpl.getInstance().getEditor().setView(editor); + + final AndroidCalculatorDisplayView display = new AndroidCalculatorDisplayView(context); + display.init(context); + CalculatorLocatorImpl.getInstance().getDisplay().setView(display); + } + + public static void staticSetUp() throws Exception { + staticSetUp(null); + } + + @NotNull static CalculatorEngineImpl newCalculatorEngine() { final MathEntityDao mathEntityDao = Mockito.mock(MathEntityDao.class);