Skip to content

Commit 14023e5

Browse files
authored
Merge pull request #134 from PSPDFKit/reinhard/automated-testing
Add automated tests for Android wrapper
2 parents 3009bbe + ea72905 commit 14023e5

File tree

16 files changed

+1020
-15
lines changed

16 files changed

+1020
-15
lines changed

android/src/main/java/com/pspdfkit/react/PSPDFKitPackage.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public class PSPDFKitPackage implements ReactPackage {
3131
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
3232
List<NativeModule> modules = new ArrayList<>();
3333
modules.add(new PSPDFKitModule(reactContext));
34+
modules.add(new TestingModule(reactContext));
3435
return modules;
3536
}
3637

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.pspdfkit.react;
2+
3+
import android.support.annotation.NonNull;
4+
5+
import com.facebook.react.bridge.ReactApplicationContext;
6+
import com.facebook.react.bridge.ReactContextBaseJavaModule;
7+
import com.facebook.react.bridge.ReactMethod;
8+
9+
import java.util.HashMap;
10+
11+
public class TestingModule extends ReactContextBaseJavaModule {
12+
13+
private static final HashMap<String, String> values = new HashMap<>();
14+
15+
public TestingModule(ReactApplicationContext reactContext) {
16+
super(reactContext);
17+
}
18+
19+
@Override
20+
public String getName() {
21+
return "TestingModule";
22+
}
23+
24+
@ReactMethod
25+
public void setValue(@NonNull String key, @NonNull String value) {
26+
synchronized (values) {
27+
values.put(key, value);
28+
values.notifyAll();
29+
}
30+
}
31+
32+
public static void resetValues() {
33+
synchronized (values) {
34+
values.clear();
35+
}
36+
}
37+
38+
public static String getValue(@NonNull String key) throws InterruptedException {
39+
synchronized (values) {
40+
if (!values.containsKey(key)) {
41+
values.wait(60000);
42+
if (!values.containsKey(key)) {
43+
throw new IllegalArgumentException("Key " + key + " was not found. Got: " + values.toString());
44+
}
45+
}
46+
return values.get(key);
47+
}
48+
}
49+
}

