react-native-navigation 8.2.1 → 8.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/lib/android/app/build.gradle +29 -0
  2. package/lib/android/app/src/androidTest/AndroidManifest.xml +17 -0
  3. package/lib/android/app/src/androidTest/java/com/reactnativenavigation/BaseAndroidTest.kt +4 -0
  4. package/lib/android/app/src/androidTest/java/com/reactnativenavigation/TestActivity.kt +4 -0
  5. package/lib/android/app/src/androidTest/java/com/reactnativenavigation/TestApplication.kt +40 -0
  6. package/lib/android/app/src/androidTest/java/com/reactnativenavigation/TestUtils.java +65 -0
  7. package/lib/android/app/src/androidTest/java/com/reactnativenavigation/fakes/IconResolverFake.kt +8 -0
  8. package/lib/android/app/src/androidTest/java/com/reactnativenavigation/mocks/BackDrawable.java +30 -0
  9. package/lib/android/app/src/androidTest/java/com/reactnativenavigation/mocks/ImageLoaderMock.kt +49 -0
  10. package/lib/android/app/src/androidTest/java/com/reactnativenavigation/mocks/SimpleViewController.java +110 -0
  11. package/lib/android/app/src/androidTest/java/com/reactnativenavigation/mocks/TitleBarButtonCreatorMock.java +26 -0
  12. package/lib/android/app/src/androidTest/java/com/reactnativenavigation/mocks/TitleBarReactViewCreatorMock.java +8 -0
  13. package/lib/android/app/src/androidTest/java/com/reactnativenavigation/mocks/TopBarBackgroundViewCreatorMock.java +8 -0
  14. package/lib/android/app/src/androidTest/java/com/reactnativenavigation/mocks/TypefaceLoaderMock.java +34 -0
  15. package/lib/android/app/src/androidTest/java/com/reactnativenavigation/utils/ButtonPresenterTest.kt +379 -0
  16. package/lib/android/app/src/androidTest/java/com/reactnativenavigation/viewcontrollers/bottomtabs/attacher/modes/AfterInitialTabTest.kt +42 -0
  17. package/lib/android/app/src/androidTest/java/com/reactnativenavigation/viewcontrollers/bottomtabs/attacher/modes/AttachModeTest.kt +98 -0
  18. package/lib/android/app/src/androidTest/java/com/reactnativenavigation/viewcontrollers/bottomtabs/attacher/modes/OnSwitchToTabTest.kt +32 -0
  19. package/lib/android/app/src/androidTest/java/com/reactnativenavigation/viewcontrollers/bottomtabs/attacher/modes/TogetherTest.kt +19 -0
  20. package/lib/android/app/src/androidTest/java/com/reactnativenavigation/viewcontrollers/child/ChildControllerTest.java +102 -0
  21. package/lib/android/app/src/androidTest/java/com/reactnativenavigation/viewcontrollers/child/ChildControllersRegistryTest.java +67 -0
  22. package/lib/android/app/src/androidTest/java/com/reactnativenavigation/viewcontrollers/parent/ParentControllerTest.java +349 -0
  23. package/lib/android/app/src/androidTest/java/com/reactnativenavigation/views/TitleSubTitleLayoutTest.kt +51 -0
  24. package/lib/ios/RNNAppDelegate.mm +0 -22
  25. package/package.json +1 -1
