From 89f2ff570abd6702782c78af157c9926f6950344 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=80lex=20Magaz=20Gra=C3=A7a?= Date: Mon, 14 Dec 2015 18:27:05 +0100 Subject: [PATCH 1/3] Add instrumentation test for CalculatorEditText. Just basic show/hide tests for now. --- .../test/ui/CalculatorEditTextTest.java | 146 ++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 app/src/androidTest/java/org/gnucash/android/test/ui/CalculatorEditTextTest.java diff --git a/app/src/androidTest/java/org/gnucash/android/test/ui/CalculatorEditTextTest.java b/app/src/androidTest/java/org/gnucash/android/test/ui/CalculatorEditTextTest.java new file mode 100644 index 000000000..141ca5c22 --- /dev/null +++ b/app/src/androidTest/java/org/gnucash/android/test/ui/CalculatorEditTextTest.java @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2012 - 2015 Ngewi Fet + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.gnucash.android.test.ui; + +import android.content.Intent; +import android.database.SQLException; +import android.database.sqlite.SQLiteDatabase; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; +import android.test.ActivityInstrumentationTestCase2; +import android.util.Log; + +import org.gnucash.android.R; +import org.gnucash.android.db.AccountsDbAdapter; +import org.gnucash.android.db.DatabaseHelper; +import org.gnucash.android.db.SplitsDbAdapter; +import org.gnucash.android.db.TransactionsDbAdapter; +import org.gnucash.android.model.Account; +import org.gnucash.android.model.Commodity; +import org.gnucash.android.ui.common.UxArgument; +import org.gnucash.android.ui.transaction.TransactionsActivity; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.Espresso.pressBack; +import static android.support.test.espresso.action.ViewActions.click; +import static android.support.test.espresso.assertion.ViewAssertions.matches; +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static org.hamcrest.Matchers.not; + +// TODO: Find out how to press the keys in the KeyboardView. +@RunWith(AndroidJUnit4.class) +public class CalculatorEditTextTest extends + ActivityInstrumentationTestCase2 { + private static final String DUMMY_ACCOUNT_UID = "transactions-account"; + private static final String DUMMY_ACCOUNT_NAME = "Transactions Account"; + + private static final String TRANSFER_ACCOUNT_NAME = "Transfer account"; + private static final String TRANSFER_ACCOUNT_UID = "transfer_account"; + public static final String CURRENCY_CODE = "USD"; + + private SQLiteDatabase mDb; + private DatabaseHelper mDbHelper; + private AccountsDbAdapter mAccountsDbAdapter; + private TransactionsDbAdapter mTransactionsDbAdapter; + private SplitsDbAdapter mSplitsDbAdapter; + private TransactionsActivity mTransactionsActivity; + + public CalculatorEditTextTest() { + super(TransactionsActivity.class); + } + + @Override + @Before + public void setUp() throws Exception { + super.setUp(); + injectInstrumentation(InstrumentationRegistry.getInstrumentation()); + AccountsActivityTest.preventFirstRunDialogs(getInstrumentation().getTargetContext()); + + + mDbHelper = new DatabaseHelper(getInstrumentation().getTargetContext()); + try { + mDb = mDbHelper.getWritableDatabase(); + } catch (SQLException e) { + Log.e(getClass().getName(), "Error getting database: " + e.getMessage()); + mDb = mDbHelper.getReadableDatabase(); + } + mSplitsDbAdapter = new SplitsDbAdapter(mDb); + mTransactionsDbAdapter = new TransactionsDbAdapter(mDb, mSplitsDbAdapter); + mAccountsDbAdapter = new AccountsDbAdapter(mDb, mTransactionsDbAdapter); + mAccountsDbAdapter.deleteAllRecords(); + + Account account = new Account(DUMMY_ACCOUNT_NAME); + account.setUID(DUMMY_ACCOUNT_UID); + account.setCommodity(Commodity.getInstance(CURRENCY_CODE)); + + Account account2 = new Account(TRANSFER_ACCOUNT_NAME); + account2.setUID(TRANSFER_ACCOUNT_UID); + account2.setCommodity(Commodity.getInstance(CURRENCY_CODE)); + + mAccountsDbAdapter.addRecord(account); + mAccountsDbAdapter.addRecord(account2); + + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.putExtra(UxArgument.SELECTED_ACCOUNT_UID, DUMMY_ACCOUNT_UID); + setActivityIntent(intent); + mTransactionsActivity = getActivity(); + } + + /** + * Checks the calculator keyboard is showed/hided as expected. + */ + @Test + public void testShowingHidingOfCalculatorKeyboard() { + clickOnView(R.id.fab_create_transaction); + + // Giving the focus to the amount field shows the keyboard + onView(withId(R.id.input_transaction_amount)).perform(click()); + onView(withId(R.id.calculator_keyboard)).check(matches(isDisplayed())); + + // Pressing back hides the keyboard (still with focus) + pressBack(); + onView(withId(R.id.calculator_keyboard)).check(matches(not(isDisplayed()))); + + // Clicking the amount field already focused shows the keyboard again + clickOnView(R.id.input_transaction_amount); + onView(withId(R.id.calculator_keyboard)).check(matches(isDisplayed())); + + // Changing the focus to another field hides the keyboard + clickOnView(R.id.input_transaction_name); + onView(withId(R.id.calculator_keyboard)).check(matches(not(isDisplayed()))); + } + + /** + * Simple wrapper for clicking on views with espresso + * @param viewId View resource ID + */ + private void clickOnView(int viewId){ + onView(withId(viewId)).perform(click()); + } + + @Override + @After + public void tearDown() throws Exception { + mTransactionsActivity.finish(); + super.tearDown(); + } +} From ac884e1dc30b70fdb2eeed420598eeafbcf4576a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=80lex=20Magaz=20Gra=C3=A7a?= Date: Thu, 17 Dec 2015 18:36:43 +0100 Subject: [PATCH 2/3] Fix amount text boxes in split editor not getting the focus sometimes. Fixes https://github.com/codinguser/gnucash-android/issues/417 --- .../gnucash/android/ui/util/widget/CalculatorEditText.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/gnucash/android/ui/util/widget/CalculatorEditText.java b/app/src/main/java/org/gnucash/android/ui/util/widget/CalculatorEditText.java index cad60a0b6..dcf01626e 100644 --- a/app/src/main/java/org/gnucash/android/ui/util/widget/CalculatorEditText.java +++ b/app/src/main/java/org/gnucash/android/ui/util/widget/CalculatorEditText.java @@ -159,14 +159,11 @@ public boolean onLongClick(View v) { } }); - // Although it looks redundant having both onClickListener and OnTouchListener, removing - // one of them makes the standard keyboard show up in addition to the calculator one. + // Although this handler doesn't make sense, if removed, the standard keyboard + // shows up in addition to the calculator one when the EditText gets a touch event. setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { - if (!mCalculatorKeyboard.isCustomKeyboardVisible()) - mCalculatorKeyboard.showCustomKeyboard(v); - // XXX: Use dispatchTouchEvent()? onTouchEvent(event); return false; From 4586a62423b832ea41fd0c775424b4ce325ef311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=80lex=20Magaz=20Gra=C3=A7a?= Date: Thu, 17 Dec 2015 19:14:22 +0100 Subject: [PATCH 3/3] Code clean up. --- .../ui/util/widget/CalculatorEditText.java | 71 +++---------------- 1 file changed, 9 insertions(+), 62 deletions(-) diff --git a/app/src/main/java/org/gnucash/android/ui/util/widget/CalculatorEditText.java b/app/src/main/java/org/gnucash/android/ui/util/widget/CalculatorEditText.java index dcf01626e..32857d9f0 100644 --- a/app/src/main/java/org/gnucash/android/ui/util/widget/CalculatorEditText.java +++ b/app/src/main/java/org/gnucash/android/ui/util/widget/CalculatorEditText.java @@ -19,7 +19,6 @@ import android.content.Context; import android.content.res.TypedArray; import android.inputmethodservice.KeyboardView; -import android.support.annotation.XmlRes; import android.text.Editable; import android.text.InputType; import android.text.TextWatcher; @@ -47,12 +46,12 @@ /** * A custom EditText which supports computations and uses a custom calculator keyboard. - *

