@thelacanians/vue-native-cli 0.4.15 → 0.6.0

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 (116) hide show
  1. package/dist/cli.js +329 -15
  2. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/NativeBridge.kt +118 -0
  3. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VViewFactory.kt +178 -1
  4. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/GeneratedModuleRegistry.kt +28 -0
  5. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/NativeModuleRegistry.kt +3 -0
  6. package/native/android/VueNativeCore/src/test/kotlin/com/vuenative/core/ComponentFactoryTest.kt +674 -0
  7. package/native/android/VueNativeCore/src/test/kotlin/com/vuenative/core/ErrorOverlayViewTest.kt +183 -0
  8. package/native/android/VueNativeCore/src/test/kotlin/com/vuenative/core/EventThrottleTest.kt +203 -0
  9. package/native/android/VueNativeCore/src/test/kotlin/com/vuenative/core/HotReloadManagerTest.kt +162 -0
  10. package/native/android/VueNativeCore/src/test/kotlin/com/vuenative/core/JSPolyfillsTest.kt +153 -0
  11. package/native/android/VueNativeCore/src/test/kotlin/com/vuenative/core/NativeBridgeTest.kt +6 -3
  12. package/native/android/VueNativeCore/src/test/kotlin/com/vuenative/core/NativeModuleTest.kt +475 -0
  13. package/native/android/gradle.properties +1 -0
  14. package/native/android/gradlew +1 -1
  15. package/native/ios/VueNativeCore/Package.swift +1 -1
  16. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/EventThrottle.swift +1 -0
  17. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/NativeBridge.swift +143 -5
  18. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VTextFactory.swift +43 -0
  19. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VViewFactory.swift +116 -4
  20. package/native/ios/VueNativeCore/Sources/VueNativeCore/Helpers/GestureWrapper.swift +100 -0
  21. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/GeneratedModuleRegistry.swift +28 -0
  22. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/NativeModuleRegistry.swift +3 -0
  23. package/native/ios/VueNativeCore/Tests/VueNativeCoreTests/CertificatePinningTests.swift +190 -0
  24. package/native/ios/VueNativeCore/Tests/VueNativeCoreTests/ComponentFactoryTests.swift +585 -0
  25. package/native/ios/VueNativeCore/Tests/VueNativeCoreTests/EventThrottleTests.swift +161 -0
  26. package/native/ios/VueNativeCore/Tests/VueNativeCoreTests/HotReloadManagerTests.swift +88 -0
  27. package/native/ios/VueNativeCore/Tests/VueNativeCoreTests/JSPolyfillsTests.swift +319 -0
  28. package/native/ios/VueNativeCore/Tests/VueNativeCoreTests/NativeModuleTests.swift +400 -0
  29. package/native/macos/VueNativeMacOS/Package.swift +34 -0
  30. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Bridge/ErrorOverlayView.swift +112 -0
  31. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Bridge/EventThrottle.swift +58 -0
  32. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Bridge/HotReloadManager.swift +153 -0
  33. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Bridge/JSPolyfills.swift +696 -0
  34. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Bridge/JSRuntime.swift +347 -0
  35. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Bridge/NativeBridge.swift +877 -0
  36. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Bridge/VueNativeWindowController.swift +125 -0
  37. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/ComponentRegistry.swift +209 -0
  38. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VActionSheetFactory.swift +155 -0
  39. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VActivityIndicatorFactory.swift +85 -0
  40. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VAlertDialogFactory.swift +132 -0
  41. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VButtonFactory.swift +83 -0
  42. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VCheckboxFactory.swift +108 -0
  43. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VDropdownFactory.swift +155 -0
  44. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VImageFactory.swift +270 -0
  45. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VInputFactory.swift +257 -0
  46. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VKeyboardAvoidingFactory.swift +22 -0
  47. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VListFactory.swift +324 -0
  48. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VModalFactory.swift +231 -0
  49. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VOutlineViewFactory.swift +276 -0
  50. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VPickerFactory.swift +134 -0
  51. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VPressableFactory.swift +120 -0
  52. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VProgressBarFactory.swift +71 -0
  53. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VRadioFactory.swift +193 -0
  54. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VRefreshControlFactory.swift +25 -0
  55. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VSafeAreaFactory.swift +46 -0
  56. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VScrollViewFactory.swift +190 -0
  57. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VSectionListFactory.swift +374 -0
  58. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VSegmentedControlFactory.swift +125 -0
  59. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VSliderFactory.swift +131 -0
  60. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VSplitViewFactory.swift +215 -0
  61. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VStatusBarFactory.swift +25 -0
  62. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VSwitchFactory.swift +92 -0
  63. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VTextFactory.swift +336 -0
  64. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VToolbarFactory.swift +212 -0
  65. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VVideoFactory.swift +245 -0
  66. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VViewFactory.swift +314 -0
  67. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/Factories/VWebViewFactory.swift +162 -0
  68. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Components/NativeComponentFactory.swift +54 -0
  69. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Helpers/ClickableView.swift +100 -0
  70. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Helpers/Extensions.swift +23 -0
  71. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Helpers/GestureWrapper.swift +183 -0
  72. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Helpers/NSColor+Hex.swift +78 -0
  73. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Layout/FlippedView.swift +19 -0
  74. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Layout/LayoutNode.swift +493 -0
  75. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/AnimationModule.swift +354 -0
  76. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/AppStateModule.swift +62 -0
  77. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/BiometryModule.swift +60 -0
  78. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/CameraModule.swift +167 -0
  79. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/ClipboardModule.swift +34 -0
  80. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/DeviceInfoModule.swift +49 -0
  81. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/DragDropModule.swift +50 -0
  82. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/FileDialogModule.swift +86 -0
  83. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/HapticsModule.swift +42 -0
  84. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/KeyboardModule.swift +28 -0
  85. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/LinkingModule.swift +49 -0
  86. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/MenuModule.swift +95 -0
  87. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/NativeModuleRegistry.swift +63 -0
  88. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/NotificationsModule.swift +112 -0
  89. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/PermissionsModule.swift +149 -0
  90. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/ShareModule.swift +37 -0
  91. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Modules/WindowModule.swift +71 -0
  92. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Resources/vue-native-placeholder.js +2 -0
  93. package/native/macos/VueNativeMacOS/Sources/VueNativeMacOS/Styling/StyleEngine.swift +885 -0
  94. package/native/macos/VueNativeMacOS/Tests/VueNativeMacOSTests/ComponentFactoryTests.swift +80 -0
  95. package/native/macos/VueNativeMacOS/Tests/VueNativeMacOSTests/VueNativeMacOSTests.swift +149 -0
  96. package/native/shared/VueNativeShared/AGENTS.md +129 -0
  97. package/native/shared/VueNativeShared/Package.swift +14 -0
  98. package/native/shared/VueNativeShared/Sources/VueNativeShared/CertificatePinning.swift +134 -0
  99. package/native/shared/VueNativeShared/Sources/VueNativeShared/EventThrottle.swift +78 -0
  100. package/native/shared/VueNativeShared/Sources/VueNativeShared/HotReloadManager.swift +162 -0
  101. package/native/shared/VueNativeShared/Sources/VueNativeShared/JSRuntime.swift +412 -0
  102. package/native/shared/VueNativeShared/Sources/VueNativeShared/Modules/AsyncStorageModule.swift +68 -0
  103. package/native/shared/VueNativeShared/Sources/VueNativeShared/Modules/AudioModule.swift +359 -0
  104. package/native/shared/VueNativeShared/Sources/VueNativeShared/Modules/DatabaseModule.swift +259 -0
  105. package/native/shared/VueNativeShared/Sources/VueNativeShared/Modules/FileSystemModule.swift +233 -0
  106. package/native/shared/VueNativeShared/Sources/VueNativeShared/Modules/GeolocationModule.swift +156 -0
  107. package/native/shared/VueNativeShared/Sources/VueNativeShared/Modules/NetworkModule.swift +59 -0
  108. package/native/shared/VueNativeShared/Sources/VueNativeShared/Modules/PerformanceModule.swift +113 -0
  109. package/native/shared/VueNativeShared/Sources/VueNativeShared/Modules/SecureStorageModule.swift +119 -0
  110. package/native/shared/VueNativeShared/Sources/VueNativeShared/Modules/WebSocketModule.swift +212 -0
  111. package/native/shared/VueNativeShared/Sources/VueNativeShared/NativeEventDispatcher.swift +6 -0
  112. package/native/shared/VueNativeShared/Sources/VueNativeShared/NativeModule.swift +26 -0
  113. package/native/shared/VueNativeShared/Sources/VueNativeShared/NativeModuleRegistry.swift +37 -0
  114. package/native/shared/VueNativeShared/Sources/VueNativeShared/SharedJSPolyfills.swift +673 -0
  115. package/native/shared/VueNativeShared/Tests/VueNativeSharedTests/VueNativeSharedTests.swift +44 -0
  116. package/package.json +8 -2