@@ -39,6 +39,8 @@ android {
39
39
  defaultConfig {
40
40
  minSdkVersion safeExtGetFallbackLowerBound('minSdkVersion', DEFAULT_MIN_SDK_VERSION)
41
41
  targetSdkVersion safeExtGetFallbackLowerBound('targetSdkVersion', DEFAULT_TARGET_SDK_VERSION)
42
+
43
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
42
44
  }
43
45
  buildTypes {
44
46
  release {
@@ -53,6 +55,15 @@ android {
53
55
  }
54
56
 
55
57
  testOptions {
58
+ managedDevices {
59
+ localDevices {
60
+ pixel3aapi34 {
61
+ device = "Pixel 3a"
62
+ apiLevel = 34
63
+ systemImageSource = "aosp-atd"
64
+ }
65
+ }
66
+ }
56
67
  unitTests.includeAndroidResources = true
57
68
  unitTests.all { t ->
58
69
  maxHeapSize = "4g"
@@ -103,6 +114,7 @@ dependencies {
103
114
  //noinspection GradleDynamicVersion
104
115
  implementation 'com.facebook.react:react-native:+'
105
116
 
117
+
106
118
  if ("Playground".toLowerCase() == rootProject.name.toLowerCase()) {
107
119
  // tests only for our playground
108
120
  testImplementation 'junit:junit:4.13.2'
@@ -113,5 +125,22 @@ dependencies {
113
125
  testImplementation 'org.mockito:mockito-inline:4.6.1'
114
126
  testImplementation "org.mockito.kotlin:mockito-kotlin:4.0.0"
115
127
  testImplementation "org.jetbrains.kotlin:kotlin-test:$kotlinVersion"
128
+
129
+ // Core testing libraries
130
+ androidTestImplementation "androidx.test.ext:junit:1.2.1"
131
+ androidTestImplementation 'org.assertj:assertj-core:3.11.1'
132
+
133
+ androidTestImplementation "androidx.test.espresso:espresso-core:3.6.1"
134
+
135
+ androidTestImplementation "com.linkedin.dexmaker:dexmaker-mockito-inline:2.28.4"
136
+ androidTestImplementation 'org.opentest4j:opentest4j:1.2.0'
137
+ androidTestImplementation ("org.mockito.kotlin:mockito-kotlin:5.4.0") {
138
+ exclude group: 'org.mockito', module: 'mockito-core'
139
+ }
140
+
141
+ androidTestImplementation "androidx.test.uiautomator:uiautomator:2.3.0"
142
+
143
+ androidTestImplementation("com.facebook.react:hermes-android")
144
+
116
145
  }
117
146
  }
@@ -0,0 +1,17 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
2
+ package="com.reactnativenavigation.test">
3
+
4
+ <application
5
+ android:name="com.reactnativenavigation.TestApplication">
6
+ <activity
7
+ android:name="com.reactnativenavigation.TestActivity"
8
+ android:exported="true"
9
+ android:theme="@style/Theme.AppCompat.Light.NoActionBar"
10
+ >
11
+ <intent-filter>
12
+ <action android:name="android.intent.action.MAIN" />
13
+ <category android:name="android.intent.category.LAUNCHER" />
14
+ </intent-filter>
15
+ </activity>
16
+ </application>
17
+ </manifest>
@@ -0,0 +1,4 @@
1
+ package com.reactnativenavigation
2
+
3
+ abstract class BaseAndroidTest {
4
+ }
@@ -0,0 +1,4 @@
1
+ package com.reactnativenavigation
2
+
3
+ class TestActivity : NavigationActivity() {
4
+ }
@@ -0,0 +1,40 @@
1
+ package com.reactnativenavigation
2
+
3
+ import com.facebook.react.ReactHost
4
+ import com.facebook.react.ReactNativeHost
5
+ import com.facebook.react.ReactPackage
6
+ import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
7
+ import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
8
+ import com.facebook.react.shell.MainReactPackage
9
+ import com.reactnativenavigation.react.NavigationPackage
10
+ import com.reactnativenavigation.react.NavigationReactNativeHost
11
+
12
+ class TestApplication : NavigationApplication() {
13
+
14
+
15
+ override val reactNativeHost: ReactNativeHost
16
+ get() = object : NavigationReactNativeHost(this) {
17
+ override fun getJSMainModuleName(): String {
18
+ return "index"
19
+ }
20
+
21
+ override fun getUseDeveloperSupport(): Boolean {
22
+ return false
23
+ }
24
+
25
+ public override fun getPackages(): List<ReactPackage> {
26
+ val packages = listOf(MainReactPackage(null), NavigationPackage())
27
+ return packages
28
+ }
29
+
30
+ override val isHermesEnabled: Boolean
31
+ get() = true
32
+
33
+ override val isNewArchEnabled: Boolean
34
+ get() = true
35
+ }
36
+
37
+ override val reactHost: ReactHost
38
+ get() = getDefaultReactHost(this, reactNativeHost)
39
+
40
+ }
@@ -0,0 +1,65 @@
1
+ package com.reactnativenavigation;
2
+
3
+ import android.app.Activity;
4
+ import android.content.Context;
5
+ import android.view.View;
6
+ import android.view.ViewGroup;
7
+
8
+ import androidx.annotation.NonNull;
9
+
10
+ import com.reactnativenavigation.mocks.TitleBarReactViewCreatorMock;
11
+ import com.reactnativenavigation.mocks.TopBarBackgroundViewCreatorMock;
12
+ import com.reactnativenavigation.mocks.TitleBarButtonCreatorMock;
13
+ import com.reactnativenavigation.mocks.TypefaceLoaderMock;
14
+ import com.reactnativenavigation.options.Options;
15
+ import com.reactnativenavigation.options.params.Bool;
16
+ import com.reactnativenavigation.utils.RenderChecker;
17
+ import com.reactnativenavigation.viewcontrollers.stack.StackPresenter;
18
+ import com.reactnativenavigation.react.events.EventEmitter;
19
+ import com.reactnativenavigation.utils.CompatUtils;
20
+ import com.reactnativenavigation.utils.ImageLoader;
21
+ import com.reactnativenavigation.utils.UiUtils;
22
+ import com.reactnativenavigation.viewcontrollers.child.ChildControllersRegistry;
23
+ import com.reactnativenavigation.viewcontrollers.viewcontroller.ViewController;
24
+ import com.reactnativenavigation.viewcontrollers.stack.topbar.button.IconResolver;
25
+ import com.reactnativenavigation.viewcontrollers.stack.StackControllerBuilder;
26
+ import com.reactnativenavigation.viewcontrollers.stack.topbar.TopBarController;
27
+ import com.reactnativenavigation.views.stack.StackLayout;
28
+ import com.reactnativenavigation.views.stack.topbar.TopBar;
29
+
30
+ import org.mockito.Mockito;
31
+
32
+ public class TestUtils {
33
+ public static StackControllerBuilder newStackController(Activity activity) {
34
+ TopBarController topBarController = new TopBarController() {
35
+ @Override
36
+ protected TopBar createTopBar(@NonNull Context context, @NonNull StackLayout stackLayout) {
37
+ TopBar topBar = super.createTopBar(context, stackLayout);
38
+ topBar.layout(0, 0, 1000, UiUtils.getTopBarHeight(context));
39
+ return topBar;
40
+ }
41
+ };
42
+ return new StackControllerBuilder(activity, Mockito.mock(EventEmitter.class))
43
+ .setId("stack" + CompatUtils.generateViewId())
44
+ .setChildRegistry(new ChildControllersRegistry())
45
+ .setTopBarController(topBarController)
46
+ .setStackPresenter(new StackPresenter(activity, new TitleBarReactViewCreatorMock(),
47
+ new TopBarBackgroundViewCreatorMock(), new TitleBarButtonCreatorMock(),
48
+ new IconResolver(activity, new ImageLoader()), new TypefaceLoaderMock(), new RenderChecker(),
49
+ new Options()))
50
+ .setInitialOptions(new Options());
51
+ }
52
+
53
+ public static void hideBackButton(ViewController<?> viewController) {
54
+ viewController.options.topBar.buttons.back.visible = new Bool(false);
55
+ }
56
+
57
+ public static <T extends View> T spyOn(T child) {
58
+ ViewGroup parent = (ViewGroup) child.getParent();
59
+ int indexOf = parent.indexOfChild(child);
60
+ parent.removeView(child);
61
+ T spy = Mockito.spy(child);
62
+ parent.addView(spy, indexOf);
63
+ return spy;
64
+ }
65
+ }
@@ -0,0 +1,8 @@
1
+ package com.reactnativenavigation.fakes
2
+
3
+ import android.app.Activity
4
+ import com.reactnativenavigation.mocks.ImageLoaderMock
5
+ import com.reactnativenavigation.utils.ImageLoader
6
+ import com.reactnativenavigation.viewcontrollers.stack.topbar.button.IconResolver
7
+
8
+ class IconResolverFake(activity: Activity, imageLoader: ImageLoader = ImageLoaderMock.mock()) : IconResolver(activity, imageLoader)
@@ -0,0 +1,30 @@
1
+ package com.reactnativenavigation.mocks;
2
+
3
+ import android.graphics.Canvas;
4
+ import android.graphics.ColorFilter;
5
+ import android.graphics.drawable.Drawable;
6
+
7
+ import androidx.annotation.NonNull;
8
+ import androidx.annotation.Nullable;
9
+
10
+ public class BackDrawable extends Drawable {
11
+ @Override
12
+ public void draw(@NonNull Canvas canvas) {
13
+
14
+ }
15
+
16
+ @Override
17
+ public void setAlpha(int alpha) {
18
+
19
+ }
20
+
21
+ @Override
22
+ public void setColorFilter(@Nullable ColorFilter colorFilter) {
23
+
24
+ }
25
+
26
+ @Override
27
+ public int getOpacity() {
28
+ return 0;
29
+ }
30
+ }
@@ -0,0 +1,49 @@
1
+ package com.reactnativenavigation.mocks
2
+
3
+ import android.graphics.Canvas
4
+ import android.graphics.ColorFilter
5
+ import android.graphics.drawable.Drawable
6
+
7
+ import com.reactnativenavigation.utils.ImageLoader
8
+ import com.reactnativenavigation.utils.ImageLoader.ImagesLoadingListener
9
+ import org.mockito.Mockito.doAnswer
10
+ import org.mockito.kotlin.any
11
+ import org.mockito.kotlin.mock
12
+ import org.mockito.kotlin.whenever
13
+ import java.util.*
14
+
15
+ object ImageLoaderMock {
16
+ val mockDrawable: Drawable = object : Drawable() {
17
+ override fun draw(canvas: Canvas) {}
18
+ override fun setAlpha(alpha: Int) {}
19
+ override fun setColorFilter(colorFilter: ColorFilter?) {}
20
+ override fun getOpacity(): Int {
21
+ return 0
22
+ }
23
+ }
24
+ private val backIcon: Drawable = BackDrawable()
25
+
26
+ @JvmStatic
27
+ fun mock(): ImageLoader {
28
+ return this.mock(mockDrawable)
29
+ }
30
+
31
+ @JvmStatic
32
+ fun mock(returnDrawable: Drawable = mockDrawable): ImageLoader {
33
+ val imageLoader = mock<ImageLoader>()
34
+ doAnswer { invocation ->
35
+ val urlCount = (invocation.arguments[1] as Collection<*>).size
36
+ val drawables = Collections.nCopies(urlCount, returnDrawable)
37
+ (invocation.arguments[2] as ImagesLoadingListener).onComplete(drawables)
38
+ null
39
+ }.`when`(imageLoader).loadIcons(any(), any(), any())
40
+
41
+ doAnswer { invocation ->
42
+ (invocation.arguments[2] as ImagesLoadingListener).onComplete(returnDrawable)
43
+ null
44
+ }.`when`(imageLoader).loadIcon(any(), any(), any())
45
+
46
+ whenever(imageLoader.getBackButtonIcon(any())).thenReturn(backIcon)
47
+ return imageLoader
48
+ }
49
+ }
@@ -0,0 +1,110 @@
1
+ package com.reactnativenavigation.mocks;
2
+
3
+ import static com.reactnativenavigation.utils.ObjectUtils.perform;
4
+
5
+ import android.app.Activity;
6
+ import android.content.Context;
7
+ import android.view.MotionEvent;
8
+
9
+ import androidx.annotation.NonNull;
10
+
11
+ import com.reactnativenavigation.options.Options;
12
+ import com.reactnativenavigation.react.ReactView;
13
+ import com.reactnativenavigation.viewcontrollers.child.ChildController;
14
+ import com.reactnativenavigation.viewcontrollers.child.ChildControllersRegistry;
15
+ import com.reactnativenavigation.viewcontrollers.component.ComponentPresenterBase;
16
+ import com.reactnativenavigation.viewcontrollers.viewcontroller.Presenter;
17
+ import com.reactnativenavigation.viewcontrollers.viewcontroller.ScrollEventListener;
18
+ import com.reactnativenavigation.views.component.ReactComponent;
19
+
20
+ public class SimpleViewController extends ChildController<SimpleViewController.SimpleView> {
21
+ private final ComponentPresenterBase presenter = new ComponentPresenterBase();
22
+
23
+ public SimpleViewController(Activity activity, ChildControllersRegistry childRegistry, String id, Options options) {
24
+ this(activity, childRegistry, id, new Presenter(activity, new Options()), options);
25
+ }
26
+
27
+ public SimpleViewController(Activity activity, ChildControllersRegistry childRegistry, String id, Presenter presenter, Options options) {
28
+ super(activity, childRegistry, id, presenter, options);
29
+ }
30
+
31
+ @Override
32
+ public SimpleView createView() {
33
+ return new SimpleView(getActivity());
34
+ }
35
+
36
+ @Override
37
+ public void sendOnNavigationButtonPressed(String buttonId) {
38
+ getView().sendOnNavigationButtonPressed(buttonId);
39
+ }
40
+
41
+ @Override
42
+ public void destroy() {
43
+ if (!isDestroyed()) performOnParentController(parent -> parent.onChildDestroyed(this));
44
+ super.destroy();
45
+ }
46
+
47
+ @NonNull
48
+ @Override
49
+ public String toString() {
50
+ return "SimpleViewController " + getId();
51
+ }
52
+
53
+ @Override
54
+ public int getTopInset() {
55
+ int statusBarInset = resolveCurrentOptions().statusBar.isHiddenOrDrawBehind() ? 0 : 63;
56
+ return statusBarInset + perform(getParentController(), 0, p -> p.getTopInset(this));
57
+ }
58
+
59
+ @Override
60
+ public void applyBottomInset() {
61
+ if (view != null) presenter.applyBottomInset(view, getBottomInset());
62
+ }
63
+
64
+ @Override
65
+ public String getCurrentComponentName() {
66
+ return null;
67
+ }
68
+
69
+ public static class SimpleView extends ReactView implements ReactComponent {
70
+
71
+ public SimpleView(@NonNull Context context) {
72
+ super(context, "compId", "compName");
73
+ }
74
+
75
+ @Override
76
+ public boolean isRendered() {
77
+ return getChildCount() >= 1;
78
+ }
79
+
80
+ @Override
81
+ public boolean isReady() {
82
+ return false;
83
+ }
84
+
85
+ @Override
86
+ public ReactView asView() {
87
+ return this;
88
+ }
89
+
90
+ @Override
91
+ public void destroy() {
92
+
93
+ }
94
+
95
+ @Override
96
+ public void sendOnNavigationButtonPressed(String buttonId) {
97
+
98
+ }
99
+
100
+ @Override
101
+ public ScrollEventListener getScrollEventListener() {
102
+ return null;
103
+ }
104
+
105
+ @Override
106
+ public void dispatchTouchEventToJs(MotionEvent event) {
107
+
108
+ }
109
+ }
110
+ }
@@ -0,0 +1,26 @@
1
+ package com.reactnativenavigation.mocks;
2
+
3
+ import android.app.Activity;
4
+
5
+ import com.reactnativenavigation.options.ComponentOptions;
6
+ import com.reactnativenavigation.react.events.ComponentType;
7
+ import com.reactnativenavigation.views.stack.topbar.titlebar.TitleBarButtonCreator;
8
+ import com.reactnativenavigation.views.stack.topbar.titlebar.TitleBarReactButtonView;
9
+
10
+ public class TitleBarButtonCreatorMock extends TitleBarButtonCreator {
11
+ public TitleBarButtonCreatorMock() {
12
+ }
13
+
14
+ @Override
15
+ public TitleBarReactButtonView create(Activity activity, ComponentOptions component) {
16
+ return new TitleBarReactButtonView(activity, component) {
17
+ @Override
18
+ public void sendComponentStart(ComponentType type) {
19
+ }
20
+
21
+ @Override
22
+ public void sendComponentStop(ComponentType type) {
23
+ }
24
+ };
25
+ }
26
+ }
@@ -0,0 +1,8 @@
1
+ package com.reactnativenavigation.mocks;
2
+
3
+ import com.reactnativenavigation.views.stack.topbar.titlebar.TitleBarReactViewCreator;
4
+
5
+ public class TitleBarReactViewCreatorMock extends TitleBarReactViewCreator {
6
+ public TitleBarReactViewCreatorMock() {
7
+ }
8
+ }
@@ -0,0 +1,8 @@
1
+ package com.reactnativenavigation.mocks;
2
+
3
+ import com.reactnativenavigation.views.stack.topbar.TopBarBackgroundViewCreator;
4
+
5
+ public class TopBarBackgroundViewCreatorMock extends TopBarBackgroundViewCreator {
6
+ public TopBarBackgroundViewCreatorMock() {
7
+ }
8
+ }
@@ -0,0 +1,34 @@
1
+ package com.reactnativenavigation.mocks;
2
+
3
+ import android.content.Context;
4
+ import android.graphics.Typeface;
5
+ import com.reactnativenavigation.options.parsers.TypefaceLoader;
6
+ import org.mockito.Mockito;
7
+
8
+ import java.util.Map;
9
+
10
+ public class TypefaceLoaderMock extends TypefaceLoader {
11
+ private Map<String, Typeface> mockTypefaces;
12
+
13
+ public TypefaceLoaderMock() {
14
+ super(Mockito.mock(Context.class));
15
+ }
16
+
17
+ public TypefaceLoaderMock(Map<String, Typeface> mockTypefaces) {
18
+ this();
19
+ this.mockTypefaces = mockTypefaces;
20
+ }
21
+
22
+ @Override
23
+ public Typeface getDefaultTypeFace() {
24
+ return Typeface.DEFAULT;
25
+ }
26
+
27
+ @Override
28
+ public Typeface getTypeFace(String fontFamilyName, String fontStyle, String fontWeight, Typeface defaultTypeFace) {
29
+ if (mockTypefaces != null && mockTypefaces.containsKey(fontFamilyName)) {
30
+ return mockTypefaces.get(fontFamilyName);
31
+ }
32
+ return defaultTypeFace;
33
+ }
34
+ }