Afer the view is inflated, make sure to call {@link #bindListeners(KeyboardView)} - * with the view from your layout where the calculator keyboard should be displayed:

+ *

After the view is inflated, make sure to call {@link #bindListeners(KeyboardView)} + * with the view from your layout where the calculator keyboard should be displayed.

* @author Ngewi Fet */ public class CalculatorEditText extends EditText { - CalculatorKeyboard mCalculatorKeyboard; + private CalculatorKeyboard mCalculatorKeyboard; private Commodity mCommodity = Commodity.DEFAULT_COMMODITY; private Context mContext; @@ -63,7 +62,6 @@ public class CalculatorEditText extends EditText { private boolean isContentModified = false; private int mCalculatorKeysLayout; - private KeyboardView mCalculatorKeyboardView; public CalculatorEditText(Context context) { super(context); @@ -121,7 +119,6 @@ public void bindListeners(CalculatorKeyboard calculatorKeyboard){ mCalculatorKeyboard = calculatorKeyboard; mContext = calculatorKeyboard.getContext(); setOnFocusChangeListener(new OnFocusChangeListener() { - // NOTE By setting the on focus listener, we can show the custom keyboard when the edit box gets focus, but also hide it when the edit box loses focus @Override public void onFocusChange(View v, boolean hasFocus) { if (hasFocus) { @@ -174,14 +171,14 @@ public boolean onTouch(View v, MotionEvent event) { } /** - * Initializes listeners on the edittext + * Initializes listeners on the EditText */ public void bindListeners(KeyboardView keyboardView){ bindListeners(new CalculatorKeyboard(mContext, keyboardView, mCalculatorKeysLayout)); } /** - * Returns the calculator keyboard instantiated by this edittext + * Returns the calculator keyboard instantiated by this EditText * @return CalculatorKeyboard */ public CalculatorKeyboard getCalculatorKeyboard(){ @@ -189,57 +186,7 @@ public CalculatorKeyboard getCalculatorKeyboard(){ } /** - * Returns the view Id of the keyboard view - * @return Keyboard view - */ - public KeyboardView getCalculatorKeyboardView() { - return mCalculatorKeyboardView; - } - - /** - * Set the keyboard view used for displaying the keyboard - * @param calculatorKeyboardView Calculator keyboard view - */ - public void setCalculatorKeyboardView(KeyboardView calculatorKeyboardView) { - this.mCalculatorKeyboardView = calculatorKeyboardView; - bindListeners(calculatorKeyboardView); - } - - /** - * Returns the XML resource ID describing the calculator keys layout - * @return XML resource ID - */ - public int getCalculatorKeysLayout() { - return mCalculatorKeysLayout; - } - - /** - * Sets the XML resource describing the layout of the calculator keys - * @param mCalculatorKeysLayout XML resource ID - */ - public void setCalculatorKeysLayout(@XmlRes int mCalculatorKeysLayout) { - this.mCalculatorKeysLayout = mCalculatorKeysLayout; - bindListeners(mCalculatorKeyboardView); - } - - /** - * Sets the calculator keyboard to use for this EditText - * @param keyboard Properly intialized calculator keyobard - */ - public void setCalculatorKeyboard(CalculatorKeyboard keyboard){ - this.mCalculatorKeyboard = keyboard; - } - - /** - * Returns the currency used for computations - * @return ISO 4217 currency - */ - public Commodity getCommodity() { - return mCommodity; - } - - /** - * Sets the commodity to use for calculations + * Sets the commodity to use for calculations. * The commodity determines the number of decimal places used * @param commodity ISO 4217 currency */ @@ -248,8 +195,8 @@ public void setCommodity(Commodity commodity) { } /** - * Evaluates the arithmetic expression in the editText and sets the text property - * @return Result of arithmetic evaluation which is same as text displayed in edittext + * Evaluates the arithmetic expression in the EditText and sets the text property + * @return Result of arithmetic evaluation which is same as text displayed in EditText */ public String evaluate(){ String amountString = getCleanString(); @@ -327,7 +274,7 @@ public BigDecimal getValue(){ } /** - * Set the text to the value of {@code amount} formatted according to the locale + * Set the text to the value of {@code amount} formatted according to the locale. *

The number of decimal places are determined by the currency set to the view, and the * decimal separator is determined by the device locale. There are no thousandths separators.

* @param amount BigDecimal amount