android/src/main/java/com/pspdfkit/react/events/PdfViewDataReturnedEvent.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ public class PdfViewDataReturnedEvent extends Event<PdfViewDataReturnedEvent> {
2222

2323
public static final String EVENT_NAME = "pdfViewDataReturned";
2424

25+
private final int requestId;
2526
private final WritableMap payload;
2627

2728
public PdfViewDataReturnedEvent(@IdRes int viewId, int requestId, @NonNull List<Annotation> annotationsToSerialize) {
2829
super(viewId);
30+
this.requestId = requestId;
2931
Map<String, Object> map = new HashMap<>();
3032
map.put("requestId", requestId);
3133
try {
@@ -47,6 +49,7 @@ public PdfViewDataReturnedEvent(@IdRes int viewId, int requestId, @NonNull List<
4749

4850
public PdfViewDataReturnedEvent(@IdRes int viewId, int requestId, @NonNull JSONObject jsonObject) {
4951
super(viewId);
52+
this.requestId = requestId;
5053
Map<String, Object> map = new HashMap<>();
5154
map.put("requestId", requestId);
5255

@@ -61,7 +64,7 @@ public PdfViewDataReturnedEvent(@IdRes int viewId, int requestId, @NonNull JSONO
6164

6265
public PdfViewDataReturnedEvent(@IdRes int viewId, int requestId, @NonNull Throwable throwable) {
6366
super(viewId);
64-
67+
this.requestId = requestId;
6568
payload = Arguments.createMap();
6669
payload.putInt("requestId", requestId);
6770
payload.putString("error", throwable.getMessage());
@@ -76,4 +79,9 @@ public String getEventName() {
7679
public void dispatch(RCTEventEmitter rctEventEmitter) {
7780
rctEventEmitter.receiveEvent(getViewTag(), getEventName(), payload);
7881
}
82+
83+
@Override
84+
public short getCoalescingKey() {
85+
return (short) requestId;
86+
}
7987
}

android/src/main/java/com/pspdfkit/views/PdfView.java

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,16 @@
4949
import java.util.List;
5050
import java.util.concurrent.Callable;
5151

52+
import io.reactivex.ObservableSource;
5253
import io.reactivex.Single;
5354
import io.reactivex.android.schedulers.AndroidSchedulers;
55+
import io.reactivex.disposables.CompositeDisposable;
5456
import io.reactivex.disposables.Disposable;
5557
import io.reactivex.functions.Action;
5658
import io.reactivex.functions.Consumer;
59+
import io.reactivex.functions.Function;
5760
import io.reactivex.schedulers.Schedulers;
61+
import io.reactivex.subjects.BehaviorSubject;
5862

5963
/**
6064
* This view displays a {@link com.pspdfkit.ui.PdfFragment} and all associated toolbars.
@@ -79,7 +83,12 @@ public class PdfView extends FrameLayout {
7983

8084
private PdfThumbnailBar pdfThumbnailBar;
8185

86+
@NonNull
87+
private CompositeDisposable pendingFragmentActions = new CompositeDisposable();
88+
89+
@Nullable
8290
private PdfFragment fragment;
91+
private BehaviorSubject<PdfFragment> fragmentGetter = BehaviorSubject.create();
8392

8493
public PdfView(@NonNull Context context) {
8594
super(context);
@@ -218,6 +227,7 @@ private void setupFragment() {
218227
}
219228

220229
fragment = pdfFragment;
230+
fragmentGetter.onNext(fragment);
221231
}
222232
}
223233

@@ -280,6 +290,10 @@ public void removeFragment() {
280290
isActive = false;
281291

282292
fragment = null;
293+
fragmentGetter.onComplete();
294+
fragmentGetter = BehaviorSubject.create();
295+
pendingFragmentActions.dispose();
296+
pendingFragmentActions = new CompositeDisposable();
283297
}
284298

285299
void manuallyLayoutChildren() {
@@ -330,15 +344,25 @@ public EventDispatcher getEventDispatcher() {
330344
}
331345

332346
public void enterAnnotationCreationMode() {
333-
if (fragment != null) {
334-
fragment.enterAnnotationCreationMode();
335-
}
347+
pendingFragmentActions.add(fragmentGetter.take(1)
348+
.observeOn(Schedulers.io())
349+
.subscribe(new Consumer<PdfFragment>() {
350+
@Override
351+
public void accept(PdfFragment pdfFragment) {
352+
pdfFragment.enterAnnotationCreationMode();
353+
}
354+
}));
336355
}
337356

338357
public void exitCurrentlyActiveMode() {
339-
if (fragment != null) {
340-
fragment.exitCurrentlyActiveMode();
341-
}
358+
pendingFragmentActions.add(fragmentGetter.take(1)
359+
.observeOn(Schedulers.io())
360+
.subscribe(new Consumer<PdfFragment>() {
361+
@Override
362+
public void accept(PdfFragment pdfFragment) {
363+
pdfFragment.exitCurrentlyActiveMode();
364+
}
365+
}));
342366
}
343367

344368
public void saveCurrentDocument() {
@@ -354,9 +378,19 @@ public void saveCurrentDocument() {
354378
}
355379
}
356380

357-
public Single<List<Annotation>> getAnnotations(int pageIndex, @Nullable String type) {
358-
return fragment.getDocument().getAnnotationProvider().getAllAnnotationsOfType(getTypeFromString(type), pageIndex, 1)
359-
.toList();
381+
public Single<List<Annotation>> getAnnotations(final int pageIndex, @Nullable final String type) {
382+
return fragmentGetter.take(1).map(new Function<PdfFragment, PdfDocument>() {
383+
384+
@Override
385+
public PdfDocument apply(PdfFragment pdfFragment) {
386+
return pdfFragment.getDocument();
387+
}
388+
}).flatMap(new Function<PdfDocument, ObservableSource<Annotation>>() {
389+
@Override
390+
public ObservableSource<Annotation> apply(PdfDocument pdfDocument) {
391+
return pdfDocument.getAnnotationProvider().getAllAnnotationsOfType(getTypeFromString(type), pageIndex, 1);
392+
}
393+
}).toList();
360394
}
361395

362396
private EnumSet<AnnotationType> getTypeFromString(@Nullable String type) {
@@ -526,7 +560,7 @@ public void accept(FormElement formElement) {
526560
selectedIndices.add(indices.getInt(i));
527561
}
528562
choiceFormElement.setSelectedIndexes(selectedIndices);
529-
}catch (JSONException ex) {
563+
} catch (JSONException ex) {
530564
// This isn't an index maybe we can set a custom value on a combobox.
531565
if (formElement instanceof ComboBoxFormElement) {
532566
((ComboBoxFormElement) formElement).setCustomText(value);

samples/Catalog/android/app/build.gradle

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ import com.android.build.OutputFile
6666
*/
6767

6868
project.ext.react = [
69-
entryFile: "index.js"
69+
entryFile: "index.js",
70+
bundleInDebug: true
7071
]
7172

7273
apply from: "../../node_modules/react-native/react.gradle"
@@ -100,6 +101,7 @@ android {
100101
ndk {
101102
abiFilters "armeabi-v7a", "x86"
102103
}
104+
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
103105
}
104106
splits {
105107
abi {
@@ -128,7 +130,7 @@ android {
128130
}
129131
}
130132
}
131-
sourceSets { main { assets.srcDirs = ['src/main/assets', '../../../PDFs' , '../../../Images'] } }
133+
sourceSets { main { assets.srcDirs = ['src/main/assets', '../../../PDFs', '../../../Images'] } }
132134
}
133135

134136
dependencies {
@@ -137,11 +139,27 @@ dependencies {
137139
// From node_modules
138140
compile project(':react-native-pspdfkit')
139141
compile project(':react-native-fs')
142+
143+
androidTestCompile('com.android.support.test:runner:1.0.2') {
144+
exclude group: 'com.android.support'
145+
}
146+
androidTestCompile('com.android.support.test:rules:1.0.2') {
147+
exclude group: 'com.android.support'
148+
}
149+
// Optional -- Hamcrest library
150+
androidTestCompile 'org.hamcrest:hamcrest-library:1.3'
151+
// Optional -- UI testing with Espresso
152+
androidTestCompile('com.android.support.test.espresso:espresso-core:3.0.2') {
153+
exclude group: 'com.android.support'
154+
exclude group: 'com.google.code.findbugs'
155+
}
156+
// Optional -- UI testing with UI Automator
157+
androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.3'
140158
}
141159

142160
// Run this once to be able to run the application with BUCK
143161
// puts all compile dependencies into folder libs for BUCK to use
144162
task copyDownloadableDepsToLibs(type: Copy) {
145-
from configurations.compile
146-
into 'libs'
163+
from configurations.compile
164+
into 'libs'
147165
}

0 commit comments

Comments
 (0)