@datadog/mobile-react-native-session-replay 2.0.2-alpha.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 (77) hide show
  1. package/DatadogSDKReactNativeSessionReplay.podspec +41 -0
  2. package/README.md +3 -0
  3. package/android/build.gradle +239 -0
  4. package/android/detekt.yml +572 -0
  5. package/android/gradle.properties +5 -0
  6. package/android/src/main/AndroidManifest.xml +11 -0
  7. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/DatadogSDKReactNativeSessionReplayPackage.kt +46 -0
  8. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/DdSessionReplayImplementation.kt +57 -0
  9. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/NoopTextPropertiesResolver.kt +22 -0
  10. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/ReactNativeSessionReplayExtensionSupport.kt +77 -0
  11. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/ReactTextPropertiesResolver.kt +196 -0
  12. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/SessionReplaySDKWrapper.kt +24 -0
  13. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/SessionReplayWrapper.kt +22 -0
  14. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/ShadowNodeWrapper.kt +70 -0
  15. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/TextPropertiesResolver.kt +20 -0
  16. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/extensions/LongExt.kt +15 -0
  17. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/mappers/ReactMaskInputTextMapper.kt +54 -0
  18. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/mappers/ReactMaskTextMapper.kt +55 -0
  19. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/mappers/ReactTextMapper.kt +54 -0
  20. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/mappers/ReactViewGroupMapper.kt +58 -0
  21. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/utils/ColorUtils.kt +22 -0
  22. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/utils/DrawableUtils.kt +35 -0
  23. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/utils/ReactViewBackgroundDrawableUtils.kt +66 -0
  24. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/utils/ReflectionUtils.kt +30 -0
  25. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/utils/TextViewUtils.kt +40 -0
  26. package/android/src/newarch/kotlin/com/datadog/reactnative/sessionreplay/DdSessionReplay.kt +33 -0
  27. package/android/src/oldarch/kotlin/com/datadog/reactnative/sessionreplay/DdSessionReplay.kt +34 -0
  28. package/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/DdSessionReplayImplementationTest.kt +105 -0
  29. package/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/ReactNativeSessionReplayExtensionSupportTest.kt +127 -0
  30. package/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/ReactTextPropertiesResolverTest.kt +271 -0
  31. package/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/mappers/ReactViewGroupMapperTest.kt +131 -0
  32. package/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/utils/ColorUtilsTest.kt +42 -0
  33. package/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/utils/DrawableUtilsTest.kt +101 -0
  34. package/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/utils/TextViewUtilsTest.kt +109 -0
  35. package/android/src/test/kotlin/com/datadog/reactnative/tools/unit/GenericAssert.kt +69 -0
  36. package/android/src/test/kotlin/com/datadog/reactnative/tools/unit/MapExt.kt +29 -0
  37. package/android/src/test/kotlin/com/datadog/reactnative/tools/unit/ReflectUtils.kt +266 -0
  38. package/android/src/test/kotlin/com/datadog/reactnative/tools/unit/forge/BaseConfigurator.kt +24 -0
  39. package/android/src/test/kotlin/com/datadog/reactnative/tools/unit/forge/ForgeConfigurator.kt +24 -0
  40. package/android/src/test/kotlin/com/datadog/reactnative/tools/unit/forge/TextWireframeForgeryFactory.kt +64 -0
  41. package/android/src/test/kotlin/com/datadog/reactnative/tools/unit/forge/Throwable.kt +31 -0
  42. package/android/src/test/kotlin/com/datadog/reactnative/tools/unit/forge/ThrowableForgeryFactory.kt +21 -0
  43. package/android/src/test/kotlin/com/datadog/reactnative/tools/unit/forge/WireframeClipForgeryFactory.kt +25 -0
  44. package/android/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker +1 -0
  45. package/ios/DatadogSDKReactNativeSessionReplay.xcodeproj/project.pbxproj +272 -0
  46. package/ios/DatadogSDKReactNativeSessionReplay.xcodeproj/project.xcworkspace/contents.xcworkspacedata +4 -0
  47. package/ios/Sources/DatadogSDKReactNativeSessionReplay.h +8 -0
  48. package/ios/Sources/DdSessionReplay.h +24 -0
  49. package/ios/Sources/DdSessionReplay.mm +53 -0
  50. package/ios/Sources/DdSessionReplayImplementation.swift +70 -0
  51. package/ios/Sources/RCTTextViewRecorder.swift +157 -0
  52. package/lib/commonjs/SessionReplay.js +66 -0
  53. package/lib/commonjs/SessionReplay.js.map +1 -0
  54. package/lib/commonjs/index.js +26 -0
  55. package/lib/commonjs/index.js.map +1 -0
  56. package/lib/commonjs/nativeModulesTypes.js +2 -0
  57. package/lib/commonjs/nativeModulesTypes.js.map +1 -0
  58. package/lib/commonjs/specs/NativeDdSessionReplay.js +20 -0
  59. package/lib/commonjs/specs/NativeDdSessionReplay.js.map +1 -0
  60. package/lib/module/SessionReplay.js +53 -0
  61. package/lib/module/SessionReplay.js.map +1 -0
  62. package/lib/module/index.js +8 -0
  63. package/lib/module/index.js.map +1 -0
  64. package/lib/module/nativeModulesTypes.js +2 -0
  65. package/lib/module/nativeModulesTypes.js.map +1 -0
  66. package/lib/module/specs/NativeDdSessionReplay.js +14 -0
  67. package/lib/module/specs/NativeDdSessionReplay.js.map +1 -0
  68. package/lib/typescript/SessionReplay.d.ts +34 -0
  69. package/lib/typescript/index.d.ts +2 -0
  70. package/lib/typescript/nativeModulesTypes.d.ts +18 -0
  71. package/lib/typescript/specs/NativeDdSessionReplay.d.ts +15 -0
  72. package/package.json +90 -0
  73. package/src/SessionReplay.ts +84 -0
  74. package/src/__tests__/SessionReplay.test.ts +49 -0
  75. package/src/index.ts +13 -0
  76. package/src/nativeModulesTypes.ts +29 -0
  77. package/src/specs/NativeDdSessionReplay.ts +28 -0
