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.
- package/lib/android/app/build.gradle +29 -0
- package/lib/android/app/src/androidTest/AndroidManifest.xml +17 -0
- package/lib/android/app/src/androidTest/java/com/reactnativenavigation/BaseAndroidTest.kt +4 -0
- package/lib/android/app/src/androidTest/java/com/reactnativenavigation/TestActivity.kt +4 -0
- package/lib/android/app/src/androidTest/java/com/reactnativenavigation/TestApplication.kt +40 -0
- package/lib/android/app/src/androidTest/java/com/reactnativenavigation/TestUtils.java +65 -0
- package/lib/android/app/src/androidTest/java/com/reactnativenavigation/fakes/IconResolverFake.kt +8 -0
- package/lib/android/app/src/androidTest/java/com/reactnativenavigation/mocks/BackDrawable.java +30 -0
- package/lib/android/app/src/androidTest/java/com/reactnativenavigation/mocks/ImageLoaderMock.kt +49 -0
- package/lib/android/app/src/androidTest/java/com/reactnativenavigation/mocks/SimpleViewController.java +110 -0
- package/lib/android/app/src/androidTest/java/com/reactnativenavigation/mocks/TitleBarButtonCreatorMock.java +26 -0
- package/lib/android/app/src/androidTest/java/com/reactnativenavigation/mocks/TitleBarReactViewCreatorMock.java +8 -0
- package/lib/android/app/src/androidTest/java/com/reactnativenavigation/mocks/TopBarBackgroundViewCreatorMock.java +8 -0
- package/lib/android/app/src/androidTest/java/com/reactnativenavigation/mocks/TypefaceLoaderMock.java +34 -0
- package/lib/android/app/src/androidTest/java/com/reactnativenavigation/utils/ButtonPresenterTest.kt +379 -0
- package/lib/android/app/src/androidTest/java/com/reactnativenavigation/viewcontrollers/bottomtabs/attacher/modes/AfterInitialTabTest.kt +42 -0
- package/lib/android/app/src/androidTest/java/com/reactnativenavigation/viewcontrollers/bottomtabs/attacher/modes/AttachModeTest.kt +98 -0
- package/lib/android/app/src/androidTest/java/com/reactnativenavigation/viewcontrollers/bottomtabs/attacher/modes/OnSwitchToTabTest.kt +32 -0
- package/lib/android/app/src/androidTest/java/com/reactnativenavigation/viewcontrollers/bottomtabs/attacher/modes/TogetherTest.kt +19 -0
- package/lib/android/app/src/androidTest/java/com/reactnativenavigation/viewcontrollers/child/ChildControllerTest.java +102 -0
- package/lib/android/app/src/androidTest/java/com/reactnativenavigation/viewcontrollers/child/ChildControllersRegistryTest.java +67 -0
- package/lib/android/app/src/androidTest/java/com/reactnativenavigation/viewcontrollers/parent/ParentControllerTest.java +349 -0
- package/lib/android/app/src/androidTest/java/com/reactnativenavigation/views/TitleSubTitleLayoutTest.kt +51 -0
- package/lib/ios/RNNAppDelegate.mm +0 -22
- package/package.json +1 -1
package/lib/android/app/src/androidTest/java/com/reactnativenavigation/utils/ButtonPresenterTest.kt
ADDED
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
package com.reactnativenavigation.utils
|
|
2
|
+
|
|
3
|
+
import android.app.Activity
|
|
4
|
+
import android.app.Application
|
|
5
|
+
import android.content.res.Configuration
|
|
6
|
+
import android.graphics.Color
|
|
7
|
+
import android.graphics.PorterDuff
|
|
8
|
+
import android.graphics.PorterDuffColorFilter
|
|
9
|
+
import android.text.SpannableString
|
|
10
|
+
import android.view.Menu
|
|
11
|
+
import android.view.MenuItem
|
|
12
|
+
import android.widget.TextView
|
|
13
|
+
import androidx.appcompat.widget.ActionMenuView
|
|
14
|
+
import androidx.test.espresso.Espresso
|
|
15
|
+
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
|
16
|
+
import androidx.test.ext.junit.runners.AndroidJUnit4
|
|
17
|
+
import androidx.test.platform.app.InstrumentationRegistry
|
|
18
|
+
import com.reactnativenavigation.BaseAndroidTest
|
|
19
|
+
import com.reactnativenavigation.TestActivity
|
|
20
|
+
import com.reactnativenavigation.fakes.IconResolverFake
|
|
21
|
+
import com.reactnativenavigation.mocks.ImageLoaderMock.mock
|
|
22
|
+
import com.reactnativenavigation.options.ButtonOptions
|
|
23
|
+
import com.reactnativenavigation.options.IconBackgroundOptions
|
|
24
|
+
import com.reactnativenavigation.options.params.Bool
|
|
25
|
+
import com.reactnativenavigation.options.params.Colour
|
|
26
|
+
import com.reactnativenavigation.options.params.Number
|
|
27
|
+
import com.reactnativenavigation.options.params.Text
|
|
28
|
+
import com.reactnativenavigation.options.params.ThemeColour
|
|
29
|
+
import com.reactnativenavigation.viewcontrollers.stack.topbar.button.ButtonController
|
|
30
|
+
import com.reactnativenavigation.viewcontrollers.stack.topbar.button.ButtonPresenter
|
|
31
|
+
import com.reactnativenavigation.views.stack.topbar.titlebar.ButtonBar
|
|
32
|
+
import com.reactnativenavigation.views.stack.topbar.titlebar.IconBackgroundDrawable
|
|
33
|
+
import com.reactnativenavigation.views.stack.topbar.titlebar.TitleBarButtonCreator
|
|
34
|
+
import org.assertj.core.api.Java6Assertions
|
|
35
|
+
import org.junit.Before
|
|
36
|
+
import org.junit.Rule
|
|
37
|
+
import org.junit.Test
|
|
38
|
+
import org.junit.runner.RunWith
|
|
39
|
+
import org.mockito.Mockito
|
|
40
|
+
import java.util.Objects
|
|
41
|
+
|
|
42
|
+
@RunWith(AndroidJUnit4::class)
|
|
43
|
+
class ButtonPresenterTest : BaseAndroidTest() {
|
|
44
|
+
private lateinit var titleBar: ButtonBar
|
|
45
|
+
private lateinit var uut: ButtonPresenter
|
|
46
|
+
private lateinit var buttonController: ButtonController
|
|
47
|
+
private lateinit var button: ButtonOptions
|
|
48
|
+
private lateinit var activity: Activity
|
|
49
|
+
|
|
50
|
+
@get:Rule
|
|
51
|
+
val rule = ActivityScenarioRule(TestActivity::class.java)
|
|
52
|
+
|
|
53
|
+
@Before
|
|
54
|
+
fun beforeEach() {
|
|
55
|
+
rule.scenario.onActivity { activity: TestActivity ->
|
|
56
|
+
this.activity =
|
|
57
|
+
activity
|
|
58
|
+
titleBar = ButtonBar(activity)
|
|
59
|
+
activity.setContentView(titleBar)
|
|
60
|
+
button = createButton()
|
|
61
|
+
|
|
62
|
+
val imageLoaderMock =
|
|
63
|
+
mock()
|
|
64
|
+
initUUt(imageLoaderMock)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
private fun initUUt(imageLoaderMock: ImageLoader) {
|
|
69
|
+
val iconResolver = IconResolverFake(
|
|
70
|
+
activity, imageLoaderMock
|
|
71
|
+
)
|
|
72
|
+
uut = ButtonPresenter(activity, button, iconResolver)
|
|
73
|
+
buttonController = ButtonController(
|
|
74
|
+
activity,
|
|
75
|
+
uut,
|
|
76
|
+
button,
|
|
77
|
+
Mockito.mock(TitleBarButtonCreator::class.java),
|
|
78
|
+
Mockito.mock(
|
|
79
|
+
ButtonController.OnClickListener::class.java
|
|
80
|
+
)
|
|
81
|
+
)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@Test
|
|
85
|
+
fun applyOptions_buttonIsAddedToMenu() {
|
|
86
|
+
InstrumentationRegistry.getInstrumentation().runOnMainSync {
|
|
87
|
+
addButtonAndApplyOptions()
|
|
88
|
+
Java6Assertions.assertThat(findButtonView().text.toString())
|
|
89
|
+
.isEqualTo(BTN_TEXT)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
@Test
|
|
94
|
+
fun applyOptions_appliesColorOnButtonTextView() {
|
|
95
|
+
InstrumentationRegistry.getInstrumentation().runOnMainSync {
|
|
96
|
+
button.color =
|
|
97
|
+
ThemeColour(Colour(Color.RED), Colour(Color.RED))
|
|
98
|
+
addButtonAndApplyOptions()
|
|
99
|
+
}
|
|
100
|
+
Espresso.onIdle()
|
|
101
|
+
Java6Assertions.assertThat(findButtonView().currentTextColor).isEqualTo(Color.RED)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
@Test
|
|
105
|
+
fun applyOptions_appliesColorOnButtonTextViewOnDarkMode() {
|
|
106
|
+
val application = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext as Application
|
|
107
|
+
application.resources.configuration.uiMode = Configuration.UI_MODE_NIGHT_NO
|
|
108
|
+
button.color = ThemeColour(Colour(Color.RED), Colour(Color.BLACK))
|
|
109
|
+
var menuItem: MenuItem? = null
|
|
110
|
+
InstrumentationRegistry.getInstrumentation().runOnMainSync {
|
|
111
|
+
menuItem = addButtonAndApplyOptions()
|
|
112
|
+
}
|
|
113
|
+
Espresso.onIdle()
|
|
114
|
+
Java6Assertions.assertThat(findButtonView().currentTextColor).isEqualTo(Color.RED)
|
|
115
|
+
|
|
116
|
+
InstrumentationRegistry.getInstrumentation().runOnMainSync {
|
|
117
|
+
application.resources.configuration.uiMode = Configuration.UI_MODE_NIGHT_YES
|
|
118
|
+
uut.applyOptions(titleBar, menuItem!!) { buttonController.view }
|
|
119
|
+
}
|
|
120
|
+
Espresso.onIdle()
|
|
121
|
+
Java6Assertions.assertThat(findButtonView().currentTextColor).isEqualTo(Color.BLACK)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
@Test
|
|
125
|
+
fun apply_disabledColor() {
|
|
126
|
+
InstrumentationRegistry.getInstrumentation().runOnMainSync {
|
|
127
|
+
button.enabled = Bool(false)
|
|
128
|
+
addButtonAndApplyOptions()
|
|
129
|
+
}
|
|
130
|
+
Espresso.onIdle()
|
|
131
|
+
Java6Assertions.assertThat(findButtonView().currentTextColor)
|
|
132
|
+
.isEqualTo(ButtonPresenter.DISABLED_COLOR)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
@Test
|
|
136
|
+
fun applyColor_shouldChangeColor() {
|
|
137
|
+
InstrumentationRegistry.getInstrumentation().runOnMainSync {
|
|
138
|
+
val menuItem = addMenuButton()
|
|
139
|
+
uut.applyOptions(titleBar, menuItem) { buttonController.view }
|
|
140
|
+
val color =
|
|
141
|
+
ThemeColour(Colour(Color.RED), Colour(Color.RED))
|
|
142
|
+
uut.applyColor(titleBar, menuItem, color)
|
|
143
|
+
}
|
|
144
|
+
Espresso.onIdle()
|
|
145
|
+
Java6Assertions.assertThat(findButtonView().currentTextColor).isEqualTo(Color.RED)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
@Test
|
|
149
|
+
fun applyBackgroundColor_shouldChangeBackgroundColor() {
|
|
150
|
+
InstrumentationRegistry.getInstrumentation().runOnMainSync {
|
|
151
|
+
val mockD = Mockito.mock(
|
|
152
|
+
IconBackgroundDrawable::class.java
|
|
153
|
+
)
|
|
154
|
+
initUUt(mock(mockD))
|
|
155
|
+
button.enabled = Bool(true)
|
|
156
|
+
button.icon = Text("icon")
|
|
157
|
+
button.color =
|
|
158
|
+
ThemeColour(Colour(Color.RED), Colour(Color.RED))
|
|
159
|
+
val iconBackground = IconBackgroundOptions()
|
|
160
|
+
iconBackground.color = ThemeColour(
|
|
161
|
+
Colour(Color.GREEN),
|
|
162
|
+
Colour(Color.GREEN)
|
|
163
|
+
)
|
|
164
|
+
button.iconBackground = iconBackground
|
|
165
|
+
val menuItem = Mockito.spy(addMenuButton())
|
|
166
|
+
uut.applyOptions(titleBar, menuItem) { buttonController.view }
|
|
167
|
+
|
|
168
|
+
Java6Assertions.assertThat((menuItem.icon as IconBackgroundDrawable).backgroundColor)
|
|
169
|
+
.isEqualTo(Color.GREEN)
|
|
170
|
+
|
|
171
|
+
uut.applyBackgroundColor(
|
|
172
|
+
titleBar, menuItem,
|
|
173
|
+
ThemeColour(
|
|
174
|
+
Colour(Color.BLACK),
|
|
175
|
+
Colour(Color.BLACK)
|
|
176
|
+
)
|
|
177
|
+
)
|
|
178
|
+
Java6Assertions.assertThat((menuItem.icon as IconBackgroundDrawable).backgroundColor)
|
|
179
|
+
.isEqualTo(Color.BLACK)
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
@Test
|
|
184
|
+
fun applyOptions_shouldChangeIconColorTint() {
|
|
185
|
+
InstrumentationRegistry.getInstrumentation().runOnMainSync {
|
|
186
|
+
val mockD = Mockito.mock(
|
|
187
|
+
IconBackgroundDrawable::class.java
|
|
188
|
+
)
|
|
189
|
+
initUUt(mock(mockD))
|
|
190
|
+
button.enabled = Bool(true)
|
|
191
|
+
button.icon = Text("icon")
|
|
192
|
+
button.color =
|
|
193
|
+
ThemeColour(Colour(Color.RED), Colour(Color.RED))
|
|
194
|
+
val menuItem = Mockito.spy(addMenuButton())
|
|
195
|
+
uut.applyOptions(titleBar, menuItem) { buttonController.view }
|
|
196
|
+
|
|
197
|
+
val icon = menuItem.icon
|
|
198
|
+
Java6Assertions.assertThat(
|
|
199
|
+
icon
|
|
200
|
+
).isNotNull()
|
|
201
|
+
Mockito.verify(icon)?.colorFilter =
|
|
202
|
+
PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SRC_IN)
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
@Test
|
|
207
|
+
fun applyOptions_shouldChangeIconDisabledColorTint() {
|
|
208
|
+
InstrumentationRegistry.getInstrumentation().runOnMainSync {
|
|
209
|
+
val mockD = Mockito.mock(
|
|
210
|
+
IconBackgroundDrawable::class.java
|
|
211
|
+
)
|
|
212
|
+
initUUt(mock(mockD))
|
|
213
|
+
button.enabled = Bool(false)
|
|
214
|
+
button.icon = Text("icon")
|
|
215
|
+
button.color =
|
|
216
|
+
ThemeColour(Colour(Color.RED), Colour(Color.RED))
|
|
217
|
+
button.disabledColor = ThemeColour(
|
|
218
|
+
Colour(Color.YELLOW),
|
|
219
|
+
Colour(Color.YELLOW)
|
|
220
|
+
)
|
|
221
|
+
val menuItem = Mockito.spy(addMenuButton())
|
|
222
|
+
uut.applyOptions(titleBar, menuItem) { buttonController.view }
|
|
223
|
+
|
|
224
|
+
val icon = menuItem.icon
|
|
225
|
+
Java6Assertions.assertThat(
|
|
226
|
+
icon
|
|
227
|
+
).isNotNull()
|
|
228
|
+
Mockito.verify(icon)?.colorFilter =
|
|
229
|
+
PorterDuffColorFilter(Color.YELLOW, PorterDuff.Mode.SRC_IN)
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
@Test
|
|
234
|
+
fun applyOptions_shouldChangeIconColorBackground() {
|
|
235
|
+
InstrumentationRegistry.getInstrumentation().runOnMainSync {
|
|
236
|
+
val mockD = Mockito.mock(
|
|
237
|
+
IconBackgroundDrawable::class.java
|
|
238
|
+
)
|
|
239
|
+
initUUt(mock(mockD))
|
|
240
|
+
button.enabled = Bool(true)
|
|
241
|
+
button.icon = Text("icon")
|
|
242
|
+
button.color =
|
|
243
|
+
ThemeColour(Colour(Color.RED), Colour(Color.RED))
|
|
244
|
+
val iconBackground = IconBackgroundOptions()
|
|
245
|
+
iconBackground.color = ThemeColour(
|
|
246
|
+
Colour(Color.GREEN),
|
|
247
|
+
Colour(Color.GREEN)
|
|
248
|
+
)
|
|
249
|
+
button.iconBackground = iconBackground
|
|
250
|
+
val menuItem = Mockito.spy(addMenuButton())
|
|
251
|
+
uut.applyOptions(titleBar, menuItem) { buttonController.view }
|
|
252
|
+
|
|
253
|
+
val icon = menuItem.icon
|
|
254
|
+
Java6Assertions.assertThat(
|
|
255
|
+
icon
|
|
256
|
+
).isNotNull()
|
|
257
|
+
Java6Assertions.assertThat(
|
|
258
|
+
icon
|
|
259
|
+
).isInstanceOf(
|
|
260
|
+
IconBackgroundDrawable::class.java
|
|
261
|
+
)
|
|
262
|
+
val modifed = icon as IconBackgroundDrawable?
|
|
263
|
+
Mockito.verify(modifed!!.getWrappedDrawable()).colorFilter =
|
|
264
|
+
PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SRC_IN)
|
|
265
|
+
Java6Assertions.assertThat(modifed.backgroundColor)
|
|
266
|
+
.isEqualTo(Color.GREEN)
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
@Test
|
|
271
|
+
fun applyOptions_shouldChangeIconDisabledColorBackground() {
|
|
272
|
+
InstrumentationRegistry.getInstrumentation().runOnMainSync {
|
|
273
|
+
val mockD = Mockito.mock(
|
|
274
|
+
IconBackgroundDrawable::class.java
|
|
275
|
+
)
|
|
276
|
+
initUUt(mock(mockD))
|
|
277
|
+
button.enabled = Bool(false)
|
|
278
|
+
button.icon = Text("icon")
|
|
279
|
+
button.color =
|
|
280
|
+
ThemeColour(Colour(Color.RED), Colour(Color.RED))
|
|
281
|
+
button.disabledColor = ThemeColour(
|
|
282
|
+
Colour(Color.YELLOW),
|
|
283
|
+
Colour(Color.YELLOW)
|
|
284
|
+
)
|
|
285
|
+
val iconBackground = IconBackgroundOptions()
|
|
286
|
+
iconBackground.color = ThemeColour(
|
|
287
|
+
Colour(Color.GREEN),
|
|
288
|
+
Colour(Color.GREEN)
|
|
289
|
+
)
|
|
290
|
+
iconBackground.disabledColor = ThemeColour(
|
|
291
|
+
Colour(Color.CYAN),
|
|
292
|
+
Colour(Color.CYAN)
|
|
293
|
+
)
|
|
294
|
+
button.iconBackground = iconBackground
|
|
295
|
+
val menuItem = Mockito.spy(addMenuButton())
|
|
296
|
+
uut.applyOptions(titleBar, menuItem) { buttonController.view }
|
|
297
|
+
|
|
298
|
+
val icon = menuItem.icon
|
|
299
|
+
Java6Assertions.assertThat(
|
|
300
|
+
icon
|
|
301
|
+
).isNotNull()
|
|
302
|
+
Java6Assertions.assertThat(
|
|
303
|
+
icon
|
|
304
|
+
).isInstanceOf(
|
|
305
|
+
IconBackgroundDrawable::class.java
|
|
306
|
+
)
|
|
307
|
+
val modifed = icon as IconBackgroundDrawable?
|
|
308
|
+
Mockito.verify(modifed!!.getWrappedDrawable()).colorFilter =
|
|
309
|
+
PorterDuffColorFilter(Color.YELLOW, PorterDuff.Mode.SRC_IN)
|
|
310
|
+
Java6Assertions.assertThat(modifed.backgroundColor)
|
|
311
|
+
.isEqualTo(Color.CYAN)
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
@Test
|
|
316
|
+
fun applyColor_shouldChangeDisabledColor() {
|
|
317
|
+
InstrumentationRegistry.getInstrumentation().runOnMainSync {
|
|
318
|
+
button.enabled = Bool(false)
|
|
319
|
+
val menuItem = addMenuButton()
|
|
320
|
+
uut.applyOptions(titleBar, menuItem) { buttonController.view }
|
|
321
|
+
val disabledColor = ThemeColour(
|
|
322
|
+
Colour(Color.BLUE),
|
|
323
|
+
Colour(Color.BLUE)
|
|
324
|
+
)
|
|
325
|
+
uut.applyDisabledColor(titleBar, menuItem, disabledColor)
|
|
326
|
+
}
|
|
327
|
+
Espresso.onIdle()
|
|
328
|
+
Java6Assertions.assertThat(findButtonView().currentTextColor).isEqualTo(Color.BLUE)
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
@Test
|
|
332
|
+
fun apply_allCaps() {
|
|
333
|
+
InstrumentationRegistry.getInstrumentation().runOnMainSync {
|
|
334
|
+
button.allCaps = Bool(false)
|
|
335
|
+
addButtonAndApplyOptions()
|
|
336
|
+
Java6Assertions.assertThat(findButtonView().isAllCaps)
|
|
337
|
+
.isEqualTo(false)
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
private fun addButtonAndApplyOptions(): MenuItem {
|
|
342
|
+
val menuItem = addMenuButton()
|
|
343
|
+
uut.applyOptions(titleBar, menuItem) { buttonController.view }
|
|
344
|
+
return menuItem
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
private fun addMenuButton(): MenuItem {
|
|
348
|
+
return titleBar.addButton(
|
|
349
|
+
Menu.NONE,
|
|
350
|
+
1,
|
|
351
|
+
0,
|
|
352
|
+
SpannableString.valueOf(button.text["text"])
|
|
353
|
+
) ?: throw IllegalStateException("MenuItem should not be null")
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
private fun findButtonView(): TextView {
|
|
357
|
+
return ViewUtils.findChildrenByClass(
|
|
358
|
+
Objects.requireNonNull(
|
|
359
|
+
ViewUtils.findChildByClass(
|
|
360
|
+
titleBar,
|
|
361
|
+
ActionMenuView::class.java
|
|
362
|
+
)
|
|
363
|
+
),
|
|
364
|
+
TextView::class.java
|
|
365
|
+
) { child: Any? -> true }[0] as TextView
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
private fun createButton(): ButtonOptions {
|
|
369
|
+
val b = ButtonOptions()
|
|
370
|
+
b.id = "btn1"
|
|
371
|
+
b.text = Text(BTN_TEXT)
|
|
372
|
+
b.showAsAction = Number(MenuItem.SHOW_AS_ACTION_ALWAYS)
|
|
373
|
+
return b
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
companion object {
|
|
377
|
+
private const val BTN_TEXT = "button1"
|
|
378
|
+
}
|
|
379
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
package com.reactnativenavigation.viewcontrollers.bottomtabs.attacher.modes
|
|
2
|
+
|
|
3
|
+
import androidx.test.espresso.Espresso
|
|
4
|
+
import androidx.test.platform.app.InstrumentationRegistry
|
|
5
|
+
import org.junit.Before
|
|
6
|
+
import org.junit.Test
|
|
7
|
+
import org.mockito.Mockito.verify
|
|
8
|
+
import org.mockito.kotlin.any
|
|
9
|
+
|
|
10
|
+
class AfterInitialTabTest : AttachModeTest() {
|
|
11
|
+
|
|
12
|
+
@Before
|
|
13
|
+
override fun setup() {
|
|
14
|
+
super.setup()
|
|
15
|
+
uut = AfterInitialTab(parent, tabs, presenter, options)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@Test
|
|
19
|
+
fun attach_initialTabIsAttached() {
|
|
20
|
+
uut.attach()
|
|
21
|
+
assertIsChild(parent, tab2)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@Test
|
|
25
|
+
fun attach_otherTabsAreAttachedAfterInitialTab() {
|
|
26
|
+
InstrumentationRegistry.getInstrumentation().runOnMainSync {
|
|
27
|
+
uut.attach()
|
|
28
|
+
|
|
29
|
+
assertNotChildOf(parent, *otherTabs())
|
|
30
|
+
|
|
31
|
+
initialTab().onViewWillAppear()
|
|
32
|
+
}
|
|
33
|
+
Espresso.onIdle()
|
|
34
|
+
assertIsChild(parent, *otherTabs())
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@Test
|
|
38
|
+
fun destroy() {
|
|
39
|
+
uut.destroy()
|
|
40
|
+
verify(initialTab()).removeOnAppearedListener(any())
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
package com.reactnativenavigation.viewcontrollers.bottomtabs.attacher.modes
|
|
2
|
+
|
|
3
|
+
import android.view.View
|
|
4
|
+
import android.view.ViewGroup
|
|
5
|
+
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
|
6
|
+
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
|
7
|
+
import androidx.test.ext.junit.runners.AndroidJUnit4
|
|
8
|
+
import com.reactnativenavigation.TestActivity
|
|
9
|
+
import com.reactnativenavigation.mocks.SimpleViewController
|
|
10
|
+
import com.reactnativenavigation.options.Options
|
|
11
|
+
import com.reactnativenavigation.options.params.Number
|
|
12
|
+
import com.reactnativenavigation.viewcontrollers.bottomtabs.BottomTabsPresenter
|
|
13
|
+
import com.reactnativenavigation.viewcontrollers.child.ChildControllersRegistry
|
|
14
|
+
import com.reactnativenavigation.viewcontrollers.viewcontroller.ViewController
|
|
15
|
+
import com.reactnativenavigation.views.bottomtabs.BottomTabsBehaviour
|
|
16
|
+
import org.assertj.core.api.AssertionsForInterfaceTypes.assertThat
|
|
17
|
+
import org.junit.Before
|
|
18
|
+
import org.junit.Rule
|
|
19
|
+
import org.junit.Test
|
|
20
|
+
import org.junit.runner.RunWith
|
|
21
|
+
import org.mockito.Mockito
|
|
22
|
+
import org.mockito.Mockito.spy
|
|
23
|
+
|
|
24
|
+
@RunWith(AndroidJUnit4::class)
|
|
25
|
+
abstract class AttachModeTest {
|
|
26
|
+
private val INITIAL_TAB = 1
|
|
27
|
+
|
|
28
|
+
private lateinit var childRegistry: ChildControllersRegistry
|
|
29
|
+
protected lateinit var parent: ViewGroup
|
|
30
|
+
protected lateinit var tab1: ViewController<*>
|
|
31
|
+
protected lateinit var tab2: ViewController<*>
|
|
32
|
+
protected lateinit var tabs: List<ViewController<*>>
|
|
33
|
+
protected lateinit var options: Options
|
|
34
|
+
protected lateinit var presenter: BottomTabsPresenter
|
|
35
|
+
protected lateinit var uut: AttachMode
|
|
36
|
+
|
|
37
|
+
@get:Rule
|
|
38
|
+
val rule = ActivityScenarioRule(TestActivity::class.java)
|
|
39
|
+
|
|
40
|
+
@Before
|
|
41
|
+
open fun setup() {
|
|
42
|
+
rule.scenario.onActivity { activity ->
|
|
43
|
+
childRegistry = ChildControllersRegistry()
|
|
44
|
+
parent = CoordinatorLayout(activity)
|
|
45
|
+
tabs = createTabs(activity)
|
|
46
|
+
}
|
|
47
|
+
options = Options()
|
|
48
|
+
options.bottomTabsOptions.currentTabIndex = Number(INITIAL_TAB)
|
|
49
|
+
presenter = Mockito.mock(BottomTabsPresenter::class.java)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@Test
|
|
53
|
+
fun attach_layoutOptionsAreApplied() {
|
|
54
|
+
uut.attach(tab1)
|
|
55
|
+
val lp = tab1.getView().layoutParams as CoordinatorLayout.LayoutParams
|
|
56
|
+
assertThat(lp).isNotNull
|
|
57
|
+
assertThat(lp.behavior).isInstanceOf(BottomTabsBehaviour::class.java)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@Test
|
|
61
|
+
fun attach_initialTabIsVisible() {
|
|
62
|
+
uut.attach(initialTab())
|
|
63
|
+
assertThat(initialTab().getView().visibility).isEqualTo(View.VISIBLE)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@Test
|
|
67
|
+
fun attach_otherTabsAreInvisibleWhenAttached() {
|
|
68
|
+
otherTabs().forEach { t -> uut.attach(t) }
|
|
69
|
+
otherTabs().forEach { t -> assertThat(t.getView().visibility).isEqualTo(View.INVISIBLE) }
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
protected fun otherTabs(): Array<ViewController<*>> {
|
|
73
|
+
return tabs.filter { t -> t != initialTab() }.toTypedArray()
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
protected fun initialTab(): ViewController<*> {
|
|
77
|
+
return tabs[INITIAL_TAB]
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
private fun createTabs(activity: android.app.Activity): List<ViewController<*>> {
|
|
81
|
+
tab1 = SimpleViewController(activity, childRegistry, "child1", Options())
|
|
82
|
+
tab2 = spy(SimpleViewController(activity, childRegistry, "child2", Options()))
|
|
83
|
+
val tab3 = SimpleViewController(activity, childRegistry, "child3", Options())
|
|
84
|
+
return listOf(tab1, tab2, tab3)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
protected fun assertIsChild(parent: ViewGroup, vararg children: ViewController<*>) {
|
|
88
|
+
children.forEach { child ->
|
|
89
|
+
assertThat(child.getView().parent).isEqualTo(parent)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
protected fun assertNotChildOf(parent: ViewGroup, vararg children: ViewController<*>) {
|
|
94
|
+
children.forEach { child ->
|
|
95
|
+
assertThat(child.getView().parent).isNotEqualTo(parent)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
package com.reactnativenavigation.viewcontrollers.bottomtabs.attacher.modes
|
|
2
|
+
|
|
3
|
+
import org.junit.Before
|
|
4
|
+
import org.junit.Test
|
|
5
|
+
|
|
6
|
+
class OnSwitchToTabTest : AttachModeTest() {
|
|
7
|
+
|
|
8
|
+
@Before
|
|
9
|
+
override fun setup() {
|
|
10
|
+
super.setup()
|
|
11
|
+
uut = OnSwitchToTab(parent, tabs, presenter, options)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
@Test
|
|
15
|
+
fun attach_onlyInitialTabIsAttached() {
|
|
16
|
+
uut.attach()
|
|
17
|
+
assertIsChild(parent, initialTab())
|
|
18
|
+
assertNotChildOf(parent, *otherTabs())
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@Test
|
|
22
|
+
fun onTabSelected_initialTabIsNotHandled() {
|
|
23
|
+
uut.onTabSelected(initialTab())
|
|
24
|
+
assertNotChildOf(parent, initialTab())
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@Test
|
|
28
|
+
fun onTabSelected_otherTabIsAttached() {
|
|
29
|
+
uut.onTabSelected(tab1)
|
|
30
|
+
assertIsChild(parent, tab1)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
package com.reactnativenavigation.viewcontrollers.bottomtabs.attacher.modes
|
|
2
|
+
|
|
3
|
+
import org.junit.Before
|
|
4
|
+
import org.junit.Test
|
|
5
|
+
|
|
6
|
+
class TogetherTest : AttachModeTest() {
|
|
7
|
+
|
|
8
|
+
@Before
|
|
9
|
+
override fun setup() {
|
|
10
|
+
super.setup()
|
|
11
|
+
uut = Together(parent, tabs, presenter, options)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
@Test
|
|
15
|
+
fun attach_allTabsAreAttached() {
|
|
16
|
+
uut.attach()
|
|
17
|
+
assertIsChild(parent, *tabs.toTypedArray())
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
package com.reactnativenavigation.viewcontrollers.child;
|
|
2
|
+
|
|
3
|
+
import androidx.test.ext.junit.rules.ActivityScenarioRule;
|
|
4
|
+
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
|
5
|
+
import androidx.test.platform.app.InstrumentationRegistry;
|
|
6
|
+
import androidx.test.core.app.ActivityScenario;
|
|
7
|
+
|
|
8
|
+
import com.reactnativenavigation.BaseAndroidTest;
|
|
9
|
+
import com.reactnativenavigation.TestActivity;
|
|
10
|
+
import com.reactnativenavigation.mocks.SimpleViewController;
|
|
11
|
+
import com.reactnativenavigation.options.Options;
|
|
12
|
+
import com.reactnativenavigation.viewcontrollers.viewcontroller.Presenter;
|
|
13
|
+
import com.reactnativenavigation.viewcontrollers.parent.ParentController;
|
|
14
|
+
|
|
15
|
+
import org.junit.Before;
|
|
16
|
+
import org.junit.Rule;
|
|
17
|
+
import org.junit.Test;
|
|
18
|
+
import org.junit.runner.RunWith;
|
|
19
|
+
import org.mockito.Mockito;
|
|
20
|
+
|
|
21
|
+
import static org.mockito.ArgumentMatchers.any;
|
|
22
|
+
import static org.mockito.Mockito.spy;
|
|
23
|
+
import static org.mockito.Mockito.times;
|
|
24
|
+
import static org.mockito.Mockito.verify;
|
|
25
|
+
|
|
26
|
+
@RunWith(AndroidJUnit4.class)
|
|
27
|
+
public class ChildControllerTest extends BaseAndroidTest {
|
|
28
|
+
private ChildController<?> uut;
|
|
29
|
+
private ChildControllersRegistry childRegistry;
|
|
30
|
+
private Presenter presenter;
|
|
31
|
+
private Options resolvedOptions = new Options();
|
|
32
|
+
|
|
33
|
+
@Rule
|
|
34
|
+
public ActivityScenarioRule<TestActivity> rule = new ActivityScenarioRule<>(TestActivity.class);
|
|
35
|
+
|
|
36
|
+
@Before
|
|
37
|
+
public void beforeEach() {
|
|
38
|
+
rule.getScenario().onActivity(activity -> {
|
|
39
|
+
childRegistry = spy(new ChildControllersRegistry());
|
|
40
|
+
presenter = Mockito.mock(Presenter.class);
|
|
41
|
+
uut = new SimpleViewController(activity, childRegistry, "childId", presenter, new Options()) {
|
|
42
|
+
@Override
|
|
43
|
+
public Options resolveCurrentOptions() {
|
|
44
|
+
return resolvedOptions;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
ParentController<?> parent = Mockito.mock(ParentController.class);
|
|
48
|
+
Mockito.when(parent.resolveChildOptions(uut)).thenReturn(Options.EMPTY);
|
|
49
|
+
uut.setParentController(parent);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@Test
|
|
54
|
+
public void onViewAppeared() {
|
|
55
|
+
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> uut.onViewWillAppear());
|
|
56
|
+
verify(childRegistry, times(1)).onViewAppeared(uut);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@Test
|
|
60
|
+
public void onViewDisappear() {
|
|
61
|
+
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
|
|
62
|
+
uut.onViewWillAppear();
|
|
63
|
+
uut.onViewDisappear();
|
|
64
|
+
});
|
|
65
|
+
verify(childRegistry, times(1)).onViewDisappear(uut);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@Test
|
|
69
|
+
public void mergeOptions() {
|
|
70
|
+
try (ActivityScenario<TestActivity> scenario = ActivityScenario.launch(TestActivity.class)) {
|
|
71
|
+
scenario.onActivity(activity -> {
|
|
72
|
+
activity.setContentView(uut.getView());
|
|
73
|
+
Options options = new Options();
|
|
74
|
+
uut.mergeOptions(options);
|
|
75
|
+
verify(presenter).mergeOptions(uut, options);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
@Test
|
|
81
|
+
public void mergeOptions_emptyOptionsAreIgnored() {
|
|
82
|
+
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
|
|
83
|
+
uut.mergeOptions(Options.EMPTY);
|
|
84
|
+
verify(presenter, times(0)).mergeOptions(any(), any());
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@Test
|
|
89
|
+
public void mergeOptions_mergeWithParentViewController() {
|
|
90
|
+
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
|
|
91
|
+
Options options = new Options();
|
|
92
|
+
uut.mergeOptions(options);
|
|
93
|
+
verify(uut.getParentController()).mergeChildOptions(options, uut);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
@Test
|
|
98
|
+
public void destroy() {
|
|
99
|
+
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> uut.destroy());
|
|
100
|
+
verify(childRegistry).onChildDestroyed(uut);
|
|
101
|
+
}
|
|
102
|
+
}
|