@react-native/gradle-plugin 0.74.85 → 0.74.86

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 (60) hide show
  1. package/build.gradle.kts +2 -75
  2. package/package.json +4 -3
  3. package/react-native-gradle-plugin/build.gradle.kts +84 -0
  4. package/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/TestReactExtension.kt +12 -0
  5. package/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tasks/BundleHermesCTaskTest.kt +434 -0
  6. package/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tasks/GenerateCodegenArtifactsTaskTest.kt +212 -0
  7. package/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tasks/GenerateCodegenSchemaTaskTest.kt +192 -0
  8. package/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tasks/internal/BuildCodegenCLITaskTest.kt +27 -0
  9. package/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tasks/internal/PrepareBoostTaskTest.kt +105 -0
  10. package/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tasks/internal/PrepareGlogTaskTest.kt +130 -0
  11. package/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tasks/internal/PrepareJSCTaskTest.kt +128 -0
  12. package/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tasks/internal/PreparePrefabHeadersTaskTest.kt +201 -0
  13. package/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tasks/internal/utils/PrefabPreprocessingEntryTest.kt +25 -0
  14. package/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tests/OsRule.kt +52 -0
  15. package/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tests/TaskTestUtils.kt +69 -0
  16. package/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/tests/WithOs.kt +17 -0
  17. package/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/AgpConfiguratorUtilsTest.kt +65 -0
  18. package/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/BackwardCompatUtilsTest.kt +43 -0
  19. package/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/DependencyUtilsTest.kt +404 -0
  20. package/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/FileUtilsTest.kt +45 -0
  21. package/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/JsonUtilsTest.kt +126 -0
  22. package/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/KotlinStdlibCompatUtilsTest.kt +82 -0
  23. package/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/NdkConfiguratorUtilsTest.kt +46 -0
  24. package/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/OsTest.kt +86 -0
  25. package/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/PathUtilsTest.kt +325 -0
  26. package/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/ProjectUtilsTest.kt +533 -0
  27. package/react-native-gradle-plugin/src/test/kotlin/com/facebook/react/utils/TaskUtilsTest.kt +77 -0
  28. package/settings-plugin/build.gradle.kts +50 -0
  29. package/settings-plugin/src/main/kotlin/com/facebook/react/ReactSettingsPlugin.kt +24 -0
  30. package/settings.gradle.kts +6 -1
  31. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/ReactExtension.kt +0 -0
  32. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/ReactPlugin.kt +0 -0
  33. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/ReactRootProjectPlugin.kt +0 -0
  34. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/TaskConfiguration.kt +0 -0
  35. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/internal/PrivateReactExtension.kt +0 -0
  36. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/model/ModelCodegenConfig.kt +0 -0
  37. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/model/ModelCodegenConfigAndroid.kt +0 -0
  38. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/model/ModelPackageJson.kt +0 -0
  39. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/tasks/BundleHermesCTask.kt +0 -0
  40. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/tasks/GenerateCodegenArtifactsTask.kt +0 -0
  41. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/tasks/GenerateCodegenSchemaTask.kt +0 -0
  42. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/tasks/internal/BuildCodegenCLITask.kt +0 -0
  43. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/tasks/internal/PrepareBoostTask.kt +0 -0
  44. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/tasks/internal/PrepareGlogTask.kt +0 -0
  45. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/tasks/internal/PrepareJSCTask.kt +0 -0
  46. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/tasks/internal/PreparePrefabHeadersTask.kt +0 -0
  47. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/tasks/internal/utils/PrefabPreprocessingEntry.kt +0 -0
  48. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/utils/AgpConfiguratorUtils.kt +0 -0
  49. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/utils/BackwardCompatUtils.kt +0 -0
  50. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/utils/DependencyUtils.kt +0 -0
  51. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/utils/FileUtils.kt +0 -0
  52. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/utils/JdkConfiguratorUtils.kt +0 -0
  53. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/utils/JsonUtils.kt +0 -0
  54. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/utils/KotlinStdlibCompatUtils.kt +0 -0
  55. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/utils/NdkConfiguratorUtils.kt +0 -0
  56. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/utils/Os.kt +0 -0
  57. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/utils/PathUtils.kt +0 -0
  58. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/utils/ProjectUtils.kt +0 -0
  59. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/utils/PropertyUtils.kt +0 -0
  60. /package/{src → react-native-gradle-plugin/src}/main/kotlin/com/facebook/react/utils/TaskUtils.kt +0 -0
