From e8f3ef7140c629fe18f1bf6d3e50dbff76fe5a0d Mon Sep 17 00:00:00 2001 From: Billy Brawner Date: Tue, 16 Jan 2018 20:39:38 -0600 Subject: [PATCH] Add autosave test and fix bugs with saving --- .../view/activity/AutosaveTest.java | 173 ++++++++++++++++++ .../simplemarkdown/model/MarkdownFile.java | 1 + .../view/activity/ExplorerActivity.java | 3 +- .../view/activity/MainActivity.java | 25 +-- 4 files changed, 176 insertions(+), 26 deletions(-) create mode 100644 app/src/androidTest/java/com/wbrawner/simplemarkdown/view/activity/AutosaveTest.java diff --git a/app/src/androidTest/java/com/wbrawner/simplemarkdown/view/activity/AutosaveTest.java b/app/src/androidTest/java/com/wbrawner/simplemarkdown/view/activity/AutosaveTest.java new file mode 100644 index 0000000..1de3d0c --- /dev/null +++ b/app/src/androidTest/java/com/wbrawner/simplemarkdown/view/activity/AutosaveTest.java @@ -0,0 +1,173 @@ +package com.wbrawner.simplemarkdown.view.activity; + + +import android.Manifest; +import android.support.test.espresso.DataInteraction; +import android.support.test.espresso.ViewInteraction; +import android.support.test.rule.ActivityTestRule; +import android.support.test.rule.GrantPermissionRule; +import android.support.test.runner.AndroidJUnit4; +import android.test.suitebuilder.annotation.LargeTest; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewParent; + +import com.wbrawner.simplemarkdown.R; + +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.hamcrest.TypeSafeMatcher; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static android.support.test.InstrumentationRegistry.getInstrumentation; +import static android.support.test.espresso.Espresso.onData; +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu; +import static android.support.test.espresso.Espresso.pressBack; +import static android.support.test.espresso.action.ViewActions.click; +import static android.support.test.espresso.action.ViewActions.closeSoftKeyboard; +import static android.support.test.espresso.action.ViewActions.replaceText; +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.withClassName; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static android.support.test.espresso.matcher.ViewMatchers.withParent; +import static android.support.test.espresso.matcher.ViewMatchers.withText; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.anything; +import static org.hamcrest.Matchers.is; + +@LargeTest +@RunWith(AndroidJUnit4.class) +public class AutosaveTest { + + @Rule + public ActivityTestRule mActivityTestRule = new ActivityTestRule<>(SplashActivity.class); + + @Rule + public GrantPermissionRule permissionRule = GrantPermissionRule.grant(Manifest.permission.WRITE_EXTERNAL_STORAGE); + + @Test + public void autosaveTest() { + String dummyFileName = "dummy-autosave.md"; + String realFileName = "test-autosave.md"; + String testText = "This should be automatically saved"; + + // Create a dummy file that we'll later use to provoke the autosave + saveFile(dummyFileName); + + // Then create our actual file that we expect to be automatically saved. + saveFile(realFileName); + + ViewInteraction appCompatEditText3 = onView( + allOf(withId(R.id.markdown_edit), + childAtPosition( + withParent(withId(R.id.pager)), + 0), + isDisplayed())); + appCompatEditText3.perform(click()); + + ViewInteraction appCompatEditText4 = onView( + allOf(withId(R.id.markdown_edit), + childAtPosition( + withParent(withId(R.id.pager)), + 0), + isDisplayed())); + appCompatEditText4.perform(replaceText(testText), closeSoftKeyboard()); + + // Jump back to the dummy file. This should provoke the autosave + openFile(dummyFileName); + + ViewInteraction editText = onView( + allOf(withId( + R.id.markdown_edit), + childAtPosition( + withParent(withId(R.id.pager)), 0), + isDisplayed()) + ); + + // Assert that the text is empty + editText.check(matches(withText(""))); + + // Then re-open the actual file + openFile(realFileName); + + // And assert that we have our expected text (a newline is appended upon reading the file + // so we'll need to account for that here as well) + editText.check(matches(withText(testText + "\n"))); + } + + private void saveFile(String fileName) { + openActionBarOverflowOrOptionsMenu(getInstrumentation().getTargetContext()); + + ViewInteraction appCompatTextView = onView( + allOf(withId(R.id.title), withText("Save"), + childAtPosition( + childAtPosition( + withClassName(is("android.support.v7.view.menu.ListMenuItemView")), + 0), + 0), + isDisplayed())); + appCompatTextView.perform(click()); + + ViewInteraction appCompatEditText = onView( + allOf(withId(R.id.file_name), + childAtPosition( + childAtPosition( + withId(android.R.id.content), + 0), + 3), + isDisplayed())); + appCompatEditText.perform(replaceText(fileName)); + + appCompatEditText.perform(closeSoftKeyboard()); + + ViewInteraction appCompatButton = onView( + allOf(withId(R.id.button_save), + childAtPosition( + childAtPosition( + withId(android.R.id.content), + 0), + 4), + isDisplayed())); + appCompatButton.perform(click()); + } + + private void openFile(String fileName) { + openActionBarOverflowOrOptionsMenu(getInstrumentation().getTargetContext()); + + ViewInteraction openMenuItem = onView( + allOf(withId(R.id.title), withText("Open"), + childAtPosition( + childAtPosition( + withClassName(is("android.support.v7.view.menu.ListMenuItemView")), + 0), + 0), + isDisplayed())); + openMenuItem.perform(click()); + + onView(withText(fileName)) + .perform(click()); + } + + private static Matcher childAtPosition( + final Matcher parentMatcher, final int position) { + + return new TypeSafeMatcher() { + @Override + public void describeTo(Description description) { + description.appendText("Child at position " + position + " in parent "); + parentMatcher.describeTo(description); + } + + @Override + public boolean matchesSafely(View view) { + ViewParent parent = view.getParent(); + return parent instanceof ViewGroup && parentMatcher.matches(parent) + && view.equals(((ViewGroup) parent).getChildAt(position)); + } + }; + } +} diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/model/MarkdownFile.java b/app/src/main/java/com/wbrawner/simplemarkdown/model/MarkdownFile.java index 2282558..a8f347e 100644 --- a/app/src/main/java/com/wbrawner/simplemarkdown/model/MarkdownFile.java +++ b/app/src/main/java/com/wbrawner/simplemarkdown/model/MarkdownFile.java @@ -175,6 +175,7 @@ public class MarkdownFile { try { markdownFile.createNewFile(); } catch (IOException e) { + e.printStackTrace(); return WRITE_ERROR; } } diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/ExplorerActivity.java b/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/ExplorerActivity.java index bcd4908..9b12efd 100644 --- a/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/ExplorerActivity.java +++ b/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/ExplorerActivity.java @@ -31,7 +31,6 @@ public class ExplorerActivity extends AppCompatActivity { private ListView listView; private File[] mounts; private String docsDirPath; - private String defaultDocsDirPath; private int requestCode; private String filePath; private boolean isSave = false; @@ -128,7 +127,7 @@ public class ExplorerActivity extends AppCompatActivity { if (item.isChecked()) { updateListView(mounts[1]); } else { - updateListView(new File(defaultDocsDirPath)); + updateListView(new File(docsDirPath)); } } return true; diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/MainActivity.java b/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/MainActivity.java index b929d87..3619163 100644 --- a/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/MainActivity.java +++ b/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/MainActivity.java @@ -199,29 +199,6 @@ public class MainActivity extends AppCompatActivity } } - private void showSaveDialog() { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(R.string.action_save); - - final EditText input = new EditText(this); - input.setInputType(InputType.TYPE_CLASS_TEXT); - input.setHint(R.string.hint_filename); - input.setText(presenter.getFileName()); - builder.setView(input); - - builder.setPositiveButton("OK", (dialog, which) -> { - if (input.getText().length() > 0) { - presenter.setFileName(input.getText().toString()); - setTitle(presenter.getFileName()); - } - }); - builder.setNegativeButton("Cancel", (dialog, which) -> { - dialog.cancel(); - }); - - builder.show(); - } - @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { @@ -231,7 +208,7 @@ public class MainActivity extends AppCompatActivity if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // Permission granted, open file save dialog - showSaveDialog(); + requestSave(); } else { // Permission denied, do nothing Toast.makeText(MainActivity.this, R.string.no_permissions, Toast.LENGTH_SHORT)