From df23339dba64f1d8208074566d1db1fdd134516f Mon Sep 17 00:00:00 2001 From: Dimitry Ivanov Date: Sat, 11 Jul 2020 19:52:12 +0300 Subject: [PATCH] Sample app, all samples test --- app-sample/README.md | 48 ++++++- app-sample/build.gradle | 6 + .../main/java/io/noties/markwon/app/App.kt | 3 +- .../app/samples/SimpleExtensionSample.java | 6 +- .../app/samples/html/HtmlDetailsSample.java | 2 +- .../noties/markwon/app/utils/SampleUtils.java | 19 ++- .../layout/view_html_details_text_view.xml | 2 +- .../java/io/noties/markwon/app/AllSamples.kt | 125 ++++++++++++++++++ app-sample/src/test/resources/samples.json | 1 + 9 files changed, 198 insertions(+), 14 deletions(-) create mode 100644 app-sample/src/test/java/io/noties/markwon/app/AllSamples.kt create mode 120000 app-sample/src/test/resources/samples.json diff --git a/app-sample/README.md b/app-sample/README.md index f9056622..ffb738fb 100644 --- a/app-sample/README.md +++ b/app-sample/README.md @@ -1,5 +1,33 @@ # Markwon sample app +## Distribution + +Sample app is distributed via special parent-less branch [sample-store](https://github.com/noties/Markwon/tree/sample-store). +Inside the app, under version badges, tap `CHECK FOR UPDATES` to check for updates. Sample app +is not attached to main libraries versions and can be _released_ independently. + +Application is signed with `keystore.jks`, which fingerprints are: +* __SHA1__: `BA:70:A5:D2:40:65:F1:FA:88:90:59:BA:FC:B7:31:81:E6:37:D9:41` +* __SHA256__: `82:C9:61:C5:DF:35:B1:CB:29:D5:48:83:FB:EB:9F:3E:7D:52:67:63:4F:D2:CE:0A:2D:70:17:85:FF:48:67:51` + +[Download latest APK](https://github.com/noties/Markwon/raw/sample-store/markwon-debug.apk) + +## Deeplink + +Sample app handles special `markwon` scheme: +* `markwon://sample/{ID}` to open specific sample given the `{ID}` +* `markwon://search?q={TEXT TO SEARCH}&a={ARTIFACT}&t={TAG}` + +Please note that search deeplink can have one of type: artifact or tag (if both are specified artifact will be used). + +To test locally: + +``` +adb shell am start -a android.intent.action.ACTION_VIEW -d markwon://sample/ID +``` + +Please note that you might need to _url encode_ the `-d` argument + ## Building When adding/removing samples _most likely_ a clean build would be required. @@ -7,6 +35,22 @@ First, for annotation processor to create `samples.json`. And secondly, in order for Android Gradle plugin to bundle resources references via symbolic links (the `sample.json` itself and `io.noties.markwon.app.samples.*` directory) -```gradle +``` ./gradlew :app-s:clean :app-s:asDe -``` \ No newline at end of file +``` + + +## Tests + +This app uses [Robolectric](https://robolectric.org)(v3.8) for tests which is incompatible +with JDK > 1.8. In order to run tests from command line with IDEA-bundled JDK - a special argument is +required: + +``` +./gradlew :app-s:testDe -Dorg.gradle.java.home="{INSERT BUNDLED JDK PATH HERE}" +``` + +To obtain bundled JDK: +* open `Project Structure...` +* open `SDK Location` +* copy contents of the field under `JDK Location` \ No newline at end of file diff --git a/app-sample/build.gradle b/app-sample/build.gradle index 2cdb4126..8b838383 100644 --- a/app-sample/build.gradle +++ b/app-sample/build.gradle @@ -139,4 +139,10 @@ dependencies { implementation it['android-svg'] implementation it['android-gif-impl'] } + + deps['test'].with { + testImplementation it['junit'] + testImplementation it['robolectric'] + testImplementation it['mockito'] + } } diff --git a/app-sample/src/main/java/io/noties/markwon/app/App.kt b/app-sample/src/main/java/io/noties/markwon/app/App.kt index 55c08b9a..682a7a20 100644 --- a/app-sample/src/main/java/io/noties/markwon/app/App.kt +++ b/app-sample/src/main/java/io/noties/markwon/app/App.kt @@ -14,7 +14,8 @@ import java.util.concurrent.ExecutorService import java.util.concurrent.Executors @Suppress("unused") -class App : Application() { +// `open` is required for tests (to create a spy mockito instance) +open class App : Application() { override fun onCreate() { super.onCreate() diff --git a/app-sample/src/main/java/io/noties/markwon/app/samples/SimpleExtensionSample.java b/app-sample/src/main/java/io/noties/markwon/app/samples/SimpleExtensionSample.java index 9ab1484a..bf081e14 100644 --- a/app-sample/src/main/java/io/noties/markwon/app/samples/SimpleExtensionSample.java +++ b/app-sample/src/main/java/io/noties/markwon/app/samples/SimpleExtensionSample.java @@ -26,7 +26,9 @@ public class SimpleExtensionSample extends MarkwonTextViewSample { "# SimpleExt\n" + "\n" + "+let's start with `+`, ??then we can use this, and finally @@this$$??+"; - ; + + // NB! we cannot have multiple delimiter processor with the same character + // (even if lengths are different) final Markwon markwon = Markwon.builder(context) .usePlugin(SimpleExtPlugin.create(plugin -> { @@ -36,7 +38,7 @@ public class SimpleExtensionSample extends MarkwonTextViewSample { .addExtension( 2, '@', - '?', + '$', (configuration, props) -> new ForegroundColorSpan(Color.RED) ); })) diff --git a/app-sample/src/main/java/io/noties/markwon/app/samples/html/HtmlDetailsSample.java b/app-sample/src/main/java/io/noties/markwon/app/samples/html/HtmlDetailsSample.java index dba85a94..6f57ff9d 100644 --- a/app-sample/src/main/java/io/noties/markwon/app/samples/html/HtmlDetailsSample.java +++ b/app-sample/src/main/java/io/noties/markwon/app/samples/html/HtmlDetailsSample.java @@ -162,7 +162,7 @@ public class HtmlDetailsSample extends MarkwonSample { private TextView appendTextView() { final View view = LayoutInflater.from(context) .inflate(R.layout.view_html_details_text_view, content, false); - final TextView textView = view.findViewById(R.id.text); + final TextView textView = view.findViewById(R.id.text_view); content.addView(view); return textView; } diff --git a/app-sample/src/main/java/io/noties/markwon/app/utils/SampleUtils.java b/app-sample/src/main/java/io/noties/markwon/app/utils/SampleUtils.java index 2f500f9b..c25c7dbc 100644 --- a/app-sample/src/main/java/io/noties/markwon/app/utils/SampleUtils.java +++ b/app-sample/src/main/java/io/noties/markwon/app/utils/SampleUtils.java @@ -19,19 +19,24 @@ public abstract class SampleUtils { @NonNull public static List readSamples(@NonNull Context context) { - final Gson gson = new Gson(); - try (InputStream inputStream = context.getAssets().open("samples.json")) { - return gson.fromJson( - new InputStreamReader(inputStream), - new TypeToken>() { - }.getType() - ); + return readSamples(inputStream); } catch (IOException e) { throw new RuntimeException(e); } } + // NB! stream is not closed by this method + @NonNull + public static List readSamples(@NonNull InputStream inputStream) { + final Gson gson = new Gson(); + return gson.fromJson( + new InputStreamReader(inputStream), + new TypeToken>() { + }.getType() + ); + } + private SampleUtils() { } } diff --git a/app-sample/src/main/res/layout/view_html_details_text_view.xml b/app-sample/src/main/res/layout/view_html_details_text_view.xml index 36775ea9..f42e1b6c 100644 --- a/app-sample/src/main/res/layout/view_html_details_text_view.xml +++ b/app-sample/src/main/res/layout/view_html_details_text_view.xml @@ -1,6 +1,6 @@ (eq(R.id.text_view))) + .thenReturn(textView) + + `when`(findViewById(eq(R.id.edit_text))) + .thenReturn(mock(EditText::class.java)) + + // scrollView + `when`(findViewById(eq(R.id.scroll_view))) + .thenReturn(mock(ScrollView::class.java)) + + // recyclerView + `when`(findViewById(eq(R.id.recycler_view))) + .thenReturn(mock(RecyclerView::class.java)) + + // html-details ViewGroup + `when`(findViewById(R.id.content)) + .thenReturn(mock(ViewGroup::class.java)) + + // special editor views + arrayOf( + R.id.bold, + R.id.italic, + R.id.strike, + R.id.quote, + R.id.code) + .forEach { + val button = mock(Button::class.java).apply { + `when`(text).thenReturn("") + } + `when`(findViewById