@@ -0,0 +1,128 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ package com.facebook.react.tasks.internal
9
+
10
+ import com.facebook.react.tests.createProject
11
+ import com.facebook.react.tests.createTestTask
12
+ import com.facebook.react.tests.zipFiles
13
+ import java.io.*
14
+ import org.junit.Assert.*
15
+ import org.junit.Rule
16
+ import org.junit.Test
17
+ import org.junit.rules.TemporaryFolder
18
+
19
+ class PrepareJSCTaskTest {
20
+
21
+ @get:Rule val tempFolder = TemporaryFolder()
22
+
23
+ @Test(expected = IllegalStateException::class)
24
+ fun prepareJSCTask_withMissingPackage_fails() {
25
+ val task = createTestTask<PrepareJSCTask>()
26
+
27
+ task.taskAction()
28
+ }
29
+
30
+ @Test(expected = IllegalStateException::class)
31
+ fun prepareJSCTask_withNullPackage_fails() {
32
+ val task = createTestTask<PrepareJSCTask> { it.jscPackagePath.set(null as String?) }
33
+
34
+ task.taskAction()
35
+ }
36
+
37
+ @Test(expected = IllegalStateException::class)
38
+ fun prepareJSCTask_withMissingDistFolder_fails() {
39
+ val task =
40
+ createTestTask<PrepareJSCTask> { it.jscPackagePath.set(tempFolder.root.absolutePath) }
41
+
42
+ task.taskAction()
43
+ }
44
+
45
+ @Test
46
+ fun prepareJSCTask_ignoresEmptyDirs() {
47
+ prepareInputFolder()
48
+ val output = tempFolder.newFolder("output")
49
+ File(tempFolder.root, "dist/just/an/empty/folders/").apply { mkdirs() }
50
+
51
+ val task =
52
+ createTestTask<PrepareJSCTask> {
53
+ it.jscPackagePath.set(tempFolder.root.absolutePath)
54
+ it.outputDir.set(output)
55
+ }
56
+
57
+ task.taskAction()
58
+
59
+ assertFalse(File(output, "just/an/empty/folders/").exists())
60
+ }
61
+
62
+ @Test
63
+ fun prepareJSCTask_copiesSoFiles() {
64
+ val soFile = tempFolder.newFile("libsomething.so")
65
+ prepareInputFolder(aarContent = listOf(soFile))
66
+ val output = tempFolder.newFolder("output")
67
+
68
+ val task =
69
+ createTestTask<PrepareJSCTask> {
70
+ it.jscPackagePath.set(tempFolder.root.absolutePath)
71
+ it.outputDir.set(output)
72
+ }
73
+
74
+ task.taskAction()
75
+
76
+ assertEquals("libsomething.so", output.listFiles()?.first()?.name)
77
+ }
78
+
79
+ @Test
80
+ fun prepareJSCTask_copiesHeaderFilesToCorrectFolder() {
81
+ prepareInputFolder()
82
+ File(tempFolder.root, "dist/include/justaheader.h").apply {
83
+ parentFile.mkdirs()
84
+ createNewFile()
85
+ }
86
+ val output = tempFolder.newFolder("output")
87
+
88
+ val task =
89
+ createTestTask<PrepareJSCTask> {
90
+ it.jscPackagePath.set(tempFolder.root.absolutePath)
91
+ it.outputDir.set(output)
92
+ }
93
+
94
+ task.taskAction()
95
+
96
+ assertTrue(File(output, "JavaScriptCore/justaheader.h").exists())
97
+ }
98
+
99
+ @Test
100
+ fun prepareJSCTask_copiesCMakefile() {
101
+ val project = createProject()
102
+ prepareInputFolder()
103
+ File(project.projectDir, "src/main/jni/third-party/jsc/CMakeLists.txt").apply {
104
+ parentFile.mkdirs()
105
+ createNewFile()
106
+ }
107
+ val output = tempFolder.newFolder("output")
108
+
109
+ val task =
110
+ createTestTask<PrepareJSCTask>(project = project) {
111
+ it.jscPackagePath.set(tempFolder.root.absolutePath)
112
+ it.outputDir.set(output)
113
+ }
114
+
115
+ task.taskAction()
116
+
117
+ assertTrue(File(output, "CMakeLists.txt").exists())
118
+ }
119
+
120
+ private fun prepareInputFolder(aarContent: List<File> = listOf(tempFolder.newFile())) {
121
+ val dist = tempFolder.newFolder("dist")
122
+ File(dist, "android-jsc/android-library.aar").apply {
123
+ parentFile.mkdirs()
124
+ createNewFile()
125
+ }
126
+ zipFiles(File(dist, "android-jsc/android-library.aar"), aarContent)
127
+ }
128
+ }
@@ -0,0 +1,201 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ package com.facebook.react.tasks.internal
9
+
10
+ import com.facebook.react.tasks.internal.utils.PrefabPreprocessingEntry
11
+ import com.facebook.react.tests.createProject
12
+ import com.facebook.react.tests.createTestTask
13
+ import java.io.*
14
+ import org.junit.Assert.*
15
+ import org.junit.Rule
16
+ import org.junit.Test
17
+ import org.junit.rules.TemporaryFolder
18
+
19
+ class PreparePrefabHeadersTaskTest {
20
+
21
+ @get:Rule val tempFolder = TemporaryFolder()
22
+
23
+ @Test
24
+ fun preparePrefabHeadersTask_withMissingConfiguration_doesNothing() {
25
+ val task = createTestTask<PreparePrefabHeadersTask>()
26
+
27
+ task.taskAction()
28
+ }
29
+
30
+ @Test
31
+ fun preparePrefabHeadersTask_withSingleEntry_copiesHeaderFile() {
32
+ val outputDir = tempFolder.newFolder("output")
33
+ File(tempFolder.root, "input/hello.h").createNewPathAndFile()
34
+
35
+ val project = createProject(projectDir = tempFolder.root)
36
+ val task =
37
+ createTestTask<PreparePrefabHeadersTask>(project = project) {
38
+ it.outputDir.set(outputDir)
39
+ it.input.set(listOf(PrefabPreprocessingEntry("sample_library", "input/" to "")))
40
+ }
41
+
42
+ task.taskAction()
43
+
44
+ assertTrue(File(outputDir, "sample_library/hello.h").exists())
45
+ }
46
+
47
+ @Test
48
+ fun preparePrefabHeadersTask_withSingleEntry_respectsPrefix() {
49
+ val expectedPrefix = "react/render/something/"
50
+ val outputDir = tempFolder.newFolder("output")
51
+ File(tempFolder.root, "input/hello.h").createNewPathAndFile()
52
+
53
+ val project = createProject(projectDir = tempFolder.root)
54
+ val task =
55
+ createTestTask<PreparePrefabHeadersTask>(project = project) {
56
+ it.outputDir.set(outputDir)
57
+ it.input.set(
58
+ listOf(PrefabPreprocessingEntry("sample_library", "input/" to expectedPrefix)))
59
+ }
60
+
61
+ task.taskAction()
62
+
63
+ assertTrue(File(outputDir, "sample_library/${expectedPrefix}hello.h").exists())
64
+ }
65
+
66
+ @Test
67
+ fun preparePrefabHeadersTask_ignoresUnnecessaryFiles() {
68
+ val expectedPrefix = "react/render/something/"
69
+ val outputDir = tempFolder.newFolder("output")
70
+ File(tempFolder.root, "input/hello.hpp").createNewPathAndFile()
71
+ File(tempFolder.root, "input/hello.cpp").createNewPathAndFile()
72
+ File(tempFolder.root, "input/CMakeLists.txt").createNewPathAndFile()
73
+
74
+ val project = createProject(projectDir = tempFolder.root)
75
+ val task =
76
+ createTestTask<PreparePrefabHeadersTask>(project = project) {
77
+ it.outputDir.set(outputDir)
78
+ it.input.set(
79
+ listOf(PrefabPreprocessingEntry("sample_library", "input/" to expectedPrefix)))
80
+ }
81
+
82
+ task.taskAction()
83
+
84
+ assertFalse(File(outputDir, "sample_library/hello.hpp").exists())
85
+ assertFalse(File(outputDir, "sample_library/hello.cpp").exists())
86
+ assertFalse(File(outputDir, "sample_library/CMakeLists.txt").exists())
87
+ }
88
+
89
+ @Test
90
+ fun preparePrefabHeadersTask_withMultiplePaths_copiesHeaderFiles() {
91
+ val outputDir = tempFolder.newFolder("output")
92
+ File(tempFolder.root, "input/component1/hello1.h").createNewPathAndFile()
93
+ File(tempFolder.root, "input/component2/debug/hello2.h").createNewPathAndFile()
94
+
95
+ val project = createProject(projectDir = tempFolder.root)
96
+ val task =
97
+ createTestTask<PreparePrefabHeadersTask>(project = project) {
98
+ it.outputDir.set(outputDir)
99
+ it.input.set(
100
+ listOf(
101
+ PrefabPreprocessingEntry(
102
+ "sample_library",
103
+ listOf("input/component1/" to "", "input/component2/" to "")),
104
+ ))
105
+ }
106
+
107
+ task.taskAction()
108
+
109
+ assertTrue(File(outputDir, "sample_library/hello1.h").exists())
110
+ assertTrue(File(outputDir, "sample_library/debug/hello2.h").exists())
111
+ }
112
+
113
+ @Test
114
+ fun preparePrefabHeadersTask_withMultipleEntries_copiesHeaderFiles() {
115
+ val outputDir = tempFolder.newFolder("output")
116
+ File(tempFolder.root, "input/lib1/hello1.h").createNewPathAndFile()
117
+ File(tempFolder.root, "input/lib2/hello2.h").createNewPathAndFile()
118
+
119
+ val project = createProject(projectDir = tempFolder.root)
120
+ val task =
121
+ createTestTask<PreparePrefabHeadersTask>(project = project) {
122
+ it.outputDir.set(outputDir)
123
+ it.input.set(
124
+ listOf(
125
+ PrefabPreprocessingEntry("libraryone", "input/lib1/" to ""),
126
+ PrefabPreprocessingEntry("librarytwo", "input/lib2/" to "")))
127
+ }
128
+
129
+ task.taskAction()
130
+
131
+ assertTrue(File(outputDir, "libraryone/hello1.h").exists())
132
+ assertTrue(File(outputDir, "librarytwo/hello2.h").exists())
133
+ }
134
+
135
+ @Test
136
+ fun preparePrefabHeadersTask_withReusedHeaders_copiesHeadersTwice() {
137
+ val outputDir = tempFolder.newFolder("output")
138
+ File(tempFolder.root, "input/lib1/hello1.h").createNewPathAndFile()
139
+ File(tempFolder.root, "input/lib2/hello2.h").createNewPathAndFile()
140
+ File(tempFolder.root, "input/shared/sharedheader.h").createNewPathAndFile()
141
+
142
+ val project = createProject(projectDir = tempFolder.root)
143
+ val task =
144
+ createTestTask<PreparePrefabHeadersTask>(project = project) {
145
+ it.outputDir.set(outputDir)
146
+ it.input.set(
147
+ listOf(
148
+ PrefabPreprocessingEntry(
149
+ "libraryone", listOf("input/lib1/" to "", "input/shared/" to "shared/")),
150
+ PrefabPreprocessingEntry(
151
+ "librarytwo", listOf("input/lib2/" to "", "input/shared/" to "shared/")),
152
+ ))
153
+ }
154
+
155
+ task.taskAction()
156
+
157
+ assertTrue(File(outputDir, "libraryone/hello1.h").exists())
158
+ assertTrue(File(outputDir, "libraryone/shared/sharedheader.h").exists())
159
+ assertTrue(File(outputDir, "librarytwo/hello2.h").exists())
160
+ assertTrue(File(outputDir, "librarytwo/shared/sharedheader.h").exists())
161
+ }
162
+
163
+ @Test
164
+ fun preparePrefabHeadersTask_withBoostHeaders_filtersThemCorrectly() {
165
+ val outputDir = tempFolder.newFolder("output")
166
+ File(tempFolder.root, "boost/boost/config.hpp").createNewPathAndFile()
167
+ File(tempFolder.root, "boost/boost/operators.hpp").createNewPathAndFile()
168
+ File(tempFolder.root, "boost/boost/config/default/default.hpp").createNewPathAndFile()
169
+ File(tempFolder.root, "boost/boost/core/core.hpp").createNewPathAndFile()
170
+ File(tempFolder.root, "boost/boost/detail/workaround.hpp").createNewPathAndFile()
171
+ File(tempFolder.root, "boost/boost/preprocessor/preprocessor.hpp").createNewPathAndFile()
172
+ File(tempFolder.root, "boost/boost/preprocessor/detail/preprocessor_detail.hpp")
173
+ .createNewPathAndFile()
174
+ File(tempFolder.root, "boost/boost/anothermodule/wedontuse.hpp").createNewPathAndFile()
175
+
176
+ val project = createProject(projectDir = tempFolder.root)
177
+ val task =
178
+ createTestTask<PreparePrefabHeadersTask>(project = project) {
179
+ it.outputDir.set(outputDir)
180
+ it.input.set(listOf(PrefabPreprocessingEntry("sample_library", "boost/" to "")))
181
+ }
182
+
183
+ task.taskAction()
184
+
185
+ assertTrue(File(outputDir, "sample_library/boost/config.hpp").exists())
186
+ assertTrue(File(outputDir, "sample_library/boost/operators.hpp").exists())
187
+ assertTrue(File(outputDir, "sample_library/boost/config/default/default.hpp").exists())
188
+ assertTrue(File(outputDir, "sample_library/boost/core/core.hpp").exists())
189
+ assertTrue(File(outputDir, "sample_library/boost/detail/workaround.hpp").exists())
190
+ assertTrue(File(outputDir, "sample_library/boost/preprocessor/preprocessor.hpp").exists())
191
+ assertTrue(
192
+ File(outputDir, "sample_library/boost/preprocessor/detail/preprocessor_detail.hpp")
193
+ .exists())
194
+ assertFalse(File(outputDir, "sample_library/boost/anothermodule/wedontuse.hpp").exists())
195
+ }
196
+
197
+ private fun File.createNewPathAndFile() {
198
+ parentFile.mkdirs()
199
+ createNewFile()
200
+ }
201
+ }
@@ -0,0 +1,25 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ package com.facebook.react.tasks.internal.utils
9
+
10
+ import groovy.test.GroovyTestCase.assertEquals
11
+ import org.junit.Test
12
+
13
+ class PrefabPreprocessingEntryTest {
14
+
15
+ @Test
16
+ fun secondaryConstructor_createsAList() {
17
+ val sampleEntry =
18
+ PrefabPreprocessingEntry(
19
+ libraryName = "justALibrary", pathToPrefixCouple = "aPath" to "andAPrefix")
20
+
21
+ assertEquals(1, sampleEntry.pathToPrefixCouples.size)
22
+ assertEquals("aPath", sampleEntry.pathToPrefixCouples[0].first)
23
+ assertEquals("andAPrefix", sampleEntry.pathToPrefixCouples[0].second)
24
+ }
25
+ }
@@ -0,0 +1,52 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ package com.facebook.react.tests
9
+
10
+ import org.junit.rules.TestRule
11
+ import org.junit.runner.Description
12
+ import org.junit.runners.model.Statement
13
+
14
+ /**
15
+ * A JUnit [TestRule] to override values of [System.getProperties] with the support of the [WithOs]
16
+ * annotation.
17
+ */
18
+ class OsRule : TestRule {
19
+
20
+ private var retainOs: String? = null
21
+ private var retainArch: String? = null
22
+
23
+ override fun apply(statement: Statement, description: Description): Statement {
24
+ return object : Statement() {
25
+ override fun evaluate() {
26
+ val annotation = description.annotations.filterIsInstance<WithOs>().firstOrNull()
27
+
28
+ annotation?.os?.propertyName?.let {
29
+ retainOs = System.getProperty(OS_NAME_KEY)
30
+ System.setProperty(OS_NAME_KEY, it)
31
+ }
32
+ annotation?.arch?.let {
33
+ if (it.isNotBlank()) {
34
+ retainArch = System.getProperty(OS_ARCH_KEY)
35
+ System.setProperty(OS_ARCH_KEY, it)
36
+ }
37
+ }
38
+ try {
39
+ statement.evaluate()
40
+ } finally {
41
+ retainOs?.let { System.setProperty(OS_NAME_KEY, it) }
42
+ retainArch?.let { System.setProperty(OS_ARCH_KEY, it) }
43
+ }
44
+ }
45
+ }
46
+ }
47
+
48
+ companion object {
49
+ const val OS_NAME_KEY = "os.name"
50
+ const val OS_ARCH_KEY = "os.arch"
51
+ }
52
+ }
@@ -0,0 +1,69 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ package com.facebook.react.tests
9
+
10
+ import java.io.*
11
+ import java.net.URI
12
+ import java.nio.file.FileSystems
13
+ import java.nio.file.Files
14
+ import java.util.zip.ZipEntry
15
+ import java.util.zip.ZipOutputStream
16
+ import org.gradle.api.Project
17
+ import org.gradle.api.Task
18
+ import org.gradle.testfixtures.ProjectBuilder
19
+
20
+ internal fun createProject(projectDir: File? = null): Project {
21
+ val project =
22
+ ProjectBuilder.builder()
23
+ .apply {
24
+ if (projectDir != null) {
25
+ withProjectDir(projectDir)
26
+ }
27
+ }
28
+ .build()
29
+
30
+ project.plugins.apply("com.android.library")
31
+ project.plugins.apply("com.facebook.react")
32
+ return project
33
+ }
34
+
35
+ internal inline fun <reified T : Task> createTestTask(
36
+ project: Project = createProject(),
37
+ taskName: String = T::class.java.simpleName,
38
+ crossinline block: (T) -> Unit = {}
39
+ ): T = project.tasks.register(taskName, T::class.java) { block(it) }.get()
40
+
41
+ /** A util function to zip a list of files from [contents] inside the zipfile at [destination]. */
42
+ internal fun zipFiles(destination: File, contents: List<File>) {
43
+ ZipOutputStream(BufferedOutputStream(FileOutputStream(destination.absolutePath))).use { out ->
44
+ for (file in contents) {
45
+ FileInputStream(file).use { fi ->
46
+ BufferedInputStream(fi).use { origin ->
47
+ val entry = ZipEntry(file.name)
48
+ out.putNextEntry(entry)
49
+ origin.copyTo(out, 1024)
50
+ }
51
+ }
52
+ }
53
+ }
54
+ }
55
+
56
+ /** A util function to create a zip given a list of dummy files path. */
57
+ internal fun createZip(dest: File, paths: List<String>) {
58
+ val env = mapOf("create" to "true")
59
+ val uri = URI.create("jar:file:$dest")
60
+
61
+ FileSystems.newFileSystem(uri, env).use { zipfs ->
62
+ paths.forEach {
63
+ val zipEntryPath = zipfs.getPath(it)
64
+ val zipEntryFolder = zipEntryPath.subpath(0, zipEntryPath.nameCount - 1)
65
+ Files.createDirectories(zipEntryFolder)
66
+ Files.createFile(zipEntryPath)
67
+ }
68
+ }
69
+ }
@@ -0,0 +1,17 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ package com.facebook.react.tests
9
+
10
+ /** Annotation to specify an Operating System to override the "os.name" System Property. */
11
+ @Retention(AnnotationRetention.RUNTIME) annotation class WithOs(val os: OS, val arch: String = "")
12
+
13
+ enum class OS(val propertyName: String) {
14
+ WIN("Windows"),
15
+ MAC("MacOs"),
16
+ LINUX("Linux")
17
+ }
@@ -0,0 +1,65 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ package com.facebook.react.utils
9
+
10
+ import java.io.File
11
+ import org.junit.Assert.*
12
+ import org.junit.Rule
13
+ import org.junit.Test
14
+ import org.junit.rules.TemporaryFolder
15
+
16
+ class AgpConfiguratorUtilsTest {
17
+
18
+ @get:Rule val tempFolder = TemporaryFolder()
19
+
20
+ @Test
21
+ fun getPackageNameFromManifest_withEmptyFile_returnsNull() {
22
+ val mainFolder = tempFolder.newFolder("awesome-module/src/main/")
23
+ val manifest = File(mainFolder, "AndroidManifest.xml").apply { writeText("") }
24
+
25
+ val actual = getPackageNameFromManifest(manifest)
26
+ assertNull(actual)
27
+ }
28
+
29
+ @Test
30
+ fun getPackageNameFromManifest_withMissingPackage_returnsNull() {
31
+ val mainFolder = tempFolder.newFolder("awesome-module/src/main/")
32
+ val manifest =
33
+ File(mainFolder, "AndroidManifest.xml").apply {
34
+ writeText(
35
+ // language=xml
36
+ """
37
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
38
+ </manifest>
39
+ """
40
+ .trimIndent())
41
+ }
42
+
43
+ val actual = getPackageNameFromManifest(manifest)
44
+ assertNull(actual)
45
+ }
46
+
47
+ @Test
48
+ fun getPackageNameFromManifest_withPackage_returnsPackage() {
49
+ val mainFolder = tempFolder.newFolder("awesome-module/src/main/")
50
+ val manifest =
51
+ File(mainFolder, "AndroidManifest.xml").apply {
52
+ writeText(
53
+ // language=xml
54
+ """
55
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.facebook.react" >
56
+ </manifest>
57
+ """
58
+ .trimIndent())
59
+ }
60
+
61
+ val actual = getPackageNameFromManifest(manifest)
62
+ assertNotNull(actual)
63
+ assertEquals("com.facebook.react", actual)
64
+ }
65
+ }
@@ -0,0 +1,43 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ package com.facebook.react.utils
9
+
10
+ import com.facebook.react.tests.createProject
11
+ import com.facebook.react.utils.BackwardCompatUtils.configureBackwardCompatibilityReactMap
12
+ import org.junit.Assert.assertTrue
13
+ import org.junit.Rule
14
+ import org.junit.Test
15
+ import org.junit.rules.TemporaryFolder
16
+
17
+ class BackwardCompatUtilsTest {
18
+
19
+ @get:Rule val tempFolder = TemporaryFolder()
20
+
21
+ @Test
22
+ fun configureBackwardCompatibilityReactMap_addsEmptyReactMap() {
23
+ val project = createProject()
24
+
25
+ configureBackwardCompatibilityReactMap(project)
26
+
27
+ assertTrue(project.extensions.extraProperties.has("react"))
28
+ @Suppress("UNCHECKED_CAST")
29
+ assertTrue((project.extensions.extraProperties.get("react") as Map<String, Any?>).isEmpty())
30
+ }
31
+
32
+ @Test
33
+ fun configureBackwardCompatibilityReactMap_withExistingMapSetByUser_wipesTheMap() {
34
+ val project = createProject()
35
+ project.extensions.extraProperties.set("react", mapOf("enableHermes" to true))
36
+
37
+ configureBackwardCompatibilityReactMap(project)
38
+
39
+ assertTrue(project.extensions.extraProperties.has("react"))
40
+ @Suppress("UNCHECKED_CAST")
41
+ assertTrue((project.extensions.extraProperties.get("react") as Map<String, Any?>).isEmpty())
42
+ }
43
+ }