@granite-js/screen 1.0.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.
- package/CHANGELOG.md +7 -0
- package/GraniteScreen.podspec +25 -0
- package/LICENSE +202 -0
- package/android/CMakeLists.txt +62 -0
- package/android/build.gradle +63 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/cpp/BundleEvaluator.cpp +27 -0
- package/android/src/main/cpp/BundleEvaluator.h +17 -0
- package/android/src/main/cpp/onLoad.cpp +6 -0
- package/android/src/main/kotlin/run/granite/BundleEvaluator.kt +50 -0
- package/android/src/main/kotlin/run/granite/BundleLoader.kt +40 -0
- package/android/src/main/kotlin/run/granite/DefaultBundleLoader.kt +20 -0
- package/android/src/main/kotlin/run/granite/DefaultErrorView.kt +58 -0
- package/android/src/main/kotlin/run/granite/DefaultLoadingView.kt +51 -0
- package/android/src/main/kotlin/run/granite/GraniteReactDelegate.kt +76 -0
- package/android/src/main/kotlin/run/granite/GraniteReactDelegateImpl.kt +448 -0
- package/android/src/main/kotlin/run/granite/GraniteReactHost.kt +113 -0
- package/android/src/main/kotlin/run/granite/ReactHostFactory.kt +106 -0
- package/gradle-plugin/LICENSE +201 -0
- package/gradle-plugin/README.md +578 -0
- package/gradle-plugin/build.gradle.kts +97 -0
- package/gradle-plugin/gradle/libs.versions.toml +17 -0
- package/gradle-plugin/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/gradle-plugin/gradle/wrapper/gradle-wrapper.properties +7 -0
- package/gradle-plugin/gradle.properties +12 -0
- package/gradle-plugin/gradlew +248 -0
- package/gradle-plugin/gradlew.bat +93 -0
- package/gradle-plugin/settings.gradle.kts +1 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/GraniteExtension.kt +225 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/GranitePlugin.kt +784 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/GraniteRootExtension.kt +107 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/GraniteRootProjectPlugin.kt +290 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/config/BuildConfigConfigurator.kt +69 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/config/DependencyConfigurator.kt +232 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/config/DependencyCoordinates.kt +29 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/config/DevServerResourceConfigurator.kt +101 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/config/JniPackagingConfigurator.kt +160 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/config/NdkConfigurator.kt +135 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/config/RepositoryConfigurator.kt +148 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/config/ResourceConfigurator.kt +56 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/generators/CMakeGenerator.kt +105 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/generators/CppAutolinkingGenerator.kt +152 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/generators/EntryPointGenerator.kt +100 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/models/AndroidDependencyConfig.kt +23 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/models/AutolinkingConfig.kt +89 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/models/CMakeEntry.kt +47 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/models/NativeModule.kt +177 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/tasks/AssetPackagingTask.kt +194 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/tasks/AutolinkingTask.kt +431 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/tasks/BundleTask.kt +275 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/tasks/CodegenArtifactsTask.kt +218 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/tasks/CodegenSchemaTask.kt +186 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/utils/AutolinkingParser.kt +128 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/utils/ConflictDetector.kt +121 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/utils/JdkValidator.kt +73 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/utils/NodeExecutableFinder.kt +43 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/utils/ReactNativeVersionReader.kt +329 -0
- package/gradle-plugin/src/main/kotlin/run/granite/gradle/utils/TaskDependencyValidator.kt +198 -0
- package/gradle-plugin/src/test/kotlin/run/granite/gradle/GraniteExtensionTest.kt +191 -0
- package/gradle-plugin/src/test/kotlin/run/granite/gradle/GranitePluginTest.kt +156 -0
- package/gradle-plugin/src/test/kotlin/run/granite/gradle/GraniteRootProjectPluginTest.kt +87 -0
- package/gradle-plugin/src/test/kotlin/run/granite/gradle/config/BuildConfigConfiguratorTest.kt +115 -0
- package/gradle-plugin/src/test/kotlin/run/granite/gradle/config/DependencyConfiguratorTest.kt +338 -0
- package/gradle-plugin/src/test/kotlin/run/granite/gradle/config/DevServerResourceConfiguratorTest.kt +205 -0
- package/gradle-plugin/src/test/kotlin/run/granite/gradle/config/ResourceConfiguratorTest.kt +131 -0
- package/gradle-plugin/src/test/kotlin/run/granite/gradle/fixtures/NativeModuleFixtures.kt +67 -0
- package/gradle-plugin/src/test/kotlin/run/granite/gradle/generators/CMakeGeneratorTest.kt +71 -0
- package/gradle-plugin/src/test/kotlin/run/granite/gradle/generators/CppAutolinkingGeneratorTest.kt +344 -0
- package/gradle-plugin/src/test/kotlin/run/granite/gradle/generators/EntryPointGeneratorTest.kt +40 -0
- package/gradle-plugin/src/test/kotlin/run/granite/gradle/models/AutolinkingConfigTest.kt +350 -0
- package/gradle-plugin/src/test/kotlin/run/granite/gradle/models/CMakeEntryTest.kt +200 -0
- package/gradle-plugin/src/test/kotlin/run/granite/gradle/models/NativeModuleTest.kt +562 -0
- package/gradle-plugin/src/test/kotlin/run/granite/gradle/tasks/AssetPackagingTaskTest.kt +318 -0
- package/gradle-plugin/src/test/kotlin/run/granite/gradle/tasks/AutolinkingTaskTest.kt +89 -0
- package/gradle-plugin/src/test/kotlin/run/granite/gradle/tasks/BundleTaskTest.kt +68 -0
- package/gradle-plugin/src/test/kotlin/run/granite/gradle/tasks/CodegenTasksTest.kt +410 -0
- package/gradle-plugin/src/test/kotlin/run/granite/gradle/utils/AutolinkingParserTest.kt +335 -0
- package/gradle-plugin/src/test/kotlin/run/granite/gradle/utils/ConflictDetectorTest.kt +75 -0
- package/gradle-plugin/src/test/kotlin/run/granite/gradle/utils/JdkValidatorTest.kt +88 -0
- package/gradle-plugin/src/test/kotlin/run/granite/gradle/utils/ReactNativeVersionReaderTest.kt +585 -0
- package/gradle-plugin/src/test/kotlin/run/granite/gradle/utils/TaskDependencyValidatorTest.kt +123 -0
- package/gradle-plugin/src/test/kotlin/run/granite/gradle/utils/TaskTestUtils.kt +88 -0
- package/gradle-plugin/src/test/resources/fixtures/sample-rn-config.json +45 -0
- package/ios/BundleLoader/BundleEvaluator.h +16 -0
- package/ios/BundleLoader/BundleEvaluator.mm +76 -0
- package/ios/BundleLoader/BundleLoadable.swift +91 -0
- package/ios/GraniteBundleLoaderTypes.swift +7 -0
- package/ios/GraniteScreen.h +12 -0
- package/ios/ReactNativeHosting/DefaultViews.swift +138 -0
- package/ios/ReactNativeHosting/GraniteDefaultModuleProvider.h +24 -0
- package/ios/ReactNativeHosting/GraniteDefaultModuleProvider.mm +22 -0
- package/ios/ReactNativeHosting/GraniteHostingHelper.swift +103 -0
- package/ios/ReactNativeHosting/GraniteNativeFactory.swift +35 -0
- package/ios/ReactNativeHosting/GraniteNativeFactoryDelegateImpl.swift +30 -0
- package/ios/ReactNativeHosting/GraniteNativeFactoryImpl.swift +24 -0
- package/ios/ReactNativeHosting/GraniteReactHost.swift +39 -0
- package/ios/ReactNativeHosting/GraniteScreen-Bridging-Header.h +12 -0
- package/package.json +59 -0
- package/react-native.config.js +8 -0
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
package run.granite.gradle.tasks
|
|
2
|
+
|
|
3
|
+
import com.google.gson.Gson
|
|
4
|
+
import com.google.gson.JsonObject
|
|
5
|
+
import org.assertj.core.api.Assertions.assertThat
|
|
6
|
+
import org.junit.jupiter.api.Test
|
|
7
|
+
import org.junit.jupiter.api.io.TempDir
|
|
8
|
+
import run.granite.gradle.utils.createTestFile
|
|
9
|
+
import run.granite.gradle.utils.createTestTask
|
|
10
|
+
import run.granite.gradle.utils.readFileContent
|
|
11
|
+
import java.io.File
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Unit tests for Codegen tasks (Schema and Artifacts).
|
|
15
|
+
*
|
|
16
|
+
* Tests schema generation and artifact generation for TurboModules and Fabric components.
|
|
17
|
+
*/
|
|
18
|
+
class CodegenTasksTest {
|
|
19
|
+
|
|
20
|
+
@TempDir
|
|
21
|
+
lateinit var tempDir: File
|
|
22
|
+
|
|
23
|
+
// ========== CodegenSchemaTask Tests ==========
|
|
24
|
+
|
|
25
|
+
@Test
|
|
26
|
+
fun `CodegenSchemaTask is cacheable`() {
|
|
27
|
+
val annotations = CodegenSchemaTask::class.annotations
|
|
28
|
+
assertThat(annotations)
|
|
29
|
+
.anyMatch { it.annotationClass.simpleName == "CacheableTask" }
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@Test
|
|
33
|
+
fun `CodegenSchemaTask has correct group and description`() {
|
|
34
|
+
val task = createTestTask<CodegenSchemaTask>()
|
|
35
|
+
|
|
36
|
+
assertThat(task.group).isEqualTo("granite")
|
|
37
|
+
assertThat(task.description).isEqualTo("Scans JavaScript sources and generates React Native Codegen schema")
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@Test
|
|
41
|
+
fun `scanForSpecFiles finds TurboModule specs with Native prefix`() {
|
|
42
|
+
// Create TurboModule spec files
|
|
43
|
+
val jsSourceDir = File(tempDir, "src")
|
|
44
|
+
createTestFile(jsSourceDir, "NativeSampleModule.js", "// TurboModule spec")
|
|
45
|
+
createTestFile(jsSourceDir, "NativeTestModule.ts", "// TurboModule spec")
|
|
46
|
+
createTestFile(jsSourceDir, "NativeExample.tsx", "// TurboModule spec")
|
|
47
|
+
|
|
48
|
+
// Create non-spec files (should be ignored)
|
|
49
|
+
createTestFile(jsSourceDir, "Component.js", "// Regular component")
|
|
50
|
+
createTestFile(jsSourceDir, "utils.ts", "// Utility file")
|
|
51
|
+
|
|
52
|
+
val outputDir = File(tempDir, "output")
|
|
53
|
+
val schemaFile = File(outputDir, "schema.json")
|
|
54
|
+
val reactNativeDir = File(tempDir, "react-native").apply { mkdirs() }
|
|
55
|
+
val nodeModulesDir = File(tempDir, "node_modules").apply { mkdirs() }
|
|
56
|
+
|
|
57
|
+
val task = createTestTask<CodegenSchemaTask> {
|
|
58
|
+
it.jsSourceDirs.set(listOf(jsSourceDir))
|
|
59
|
+
it.reactNativeDir.set(reactNativeDir)
|
|
60
|
+
it.nodeModulesDir.set(nodeModulesDir)
|
|
61
|
+
it.outputDir.set(outputDir)
|
|
62
|
+
it.schemaFile.set(schemaFile)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
task.execute()
|
|
66
|
+
|
|
67
|
+
// Verify schema was generated
|
|
68
|
+
assertThat(schemaFile).exists()
|
|
69
|
+
|
|
70
|
+
val schema = Gson().fromJson(readFileContent(schemaFile), JsonObject::class.java)
|
|
71
|
+
val modules = schema.getAsJsonObject("modules")
|
|
72
|
+
|
|
73
|
+
// Should find 3 TurboModule specs
|
|
74
|
+
assertThat(modules.has("NativeSampleModule")).isTrue
|
|
75
|
+
assertThat(modules.has("NativeTestModule")).isTrue
|
|
76
|
+
assertThat(modules.has("NativeExample")).isTrue
|
|
77
|
+
|
|
78
|
+
// Should NOT find non-spec files
|
|
79
|
+
assertThat(modules.has("Component")).isFalse
|
|
80
|
+
assertThat(modules.has("utils")).isFalse
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@Test
|
|
84
|
+
fun `scanForSpecFiles finds Fabric component specs with NativeComponent suffix`() {
|
|
85
|
+
// Create Fabric component spec files
|
|
86
|
+
val jsSourceDir = File(tempDir, "src")
|
|
87
|
+
createTestFile(jsSourceDir, "MyViewNativeComponent.js", "// Fabric component")
|
|
88
|
+
createTestFile(jsSourceDir, "CustomButtonNativeComponent.ts", "// Fabric component")
|
|
89
|
+
|
|
90
|
+
val outputDir = File(tempDir, "output")
|
|
91
|
+
val schemaFile = File(outputDir, "schema.json")
|
|
92
|
+
val reactNativeDir = File(tempDir, "react-native").apply { mkdirs() }
|
|
93
|
+
val nodeModulesDir = File(tempDir, "node_modules").apply { mkdirs() }
|
|
94
|
+
|
|
95
|
+
val task = createTestTask<CodegenSchemaTask> {
|
|
96
|
+
it.jsSourceDirs.set(listOf(jsSourceDir))
|
|
97
|
+
it.reactNativeDir.set(reactNativeDir)
|
|
98
|
+
it.nodeModulesDir.set(nodeModulesDir)
|
|
99
|
+
it.outputDir.set(outputDir)
|
|
100
|
+
it.schemaFile.set(schemaFile)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
task.execute()
|
|
104
|
+
|
|
105
|
+
val schema = Gson().fromJson(readFileContent(schemaFile), JsonObject::class.java)
|
|
106
|
+
val modules = schema.getAsJsonObject("modules")
|
|
107
|
+
|
|
108
|
+
assertThat(modules.has("MyViewNativeComponent")).isTrue
|
|
109
|
+
assertThat(modules.has("CustomButtonNativeComponent")).isTrue
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
@Test
|
|
113
|
+
fun `scanForSpecFiles handles nested directory structure`() {
|
|
114
|
+
// Create nested directory structure
|
|
115
|
+
val jsSourceDir = File(tempDir, "src")
|
|
116
|
+
createTestFile(File(jsSourceDir, "modules/auth"), "NativeAuthModule.ts", "// Auth module")
|
|
117
|
+
createTestFile(File(jsSourceDir, "components/views"), "ImageViewNativeComponent.js", "// Image view")
|
|
118
|
+
createTestFile(File(jsSourceDir, "deep/nested/path"), "NativeUtilsModule.tsx", "// Utils")
|
|
119
|
+
|
|
120
|
+
val outputDir = File(tempDir, "output")
|
|
121
|
+
val schemaFile = File(outputDir, "schema.json")
|
|
122
|
+
val reactNativeDir = File(tempDir, "react-native").apply { mkdirs() }
|
|
123
|
+
val nodeModulesDir = File(tempDir, "node_modules").apply { mkdirs() }
|
|
124
|
+
|
|
125
|
+
val task = createTestTask<CodegenSchemaTask> {
|
|
126
|
+
it.jsSourceDirs.set(listOf(jsSourceDir))
|
|
127
|
+
it.reactNativeDir.set(reactNativeDir)
|
|
128
|
+
it.nodeModulesDir.set(nodeModulesDir)
|
|
129
|
+
it.outputDir.set(outputDir)
|
|
130
|
+
it.schemaFile.set(schemaFile)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
task.execute()
|
|
134
|
+
|
|
135
|
+
val schema = Gson().fromJson(readFileContent(schemaFile), JsonObject::class.java)
|
|
136
|
+
val modules = schema.getAsJsonObject("modules")
|
|
137
|
+
|
|
138
|
+
// Should find all nested spec files
|
|
139
|
+
assertThat(modules.has("NativeAuthModule")).isTrue
|
|
140
|
+
assertThat(modules.has("ImageViewNativeComponent")).isTrue
|
|
141
|
+
assertThat(modules.has("NativeUtilsModule")).isTrue
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
@Test
|
|
145
|
+
fun `scanForSpecFiles handles multiple source directories`() {
|
|
146
|
+
// Create multiple source directories
|
|
147
|
+
val srcDir1 = File(tempDir, "src1")
|
|
148
|
+
val srcDir2 = File(tempDir, "src2")
|
|
149
|
+
val srcDir3 = File(tempDir, "src3")
|
|
150
|
+
|
|
151
|
+
createTestFile(srcDir1, "NativeModule1.js", "// Module 1")
|
|
152
|
+
createTestFile(srcDir2, "NativeModule2.ts", "// Module 2")
|
|
153
|
+
createTestFile(srcDir3, "NativeModule3.tsx", "// Module 3")
|
|
154
|
+
|
|
155
|
+
val outputDir = File(tempDir, "output")
|
|
156
|
+
val schemaFile = File(outputDir, "schema.json")
|
|
157
|
+
val reactNativeDir = File(tempDir, "react-native").apply { mkdirs() }
|
|
158
|
+
val nodeModulesDir = File(tempDir, "node_modules").apply { mkdirs() }
|
|
159
|
+
|
|
160
|
+
val task = createTestTask<CodegenSchemaTask> {
|
|
161
|
+
it.jsSourceDirs.set(listOf(srcDir1, srcDir2, srcDir3))
|
|
162
|
+
it.reactNativeDir.set(reactNativeDir)
|
|
163
|
+
it.nodeModulesDir.set(nodeModulesDir)
|
|
164
|
+
it.outputDir.set(outputDir)
|
|
165
|
+
it.schemaFile.set(schemaFile)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
task.execute()
|
|
169
|
+
|
|
170
|
+
val schema = Gson().fromJson(readFileContent(schemaFile), JsonObject::class.java)
|
|
171
|
+
val modules = schema.getAsJsonObject("modules")
|
|
172
|
+
|
|
173
|
+
// Should find modules from all source directories
|
|
174
|
+
assertThat(modules.size()).isEqualTo(3)
|
|
175
|
+
assertThat(modules.has("NativeModule1")).isTrue
|
|
176
|
+
assertThat(modules.has("NativeModule2")).isTrue
|
|
177
|
+
assertThat(modules.has("NativeModule3")).isTrue
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
@Test
|
|
181
|
+
fun `generateSchema creates empty schema when no spec files found`() {
|
|
182
|
+
// Create empty source directory
|
|
183
|
+
val jsSourceDir = File(tempDir, "src").apply { mkdirs() }
|
|
184
|
+
createTestFile(jsSourceDir, "Component.js", "// Regular component")
|
|
185
|
+
createTestFile(jsSourceDir, "utils.ts", "// Utils")
|
|
186
|
+
|
|
187
|
+
val outputDir = File(tempDir, "output")
|
|
188
|
+
val schemaFile = File(outputDir, "schema.json")
|
|
189
|
+
val reactNativeDir = File(tempDir, "react-native").apply { mkdirs() }
|
|
190
|
+
val nodeModulesDir = File(tempDir, "node_modules").apply { mkdirs() }
|
|
191
|
+
|
|
192
|
+
val task = createTestTask<CodegenSchemaTask> {
|
|
193
|
+
it.jsSourceDirs.set(listOf(jsSourceDir))
|
|
194
|
+
it.reactNativeDir.set(reactNativeDir)
|
|
195
|
+
it.nodeModulesDir.set(nodeModulesDir)
|
|
196
|
+
it.outputDir.set(outputDir)
|
|
197
|
+
it.schemaFile.set(schemaFile)
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
task.execute()
|
|
201
|
+
|
|
202
|
+
// Should create empty schema
|
|
203
|
+
assertThat(schemaFile).exists()
|
|
204
|
+
|
|
205
|
+
val schema = Gson().fromJson(readFileContent(schemaFile), JsonObject::class.java)
|
|
206
|
+
assertThat(schema.has("version")).isTrue
|
|
207
|
+
assertThat(schema.has("modules")).isTrue
|
|
208
|
+
|
|
209
|
+
val modules = schema.getAsJsonObject("modules")
|
|
210
|
+
assertThat(modules.size()).isEqualTo(0)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
@Test
|
|
214
|
+
fun `generateSchema includes version and module metadata`() {
|
|
215
|
+
val jsSourceDir = File(tempDir, "src")
|
|
216
|
+
createTestFile(jsSourceDir, "NativeSampleModule.ts", "// TurboModule")
|
|
217
|
+
|
|
218
|
+
val outputDir = File(tempDir, "output")
|
|
219
|
+
val schemaFile = File(outputDir, "schema.json")
|
|
220
|
+
val reactNativeDir = File(tempDir, "react-native").apply { mkdirs() }
|
|
221
|
+
val nodeModulesDir = File(tempDir, "node_modules").apply { mkdirs() }
|
|
222
|
+
|
|
223
|
+
val task = createTestTask<CodegenSchemaTask> {
|
|
224
|
+
it.jsSourceDirs.set(listOf(jsSourceDir))
|
|
225
|
+
it.reactNativeDir.set(reactNativeDir)
|
|
226
|
+
it.nodeModulesDir.set(nodeModulesDir)
|
|
227
|
+
it.outputDir.set(outputDir)
|
|
228
|
+
it.schemaFile.set(schemaFile)
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
task.execute()
|
|
232
|
+
|
|
233
|
+
val schema = Gson().fromJson(readFileContent(schemaFile), JsonObject::class.java)
|
|
234
|
+
|
|
235
|
+
// Verify version
|
|
236
|
+
assertThat(schema.has("version")).isTrue
|
|
237
|
+
assertThat(schema.get("version").asString).isEqualTo("0.81.0")
|
|
238
|
+
|
|
239
|
+
// Verify module structure
|
|
240
|
+
val modules = schema.getAsJsonObject("modules")
|
|
241
|
+
val sampleModule = modules.getAsJsonObject("NativeSampleModule")
|
|
242
|
+
|
|
243
|
+
assertThat(sampleModule.get("type").asString).isEqualTo("NativeModule")
|
|
244
|
+
assertThat(sampleModule.has("spec")).isTrue
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
@Test
|
|
248
|
+
fun `generateSchema supports all JavaScript file extensions`() {
|
|
249
|
+
val jsSourceDir = File(tempDir, "src")
|
|
250
|
+
createTestFile(jsSourceDir, "NativeModule1.js", "// .js")
|
|
251
|
+
createTestFile(jsSourceDir, "NativeModule2.ts", "// .ts")
|
|
252
|
+
createTestFile(jsSourceDir, "NativeModule3.jsx", "// .jsx")
|
|
253
|
+
createTestFile(jsSourceDir, "NativeModule4.tsx", "// .tsx")
|
|
254
|
+
|
|
255
|
+
val outputDir = File(tempDir, "output")
|
|
256
|
+
val schemaFile = File(outputDir, "schema.json")
|
|
257
|
+
val reactNativeDir = File(tempDir, "react-native").apply { mkdirs() }
|
|
258
|
+
val nodeModulesDir = File(tempDir, "node_modules").apply { mkdirs() }
|
|
259
|
+
|
|
260
|
+
val task = createTestTask<CodegenSchemaTask> {
|
|
261
|
+
it.jsSourceDirs.set(listOf(jsSourceDir))
|
|
262
|
+
it.reactNativeDir.set(reactNativeDir)
|
|
263
|
+
it.nodeModulesDir.set(nodeModulesDir)
|
|
264
|
+
it.outputDir.set(outputDir)
|
|
265
|
+
it.schemaFile.set(schemaFile)
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
task.execute()
|
|
269
|
+
|
|
270
|
+
val schema = Gson().fromJson(readFileContent(schemaFile), JsonObject::class.java)
|
|
271
|
+
val modules = schema.getAsJsonObject("modules")
|
|
272
|
+
|
|
273
|
+
// All file extensions should be supported
|
|
274
|
+
assertThat(modules.size()).isEqualTo(4)
|
|
275
|
+
assertThat(modules.has("NativeModule1")).isTrue
|
|
276
|
+
assertThat(modules.has("NativeModule2")).isTrue
|
|
277
|
+
assertThat(modules.has("NativeModule3")).isTrue
|
|
278
|
+
assertThat(modules.has("NativeModule4")).isTrue
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
@Test
|
|
282
|
+
fun `schema file is valid JSON`() {
|
|
283
|
+
val jsSourceDir = File(tempDir, "src")
|
|
284
|
+
createTestFile(jsSourceDir, "NativeTestModule.ts", "// Test")
|
|
285
|
+
|
|
286
|
+
val outputDir = File(tempDir, "output")
|
|
287
|
+
val schemaFile = File(outputDir, "schema.json")
|
|
288
|
+
val reactNativeDir = File(tempDir, "react-native").apply { mkdirs() }
|
|
289
|
+
val nodeModulesDir = File(tempDir, "node_modules").apply { mkdirs() }
|
|
290
|
+
|
|
291
|
+
val task = createTestTask<CodegenSchemaTask> {
|
|
292
|
+
it.jsSourceDirs.set(listOf(jsSourceDir))
|
|
293
|
+
it.reactNativeDir.set(reactNativeDir)
|
|
294
|
+
it.nodeModulesDir.set(nodeModulesDir)
|
|
295
|
+
it.outputDir.set(outputDir)
|
|
296
|
+
it.schemaFile.set(schemaFile)
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
task.execute()
|
|
300
|
+
|
|
301
|
+
// Should be parseable as JSON
|
|
302
|
+
val content = readFileContent(schemaFile)
|
|
303
|
+
val schema = Gson().fromJson(content, JsonObject::class.java)
|
|
304
|
+
|
|
305
|
+
assertThat(schema).isNotNull
|
|
306
|
+
assertThat(schema.isJsonObject).isTrue
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// ========== CodegenArtifactsTask Tests ==========
|
|
310
|
+
|
|
311
|
+
@Test
|
|
312
|
+
fun `CodegenArtifactsTask is cacheable`() {
|
|
313
|
+
val annotations = CodegenArtifactsTask::class.annotations
|
|
314
|
+
assertThat(annotations)
|
|
315
|
+
.anyMatch { it.annotationClass.simpleName == "CacheableTask" }
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
@Test
|
|
319
|
+
fun `CodegenArtifactsTask has correct group and description`() {
|
|
320
|
+
val task = createTestTask<CodegenArtifactsTask>()
|
|
321
|
+
|
|
322
|
+
assertThat(task.group).isEqualTo("granite")
|
|
323
|
+
assertThat(task.description).isEqualTo("Generates React Native Codegen artifacts (Java and C++)")
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
@Test
|
|
327
|
+
fun `CodegenArtifactsTask creates output directories when codegen binary not found`() {
|
|
328
|
+
// Create empty schema
|
|
329
|
+
val schemaContent = """{"version":"0.81.0","modules":{}}"""
|
|
330
|
+
val schemaFile = createTestFile(tempDir, "schema.json", schemaContent)
|
|
331
|
+
|
|
332
|
+
val reactNativeDir = File(tempDir, "react-native").apply { mkdirs() }
|
|
333
|
+
val nodeModulesDir = File(tempDir, "node_modules").apply { mkdirs() }
|
|
334
|
+
val javaOutputDir = File(tempDir, "output/java")
|
|
335
|
+
val jniOutputDir = File(tempDir, "output/jni")
|
|
336
|
+
|
|
337
|
+
val task = createTestTask<CodegenArtifactsTask> {
|
|
338
|
+
it.schemaFile.set(schemaFile)
|
|
339
|
+
it.reactNativeDir.set(reactNativeDir)
|
|
340
|
+
it.nodeModulesDir.set(nodeModulesDir)
|
|
341
|
+
it.packageName.set("com.example.test")
|
|
342
|
+
it.libraryName.set("TestLibrary")
|
|
343
|
+
it.javaOutputDir.set(javaOutputDir)
|
|
344
|
+
it.jniOutputDir.set(jniOutputDir)
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// Execute (will not find codegen binary but should not fail)
|
|
348
|
+
task.execute()
|
|
349
|
+
|
|
350
|
+
// Output directories should be created even when codegen binary is not found
|
|
351
|
+
assertThat(javaOutputDir).exists()
|
|
352
|
+
assertThat(jniOutputDir).exists()
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
@Test
|
|
356
|
+
fun `CodegenArtifactsTask uses package name property`() {
|
|
357
|
+
val task = createTestTask<CodegenArtifactsTask> {
|
|
358
|
+
it.packageName.set("com.custom.package")
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
assertThat(task.packageName.get()).isEqualTo("com.custom.package")
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
@Test
|
|
365
|
+
fun `CodegenArtifactsTask uses library name property`() {
|
|
366
|
+
val task = createTestTask<CodegenArtifactsTask> {
|
|
367
|
+
it.libraryName.set("MyNativeLibrary")
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
assertThat(task.libraryName.get()).isEqualTo("MyNativeLibrary")
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
@Test
|
|
374
|
+
fun `CodegenArtifactsTask handles valid schema file`() {
|
|
375
|
+
// Create a schema with modules
|
|
376
|
+
val schemaContent = """
|
|
377
|
+
{
|
|
378
|
+
"version": "0.81.0",
|
|
379
|
+
"modules": {
|
|
380
|
+
"NativeTestModule": {
|
|
381
|
+
"type": "NativeModule",
|
|
382
|
+
"spec": "/path/to/spec"
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
""".trimIndent()
|
|
387
|
+
|
|
388
|
+
val schemaFile = createTestFile(tempDir, "schema.json", schemaContent)
|
|
389
|
+
val reactNativeDir = File(tempDir, "react-native").apply { mkdirs() }
|
|
390
|
+
val nodeModulesDir = File(tempDir, "node_modules").apply { mkdirs() }
|
|
391
|
+
val javaOutputDir = File(tempDir, "output/java")
|
|
392
|
+
val jniOutputDir = File(tempDir, "output/jni")
|
|
393
|
+
|
|
394
|
+
val task = createTestTask<CodegenArtifactsTask> {
|
|
395
|
+
it.schemaFile.set(schemaFile)
|
|
396
|
+
it.reactNativeDir.set(reactNativeDir)
|
|
397
|
+
it.nodeModulesDir.set(nodeModulesDir)
|
|
398
|
+
it.packageName.set("com.example.test")
|
|
399
|
+
it.libraryName.set("TestLibrary")
|
|
400
|
+
it.javaOutputDir.set(javaOutputDir)
|
|
401
|
+
it.jniOutputDir.set(jniOutputDir)
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// Should not throw (will warn about missing codegen binary but continue)
|
|
405
|
+
task.execute()
|
|
406
|
+
|
|
407
|
+
assertThat(javaOutputDir).exists()
|
|
408
|
+
assertThat(jniOutputDir).exists()
|
|
409
|
+
}
|
|
410
|
+
}
|