@@ -0,0 +1,69 @@
1
+ /*
2
+ * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3
+ * This product includes software developed at Datadog (https://www.datadoghq.com/).
4
+ * Copyright 2016-Present Datadog, Inc.
5
+ */
6
+
7
+ package com.datadog.tools.unit
8
+
9
+ import org.assertj.core.api.AbstractAssert
10
+ import org.assertj.core.api.Assertions.assertThat
11
+
12
+ class GenericAssert(actual: Any?) :
13
+ AbstractAssert<GenericAssert, Any>(actual, GenericAssert::class.java) {
14
+
15
+ fun doesNotHaveField(name: String): GenericAssert {
16
+ val field: Any? = actual.getFieldValue(name)
17
+ assertThat(field)
18
+ .overridingErrorMessage(
19
+ "Expecting object to not have $name, but found it having value $field"
20
+ )
21
+ .isNull()
22
+ return this
23
+ }
24
+
25
+ fun <T> getActualValue(name: String): T {
26
+ val field: Any? = actual.getFieldValue(name)
27
+ assertThat(field)
28
+ .overridingErrorMessage(
29
+ "Expecting object to have a non null field named $name, but field was null"
30
+ )
31
+ .isNotNull()
32
+ return field!! as T
33
+ }
34
+
35
+ fun hasField(name: String, nestedAssert: (GenericAssert) -> Unit = {}): GenericAssert {
36
+ val field: Any? = actual.getFieldValue(name)
37
+ assertThat(field)
38
+ .overridingErrorMessage(
39
+ "Expecting object to have a non null field named $name, but field was null"
40
+ )
41
+ .isNotNull()
42
+ nestedAssert(GenericAssert(field!!))
43
+ return this
44
+ }
45
+
46
+ fun <F> hasFieldEqualTo(name: String, expected: F): GenericAssert {
47
+ val field: Any? = actual.getFieldValue(name)
48
+ assertThat(field).isEqualTo(expected)
49
+ return this
50
+ }
51
+
52
+ fun hasFieldWithClass(name: String, expectedClassName: String): GenericAssert {
53
+ val field: Any? = actual.getFieldValue(name)
54
+ assertThat(field?.javaClass?.name).isEqualTo(expectedClassName)
55
+ return this
56
+ }
57
+
58
+ fun isInstanceOf(expectedClassName: String): GenericAssert {
59
+ val className = actual.javaClass.canonicalName!!
60
+ assertThat(className).isEqualTo(expectedClassName)
61
+ return this
62
+ }
63
+
64
+ companion object {
65
+ fun assertThat(actual: Any?): GenericAssert {
66
+ return GenericAssert(actual)
67
+ }
68
+ }
69
+ }
@@ -0,0 +1,29 @@
1
+ /*
2
+ * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3
+ * This product includes software developed at Datadog (https://www.datadoghq.com/).
4
+ * Copyright 2016-Present Datadog, Inc.
5
+ */
6
+
7
+ package com.datadog.tools.unit
8
+
9
+ import com.facebook.react.bridge.JavaOnlyArray
10
+ import com.facebook.react.bridge.JavaOnlyMap
11
+ import com.facebook.react.bridge.ReadableArray
12
+ import com.facebook.react.bridge.ReadableMap
13
+
14
+ fun Map<*, *>.toReadableMap(): ReadableMap {
15
+ val keysAndValues = mutableListOf<Any?>()
16
+
17
+ entries.forEach {
18
+ keysAndValues.add(it.key)
19
+ keysAndValues.add(it.value)
20
+ }
21
+
22
+ // this FB implementation is not backed by Android-specific .so library, so ok for unit tests
23
+ return JavaOnlyMap.of(*keysAndValues.toTypedArray())
24
+ }
25
+
26
+ fun List<*>.toReadableArray(): ReadableArray {
27
+ // this FB implementation is not backed by Android-specific .so library, so ok for unit tests
28
+ return JavaOnlyArray.from(this)
29
+ }
@@ -0,0 +1,266 @@
1
+ /*
2
+ * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3
+ * This product includes software developed at Datadog (https://www.datadoghq.com/).
4
+ * Copyright 2016-Present Datadog, Inc.
5
+ */
6
+
7
+ package com.datadog.tools.unit
8
+
9
+ import java.lang.reflect.Field
10
+ import java.lang.reflect.InvocationTargetException
11
+ import java.lang.reflect.Method
12
+ import java.lang.reflect.Modifier
13
+ import java.util.LinkedList
14
+ import kotlin.reflect.jvm.isAccessible
15
+
16
+ /**
17
+ * Creates an instance of the given class name.
18
+ * @param className the full name of the class to instantiate
19
+ * @param params the parameters to provide the constructor
20
+ * @return the created instance
21
+ */
22
+ @Suppress("SpreadOperator")
23
+ fun createInstance(
24
+ className: String,
25
+ vararg params: Any?
26
+ ): Any {
27
+ return Class.forName(className)
28
+ .kotlin
29
+ .constructors.first()
30
+ .apply { isAccessible = true }
31
+ .call(*params)
32
+ }
33
+
34
+ /**
35
+ * Sets a static value on the target class.
36
+ * @param fieldName the name of the field
37
+ * @param fieldValue the value to set
38
+ */
39
+ @Suppress("SwallowedException")
40
+ inline fun <reified T, R> Class<T>.setStaticValue(
41
+ fieldName: String,
42
+ fieldValue: R
43
+ ) {
44
+ val field = getDeclaredField(fieldName)
45
+
46
+ // make it accessible
47
+ field.isAccessible = true
48
+
49
+ // Make it non final
50
+ try {
51
+ val modifiersField = Field::class.java.getDeclaredField("modifiers")
52
+ modifiersField.isAccessible = true
53
+ modifiersField.setInt(field, field.modifiers and Modifier.FINAL.inv())
54
+ } catch (e: NoSuchFieldException) {
55
+ // do nothing
56
+ @Suppress("PrintStackTrace")
57
+ e.printStackTrace()
58
+ }
59
+ field.set(null, fieldValue)
60
+ }
61
+
62
+ /**
63
+ * Gets the static value from the target class.
64
+ * @param className the full name of the class
65
+ * @param fieldName the name of the field
66
+ */
67
+ inline fun <reified R> getStaticValue(
68
+ className: String,
69
+ fieldName: String
70
+ ): R {
71
+ val clazz = Class.forName(className)
72
+ val field = clazz.getDeclaredField(fieldName)
73
+ // make it accessible
74
+ field.isAccessible = true
75
+
76
+ return field.get(null) as R
77
+ }
78
+
79
+ /**
80
+ * Gets the static value from the target class.
81
+ * @param fieldName the name of the field
82
+ */
83
+ inline fun <reified T, reified R> Class<T>.getStaticValue(fieldName: String): R {
84
+ val field = getDeclaredField(fieldName)
85
+
86
+ // make it accessible
87
+ field.isAccessible = true
88
+
89
+ return field.get(null) as R
90
+ }
91
+
92
+ /**
93
+ * Sets the field value on the target instance.
94
+ * @param fieldName the name of the field
95
+ * @param fieldValue the value of the field
96
+ */
97
+ @Suppress("SwallowedException")
98
+ inline fun <reified T> Any.setFieldValue(
99
+ fieldName: String,
100
+ fieldValue: T
101
+ ): Boolean {
102
+ var field: Field? = null
103
+ val classesToSearch = LinkedList<Class<*>>()
104
+ classesToSearch.add(this.javaClass)
105
+ val classesSearched = mutableSetOf<Class<*>>()
106
+
107
+ while (field == null && classesToSearch.isNotEmpty()) {
108
+ val toSearchIn = classesToSearch.remove()
109
+ try {
110
+ field = toSearchIn.getDeclaredField(fieldName)
111
+ } catch (e: NoSuchFieldException) {
112
+ // do nothing
113
+ }
114
+ classesSearched.add(toSearchIn)
115
+ toSearchIn.superclass?.let {
116
+ if (!classesSearched.contains(it)) {
117
+ classesToSearch.add(it)
118
+ }
119
+ }
120
+ }
121
+
122
+ // make it accessible
123
+ if (field != null) {
124
+ field.isAccessible = true
125
+
126
+ // Make it non final
127
+ val modifiersField = Field::class.java.getDeclaredField("modifiers")
128
+ modifiersField.isAccessible = true
129
+ modifiersField.setInt(field, field.modifiers and Modifier.FINAL.inv())
130
+
131
+ field.set(this, fieldValue)
132
+ return true
133
+ } else {
134
+ return false
135
+ }
136
+ }
137
+
138
+ /**
139
+ * Gets the field value from the target instance.
140
+ * @param fieldName the name of the field
141
+ */
142
+ inline fun <reified T, R : Any> R.getFieldValue(
143
+ fieldName: String,
144
+ enclosingClass: Class<R> = this.javaClass
145
+ ): T {
146
+ val field = enclosingClass.getDeclaredField(fieldName)
147
+ field.isAccessible = true
148
+ return field.get(this) as T
149
+ }
150
+
151
+ /**
152
+ * Invokes a method on the target instance.
153
+ * @param methodName the name of the method
154
+ * @param params the parameters to provide the method
155
+ * @return the result from the invoked method
156
+ */
157
+ @Suppress("SpreadOperator", "UNCHECKED_CAST", "TooGenericExceptionCaught")
158
+ fun <T : Any> T.invokeMethod(
159
+ methodName: String,
160
+ vararg params: Any?
161
+ ): Any? {
162
+ val declarationParams = Array<Class<*>?>(params.size) {
163
+ params[it]?.javaClass
164
+ }
165
+
166
+ val method = getDeclaredMethodRecursively(methodName, true, declarationParams)
167
+ val wasAccessible = method.isAccessible
168
+
169
+ val output: Any?
170
+ method.isAccessible = true
171
+ try {
172
+ output = if (params.isEmpty()) {
173
+ method.invoke(this)
174
+ } else {
175
+ method.invoke(this, *params)
176
+ }
177
+ } catch (e: InvocationTargetException) {
178
+ throw e.cause ?: e
179
+ } finally {
180
+ method.isAccessible = wasAccessible
181
+ }
182
+
183
+ return output
184
+ }
185
+
186
+ /**
187
+ * Invokes a method on the target instance, where one or more of the parameters
188
+ * are generics.
189
+ * @param methodName the name of the method
190
+ * @param params the parameters to provide the method
191
+ * @return the result from the invoked method
192
+ */
193
+ @Suppress("SpreadOperator", "UNCHECKED_CAST")
194
+ fun <T : Any> T.invokeGenericMethod(
195
+ methodName: String,
196
+ vararg params: Any
197
+ ): Any? {
198
+ val declarationParams = Array<Class<*>?>(params.size) {
199
+ params[it].javaClass
200
+ }
201
+
202
+ val method = getDeclaredMethodRecursively(methodName, false, declarationParams)
203
+ val wasAccessible = method.isAccessible
204
+
205
+ val output: Any?
206
+ method.isAccessible = true
207
+ try {
208
+ output = if (params.isEmpty()) {
209
+ method.invoke(this)
210
+ } else {
211
+ method.invoke(this, *params)
212
+ }
213
+ } catch (e: InvocationTargetException) {
214
+ throw e.cause ?: e
215
+ } finally {
216
+ method.isAccessible = wasAccessible
217
+ }
218
+
219
+ return output
220
+ }
221
+
222
+ @Suppress("TooGenericExceptionCaught", "SwallowedException", "SpreadOperator")
223
+ private fun <T : Any> T.getDeclaredMethodRecursively(
224
+ methodName: String,
225
+ matchingParams: Boolean,
226
+ declarationParams: Array<Class<*>?>
227
+ ): Method {
228
+ val classesToSearch = mutableListOf<Class<*>>(this.javaClass)
229
+ val classesSearched = mutableListOf<Class<*>>()
230
+ var method: Method?
231
+ do {
232
+ val lookingInClass = classesToSearch.removeAt(0)
233
+ classesSearched.add(lookingInClass)
234
+ method = try {
235
+ if (matchingParams) {
236
+ lookingInClass.getDeclaredMethod(methodName, *declarationParams)
237
+ } else {
238
+ lookingInClass.declaredMethods.firstOrNull {
239
+ it.name == methodName &&
240
+ it.parameterTypes.size == declarationParams.size
241
+ }
242
+ }
243
+ } catch (e: Throwable) {
244
+ null
245
+ }
246
+
247
+ val superclass = lookingInClass.superclass
248
+ if (superclass != null &&
249
+ !classesToSearch.contains(superclass) &&
250
+ !classesSearched.contains(superclass)
251
+ ) {
252
+ classesToSearch.add(superclass)
253
+ }
254
+ lookingInClass.interfaces.forEach {
255
+ if (!classesToSearch.contains(it) && !classesSearched.contains(it)) {
256
+ classesToSearch.add(it)
257
+ }
258
+ }
259
+ } while (method == null && classesToSearch.isNotEmpty())
260
+
261
+ checkNotNull(method) {
262
+ "Unable to access method $methodName on ${javaClass.canonicalName}"
263
+ }
264
+
265
+ return method
266
+ }
@@ -0,0 +1,24 @@
1
+ /*
2
+ * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3
+ * This product includes software developed at Datadog (https://www.datadoghq.com/).
4
+ * Copyright 2016-Present Datadog, Inc.
5
+ */
6
+
7
+ package com.datadog.tools.unit.forge
8
+
9
+ import fr.xgouchet.elmyr.Forge
10
+ import fr.xgouchet.elmyr.ForgeConfigurator
11
+ import fr.xgouchet.elmyr.jvm.useJvmFactories
12
+
13
+ /**
14
+ * Base implementation of a [ForgeConfigurator], adding the JVM Forgery Factories (Date, …) and
15
+ * a [ThrowableForgeryFactory].
16
+ */
17
+ open class BaseConfigurator :
18
+ ForgeConfigurator {
19
+ /** @inheritDoc */
20
+ override fun configure(forge: Forge) {
21
+ forge.addFactory(ThrowableForgeryFactory())
22
+ forge.useJvmFactories()
23
+ }
24
+ }
@@ -0,0 +1,24 @@
1
+ /*
2
+ *
3
+ * * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
4
+ * * This product includes software developed at Datadog (https://www.datadoghq.com/).
5
+ * * Copyright 2016-Present Datadog, Inc.
6
+ *
7
+ */
8
+
9
+ package com.datadog.reactnative.tools.unit.forge
10
+
11
+ import com.datadog.tools.unit.forge.BaseConfigurator
12
+ import fr.xgouchet.elmyr.Forge
13
+ import fr.xgouchet.elmyr.jvm.useJvmFactories
14
+
15
+ internal class ForgeConfigurator : BaseConfigurator() {
16
+ override fun configure(forge: Forge) {
17
+ super.configure(forge)
18
+
19
+ forge.addFactory(TextWireframeForgeryFactory())
20
+ forge.addFactory(WireframeClipForgeryFactory())
21
+
22
+ forge.useJvmFactories()
23
+ }
24
+ }
@@ -0,0 +1,64 @@
1
+ /*
2
+ *
3
+ * * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
4
+ * * This product includes software developed at Datadog (https://www.datadoghq.com/).
5
+ * * Copyright 2016-Present Datadog, Inc.
6
+ *
7
+ */
8
+
9
+ package com.datadog.reactnative.tools.unit.forge
10
+
11
+ import com.datadog.android.sessionreplay.model.MobileSegment
12
+ import fr.xgouchet.elmyr.Forge
13
+ import fr.xgouchet.elmyr.ForgeryFactory
14
+
15
+ internal class TextWireframeForgeryFactory :
16
+ ForgeryFactory<MobileSegment.Wireframe.TextWireframe> {
17
+ override fun getForgery(forge: Forge): MobileSegment.Wireframe.TextWireframe {
18
+ return MobileSegment.Wireframe.TextWireframe(
19
+ id = forge.aPositiveInt().toLong(),
20
+ x = forge.aPositiveLong(),
21
+ y = forge.aPositiveLong(),
22
+ width = forge.aPositiveLong(strict = true),
23
+ height = forge.aPositiveLong(strict = true),
24
+ text = forge.aString(),
25
+ shapeStyle = forge.aNullable {
26
+ MobileSegment.ShapeStyle(
27
+ forge.aStringMatching("#[0-9A-F]{6}FF"),
28
+ opacity = forge.aFloat(min = 0f, max = 1f),
29
+ cornerRadius = forge.aPositiveLong()
30
+ )
31
+ },
32
+ textStyle = MobileSegment.TextStyle(
33
+ family = forge.aString(),
34
+ size = forge.aPositiveLong(strict = true),
35
+ color = forge.aStringMatching("#[0-9A-F]{6}FF")
36
+ ),
37
+ textPosition = forge.aNullable {
38
+ MobileSegment.TextPosition(
39
+ padding = forge.aNullable {
40
+ MobileSegment.Padding(
41
+ forge.aNullable { aPositiveLong() },
42
+ forge.aNullable { aPositiveLong() },
43
+ forge.aNullable { aPositiveLong() },
44
+ forge.aNullable { aPositiveLong() }
45
+ )
46
+ },
47
+ alignment = forge.aNullable {
48
+ MobileSegment.Alignment(
49
+ horizontal = forge.aNullable {
50
+ forge.aValueFrom(MobileSegment.Horizontal::class.java)
51
+ },
52
+ vertical = forge.aNullable {
53
+ forge.aValueFrom(MobileSegment.Vertical::class.java)
54
+ }
55
+ )
56
+ }
57
+ )
58
+ },
59
+ clip = forge.aNullable {
60
+ getForgery()
61
+ }
62
+ )
63
+ }
64
+ }
@@ -0,0 +1,31 @@
1
+ /*
2
+ * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3
+ * This product includes software developed at Datadog (https://www.datadoghq.com/).
4
+ * Copyright 2016-Present Datadog, Inc.
5
+ */
6
+
7
+ package com.datadog.tools.unit.forge
8
+
9
+ import fr.xgouchet.elmyr.Forge
10
+ import fr.xgouchet.elmyr.ForgeryException
11
+ import java.io.FileNotFoundException
12
+ import java.io.IOException
13
+ import java.io.InvalidObjectException
14
+
15
+ /**
16
+ * @return a random [Throwable] instance with a forged message.
17
+ */
18
+ fun Forge.aThrowable(): Throwable {
19
+ val errorMessage = anAlphabeticalString()
20
+ return anElementFrom(
21
+ IOException(errorMessage),
22
+ IllegalStateException(errorMessage),
23
+ UnknownError(errorMessage),
24
+ ArrayIndexOutOfBoundsException(errorMessage),
25
+ NullPointerException(errorMessage),
26
+ ForgeryException(errorMessage),
27
+ InvalidObjectException(errorMessage),
28
+ UnsupportedOperationException(errorMessage),
29
+ FileNotFoundException(errorMessage)
30
+ )
31
+ }
@@ -0,0 +1,21 @@
1
+ /*
2
+ * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3
+ * This product includes software developed at Datadog (https://www.datadoghq.com/).
4
+ * Copyright 2016-Present Datadog, Inc.
5
+ */
6
+
7
+ package com.datadog.tools.unit.forge
8
+
9
+ import fr.xgouchet.elmyr.Forge
10
+ import fr.xgouchet.elmyr.ForgeryFactory
11
+
12
+ /**
13
+ * A [ForgeryFactory] generating a random [Throwable] instance with a forged message.
14
+ */
15
+ class ThrowableForgeryFactory :
16
+ ForgeryFactory<Throwable> {
17
+ /** @inheritDoc */
18
+ override fun getForgery(forge: Forge): Throwable {
19
+ return forge.aThrowable()
20
+ }
21
+ }
@@ -0,0 +1,25 @@
1
+ /*
2
+ *
3
+ * * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
4
+ * * This product includes software developed at Datadog (https://www.datadoghq.com/).
5
+ * * Copyright 2016-Present Datadog, Inc.
6
+ *
7
+ */
8
+
9
+ package com.datadog.reactnative.tools.unit.forge
10
+
11
+ import com.datadog.android.sessionreplay.model.MobileSegment
12
+ import fr.xgouchet.elmyr.Forge
13
+ import fr.xgouchet.elmyr.ForgeryFactory
14
+
15
+ internal class WireframeClipForgeryFactory :
16
+ ForgeryFactory<MobileSegment.WireframeClip> {
17
+ override fun getForgery(forge: Forge): MobileSegment.WireframeClip {
18
+ return MobileSegment.WireframeClip(
19
+ top = forge.aNullable { aLong(min = 0, max = 100) },
20
+ bottom = forge.aNullable { aLong(min = 0, max = 100) },
21
+ left = forge.aNullable { aLong(min = 0, max = 100) },
22
+ right = forge.aNullable { aLong(min = 0, max = 100) }
23
+ )
24
+ }
25
+ }