@@ -0,0 +1,674 @@
1
+ package com.vuenative.core
2
+
3
+ import android.content.Context
4
+ import android.view.View
5
+ import android.widget.CheckBox
6
+ import android.widget.EditText
7
+ import android.widget.ImageView
8
+ import android.widget.LinearLayout
9
+ import android.widget.ProgressBar
10
+ import android.widget.RadioButton
11
+ import android.widget.RadioGroup
12
+ import android.widget.SeekBar
13
+ import android.widget.TextView
14
+ import androidx.appcompat.widget.SwitchCompat
15
+ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
16
+ import androidx.test.core.app.ApplicationProvider
17
+ import com.google.android.flexbox.FlexDirection
18
+ import com.google.android.flexbox.FlexboxLayout
19
+ import org.junit.Assert.assertEquals
20
+ import org.junit.Assert.assertFalse
21
+ import org.junit.Assert.assertNotNull
22
+ import org.junit.Assert.assertTrue
23
+ import org.junit.Before
24
+ import org.junit.Test
25
+ import org.junit.runner.RunWith
26
+ import org.robolectric.RobolectricTestRunner
27
+ import org.robolectric.annotation.Config
28
+
29
+ @RunWith(RobolectricTestRunner::class)
30
+ @Config(sdk = [34])
31
+ class ComponentFactoryTest {
32
+
33
+ private lateinit var context: Context
34
+
35
+ @Before
36
+ fun setUp() {
37
+ context = ApplicationProvider.getApplicationContext()
38
+ }
39
+
40
+ // =========================================================================
41
+ // VViewFactory
42
+ // =========================================================================
43
+
44
+ @Test
45
+ fun testVViewFactoryCreatesFlexboxLayout() {
46
+ val factory = VViewFactory()
47
+ val view = factory.createView(context)
48
+
49
+ assertNotNull("VViewFactory should create a view", view)
50
+ assertTrue("VViewFactory should create a FlexboxLayout", view is FlexboxLayout)
51
+ }
52
+
53
+ @Test
54
+ fun testVViewFactoryDefaultFlexDirection() {
55
+ val factory = VViewFactory()
56
+ val view = factory.createView(context) as FlexboxLayout
57
+
58
+ assertEquals(
59
+ "Default flexDirection should be COLUMN",
60
+ FlexDirection.COLUMN,
61
+ view.flexDirection
62
+ )
63
+ }
64
+
65
+ @Test
66
+ fun testVViewFactoryUpdateProp() {
67
+ val factory = VViewFactory()
68
+ val view = factory.createView(context)
69
+
70
+ factory.updateProp(view, "opacity", 0.5)
71
+ assertEquals(0.5f, view.alpha, 0.01f)
72
+ }
73
+
74
+ @Test
75
+ fun testVViewFactoryInsertChild() {
76
+ val factory = VViewFactory()
77
+ val parent = factory.createView(context) as FlexboxLayout
78
+ val child = View(context)
79
+
80
+ factory.insertChild(parent, child, 0)
81
+ assertEquals("Parent should have 1 child", 1, parent.childCount)
82
+ assertEquals("Child should be at index 0", child, parent.getChildAt(0))
83
+ }
84
+
85
+ @Test
86
+ fun testVViewFactoryRemoveChild() {
87
+ val factory = VViewFactory()
88
+ val parent = factory.createView(context) as FlexboxLayout
89
+ val child = View(context)
90
+
91
+ factory.insertChild(parent, child, 0)
92
+ assertEquals(1, parent.childCount)
93
+
94
+ factory.removeChild(parent, child)
95
+ assertEquals("Parent should have 0 children", 0, parent.childCount)
96
+ }
97
+
98
+ @Test
99
+ fun testVViewFactoryPressEvent() {
100
+ val factory = VViewFactory()
101
+ val view = factory.createView(context)
102
+ var pressed = false
103
+
104
+ factory.addEventListener(view, "press") { pressed = true }
105
+ view.performClick()
106
+ assertTrue("Press handler should be called", pressed)
107
+
108
+ pressed = false
109
+ factory.removeEventListener(view, "press")
110
+ view.performClick()
111
+ // After removing, the click listener is null so performClick still returns
112
+ // but our handler should not be called
113
+ }
114
+
115
+ // =========================================================================
116
+ // VTextFactory
117
+ // =========================================================================
118
+
119
+ @Test
120
+ fun testVTextFactoryCreatesTextView() {
121
+ val factory = VTextFactory()
122
+ val view = factory.createView(context)
123
+
124
+ assertNotNull("VTextFactory should create a view", view)
125
+ assertTrue("VTextFactory should create a TextView", view is TextView)
126
+ }
127
+
128
+ @Test
129
+ fun testVTextFactoryDefaultTextSize() {
130
+ val factory = VTextFactory()
131
+ val view = factory.createView(context) as TextView
132
+
133
+ assertEquals(14f, view.textSize, 1f)
134
+ }
135
+
136
+ @Test
137
+ fun testVTextFactoryUpdateText() {
138
+ val factory = VTextFactory()
139
+ val view = factory.createView(context) as TextView
140
+
141
+ factory.updateProp(view, "text", "Hello World")
142
+ assertEquals("Hello World", view.text.toString())
143
+ }
144
+
145
+ @Test
146
+ fun testVTextFactoryUpdateTextNull() {
147
+ val factory = VTextFactory()
148
+ val view = factory.createView(context) as TextView
149
+
150
+ factory.updateProp(view, "text", null)
151
+ assertEquals("", view.text.toString())
152
+ }
153
+
154
+ @Test
155
+ fun testVTextFactoryNumberOfLines() {
156
+ val factory = VTextFactory()
157
+ val view = factory.createView(context) as TextView
158
+
159
+ factory.updateProp(view, "numberOfLines", 2)
160
+ assertEquals(2, view.maxLines)
161
+ }
162
+
163
+ @Test
164
+ fun testVTextFactoryNumberOfLinesZeroMeansUnlimited() {
165
+ val factory = VTextFactory()
166
+ val view = factory.createView(context) as TextView
167
+
168
+ factory.updateProp(view, "numberOfLines", 0)
169
+ assertEquals(Int.MAX_VALUE, view.maxLines)
170
+ }
171
+
172
+ // =========================================================================
173
+ // VButtonFactory
174
+ // =========================================================================
175
+
176
+ @Test
177
+ fun testVButtonFactoryCreatesTouchableView() {
178
+ val factory = VButtonFactory()
179
+ val view = factory.createView(context)
180
+
181
+ assertNotNull("VButtonFactory should create a view", view)
182
+ assertTrue("VButtonFactory should create a TouchableView", view is TouchableView)
183
+ }
184
+
185
+ @Test
186
+ fun testVButtonFactoryDisabled() {
187
+ val factory = VButtonFactory()
188
+ val view = factory.createView(context) as TouchableView
189
+
190
+ factory.updateProp(view, "disabled", true)
191
+ assertTrue("Button should be disabled", view.isDisabled)
192
+ assertEquals("Disabled button should have reduced alpha", 0.4f, view.alpha, 0.01f)
193
+ }
194
+
195
+ @Test
196
+ fun testVButtonFactoryActiveOpacity() {
197
+ val factory = VButtonFactory()
198
+ val view = factory.createView(context) as TouchableView
199
+
200
+ factory.updateProp(view, "activeOpacity", 0.3)
201
+ assertEquals(0.3f, view.activeOpacity, 0.01f)
202
+ }
203
+
204
+ @Test
205
+ fun testVButtonFactoryPressEvent() {
206
+ val factory = VButtonFactory()
207
+ val view = factory.createView(context) as TouchableView
208
+ var pressed = false
209
+
210
+ factory.addEventListener(view, "press") { pressed = true }
211
+ view.onPress?.invoke()
212
+ assertTrue("Press handler should be called", pressed)
213
+ }
214
+
215
+ @Test
216
+ fun testVButtonFactoryRemovePressEvent() {
217
+ val factory = VButtonFactory()
218
+ val view = factory.createView(context) as TouchableView
219
+
220
+ factory.addEventListener(view, "press") { }
221
+ assertNotNull("onPress should be set", view.onPress)
222
+
223
+ factory.removeEventListener(view, "press")
224
+ assertTrue("onPress should be null after remove", view.onPress == null)
225
+ }
226
+
227
+ // =========================================================================
228
+ // VInputFactory
229
+ // =========================================================================
230
+
231
+ @Test
232
+ fun testVInputFactoryCreatesEditText() {
233
+ val factory = VInputFactory()
234
+ val view = factory.createView(context)
235
+
236
+ assertNotNull("VInputFactory should create a view", view)
237
+ assertTrue("VInputFactory should create an EditText", view is EditText)
238
+ }
239
+
240
+ @Test
241
+ fun testVInputFactorySetText() {
242
+ val factory = VInputFactory()
243
+ val view = factory.createView(context) as EditText
244
+
245
+ factory.updateProp(view, "text", "Hello")
246
+ assertEquals("Hello", view.text.toString())
247
+ }
248
+
249
+ @Test
250
+ fun testVInputFactorySetValue() {
251
+ val factory = VInputFactory()
252
+ val view = factory.createView(context) as EditText
253
+
254
+ factory.updateProp(view, "value", "World")
255
+ assertEquals("World", view.text.toString())
256
+ }
257
+
258
+ @Test
259
+ fun testVInputFactoryPlaceholder() {
260
+ val factory = VInputFactory()
261
+ val view = factory.createView(context) as EditText
262
+
263
+ factory.updateProp(view, "placeholder", "Enter text...")
264
+ assertEquals("Enter text...", view.hint.toString())
265
+ }
266
+
267
+ @Test
268
+ fun testVInputFactoryEditable() {
269
+ val factory = VInputFactory()
270
+ val view = factory.createView(context) as EditText
271
+
272
+ factory.updateProp(view, "editable", false)
273
+ assertFalse("EditText should be disabled", view.isEnabled)
274
+
275
+ factory.updateProp(view, "editable", true)
276
+ assertTrue("EditText should be enabled", view.isEnabled)
277
+ }
278
+
279
+ @Test
280
+ fun testVInputFactoryChangeEvent() {
281
+ val factory = VInputFactory()
282
+ val view = factory.createView(context) as EditText
283
+ var changedValue: String? = null
284
+
285
+ factory.addEventListener(view, "change") { payload ->
286
+ @Suppress("UNCHECKED_CAST")
287
+ changedValue = (payload as? Map<String, Any?>)?.get("value") as? String
288
+ }
289
+
290
+ view.setText("typed text")
291
+ assertEquals("typed text", changedValue)
292
+ }
293
+
294
+ @Test
295
+ fun testVInputFactoryRemoveChangeEvent() {
296
+ val factory = VInputFactory()
297
+ val view = factory.createView(context) as EditText
298
+
299
+ factory.addEventListener(view, "change") { }
300
+ factory.removeEventListener(view, "change")
301
+
302
+ // Should not crash and TextWatcher should be removed
303
+ view.setText("test")
304
+ }
305
+
306
+ @Test
307
+ fun testVInputFactoryFontSize() {
308
+ val factory = VInputFactory()
309
+ val view = factory.createView(context) as EditText
310
+
311
+ factory.updateProp(view, "fontSize", 20)
312
+ assertEquals(20f, view.textSize, 1f)
313
+ }
314
+
315
+ // =========================================================================
316
+ // VSwitchFactory
317
+ // =========================================================================
318
+
319
+ @Test
320
+ fun testVSwitchFactoryCreatesSwitchCompat() {
321
+ val factory = VSwitchFactory()
322
+ val view = factory.createView(context)
323
+
324
+ assertNotNull("VSwitchFactory should create a view", view)
325
+ assertTrue("VSwitchFactory should create a SwitchCompat", view is SwitchCompat)
326
+ }
327
+
328
+ @Test
329
+ fun testVSwitchFactorySetValue() {
330
+ val factory = VSwitchFactory()
331
+ val view = factory.createView(context) as SwitchCompat
332
+
333
+ factory.updateProp(view, "value", true)
334
+ assertTrue("Switch should be checked", view.isChecked)
335
+
336
+ factory.updateProp(view, "value", false)
337
+ assertFalse("Switch should be unchecked", view.isChecked)
338
+ }
339
+
340
+ @Test
341
+ fun testVSwitchFactoryDisabled() {
342
+ val factory = VSwitchFactory()
343
+ val view = factory.createView(context) as SwitchCompat
344
+
345
+ factory.updateProp(view, "disabled", true)
346
+ assertFalse("Switch should be disabled", view.isEnabled)
347
+ }
348
+
349
+ @Test
350
+ fun testVSwitchFactoryChangeEvent() {
351
+ val factory = VSwitchFactory()
352
+ val view = factory.createView(context) as SwitchCompat
353
+ var changedValue: Boolean? = null
354
+
355
+ factory.addEventListener(view, "change") { payload ->
356
+ @Suppress("UNCHECKED_CAST")
357
+ changedValue = (payload as? Map<String, Any?>)?.get("value") as? Boolean
358
+ }
359
+
360
+ view.isChecked = true
361
+ assertEquals(true, changedValue)
362
+ }
363
+
364
+ // =========================================================================
365
+ // VImageFactory
366
+ // =========================================================================
367
+
368
+ @Test
369
+ fun testVImageFactoryCreatesImageView() {
370
+ val factory = VImageFactory()
371
+ val view = factory.createView(context)
372
+
373
+ assertNotNull("VImageFactory should create a view", view)
374
+ assertTrue("VImageFactory should create an ImageView", view is ImageView)
375
+ }
376
+
377
+ @Test
378
+ fun testVImageFactoryDefaultScaleType() {
379
+ val factory = VImageFactory()
380
+ val view = factory.createView(context) as ImageView
381
+
382
+ assertEquals(
383
+ "Default scaleType should be CENTER_CROP",
384
+ ImageView.ScaleType.CENTER_CROP,
385
+ view.scaleType
386
+ )
387
+ }
388
+
389
+ @Test
390
+ fun testVImageFactoryResizeMode() {
391
+ val factory = VImageFactory()
392
+ val view = factory.createView(context) as ImageView
393
+
394
+ factory.updateProp(view, "resizeMode", "contain")
395
+ assertEquals(ImageView.ScaleType.FIT_CENTER, view.scaleType)
396
+
397
+ factory.updateProp(view, "resizeMode", "stretch")
398
+ assertEquals(ImageView.ScaleType.FIT_XY, view.scaleType)
399
+
400
+ factory.updateProp(view, "resizeMode", "center")
401
+ assertEquals(ImageView.ScaleType.CENTER, view.scaleType)
402
+
403
+ factory.updateProp(view, "resizeMode", "cover")
404
+ assertEquals(ImageView.ScaleType.CENTER_CROP, view.scaleType)
405
+ }
406
+
407
+ // =========================================================================
408
+ // VScrollViewFactory
409
+ // =========================================================================
410
+
411
+ @Test
412
+ fun testVScrollViewFactoryCreatesSwipeRefreshLayout() {
413
+ val factory = VScrollViewFactory()
414
+ val view = factory.createView(context)
415
+
416
+ assertNotNull("VScrollViewFactory should create a view", view)
417
+ assertTrue(
418
+ "VScrollViewFactory should create a SwipeRefreshLayout",
419
+ view is SwipeRefreshLayout
420
+ )
421
+ }
422
+
423
+ @Test
424
+ fun testVScrollViewFactoryRefreshDisabledByDefault() {
425
+ val factory = VScrollViewFactory()
426
+ val view = factory.createView(context) as SwipeRefreshLayout
427
+
428
+ assertFalse("SwipeRefreshLayout should be disabled by default", view.isEnabled)
429
+ }
430
+
431
+ @Test
432
+ fun testVScrollViewFactoryInsertChild() {
433
+ val factory = VScrollViewFactory()
434
+ val parent = factory.createView(context)
435
+ val child = View(context)
436
+
437
+ factory.insertChild(parent, child, 0)
438
+
439
+ // Access the internal content FlexboxLayout through the factory's states map
440
+ val statesField = VScrollViewFactory::class.java.getDeclaredField("states")
441
+ statesField.isAccessible = true
442
+ @Suppress("UNCHECKED_CAST")
443
+ val states = statesField.get(factory) as Map<SwipeRefreshLayout, Any>
444
+ val scrollState = states[parent as SwipeRefreshLayout]!!
445
+ val contentField = scrollState::class.java.getDeclaredField("content")
446
+ contentField.isAccessible = true
447
+ val content = contentField.get(scrollState) as FlexboxLayout
448
+ assertEquals("Content should have 1 child", 1, content.childCount)
449
+ }
450
+
451
+ @Test
452
+ fun testVScrollViewFactoryRefreshingProp() {
453
+ val factory = VScrollViewFactory()
454
+ val view = factory.createView(context) as SwipeRefreshLayout
455
+
456
+ factory.updateProp(view, "refreshing", true)
457
+ assertTrue("Should be refreshing", view.isRefreshing)
458
+
459
+ factory.updateProp(view, "refreshing", false)
460
+ assertFalse("Should not be refreshing", view.isRefreshing)
461
+ }
462
+
463
+ // =========================================================================
464
+ // VSliderFactory
465
+ // =========================================================================
466
+
467
+ @Test
468
+ fun testVSliderFactoryCreatesSeekBar() {
469
+ val factory = VSliderFactory()
470
+ val view = factory.createView(context)
471
+
472
+ assertNotNull("VSliderFactory should create a view", view)
473
+ assertTrue("VSliderFactory should create a SeekBar", view is SeekBar)
474
+ }
475
+
476
+ @Test
477
+ fun testVSliderFactoryDefaults() {
478
+ val factory = VSliderFactory()
479
+ val view = factory.createView(context) as SeekBar
480
+
481
+ assertEquals("Default max should be 100", 100, view.max)
482
+ assertEquals("Default progress should be 0", 0, view.progress)
483
+ }
484
+
485
+ @Test
486
+ fun testVSliderFactoryDisabled() {
487
+ val factory = VSliderFactory()
488
+ val view = factory.createView(context) as SeekBar
489
+
490
+ factory.updateProp(view, "disabled", true)
491
+ assertFalse("SeekBar should be disabled", view.isEnabled)
492
+ }
493
+
494
+ @Test
495
+ fun testVSliderFactoryMaximumValue() {
496
+ val factory = VSliderFactory()
497
+ val view = factory.createView(context) as SeekBar
498
+
499
+ factory.updateProp(view, "maximumValue", 200)
500
+ assertEquals(200, view.max)
501
+ }
502
+
503
+ // =========================================================================
504
+ // VActivityIndicatorFactory
505
+ // =========================================================================
506
+
507
+ @Test
508
+ fun testVActivityIndicatorFactoryCreatesProgressBar() {
509
+ val factory = VActivityIndicatorFactory()
510
+ val view = factory.createView(context)
511
+
512
+ assertNotNull("VActivityIndicatorFactory should create a view", view)
513
+ assertTrue(
514
+ "VActivityIndicatorFactory should create a ProgressBar",
515
+ view is ProgressBar
516
+ )
517
+ }
518
+
519
+ @Test
520
+ fun testVActivityIndicatorFactoryIsIndeterminate() {
521
+ val factory = VActivityIndicatorFactory()
522
+ val view = factory.createView(context) as ProgressBar
523
+
524
+ assertTrue("ProgressBar should be indeterminate", view.isIndeterminate)
525
+ }
526
+
527
+ @Test
528
+ fun testVActivityIndicatorFactoryAnimatingProp() {
529
+ val factory = VActivityIndicatorFactory()
530
+ val view = factory.createView(context) as ProgressBar
531
+
532
+ factory.updateProp(view, "animating", false)
533
+ assertEquals(View.GONE, view.visibility)
534
+
535
+ factory.updateProp(view, "animating", true)
536
+ assertEquals(View.VISIBLE, view.visibility)
537
+ }
538
+
539
+ // =========================================================================
540
+ // VCheckboxFactory
541
+ // =========================================================================
542
+
543
+ @Test
544
+ fun testVCheckboxFactoryCreatesLinearLayout() {
545
+ val factory = VCheckboxFactory()
546
+ val view = factory.createView(context)
547
+
548
+ assertNotNull("VCheckboxFactory should create a view", view)
549
+ assertTrue("VCheckboxFactory should create a LinearLayout", view is LinearLayout)
550
+ }
551
+
552
+ @Test
553
+ fun testVCheckboxFactoryContainsCheckboxAndLabel() {
554
+ val factory = VCheckboxFactory()
555
+ val view = factory.createView(context) as LinearLayout
556
+
557
+ val checkbox = view.findViewWithTag<CheckBox>("checkbox")
558
+ val label = view.findViewWithTag<TextView>("label")
559
+
560
+ assertNotNull("Should contain a CheckBox", checkbox)
561
+ assertNotNull("Should contain a label TextView", label)
562
+ }
563
+
564
+ @Test
565
+ fun testVCheckboxFactorySetValue() {
566
+ val factory = VCheckboxFactory()
567
+ val view = factory.createView(context) as LinearLayout
568
+ val checkbox = view.findViewWithTag<CheckBox>("checkbox")!!
569
+
570
+ factory.updateProp(view, "value", true)
571
+ assertTrue("Checkbox should be checked", checkbox.isChecked)
572
+
573
+ factory.updateProp(view, "value", false)
574
+ assertFalse("Checkbox should be unchecked", checkbox.isChecked)
575
+ }
576
+
577
+ @Test
578
+ fun testVCheckboxFactorySetLabel() {
579
+ val factory = VCheckboxFactory()
580
+ val view = factory.createView(context) as LinearLayout
581
+ val label = view.findViewWithTag<TextView>("label")!!
582
+
583
+ factory.updateProp(view, "label", "Accept terms")
584
+ assertEquals("Accept terms", label.text.toString())
585
+ assertEquals(View.VISIBLE, label.visibility)
586
+ }
587
+
588
+ @Test
589
+ fun testVCheckboxFactoryDisabled() {
590
+ val factory = VCheckboxFactory()
591
+ val view = factory.createView(context) as LinearLayout
592
+ val checkbox = view.findViewWithTag<CheckBox>("checkbox")!!
593
+
594
+ factory.updateProp(view, "disabled", true)
595
+ assertFalse("Checkbox should be disabled", checkbox.isEnabled)
596
+ assertEquals(0.4f, view.alpha, 0.01f)
597
+ }
598
+
599
+ @Test
600
+ fun testVCheckboxFactoryChangeEvent() {
601
+ val factory = VCheckboxFactory()
602
+ val view = factory.createView(context) as LinearLayout
603
+ val checkbox = view.findViewWithTag<CheckBox>("checkbox")!!
604
+ var changedValue: Boolean? = null
605
+
606
+ factory.addEventListener(view, "change") { payload ->
607
+ @Suppress("UNCHECKED_CAST")
608
+ changedValue = (payload as? Map<String, Any?>)?.get("value") as? Boolean
609
+ }
610
+
611
+ checkbox.isChecked = true
612
+ assertEquals(true, changedValue)
613
+ }
614
+
615
+ // =========================================================================
616
+ // VRadioFactory
617
+ // =========================================================================
618
+
619
+ @Test
620
+ fun testVRadioFactoryCreatesRadioGroup() {
621
+ val factory = VRadioFactory()
622
+ val view = factory.createView(context)
623
+
624
+ assertNotNull("VRadioFactory should create a view", view)
625
+ assertTrue("VRadioFactory should create a RadioGroup", view is RadioGroup)
626
+ }
627
+
628
+ @Test
629
+ fun testVRadioFactoryDefaultOrientation() {
630
+ val factory = VRadioFactory()
631
+ val view = factory.createView(context) as RadioGroup
632
+
633
+ assertEquals(
634
+ "Default orientation should be VERTICAL",
635
+ RadioGroup.VERTICAL,
636
+ view.orientation
637
+ )
638
+ }
639
+
640
+ @Test
641
+ fun testVRadioFactorySetOptions() {
642
+ val factory = VRadioFactory()
643
+ val view = factory.createView(context) as RadioGroup
644
+
645
+ val options = listOf(
646
+ mapOf("label" to "Option A", "value" to "a"),
647
+ mapOf("label" to "Option B", "value" to "b"),
648
+ mapOf("label" to "Option C", "value" to "c")
649
+ )
650
+
651
+ factory.updateProp(view, "options", options)
652
+ assertEquals("Should have 3 radio buttons", 3, view.childCount)
653
+
654
+ val first = view.getChildAt(0) as RadioButton
655
+ assertEquals("Option A", first.text.toString())
656
+ }
657
+
658
+ @Test
659
+ fun testVRadioFactoryDisabled() {
660
+ val factory = VRadioFactory()
661
+ val view = factory.createView(context) as RadioGroup
662
+
663
+ val options = listOf(
664
+ mapOf("label" to "A", "value" to "a"),
665
+ mapOf("label" to "B", "value" to "b")
666
+ )
667
+ factory.updateProp(view, "options", options)
668
+
669
+ factory.updateProp(view, "disabled", true)
670
+ assertEquals(0.4f, view.alpha, 0.01f)
671
+ assertFalse("First child should be disabled", view.getChildAt(0).isEnabled)
672
+ assertFalse("Second child should be disabled", view.getChildAt(1).isEnabled)
673
+ }
674
+ }