sparkling-navigation 2.1.0-rc.24 → 2.1.0-rc.26
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/android/build.gradle.kts +18 -2
- package/android/src/main/java/com/tiktok/sparkling/method/router/open/AbsRouterOpenMethodIDL.kt +1 -3
- package/android/src/main/java/com/tiktok/sparkling/method/router/open/RouterOpenMethod.kt +1 -0
- package/android/src/test/java/com/tiktok/sparkling/method/router/RouterCoverageTest.kt +593 -0
- package/android/src/test/java/com/tiktok/sparkling/method/router/RouterMethodUnitTest.kt +188 -12
- package/dist/src/devServer.js +1 -1
- package/dist/src/devServer.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/ios/Sparkling-Router.podspec +8 -1
- package/ios/SparklingMethodTests/SPKRouterTest.swift +119 -0
- package/module.config.json +2 -2
- package/package.json +2 -2
- package/src/devServer.ts +1 -1
package/android/build.gradle.kts
CHANGED
|
@@ -32,6 +32,15 @@ android {
|
|
|
32
32
|
kotlinOptions {
|
|
33
33
|
jvmTarget = "11"
|
|
34
34
|
}
|
|
35
|
+
|
|
36
|
+
testOptions {
|
|
37
|
+
unitTests.all {
|
|
38
|
+
it.extensions.configure(org.gradle.testing.jacoco.plugins.JacocoTaskExtension::class.java) {
|
|
39
|
+
isIncludeNoLocationClasses = true
|
|
40
|
+
excludes = listOf("jdk.internal.*")
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
35
44
|
}
|
|
36
45
|
|
|
37
46
|
dependencies {
|
|
@@ -39,13 +48,20 @@ dependencies {
|
|
|
39
48
|
implementation(libs.androidx.core.ktx)
|
|
40
49
|
implementation(libs.androidx.appcompat)
|
|
41
50
|
testImplementation(libs.junit)
|
|
51
|
+
testImplementation("io.mockk:mockk:1.13.8")
|
|
52
|
+
testImplementation("org.robolectric:robolectric:4.11.1")
|
|
53
|
+
testImplementation("androidx.test:core:1.5.0")
|
|
42
54
|
androidTestImplementation(libs.androidx.junit)
|
|
43
55
|
androidTestImplementation(libs.androidx.espresso.core)
|
|
44
56
|
val sparklingVersion =
|
|
45
57
|
(findProperty("SPARKLING_ANDROID_SDK_VERSION") as? String)
|
|
46
58
|
?: System.getenv("SPARKLING_ANDROID_SDK_VERSION")
|
|
47
|
-
?: "2.1.0-rc.
|
|
48
|
-
|
|
59
|
+
?: "2.1.0-rc.26"
|
|
60
|
+
if (rootProject.findProject(":sparkling-method") != null) {
|
|
61
|
+
api(project(":sparkling-method"))
|
|
62
|
+
} else {
|
|
63
|
+
api("com.tiktok.sparkling:sparkling-method:$sparklingVersion")
|
|
64
|
+
}
|
|
49
65
|
}
|
|
50
66
|
|
|
51
67
|
tasks.register<JacocoReport>("jacocoTestReport") {
|
package/android/src/main/java/com/tiktok/sparkling/method/router/open/AbsRouterOpenMethodIDL.kt
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
3
3
|
// LICENSE file in the root directory of this source tree.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
// anycode-lint-ignore
|
|
6
6
|
package com.tiktok.sparkling.method.router.open
|
|
7
7
|
|
|
8
8
|
import com.tiktok.sparkling.method.registry.core.annotation.IDLMethodName
|
|
@@ -14,8 +14,6 @@ import com.tiktok.sparkling.method.registry.core.model.idl.IDLMethodBaseModel
|
|
|
14
14
|
import com.tiktok.sparkling.method.registry.core.model.idl.IDLMethodBaseParamModel
|
|
15
15
|
import com.tiktok.sparkling.method.registry.core.model.idl.IDLMethodBaseResultModel
|
|
16
16
|
|
|
17
|
-
/** anycode-lint-ignore */
|
|
18
|
-
|
|
19
17
|
/**
|
|
20
18
|
* GENERATED BY ANYCODE.
|
|
21
19
|
* DO NOT MODIFY!!!
|
|
@@ -0,0 +1,593 @@
|
|
|
1
|
+
package com.tiktok.sparkling.method.router
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import com.tiktok.sparkling.method.registry.core.BridgePlatformType
|
|
5
|
+
import com.tiktok.sparkling.method.registry.core.IBridgeContext
|
|
6
|
+
import com.tiktok.sparkling.method.registry.core.IDLBridgeMethod
|
|
7
|
+
import com.tiktok.sparkling.method.registry.core.model.context.ContextProviderFactory
|
|
8
|
+
import com.tiktok.sparkling.method.registry.core.model.idl.CompletionBlock
|
|
9
|
+
import com.tiktok.sparkling.method.router.close.AbsRouterCloseMethodIDL
|
|
10
|
+
import com.tiktok.sparkling.method.router.close.RouterCloseMethod
|
|
11
|
+
import com.tiktok.sparkling.method.router.open.AbsRouterOpenMethodIDL
|
|
12
|
+
import com.tiktok.sparkling.method.router.open.ReplaceType
|
|
13
|
+
import com.tiktok.sparkling.method.router.open.RouterOpenMethod
|
|
14
|
+
import com.tiktok.sparkling.method.router.utils.AbsRouteOpenHandler
|
|
15
|
+
import com.tiktok.sparkling.method.router.utils.IHostRouterDepend
|
|
16
|
+
import com.tiktok.sparkling.method.router.utils.RouterProvider
|
|
17
|
+
import io.mockk.every
|
|
18
|
+
import io.mockk.mockk
|
|
19
|
+
import io.mockk.verify
|
|
20
|
+
import io.mockk.verifyOrder
|
|
21
|
+
import org.junit.After
|
|
22
|
+
import org.junit.Assert.assertEquals
|
|
23
|
+
import org.junit.Assert.assertFalse
|
|
24
|
+
import org.junit.Assert.assertNotNull
|
|
25
|
+
import org.junit.Assert.assertNull
|
|
26
|
+
import org.junit.Assert.assertSame
|
|
27
|
+
import org.junit.Assert.assertTrue
|
|
28
|
+
import org.junit.Before
|
|
29
|
+
import org.junit.Test
|
|
30
|
+
import org.junit.runner.RunWith
|
|
31
|
+
import org.robolectric.RobolectricTestRunner
|
|
32
|
+
import org.robolectric.annotation.Config
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Extra unit tests for the sparkling-navigation module to cover edge cases not exercised
|
|
36
|
+
* by [RouterMethodUnitTest], including replace-type branches, exception handling,
|
|
37
|
+
* the default [IHostRouterDepend.openScheme] handler chain, and [AbsRouteOpenHandler] wiring.
|
|
38
|
+
*/
|
|
39
|
+
@RunWith(RobolectricTestRunner::class)
|
|
40
|
+
@Config(manifest = Config.NONE, sdk = [33])
|
|
41
|
+
class RouterCoverageTest {
|
|
42
|
+
private lateinit var bridgeContext: IBridgeContext
|
|
43
|
+
private lateinit var context: Context
|
|
44
|
+
|
|
45
|
+
@Before
|
|
46
|
+
fun setUp() {
|
|
47
|
+
context = mockk(relaxed = true)
|
|
48
|
+
bridgeContext = mockk(relaxed = true)
|
|
49
|
+
every { bridgeContext.context } returns context
|
|
50
|
+
RouterProvider.hostRouterDepend = null
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@After
|
|
54
|
+
fun tearDown() {
|
|
55
|
+
RouterProvider.hostRouterDepend = null
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// region RouterOpenMethod ------------------------------------------------------------------
|
|
59
|
+
|
|
60
|
+
@Test
|
|
61
|
+
fun openMethodFailsWhenSDKContextNull() {
|
|
62
|
+
val method = RouterOpenMethod()
|
|
63
|
+
val params = openParams(scheme = "hybrid://lynx?bundle=a")
|
|
64
|
+
val callback = OpenCallbackRecorder()
|
|
65
|
+
|
|
66
|
+
method.handle(params, callback, BridgePlatformType.LYNX)
|
|
67
|
+
|
|
68
|
+
assertEquals(IDLBridgeMethod.FAIL, callback.failureCode)
|
|
69
|
+
assertTrue(callback.failureMsg?.contains("Context not provided") == true)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@Test
|
|
73
|
+
fun openMethodFailsWhenInnerContextNull() {
|
|
74
|
+
val ctxLessBridge = mockk<IBridgeContext>(relaxed = true)
|
|
75
|
+
every { ctxLessBridge.context } returns null
|
|
76
|
+
|
|
77
|
+
val method = RouterOpenMethod().apply { setBridgeContext(ctxLessBridge) }
|
|
78
|
+
val params = openParams(scheme = "hybrid://lynx?bundle=a")
|
|
79
|
+
val callback = OpenCallbackRecorder()
|
|
80
|
+
|
|
81
|
+
method.handle(params, callback, BridgePlatformType.LYNX)
|
|
82
|
+
|
|
83
|
+
assertEquals(IDLBridgeMethod.FAIL, callback.failureCode)
|
|
84
|
+
assertTrue(callback.failureMsg?.contains("Context not provided") == true)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
@Test
|
|
88
|
+
fun openMethodFailsWhenRouterDependNotRegistered() {
|
|
89
|
+
// RouterProvider.hostRouterDepend stays null
|
|
90
|
+
val method = RouterOpenMethod().apply { setBridgeContext(bridgeContext) }
|
|
91
|
+
val params = openParams(scheme = "hybrid://lynx?bundle=a")
|
|
92
|
+
val callback = OpenCallbackRecorder()
|
|
93
|
+
|
|
94
|
+
method.handle(params, callback, BridgePlatformType.LYNX)
|
|
95
|
+
|
|
96
|
+
assertEquals(IDLBridgeMethod.FAIL, callback.failureCode)
|
|
97
|
+
assertTrue(callback.failureMsg?.contains("Router service not available") == true)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
@Test
|
|
101
|
+
fun openMethodFailsWhenOpenSchemeReturnsFalse() {
|
|
102
|
+
val hostRouter = mockk<IHostRouterDepend>(relaxed = true)
|
|
103
|
+
every { hostRouter.openScheme(any(), any(), any(), any(), any()) } returns false
|
|
104
|
+
RouterProvider.hostRouterDepend = hostRouter
|
|
105
|
+
|
|
106
|
+
val method = RouterOpenMethod().apply { setBridgeContext(bridgeContext) }
|
|
107
|
+
val callback = OpenCallbackRecorder()
|
|
108
|
+
|
|
109
|
+
method.handle(openParams(scheme = "hybrid://lynx?bundle=a"), callback, BridgePlatformType.LYNX)
|
|
110
|
+
|
|
111
|
+
assertEquals(IDLBridgeMethod.FAIL, callback.failureCode)
|
|
112
|
+
assertTrue(callback.failureMsg?.contains("Failed to open scheme") == true)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
@Test
|
|
116
|
+
fun openMethodSwallowsExceptionAndReportsFailure() {
|
|
117
|
+
val hostRouter = mockk<IHostRouterDepend>(relaxed = true)
|
|
118
|
+
every {
|
|
119
|
+
hostRouter.openScheme(any(), any(), any(), any(), any())
|
|
120
|
+
} throws RuntimeException("boom")
|
|
121
|
+
RouterProvider.hostRouterDepend = hostRouter
|
|
122
|
+
|
|
123
|
+
val method = RouterOpenMethod().apply { setBridgeContext(bridgeContext) }
|
|
124
|
+
val callback = OpenCallbackRecorder()
|
|
125
|
+
|
|
126
|
+
method.handle(openParams(scheme = "hybrid://lynx?bundle=a"), callback, BridgePlatformType.LYNX)
|
|
127
|
+
|
|
128
|
+
assertEquals(IDLBridgeMethod.FAIL, callback.failureCode)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
@Test
|
|
132
|
+
fun openMethodReplaceAlwaysCloseBeforeOpenInvokesCloseFirst() {
|
|
133
|
+
val hostRouter = mockk<IHostRouterDepend>(relaxed = true)
|
|
134
|
+
every { hostRouter.closeView(any(), any(), any(), any()) } returns true
|
|
135
|
+
every { hostRouter.openScheme(any(), any(), any(), any(), any()) } returns true
|
|
136
|
+
RouterProvider.hostRouterDepend = hostRouter
|
|
137
|
+
|
|
138
|
+
val method = RouterOpenMethod().apply { setBridgeContext(bridgeContext) }
|
|
139
|
+
val callback = OpenCallbackRecorder()
|
|
140
|
+
|
|
141
|
+
method.handle(
|
|
142
|
+
openParams(
|
|
143
|
+
scheme = "hybrid://lynx?bundle=a",
|
|
144
|
+
replace = true,
|
|
145
|
+
replaceType = ReplaceType.alwaysCloseBeforeOpen.name,
|
|
146
|
+
),
|
|
147
|
+
callback,
|
|
148
|
+
BridgePlatformType.LYNX,
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
assertNotNull(callback.successResult)
|
|
152
|
+
verifyOrder {
|
|
153
|
+
hostRouter.closeView(bridgeContext, BridgePlatformType.LYNX, null, false)
|
|
154
|
+
hostRouter.openScheme(any(), any(), any(), BridgePlatformType.LYNX, any())
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
@Test
|
|
159
|
+
fun openMethodReplaceAlwaysCloseAfterOpenAlwaysClosesEvenWhenOpenFails() {
|
|
160
|
+
val hostRouter = mockk<IHostRouterDepend>(relaxed = true)
|
|
161
|
+
every { hostRouter.openScheme(any(), any(), any(), any(), any()) } returns false
|
|
162
|
+
every { hostRouter.closeView(any(), any(), any(), any()) } returns true
|
|
163
|
+
RouterProvider.hostRouterDepend = hostRouter
|
|
164
|
+
|
|
165
|
+
val method = RouterOpenMethod().apply { setBridgeContext(bridgeContext) }
|
|
166
|
+
val callback = OpenCallbackRecorder()
|
|
167
|
+
|
|
168
|
+
method.handle(
|
|
169
|
+
openParams(
|
|
170
|
+
scheme = "hybrid://lynx?bundle=a",
|
|
171
|
+
replace = true,
|
|
172
|
+
replaceType = ReplaceType.alwaysCloseAfterOpen.name,
|
|
173
|
+
),
|
|
174
|
+
callback,
|
|
175
|
+
BridgePlatformType.LYNX,
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
// open returned false so overall is failure, but close must still have been invoked
|
|
179
|
+
assertEquals(IDLBridgeMethod.FAIL, callback.failureCode)
|
|
180
|
+
verify(exactly = 1) {
|
|
181
|
+
hostRouter.closeView(bridgeContext, BridgePlatformType.LYNX, null, false)
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
@Test
|
|
186
|
+
fun openMethodReplaceOnlyCloseAfterOpenSucceedSkipsCloseOnFailure() {
|
|
187
|
+
val hostRouter = mockk<IHostRouterDepend>(relaxed = true)
|
|
188
|
+
every { hostRouter.openScheme(any(), any(), any(), any(), any()) } returns false
|
|
189
|
+
RouterProvider.hostRouterDepend = hostRouter
|
|
190
|
+
|
|
191
|
+
val method = RouterOpenMethod().apply { setBridgeContext(bridgeContext) }
|
|
192
|
+
val callback = OpenCallbackRecorder()
|
|
193
|
+
|
|
194
|
+
method.handle(
|
|
195
|
+
openParams(
|
|
196
|
+
scheme = "hybrid://lynx?bundle=a",
|
|
197
|
+
replace = true,
|
|
198
|
+
// default ReplaceType.onlyCloseAfterOpenSucceed when replaceType is null
|
|
199
|
+
replaceType = null,
|
|
200
|
+
),
|
|
201
|
+
callback,
|
|
202
|
+
BridgePlatformType.LYNX,
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
assertEquals(IDLBridgeMethod.FAIL, callback.failureCode)
|
|
206
|
+
verify(exactly = 0) { hostRouter.closeView(any(), any(), any(), any()) }
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
@Test
|
|
210
|
+
fun openMethodReplaceOnlyCloseAfterOpenSucceedClosesOnSuccess() {
|
|
211
|
+
val hostRouter = mockk<IHostRouterDepend>(relaxed = true)
|
|
212
|
+
every { hostRouter.openScheme(any(), any(), any(), any(), any()) } returns true
|
|
213
|
+
every { hostRouter.closeView(any(), any(), any(), any()) } returns true
|
|
214
|
+
RouterProvider.hostRouterDepend = hostRouter
|
|
215
|
+
|
|
216
|
+
val method = RouterOpenMethod().apply { setBridgeContext(bridgeContext) }
|
|
217
|
+
val callback = OpenCallbackRecorder()
|
|
218
|
+
|
|
219
|
+
method.handle(
|
|
220
|
+
openParams(
|
|
221
|
+
scheme = "hybrid://lynx?bundle=a",
|
|
222
|
+
replace = true,
|
|
223
|
+
replaceType = ReplaceType.onlyCloseAfterOpenSucceed.name,
|
|
224
|
+
),
|
|
225
|
+
callback,
|
|
226
|
+
BridgePlatformType.LYNX,
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
assertNotNull(callback.successResult)
|
|
230
|
+
verify(exactly = 1) {
|
|
231
|
+
hostRouter.closeView(bridgeContext, BridgePlatformType.LYNX, null, false)
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
@Test
|
|
236
|
+
fun openMethodReplaceSwallowsExceptionAndReportsFailure() {
|
|
237
|
+
val hostRouter = mockk<IHostRouterDepend>(relaxed = true)
|
|
238
|
+
every {
|
|
239
|
+
hostRouter.openScheme(any(), any(), any(), any(), any())
|
|
240
|
+
} throws IllegalStateException("kaboom")
|
|
241
|
+
RouterProvider.hostRouterDepend = hostRouter
|
|
242
|
+
|
|
243
|
+
val method = RouterOpenMethod().apply { setBridgeContext(bridgeContext) }
|
|
244
|
+
val callback = OpenCallbackRecorder()
|
|
245
|
+
|
|
246
|
+
method.handle(
|
|
247
|
+
openParams(
|
|
248
|
+
scheme = "hybrid://lynx?bundle=a",
|
|
249
|
+
replace = true,
|
|
250
|
+
replaceType = ReplaceType.alwaysCloseBeforeOpen.name,
|
|
251
|
+
),
|
|
252
|
+
callback,
|
|
253
|
+
BridgePlatformType.LYNX,
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
assertEquals(IDLBridgeMethod.FAIL, callback.failureCode)
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// endregion
|
|
260
|
+
|
|
261
|
+
// region RouterCloseMethod -----------------------------------------------------------------
|
|
262
|
+
|
|
263
|
+
@Test
|
|
264
|
+
fun closeMethodReportsCurrentContainerErrorWhenIdBlank() {
|
|
265
|
+
val hostRouter = mockk<IHostRouterDepend>(relaxed = true)
|
|
266
|
+
every { hostRouter.closeView(any(), any(), any(), any()) } returns false
|
|
267
|
+
RouterProvider.hostRouterDepend = hostRouter
|
|
268
|
+
|
|
269
|
+
val method = RouterCloseMethod().apply { setBridgeContext(bridgeContext) }
|
|
270
|
+
val params = mockk<AbsRouterCloseMethodIDL.IDLMethodCloseParamModel>(relaxed = true)
|
|
271
|
+
every { params.containerID } returns " "
|
|
272
|
+
every { params.animated } returns null
|
|
273
|
+
|
|
274
|
+
val callback = CloseCallbackRecorder()
|
|
275
|
+
method.handle(params, callback, BridgePlatformType.LYNX)
|
|
276
|
+
|
|
277
|
+
assertEquals(IDLBridgeMethod.FAIL, callback.failureCode)
|
|
278
|
+
assertEquals("Failed to close current container", callback.failureMsg)
|
|
279
|
+
// animated default is true when null
|
|
280
|
+
verify(exactly = 1) {
|
|
281
|
+
hostRouter.closeView(bridgeContext, BridgePlatformType.LYNX, " ", true)
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
@Test
|
|
286
|
+
fun closeMethodReportsContainerSpecificErrorWhenIdProvided() {
|
|
287
|
+
val hostRouter = mockk<IHostRouterDepend>(relaxed = true)
|
|
288
|
+
every { hostRouter.closeView(any(), any(), any(), any()) } returns false
|
|
289
|
+
RouterProvider.hostRouterDepend = hostRouter
|
|
290
|
+
|
|
291
|
+
val method = RouterCloseMethod().apply { setBridgeContext(bridgeContext) }
|
|
292
|
+
val params = mockk<AbsRouterCloseMethodIDL.IDLMethodCloseParamModel>(relaxed = true)
|
|
293
|
+
every { params.containerID } returns "container-x"
|
|
294
|
+
every { params.animated } returns true
|
|
295
|
+
|
|
296
|
+
val callback = CloseCallbackRecorder()
|
|
297
|
+
method.handle(params, callback, BridgePlatformType.LYNX)
|
|
298
|
+
|
|
299
|
+
assertEquals(IDLBridgeMethod.FAIL, callback.failureCode)
|
|
300
|
+
assertEquals("Failed to close container: container-x", callback.failureMsg)
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
@Test
|
|
304
|
+
fun closeMethodSwallowsExceptionAndReportsFailure() {
|
|
305
|
+
val hostRouter = mockk<IHostRouterDepend>(relaxed = true)
|
|
306
|
+
every {
|
|
307
|
+
hostRouter.closeView(any(), any(), any(), any())
|
|
308
|
+
} throws RuntimeException("close-boom")
|
|
309
|
+
RouterProvider.hostRouterDepend = hostRouter
|
|
310
|
+
|
|
311
|
+
val method = RouterCloseMethod().apply { setBridgeContext(bridgeContext) }
|
|
312
|
+
val params = mockk<AbsRouterCloseMethodIDL.IDLMethodCloseParamModel>(relaxed = true)
|
|
313
|
+
every { params.containerID } returns "container-y"
|
|
314
|
+
every { params.animated } returns true
|
|
315
|
+
|
|
316
|
+
val callback = CloseCallbackRecorder()
|
|
317
|
+
method.handle(params, callback, BridgePlatformType.LYNX)
|
|
318
|
+
|
|
319
|
+
assertEquals(IDLBridgeMethod.FAIL, callback.failureCode)
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// endregion
|
|
323
|
+
|
|
324
|
+
// region AbsRouteOpenHandler ---------------------------------------------------------------
|
|
325
|
+
|
|
326
|
+
@Test
|
|
327
|
+
fun absRouteOpenHandlerStoresNextAndExceptionHandlers() {
|
|
328
|
+
val handler = StubRouteOpenHandler()
|
|
329
|
+
val next = StubRouteOpenHandler()
|
|
330
|
+
val errorHandler = StubRouteOpenHandler()
|
|
331
|
+
|
|
332
|
+
assertNull(handler.nextHandler)
|
|
333
|
+
assertNull(handler.exceptionHandler)
|
|
334
|
+
|
|
335
|
+
handler.setNextHandler(next)
|
|
336
|
+
handler.setExceptionHandler(errorHandler)
|
|
337
|
+
|
|
338
|
+
assertSame(next, handler.nextHandler)
|
|
339
|
+
assertSame(errorHandler, handler.exceptionHandler)
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// endregion
|
|
343
|
+
|
|
344
|
+
// region IHostRouterDepend default openScheme ----------------------------------------------
|
|
345
|
+
|
|
346
|
+
@Test
|
|
347
|
+
fun defaultOpenSchemeReturnsFalseWhenHandlerListEmpty() {
|
|
348
|
+
val depend =
|
|
349
|
+
object : IHostRouterDepend {
|
|
350
|
+
override fun closeView(
|
|
351
|
+
bridgeContext: IBridgeContext?,
|
|
352
|
+
type: BridgePlatformType,
|
|
353
|
+
containerID: String?,
|
|
354
|
+
animated: Boolean?,
|
|
355
|
+
) = true
|
|
356
|
+
// empty handler list (default impl)
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
val result =
|
|
360
|
+
depend.openScheme(
|
|
361
|
+
bridgeContext,
|
|
362
|
+
"hybrid://lynx?bundle=a",
|
|
363
|
+
emptyMap(),
|
|
364
|
+
BridgePlatformType.LYNX,
|
|
365
|
+
context,
|
|
366
|
+
)
|
|
367
|
+
assertFalse(result)
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
@Test
|
|
371
|
+
fun defaultOpenSchemeReturnsTrueWhenFirstHandlerHandles() {
|
|
372
|
+
val handler =
|
|
373
|
+
StubRouteOpenHandler(
|
|
374
|
+
supported = listOf(BridgePlatformType.LYNX),
|
|
375
|
+
opener = { _, _, _ -> true },
|
|
376
|
+
)
|
|
377
|
+
val depend = makeDependWithHandlers(listOf(handler))
|
|
378
|
+
|
|
379
|
+
val result =
|
|
380
|
+
depend.openScheme(
|
|
381
|
+
bridgeContext,
|
|
382
|
+
"hybrid://lynx?bundle=a",
|
|
383
|
+
emptyMap(),
|
|
384
|
+
BridgePlatformType.LYNX,
|
|
385
|
+
context,
|
|
386
|
+
)
|
|
387
|
+
|
|
388
|
+
assertTrue(result)
|
|
389
|
+
assertEquals(1, handler.callCount)
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
@Test
|
|
393
|
+
fun defaultOpenSchemeFallsThroughWhenHandlerReturnsFalse() {
|
|
394
|
+
val first =
|
|
395
|
+
StubRouteOpenHandler(
|
|
396
|
+
supported = listOf(BridgePlatformType.LYNX),
|
|
397
|
+
opener = { _, _, _ -> false },
|
|
398
|
+
)
|
|
399
|
+
val second =
|
|
400
|
+
StubRouteOpenHandler(
|
|
401
|
+
supported = listOf(BridgePlatformType.LYNX),
|
|
402
|
+
opener = { _, _, _ -> true },
|
|
403
|
+
)
|
|
404
|
+
val depend = makeDependWithHandlers(listOf(first, second))
|
|
405
|
+
|
|
406
|
+
val result =
|
|
407
|
+
depend.openScheme(
|
|
408
|
+
bridgeContext,
|
|
409
|
+
"hybrid://lynx?bundle=a",
|
|
410
|
+
emptyMap(),
|
|
411
|
+
BridgePlatformType.LYNX,
|
|
412
|
+
context,
|
|
413
|
+
)
|
|
414
|
+
|
|
415
|
+
assertTrue(result)
|
|
416
|
+
assertEquals(1, first.callCount)
|
|
417
|
+
assertEquals(1, second.callCount)
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
@Test
|
|
421
|
+
fun defaultOpenSchemeSkipsHandlerWithUnsupportedPlatform() {
|
|
422
|
+
val webOnly =
|
|
423
|
+
StubRouteOpenHandler(
|
|
424
|
+
supported = listOf(BridgePlatformType.WEB),
|
|
425
|
+
opener = { _, _, _ -> true },
|
|
426
|
+
)
|
|
427
|
+
val lynxAll =
|
|
428
|
+
StubRouteOpenHandler(
|
|
429
|
+
supported = listOf(BridgePlatformType.ALL),
|
|
430
|
+
opener = { _, _, _ -> true },
|
|
431
|
+
)
|
|
432
|
+
val depend = makeDependWithHandlers(listOf(webOnly, lynxAll))
|
|
433
|
+
|
|
434
|
+
val result =
|
|
435
|
+
depend.openScheme(
|
|
436
|
+
bridgeContext,
|
|
437
|
+
"hybrid://lynx?bundle=a",
|
|
438
|
+
emptyMap(),
|
|
439
|
+
BridgePlatformType.LYNX,
|
|
440
|
+
context,
|
|
441
|
+
)
|
|
442
|
+
|
|
443
|
+
assertTrue(result)
|
|
444
|
+
assertEquals(0, webOnly.callCount)
|
|
445
|
+
assertEquals(1, lynxAll.callCount)
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
@Test
|
|
449
|
+
fun defaultOpenSchemeRoutesToExceptionHandlerWhenHandlerThrows() {
|
|
450
|
+
val throwing =
|
|
451
|
+
StubRouteOpenHandler(
|
|
452
|
+
supported = listOf(BridgePlatformType.LYNX),
|
|
453
|
+
opener = { _, _, _ -> throw RuntimeException("failed") },
|
|
454
|
+
)
|
|
455
|
+
val errorHandler =
|
|
456
|
+
StubRouteOpenHandler(
|
|
457
|
+
supported = listOf(BridgePlatformType.LYNX),
|
|
458
|
+
opener = { _, _, _ -> true },
|
|
459
|
+
)
|
|
460
|
+
val depend =
|
|
461
|
+
object : IHostRouterDepend {
|
|
462
|
+
override fun closeView(
|
|
463
|
+
bridgeContext: IBridgeContext?,
|
|
464
|
+
type: BridgePlatformType,
|
|
465
|
+
containerID: String?,
|
|
466
|
+
animated: Boolean?,
|
|
467
|
+
) = true
|
|
468
|
+
|
|
469
|
+
override fun provideRouteOpenHandlerList(
|
|
470
|
+
contextProviderFactory: ContextProviderFactory?,
|
|
471
|
+
) = listOf<AbsRouteOpenHandler>(throwing)
|
|
472
|
+
|
|
473
|
+
override fun provideRouteOpenExceptionHandler(
|
|
474
|
+
contextProviderFactory: ContextProviderFactory?,
|
|
475
|
+
): AbsRouteOpenHandler = errorHandler
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
val result =
|
|
479
|
+
depend.openScheme(
|
|
480
|
+
bridgeContext,
|
|
481
|
+
"hybrid://lynx?bundle=a",
|
|
482
|
+
emptyMap(),
|
|
483
|
+
BridgePlatformType.LYNX,
|
|
484
|
+
context,
|
|
485
|
+
)
|
|
486
|
+
|
|
487
|
+
assertTrue(result)
|
|
488
|
+
assertEquals(1, throwing.callCount)
|
|
489
|
+
assertEquals(1, errorHandler.callCount)
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
// endregion
|
|
493
|
+
|
|
494
|
+
// region helpers ---------------------------------------------------------------------------
|
|
495
|
+
|
|
496
|
+
private fun openParams(
|
|
497
|
+
scheme: String,
|
|
498
|
+
replace: Boolean? = false,
|
|
499
|
+
replaceType: String? = null,
|
|
500
|
+
useSysBrowser: Boolean? = null,
|
|
501
|
+
): AbsRouterOpenMethodIDL.IDLMethodOpenParamModel {
|
|
502
|
+
val params = mockk<AbsRouterOpenMethodIDL.IDLMethodOpenParamModel>(relaxed = true)
|
|
503
|
+
every { params.scheme } returns scheme
|
|
504
|
+
every { params.replace } returns replace
|
|
505
|
+
every { params.replaceType } returns replaceType
|
|
506
|
+
every { params.useSysBrowser } returns useSysBrowser
|
|
507
|
+
every { params.extra } returns null
|
|
508
|
+
return params
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
private fun makeDependWithHandlers(handlers: List<AbsRouteOpenHandler>) =
|
|
512
|
+
object : IHostRouterDepend {
|
|
513
|
+
override fun closeView(
|
|
514
|
+
bridgeContext: IBridgeContext?,
|
|
515
|
+
type: BridgePlatformType,
|
|
516
|
+
containerID: String?,
|
|
517
|
+
animated: Boolean?,
|
|
518
|
+
) = true
|
|
519
|
+
|
|
520
|
+
override fun provideRouteOpenHandlerList(
|
|
521
|
+
contextProviderFactory: ContextProviderFactory?,
|
|
522
|
+
) = handlers
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
private class StubRouteOpenHandler(
|
|
526
|
+
private val supported: List<BridgePlatformType> = listOf(BridgePlatformType.ALL),
|
|
527
|
+
private val opener: (String, Map<String, Any>, Context?) -> Boolean = { _, _, _ -> false },
|
|
528
|
+
) : AbsRouteOpenHandler() {
|
|
529
|
+
var callCount: Int = 0
|
|
530
|
+
private set
|
|
531
|
+
|
|
532
|
+
override fun openScheme(
|
|
533
|
+
scheme: String,
|
|
534
|
+
extraInfo: Map<String, Any>,
|
|
535
|
+
context: Context?,
|
|
536
|
+
): Boolean {
|
|
537
|
+
callCount++
|
|
538
|
+
return opener(scheme, extraInfo, context)
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
override fun getSupportPlatformTypeList(): List<BridgePlatformType> = supported
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
private class OpenCallbackRecorder : CompletionBlock<AbsRouterOpenMethodIDL.IDLMethodOpenResultModel> {
|
|
545
|
+
var successResult: AbsRouterOpenMethodIDL.IDLMethodOpenResultModel? = null
|
|
546
|
+
var failureCode: Int? = null
|
|
547
|
+
var failureMsg: String? = null
|
|
548
|
+
|
|
549
|
+
override fun onSuccess(
|
|
550
|
+
result: AbsRouterOpenMethodIDL.IDLMethodOpenResultModel,
|
|
551
|
+
msg: String,
|
|
552
|
+
) {
|
|
553
|
+
successResult = result
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
override fun onFailure(
|
|
557
|
+
code: Int,
|
|
558
|
+
msg: String,
|
|
559
|
+
data: AbsRouterOpenMethodIDL.IDLMethodOpenResultModel?,
|
|
560
|
+
) {
|
|
561
|
+
failureCode = code
|
|
562
|
+
failureMsg = msg
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
override fun onRawSuccess(data: AbsRouterOpenMethodIDL.IDLMethodOpenResultModel?) = Unit
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
private class CloseCallbackRecorder : CompletionBlock<AbsRouterCloseMethodIDL.IDLMethodCloseResultModel> {
|
|
569
|
+
var successResult: AbsRouterCloseMethodIDL.IDLMethodCloseResultModel? = null
|
|
570
|
+
var failureCode: Int? = null
|
|
571
|
+
var failureMsg: String? = null
|
|
572
|
+
|
|
573
|
+
override fun onSuccess(
|
|
574
|
+
result: AbsRouterCloseMethodIDL.IDLMethodCloseResultModel,
|
|
575
|
+
msg: String,
|
|
576
|
+
) {
|
|
577
|
+
successResult = result
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
override fun onFailure(
|
|
581
|
+
code: Int,
|
|
582
|
+
msg: String,
|
|
583
|
+
data: AbsRouterCloseMethodIDL.IDLMethodCloseResultModel?,
|
|
584
|
+
) {
|
|
585
|
+
failureCode = code
|
|
586
|
+
failureMsg = msg
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
override fun onRawSuccess(data: AbsRouterCloseMethodIDL.IDLMethodCloseResultModel?) = Unit
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
// endregion
|
|
593
|
+
}
|
|
@@ -1,20 +1,196 @@
|
|
|
1
|
-
// Copyright (c) 2022 TikTok Pte. Ltd.
|
|
2
|
-
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
3
|
-
// LICENSE file in the root directory of this source tree.
|
|
4
1
|
package com.tiktok.sparkling.method.router
|
|
5
2
|
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import com.tiktok.sparkling.method.registry.core.BridgePlatformType
|
|
5
|
+
import com.tiktok.sparkling.method.registry.core.IBridgeContext
|
|
6
|
+
import com.tiktok.sparkling.method.registry.core.IDLBridgeMethod
|
|
7
|
+
import com.tiktok.sparkling.method.registry.core.model.idl.CompletionBlock
|
|
8
|
+
import com.tiktok.sparkling.method.router.close.AbsRouterCloseMethodIDL
|
|
9
|
+
import com.tiktok.sparkling.method.router.close.RouterCloseMethod
|
|
10
|
+
import com.tiktok.sparkling.method.router.open.AbsRouterOpenMethodIDL
|
|
11
|
+
import com.tiktok.sparkling.method.router.open.RouterOpenMethod
|
|
12
|
+
import com.tiktok.sparkling.method.router.utils.IHostRouterDepend
|
|
13
|
+
import com.tiktok.sparkling.method.router.utils.RouterProvider
|
|
14
|
+
import io.mockk.every
|
|
15
|
+
import io.mockk.mockk
|
|
16
|
+
import io.mockk.verify
|
|
17
|
+
import org.junit.After
|
|
18
|
+
import org.junit.Assert.assertEquals
|
|
19
|
+
import org.junit.Assert.assertNotNull
|
|
20
|
+
import org.junit.Assert.assertNull
|
|
21
|
+
import org.junit.Assert.assertTrue
|
|
22
|
+
import org.junit.Before
|
|
6
23
|
import org.junit.Test
|
|
24
|
+
import org.junit.runner.RunWith
|
|
25
|
+
import org.robolectric.RobolectricTestRunner
|
|
26
|
+
import org.robolectric.annotation.Config
|
|
7
27
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Example local unit test, which will execute on the development machine (host).
|
|
12
|
-
*
|
|
13
|
-
* See [testing documentation](http://d.android.com/tools/testing).
|
|
14
|
-
*/
|
|
28
|
+
@RunWith(RobolectricTestRunner::class)
|
|
29
|
+
@Config(manifest = Config.NONE, sdk = [33])
|
|
15
30
|
class RouterMethodUnitTest {
|
|
31
|
+
private lateinit var bridgeContext: IBridgeContext
|
|
32
|
+
private lateinit var context: Context
|
|
33
|
+
|
|
34
|
+
@Before
|
|
35
|
+
fun setUp() {
|
|
36
|
+
context = mockk(relaxed = true)
|
|
37
|
+
bridgeContext = mockk(relaxed = true)
|
|
38
|
+
every { bridgeContext.context } returns context
|
|
39
|
+
RouterProvider.hostRouterDepend = null
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@After
|
|
43
|
+
fun tearDown() {
|
|
44
|
+
RouterProvider.hostRouterDepend = null
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@Test
|
|
48
|
+
fun openMethodFailsWhenSchemeBlank() {
|
|
49
|
+
val method = RouterOpenMethod().apply { setBridgeContext(bridgeContext) }
|
|
50
|
+
val params = mockk<AbsRouterOpenMethodIDL.IDLMethodOpenParamModel>(relaxed = true)
|
|
51
|
+
every { params.scheme } returns " "
|
|
52
|
+
every { params.replace } returns false
|
|
53
|
+
|
|
54
|
+
val callback = OpenCallbackRecorder()
|
|
55
|
+
method.handle(params, callback, BridgePlatformType.LYNX)
|
|
56
|
+
|
|
57
|
+
assertTrue(callback.successResult == null)
|
|
58
|
+
assertEquals(IDLBridgeMethod.INVALID_PARAM, callback.failureCode)
|
|
59
|
+
assertTrue(callback.failureMsg?.contains("scheme") == true)
|
|
60
|
+
}
|
|
61
|
+
|
|
16
62
|
@Test
|
|
17
|
-
fun
|
|
18
|
-
|
|
63
|
+
fun openMethodSucceedsWithValidScheme() {
|
|
64
|
+
val hostRouter = mockk<IHostRouterDepend>(relaxed = true)
|
|
65
|
+
every {
|
|
66
|
+
hostRouter.openScheme(any(), any(), any(), any(), any())
|
|
67
|
+
} returns true
|
|
68
|
+
RouterProvider.hostRouterDepend = hostRouter
|
|
69
|
+
|
|
70
|
+
val method = RouterOpenMethod().apply { setBridgeContext(bridgeContext) }
|
|
71
|
+
val params = mockk<AbsRouterOpenMethodIDL.IDLMethodOpenParamModel>(relaxed = true)
|
|
72
|
+
every { params.scheme } returns "hybrid://lynxview?bundle=main.lynx.bundle"
|
|
73
|
+
every { params.replace } returns false
|
|
74
|
+
every { params.useSysBrowser } returns true
|
|
75
|
+
every { params.replaceType } returns null
|
|
76
|
+
every { params.extra } returns null
|
|
77
|
+
|
|
78
|
+
val callback = OpenCallbackRecorder()
|
|
79
|
+
method.handle(params, callback, BridgePlatformType.LYNX)
|
|
80
|
+
|
|
81
|
+
assertNotNull(callback.successResult)
|
|
82
|
+
assertNull(callback.failureCode)
|
|
83
|
+
verify(exactly = 1) {
|
|
84
|
+
hostRouter.openScheme(
|
|
85
|
+
bridgeContext,
|
|
86
|
+
"hybrid://lynxview?bundle=main.lynx.bundle",
|
|
87
|
+
any(),
|
|
88
|
+
BridgePlatformType.LYNX,
|
|
89
|
+
context,
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
@Test
|
|
95
|
+
fun openMethodFailsWhenReplaceTypeInvalid() {
|
|
96
|
+
val hostRouter = mockk<IHostRouterDepend>(relaxed = true)
|
|
97
|
+
RouterProvider.hostRouterDepend = hostRouter
|
|
98
|
+
|
|
99
|
+
val method = RouterOpenMethod().apply { setBridgeContext(bridgeContext) }
|
|
100
|
+
val params = mockk<AbsRouterOpenMethodIDL.IDLMethodOpenParamModel>(relaxed = true)
|
|
101
|
+
every { params.scheme } returns "hybrid://lynxview?bundle=main.lynx.bundle"
|
|
102
|
+
every { params.replace } returns true
|
|
103
|
+
every { params.replaceType } returns "not-a-valid-type"
|
|
104
|
+
|
|
105
|
+
val callback = OpenCallbackRecorder()
|
|
106
|
+
method.handle(params, callback, BridgePlatformType.LYNX)
|
|
107
|
+
|
|
108
|
+
assertEquals(IDLBridgeMethod.INVALID_PARAM, callback.failureCode)
|
|
109
|
+
assertTrue(callback.failureMsg?.contains("Invalid replaceType") == true)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
@Test
|
|
113
|
+
fun closeMethodFailsWhenRouterNotRegistered() {
|
|
114
|
+
val method = RouterCloseMethod().apply { setBridgeContext(bridgeContext) }
|
|
115
|
+
val params = mockk<AbsRouterCloseMethodIDL.IDLMethodCloseParamModel>(relaxed = true)
|
|
116
|
+
every { params.containerID } returns "container-1"
|
|
117
|
+
every { params.animated } returns true
|
|
118
|
+
|
|
119
|
+
val callback = CloseCallbackRecorder()
|
|
120
|
+
method.handle(params, callback, BridgePlatformType.LYNX)
|
|
121
|
+
|
|
122
|
+
assertEquals(IDLBridgeMethod.FAIL, callback.failureCode)
|
|
123
|
+
assertTrue(callback.failureMsg?.contains("Router service not available") == true)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
@Test
|
|
127
|
+
fun closeMethodSucceedsWhenRouterClosesView() {
|
|
128
|
+
val hostRouter = mockk<IHostRouterDepend>(relaxed = true)
|
|
129
|
+
every {
|
|
130
|
+
hostRouter.closeView(any(), any(), any(), any())
|
|
131
|
+
} returns true
|
|
132
|
+
RouterProvider.hostRouterDepend = hostRouter
|
|
133
|
+
|
|
134
|
+
val method = RouterCloseMethod().apply { setBridgeContext(bridgeContext) }
|
|
135
|
+
val params = mockk<AbsRouterCloseMethodIDL.IDLMethodCloseParamModel>(relaxed = true)
|
|
136
|
+
every { params.containerID } returns "container-2"
|
|
137
|
+
every { params.animated } returns false
|
|
138
|
+
|
|
139
|
+
val callback = CloseCallbackRecorder()
|
|
140
|
+
method.handle(params, callback, BridgePlatformType.LYNX)
|
|
141
|
+
|
|
142
|
+
assertNotNull(callback.successResult)
|
|
143
|
+
assertNull(callback.failureCode)
|
|
144
|
+
verify(exactly = 1) {
|
|
145
|
+
hostRouter.closeView(bridgeContext, BridgePlatformType.LYNX, "container-2", false)
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
private class OpenCallbackRecorder : CompletionBlock<AbsRouterOpenMethodIDL.IDLMethodOpenResultModel> {
|
|
150
|
+
var successResult: AbsRouterOpenMethodIDL.IDLMethodOpenResultModel? = null
|
|
151
|
+
var failureCode: Int? = null
|
|
152
|
+
var failureMsg: String? = null
|
|
153
|
+
|
|
154
|
+
override fun onSuccess(
|
|
155
|
+
result: AbsRouterOpenMethodIDL.IDLMethodOpenResultModel,
|
|
156
|
+
msg: String,
|
|
157
|
+
) {
|
|
158
|
+
successResult = result
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
override fun onFailure(
|
|
162
|
+
code: Int,
|
|
163
|
+
msg: String,
|
|
164
|
+
data: AbsRouterOpenMethodIDL.IDLMethodOpenResultModel?,
|
|
165
|
+
) {
|
|
166
|
+
failureCode = code
|
|
167
|
+
failureMsg = msg
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
override fun onRawSuccess(data: AbsRouterOpenMethodIDL.IDLMethodOpenResultModel?) = Unit
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
private class CloseCallbackRecorder : CompletionBlock<AbsRouterCloseMethodIDL.IDLMethodCloseResultModel> {
|
|
174
|
+
var successResult: AbsRouterCloseMethodIDL.IDLMethodCloseResultModel? = null
|
|
175
|
+
var failureCode: Int? = null
|
|
176
|
+
var failureMsg: String? = null
|
|
177
|
+
|
|
178
|
+
override fun onSuccess(
|
|
179
|
+
result: AbsRouterCloseMethodIDL.IDLMethodCloseResultModel,
|
|
180
|
+
msg: String,
|
|
181
|
+
) {
|
|
182
|
+
successResult = result
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
override fun onFailure(
|
|
186
|
+
code: Int,
|
|
187
|
+
msg: String,
|
|
188
|
+
data: AbsRouterCloseMethodIDL.IDLMethodCloseResultModel?,
|
|
189
|
+
) {
|
|
190
|
+
failureCode = code
|
|
191
|
+
failureMsg = msg
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
override fun onRawSuccess(data: AbsRouterCloseMethodIDL.IDLMethodCloseResultModel?) = Unit
|
|
19
195
|
}
|
|
20
196
|
}
|
package/dist/src/devServer.js
CHANGED
|
@@ -17,7 +17,7 @@ export function getDevServerBaseURL() {
|
|
|
17
17
|
}
|
|
18
18
|
// Prefer the actual URL the native side used to load this bundle.
|
|
19
19
|
// lynx.__globalProps.queryItems.url is set by the SDK from the scheme's
|
|
20
|
-
// url= parameter (e.g. "http://
|
|
20
|
+
// url= parameter (e.g. "http://127.0.0.1:5969/main.lynx.bundle").
|
|
21
21
|
if (typeof lynx !== 'undefined' && ((_b = (_a = lynx === null || lynx === void 0 ? void 0 : lynx.__globalProps) === null || _a === void 0 ? void 0 : _a.queryItems) === null || _b === void 0 ? void 0 : _b.url)) {
|
|
22
22
|
const pageUrl = lynx.__globalProps.queryItems.url;
|
|
23
23
|
if (pageUrl.startsWith('http://') || pageUrl.startsWith('https://')) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"devServer.js","sourceRoot":"","sources":["../../src/devServer.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,yEAAyE;AACzE,0DAA0D;AAM1D;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB;;IAC/B,IAAI,CAAC;QACD,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,CAAC,OAAO,EAAE,CAAC;YAC7C,OAAO,SAAS,CAAC;QACrB,CAAC;QAED,kEAAkE;QAClE,wEAAwE;QACxE,
|
|
1
|
+
{"version":3,"file":"devServer.js","sourceRoot":"","sources":["../../src/devServer.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,yEAAyE;AACzE,0DAA0D;AAM1D;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB;;IAC/B,IAAI,CAAC;QACD,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,CAAC,OAAO,EAAE,CAAC;YAC7C,OAAO,SAAS,CAAC;QACrB,CAAC;QAED,kEAAkE;QAClE,wEAAwE;QACxE,kEAAkE;QAClE,IAAI,OAAO,IAAI,KAAK,WAAW,KAAI,MAAA,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,aAAa,0CAAE,UAAU,0CAAE,GAAG,CAAA,EAAE,CAAC;YACtE,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,GAAG,CAAC;YAClD,IAAI,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBAClE,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;gBAC3C,IAAI,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;oBACxC,OAAO,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC;gBAC/C,CAAC;YACL,CAAC;QACL,CAAC;QAED,iCAAiC;QACjC,IAAI,OAAO,uBAAuB,KAAK,QAAQ,IAAI,uBAAuB,EAAE,CAAC;YACzE,OAAO,uBAAuB,CAAC;QACnC,CAAC;IACL,CAAC;IAAC,WAAM,CAAC;QACL,wBAAwB;IAC5B,CAAC;IACD,OAAO,SAAS,CAAC;AACrB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"fileNames":["../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es5.d.ts","../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.d.ts","../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.dom.d.ts","../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.core.d.ts","../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.collection.d.ts","../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.generator.d.ts","../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.promise.d.ts","../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.decorators.d.ts","../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.decorators.legacy.d.ts","../src/devServer.ts","../../../sparkling-method/dist/types.d.ts","../../../sparkling-method/dist/index.d.ts","../src/close/close.d.ts","../src/close/close.ts","../src/open/open.d.ts","../src/open/open.ts","../src/navigate/navigate.d.ts","../src/navigate/navigate.ts","../index.ts","../../../../node_modules/.pnpm/@jest+expect-utils@29.7.0/node_modules/@jest/expect-utils/build/index.d.ts","../../../../node_modules/.pnpm/chalk@4.1.2/node_modules/chalk/index.d.ts","../../../../node_modules/.pnpm/@sinclair+typebox@0.27.10/node_modules/@sinclair/typebox/typebox.d.ts","../../../../node_modules/.pnpm/@jest+schemas@29.6.3/node_modules/@jest/schemas/build/index.d.ts","../../../../node_modules/.pnpm/pretty-format@29.7.0/node_modules/pretty-format/build/index.d.ts","../../../../node_modules/.pnpm/jest-diff@29.7.0/node_modules/jest-diff/build/index.d.ts","../../../../node_modules/.pnpm/jest-matcher-utils@29.7.0/node_modules/jest-matcher-utils/build/index.d.ts","../../../../node_modules/.pnpm/expect@29.7.0/node_modules/expect/build/index.d.ts","../../../../node_modules/.pnpm/@types+jest@29.5.14/node_modules/@types/jest/index.d.ts"],"fileIdsList":[[27],[29,32],[25,31],[29],[26,30],[28],[18,19,20,21,22,23],[17,18],[20],[15,21,22],[15,17,20],[16]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"080941d9f9ff9307f7e27a83bcd888b7c8270716c39af943532438932ec1d0b9","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"
|
|
1
|
+
{"fileNames":["../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es5.d.ts","../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.d.ts","../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.dom.d.ts","../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.core.d.ts","../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.collection.d.ts","../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.generator.d.ts","../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.promise.d.ts","../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.decorators.d.ts","../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.decorators.legacy.d.ts","../src/devServer.ts","../../../sparkling-method/dist/types.d.ts","../../../sparkling-method/dist/index.d.ts","../src/close/close.d.ts","../src/close/close.ts","../src/open/open.d.ts","../src/open/open.ts","../src/navigate/navigate.d.ts","../src/navigate/navigate.ts","../index.ts","../../../../node_modules/.pnpm/@jest+expect-utils@29.7.0/node_modules/@jest/expect-utils/build/index.d.ts","../../../../node_modules/.pnpm/chalk@4.1.2/node_modules/chalk/index.d.ts","../../../../node_modules/.pnpm/@sinclair+typebox@0.27.10/node_modules/@sinclair/typebox/typebox.d.ts","../../../../node_modules/.pnpm/@jest+schemas@29.6.3/node_modules/@jest/schemas/build/index.d.ts","../../../../node_modules/.pnpm/pretty-format@29.7.0/node_modules/pretty-format/build/index.d.ts","../../../../node_modules/.pnpm/jest-diff@29.7.0/node_modules/jest-diff/build/index.d.ts","../../../../node_modules/.pnpm/jest-matcher-utils@29.7.0/node_modules/jest-matcher-utils/build/index.d.ts","../../../../node_modules/.pnpm/expect@29.7.0/node_modules/expect/build/index.d.ts","../../../../node_modules/.pnpm/@types+jest@29.5.14/node_modules/@types/jest/index.d.ts"],"fileIdsList":[[27],[29,32],[25,31],[29],[26,30],[28],[18,19,20,21,22,23],[17,18],[20],[15,21,22],[15,17,20],[16]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"080941d9f9ff9307f7e27a83bcd888b7c8270716c39af943532438932ec1d0b9","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"a4a7d5010a7e00e0249b9862f3ca68e90f7b5b7d2fb713f5d995ffc9b157e0e7","signature":"51d6a96a88f06928d2bf9400f47a225ab2ca51b0c290f5c5aeb232b04f0aca9d"},"f7633d7fe074d6a4f1d215bbc7a3b27fc0419a5a3bfbbe054ac07f3dbbc68487","bdddec6a06096ab2fc1460e59d0e8c1c954ffe72290bee32bc1ecce28ebe9393","582fe2e974682a46dcee0b08fac869d96c56ec3421ad48633f6289f497acc3fd",{"version":"437d1d1bf67ea36dbf6f48e75dc75f7385e58e91d5a0acc493cbc1cec23c59fa","signature":"f421088758adc5b04e44c1548f2d7ac1cebbdda08458c8e493a490002c8e6f7c"},"a078d8603e9ef86dbed7ba0ff50276734c4cefbc5e64a6ab07144911ff701e3b",{"version":"ad4667e00d7fce51bded3e210d1f271e651ea5516cea8ba121201bc1614e022f","signature":"dd1d64b74f46208aecdee3727641eff5c0262826752e37a19ca6b2eb474d45af"},"e3963382b8a425258f14e665e7a0d39b024f1e71b7c9200096cdc9604ddf5f94",{"version":"712aba6de5cf5a6724f0ecdc5ec1176d35e7ed1071e36fb69d696dabfb1e7088","signature":"e902e6d4f2877e301fa4cf11b50a18c6a1c078bd34edecb15ae62459310004d0"},{"version":"f4ef2dc4d2182f03365773c1c488eb01ebd07186a7d7e3c51eea5eed6c0d5252","signature":"4acdb0a03d91ac0b94410f47337f1dba8f947a74300a305e1e6a14fef3933d07"},{"version":"cdcc132f207d097d7d3aa75615ab9a2e71d6a478162dde8b67f88ea19f3e54de","impliedFormat":1},{"version":"0d14fa22c41fdc7277e6f71473b20ebc07f40f00e38875142335d5b63cdfc9d2","impliedFormat":1},{"version":"e1028394c1cf96d5d057ecc647e31e457b919092f882ed0c7092152b077fed9d","impliedFormat":1},{"version":"f315e1e65a1f80992f0509e84e4ae2df15ecd9ef73df975f7c98813b71e4c8da","impliedFormat":1},{"version":"5b9586e9b0b6322e5bfbd2c29bd3b8e21ab9d871f82346cb71020e3d84bae73e","impliedFormat":1},{"version":"3e70a7e67c2cb16f8cd49097360c0309fe9d1e3210ff9222e9dac1f8df9d4fb6","impliedFormat":1},{"version":"ab68d2a3e3e8767c3fba8f80de099a1cfc18c0de79e42cb02ae66e22dfe14a66","impliedFormat":1},{"version":"d96cc6598148bf1a98fb2e8dcf01c63a4b3558bdaec6ef35e087fd0562eb40ec","impliedFormat":1},{"version":"f8db4fea512ab759b2223b90ecbbe7dae919c02f8ce95ec03f7fb1cf757cfbeb","affectsGlobalScope":true,"impliedFormat":1}],"root":[15,19,21,23,24],"options":{"composite":true,"declaration":true,"declarationMap":true,"emitDeclarationOnly":false,"esModuleInterop":true,"module":5,"outDir":"./","skipLibCheck":true,"sourceMap":true,"strict":true,"target":2},"referencedMap":[[28,1],[33,2],[32,3],[30,4],[31,5],[29,6],[24,7],[19,8],[22,9],[23,10],[21,11],[17,12]],"latestChangedDtsFile":"./index.d.ts","version":"5.9.3"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Pod::Spec.new do |s|
|
|
2
2
|
s.name = 'Sparkling-Router'
|
|
3
|
-
s.version = "2.1.0-rc.
|
|
3
|
+
s.version = "2.1.0-rc.26"
|
|
4
4
|
s.summary = "iOS navigation router SDK for Sparkling"
|
|
5
5
|
s.description = "iOS navigation router SDK for Sparkling"
|
|
6
6
|
s.license = "Apache-2.0"
|
|
@@ -26,6 +26,13 @@ Pod::Spec.new do |s|
|
|
|
26
26
|
]
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
+
s.test_spec 'Tests' do |tests|
|
|
30
|
+
tests.requires_app_host = false
|
|
31
|
+
tests.source_files = [
|
|
32
|
+
'SparklingMethodTests/**/*.{h,m,swift}',
|
|
33
|
+
]
|
|
34
|
+
end
|
|
35
|
+
|
|
29
36
|
s.dependency 'SparklingMethod/Core'
|
|
30
37
|
s.dependency 'SparklingMethod/DIProvider'
|
|
31
38
|
s.dependency 'Mantle', '~> 2.2.0'
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
// Copyright 2025 The Sparkling Authors. All rights reserved.
|
|
2
|
+
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
3
|
+
// LICENSE file in the root directory of this source tree.
|
|
4
|
+
|
|
5
|
+
import XCTest
|
|
6
|
+
import SparklingMethod
|
|
7
|
+
@testable import Sparkling_Router
|
|
8
|
+
|
|
9
|
+
class SPKRouterTest: XCTestCase {
|
|
10
|
+
|
|
11
|
+
// MARK: - CloseMethod Tests
|
|
12
|
+
|
|
13
|
+
func testCloseMethodName() {
|
|
14
|
+
let method = CloseMethod()
|
|
15
|
+
XCTAssertEqual(method.methodName, "router.close")
|
|
16
|
+
XCTAssertEqual(CloseMethod.methodName(), "router.close")
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
func testCloseMethodModels() {
|
|
20
|
+
let method = CloseMethod()
|
|
21
|
+
XCTAssertTrue(method.paramsModelClass is CloseMethodParamModel.Type)
|
|
22
|
+
XCTAssertTrue(method.resultModelClass is EmptyMethodModelClass.Type)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
func testCloseMethodParamModelValidation() {
|
|
26
|
+
let paramModel = CloseMethodParamModel()
|
|
27
|
+
|
|
28
|
+
XCTAssertTrue(type(of: paramModel).requiredKeyPaths()?.isEmpty ?? false)
|
|
29
|
+
|
|
30
|
+
paramModel.containerID = "test-container"
|
|
31
|
+
XCTAssertNoThrow(try paramModel.validate())
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
func testCloseMethodParamModelJSONMapping() {
|
|
35
|
+
let paramModel = CloseMethodParamModel()
|
|
36
|
+
paramModel.containerID = "test-container"
|
|
37
|
+
paramModel.animated = true
|
|
38
|
+
|
|
39
|
+
XCTAssertEqual(type(of: paramModel).jsonKeyPathsByPropertyKey() as? [String: String], [
|
|
40
|
+
"containerID": "containerID",
|
|
41
|
+
"animated": "animated"
|
|
42
|
+
])
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// MARK: - OpenMethod Tests
|
|
46
|
+
|
|
47
|
+
func testOpenMethodName() {
|
|
48
|
+
let method = OpenMethod()
|
|
49
|
+
XCTAssertEqual(method.methodName, "router.open")
|
|
50
|
+
XCTAssertEqual(OpenMethod.methodName(), "router.open")
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
func testOpenMethodModels() {
|
|
54
|
+
let method = OpenMethod()
|
|
55
|
+
XCTAssertTrue(method.paramsModelClass is OpenMethodParamModel.Type)
|
|
56
|
+
XCTAssertTrue(method.resultModelClass is EmptyMethodModelClass.Type)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
func testOpenMethodParamModelValidation() throws {
|
|
60
|
+
XCTAssertThrowsError(try OpenMethodParamModel(dictionary: [:]))
|
|
61
|
+
|
|
62
|
+
let paramModel = try XCTUnwrap(try OpenMethodParamModel.from(dict: ["scheme": "https://example.com"]))
|
|
63
|
+
paramModel.scheme = "https://example.com"
|
|
64
|
+
XCTAssertNoThrow(try paramModel.validate())
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
func testOpenMethodParamModelJSONMapping() {
|
|
68
|
+
let paramModel = OpenMethodParamModel()
|
|
69
|
+
|
|
70
|
+
XCTAssertEqual(type(of: paramModel).jsonKeyPathsByPropertyKey() as? [String: String], [
|
|
71
|
+
"scheme": "scheme",
|
|
72
|
+
"replace": "replace",
|
|
73
|
+
"replaceType": "replaceType",
|
|
74
|
+
"useSysBrowser": "useSysBrowser",
|
|
75
|
+
"animated": "animated",
|
|
76
|
+
"interceptor": "interceptor",
|
|
77
|
+
"extra": "extra"
|
|
78
|
+
])
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
func testOpenMethodParamModelDefaultValues() {
|
|
82
|
+
let paramModel = OpenMethodParamModel()
|
|
83
|
+
paramModel.scheme = "test-scheme"
|
|
84
|
+
|
|
85
|
+
XCTAssertFalse(paramModel.replace)
|
|
86
|
+
XCTAssertFalse(paramModel.useSysBrowser)
|
|
87
|
+
XCTAssertFalse(paramModel.animated)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
func testOpenMethodParamModelAllFields() {
|
|
91
|
+
let paramModel = OpenMethodParamModel()
|
|
92
|
+
paramModel.scheme = "test-scheme"
|
|
93
|
+
paramModel.replace = true
|
|
94
|
+
paramModel.replaceType = "all"
|
|
95
|
+
paramModel.useSysBrowser = true
|
|
96
|
+
paramModel.animated = true
|
|
97
|
+
paramModel.interceptor = "test-interceptor"
|
|
98
|
+
let extraDict = NSDictionary(dictionary: ["key": "value"])
|
|
99
|
+
paramModel.extra = extraDict
|
|
100
|
+
|
|
101
|
+
XCTAssertEqual(paramModel.scheme, "test-scheme")
|
|
102
|
+
XCTAssertTrue(paramModel.replace)
|
|
103
|
+
XCTAssertEqual(paramModel.replaceType, "all")
|
|
104
|
+
XCTAssertTrue(paramModel.useSysBrowser)
|
|
105
|
+
XCTAssertTrue(paramModel.animated)
|
|
106
|
+
XCTAssertEqual(paramModel.interceptor, "test-interceptor")
|
|
107
|
+
XCTAssertEqual(paramModel.extra, extraDict)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
func testOpenMethodParamModelFromDictParsesExtraObject() throws {
|
|
111
|
+
let dict: [String: Any] = [
|
|
112
|
+
"scheme": "hybrid://lynxview_page?bundle=a.lynx.bundle",
|
|
113
|
+
"extra": ["foo": "bar"],
|
|
114
|
+
]
|
|
115
|
+
let model = try XCTUnwrap(try OpenMethodParamModel.from(dict: dict))
|
|
116
|
+
XCTAssertNotNil(model.extra)
|
|
117
|
+
XCTAssertEqual(model.extra?["foo"] as? String, "bar")
|
|
118
|
+
}
|
|
119
|
+
}
|
package/module.config.json
CHANGED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
}
|
|
30
30
|
},
|
|
31
31
|
"android": {
|
|
32
|
-
"packageName": "com.tiktok.sparkling.
|
|
32
|
+
"packageName": "com.tiktok.sparkling.method.router",
|
|
33
33
|
"className": "RouterMethod",
|
|
34
34
|
"buildGradle": "android/build.gradle.kts"
|
|
35
35
|
},
|
|
@@ -43,4 +43,4 @@
|
|
|
43
43
|
"entryPoint": "index.ts",
|
|
44
44
|
"bundleName": "router.bundle"
|
|
45
45
|
}
|
|
46
|
-
}
|
|
46
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sparkling-navigation",
|
|
3
|
-
"version": "2.1.0-rc.
|
|
3
|
+
"version": "2.1.0-rc.26",
|
|
4
4
|
"homepage": "https://tiktok.github.io/sparkling/",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"license": "Apache-2.0",
|
|
25
25
|
"description": "none",
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"sparkling-method": "2.1.0-rc.
|
|
27
|
+
"sparkling-method": "2.1.0-rc.26"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@types/jest": "^29.5.12",
|
package/src/devServer.ts
CHANGED
|
@@ -22,7 +22,7 @@ export function getDevServerBaseURL(): string | undefined {
|
|
|
22
22
|
|
|
23
23
|
// Prefer the actual URL the native side used to load this bundle.
|
|
24
24
|
// lynx.__globalProps.queryItems.url is set by the SDK from the scheme's
|
|
25
|
-
// url= parameter (e.g. "http://
|
|
25
|
+
// url= parameter (e.g. "http://127.0.0.1:5969/main.lynx.bundle").
|
|
26
26
|
if (typeof lynx !== 'undefined' && lynx?.__globalProps?.queryItems?.url) {
|
|
27
27
|
const pageUrl = lynx.__globalProps.queryItems.url;
|
|
28
28
|
if (pageUrl.startsWith('http://') || pageUrl.startsWith('https://')) {
|