first commit

This commit is contained in:
2026-03-10 16:18:05 +00:00
commit 11f9c069b5
31635 changed files with 3187747 additions and 0 deletions

View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
alias(libs.plugins.kotlin.jvm)
alias(libs.plugins.ktfmt)
}
repositories { mavenCentral() }
group = "com.facebook.react"
dependencies {
implementation(libs.gson)
implementation(libs.guava)
testImplementation(libs.junit)
testImplementation(libs.assertj)
testImplementation(project(":shared-testutil"))
}
java { targetCompatibility = JavaVersion.VERSION_11 }
kotlin { jvmToolchain(17) }
tasks.withType<KotlinCompile>().configureEach {
compilerOptions {
apiVersion.set(KotlinVersion.KOTLIN_1_8)
// See comment above on JDK 11 support
jvmTarget.set(JvmTarget.JVM_11)
allWarningsAsErrors.set(
project.properties["enableWarningsAsErrors"]?.toString()?.toBoolean() ?: false
)
}
}
tasks.withType<Test>().configureEach {
testLogging {
exceptionFormat = TestExceptionFormat.FULL
showExceptions = true
showCauses = true
showStackTraces = true
}
}

View File

@@ -0,0 +1,18 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.model
data class ModelAutolinkingAndroidProjectJson(
val sourceDir: String,
val appName: String,
val packageName: String,
val applicationId: String,
val mainActivity: String,
val watchModeCommandParams: List<String>?,
val dependencyConfiguration: String?,
)

View File

@@ -0,0 +1,14 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.model
data class ModelAutolinkingConfigJson(
val reactNativeVersion: String,
val dependencies: Map<String, ModelAutolinkingDependenciesJson>?,
val project: ModelAutolinkingProjectJson?,
)

View File

@@ -0,0 +1,18 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.model
data class ModelAutolinkingDependenciesJson(
val root: String,
val name: String,
val platforms: ModelAutolinkingDependenciesPlatformJson?,
) {
val nameCleansed: String
get() = name.replace(Regex("[~*!'()]+"), "_").replace(Regex("^@([\\w-.]+)/"), "$1_")
}

View File

@@ -0,0 +1,23 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.model
data class ModelAutolinkingDependenciesPlatformAndroidJson(
val sourceDir: String,
val packageImportPath: String,
val packageInstance: String,
val buildTypes: List<String>,
val libraryName: String? = null,
val componentDescriptors: List<String> = emptyList(),
val cmakeListsPath: String? = null,
val cxxModuleCMakeListsModuleName: String? = null,
val cxxModuleCMakeListsPath: String? = null,
val cxxModuleHeaderName: String? = null,
val dependencyConfiguration: String? = null,
val isPureCxxDependency: Boolean? = null,
)

View File

@@ -0,0 +1,12 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.model
data class ModelAutolinkingDependenciesPlatformJson(
val android: ModelAutolinkingDependenciesPlatformAndroidJson?
)

View File

@@ -0,0 +1,10 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.model
data class ModelAutolinkingProjectJson(val android: ModelAutolinkingAndroidProjectJson?)

View File

@@ -0,0 +1,16 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.model
data class ModelCodegenConfig(
val name: String?,
val type: String?,
val jsSrcsDir: String?,
val android: ModelCodegenConfigAndroid?,
val includesGeneratedCode: Boolean?,
)

View File

@@ -0,0 +1,10 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.model
data class ModelCodegenConfigAndroid(val javaPackageName: String?)

View File

@@ -0,0 +1,10 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.model
data class ModelPackageJson(val version: String, val codegenConfig: ModelCodegenConfig?)

View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.utils
import com.facebook.react.model.ModelAutolinkingConfigJson
import com.facebook.react.model.ModelPackageJson
import com.google.gson.Gson
import java.io.File
object JsonUtils {
private val gsonConverter = Gson()
fun fromPackageJson(input: File): ModelPackageJson? =
input.bufferedReader().use {
runCatching { gsonConverter.fromJson(it, ModelPackageJson::class.java) }.getOrNull()
}
fun fromAutolinkingConfigJson(input: File): ModelAutolinkingConfigJson? =
input.bufferedReader().use { reader ->
runCatching {
// We sanitize the output of the `config` command as it could contain debug logs
// such as:
//
// > AwesomeProject@0.0.1 npx
// > rnc-cli config
//
// which will render the JSON invalid.
val content =
reader
.readLines()
.filterNot { line -> line.startsWith(">") }
.joinToString("\n")
.trim()
gsonConverter.fromJson(content, ModelAutolinkingConfigJson::class.java)
}
.getOrNull()
}
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.utils
import java.util.Locale
object KotlinStdlibCompatUtils {
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
fun String.lowercaseCompat(): String = (this as java.lang.String).toLowerCase(Locale.ROOT)
fun String.capitalizeCompat(): String =
if (isNotEmpty()) {
val firstChar = this[0]
val uppercaseChar = Character.toUpperCase(firstChar)
val restString = this@capitalizeCompat.substring(1)
uppercaseChar + restString
} else {
this
}
fun String.toBooleanStrictOrNullCompat(): Boolean? =
when (this) {
"true" -> true
"false" -> false
else -> null
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.utils
import com.facebook.react.utils.KotlinStdlibCompatUtils.lowercaseCompat
import java.io.File
object Os {
fun isWindows(): Boolean =
System.getProperty("os.name")?.lowercaseCompat()?.contains("windows") ?: false
fun isMac(): Boolean = System.getProperty("os.name")?.lowercaseCompat()?.contains("mac") ?: false
fun isLinuxAmd64(): Boolean {
val osNameMatch = System.getProperty("os.name")?.lowercaseCompat()?.contains("linux") ?: false
val archMatch = System.getProperty("os.arch")?.lowercaseCompat()?.contains("amd64") ?: false
return osNameMatch && archMatch
}
fun String.unixifyPath() =
this.replace('\\', '/').replace(":", "").let {
if (!it.startsWith("/")) {
"/$it"
} else {
it
}
}
/**
* As Gradle doesn't support well path with spaces on Windows, we need to return relative path on
* Win. On Linux & Mac we'll default to return absolute path.
*/
fun File.cliPath(base: File): String =
if (isWindows()) {
this.relativeTo(base).path
} else {
absolutePath
}
}

View File

@@ -0,0 +1,27 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.utils
fun windowsAwareCommandLine(vararg args: Any): List<Any> = windowsAwareCommandLine(args.toList())
fun windowsAwareCommandLine(args: List<Any>): List<Any> =
if (Os.isWindows()) {
listOf("cmd", "/c") + args
} else {
args
}
fun windowsAwareBashCommandLine(
vararg args: String,
bashWindowsHome: String? = null,
): List<String> =
if (Os.isWindows()) {
listOf(bashWindowsHome ?: "bash", "-c") + args
} else {
args.toList()
}

View File

@@ -0,0 +1,382 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.utils
import org.assertj.core.api.Assertions.assertThat
import org.intellij.lang.annotations.Language
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
class JsonUtilsTest {
@get:Rule val tempFolder = TemporaryFolder()
@Test
fun fromPackageJson_withInvalidJson_returnsNull() {
val invalidJson = createJsonFile("""¯\_(ツ)_/¯""")
assertThat(JsonUtils.fromPackageJson(invalidJson)).isNull()
}
@Test
fun fromPackageJson_withEmptyJson_returnsEmptyObject() {
val invalidJson = createJsonFile("""{}""")
val parsed = JsonUtils.fromPackageJson(invalidJson)
assertThat(parsed).isNotNull()
assertThat(parsed?.codegenConfig).isNull()
}
@Test
fun fromPackageJson_withOldJsonConfig_returnsAnEmptyLibrary() {
val oldJsonConfig =
createJsonFile(
"""
{
"name": "yet another npm package",
"codegenConfig": {
"libraries": [
{
"name": "an awesome library",
"jsSrcsDir": "../js/",
"android": {}
}
]
}
}
"""
.trimIndent()
)
val parsed = JsonUtils.fromPackageJson(oldJsonConfig)!!
assertThat(parsed.codegenConfig?.name).isNull()
assertThat(parsed.codegenConfig?.jsSrcsDir).isNull()
assertThat(parsed.codegenConfig?.android).isNull()
}
@Test
fun fromPackageJson_withValidJson_parsesCorrectly() {
val validJson =
createJsonFile(
"""
{
"name": "yet another npm package",
"codegenConfig": {
"name": "an awesome library",
"jsSrcsDir": "../js/",
"android": {
"javaPackageName": "com.awesome.library"
},
"ios": {
"other ios only keys": "which are ignored during parsing"
}
}
}
"""
.trimIndent()
)
val parsed = JsonUtils.fromPackageJson(validJson)!!
assertThat("an awesome library").isEqualTo(parsed.codegenConfig!!.name)
assertThat("../js/").isEqualTo(parsed.codegenConfig!!.jsSrcsDir)
assertThat("com.awesome.library").isEqualTo(parsed.codegenConfig!!.android!!.javaPackageName)
}
@Test
fun fromReactNativePackageJson_withInvalidJson_returnsNull() {
val invalidJson = createJsonFile("""¯\_(ツ)_/¯""")
assertThat(JsonUtils.fromPackageJson(invalidJson)).isNull()
}
@Test
fun fromReactNativePackageJson_withEmptyJson_returnsEmptyObject() {
val invalidJson = createJsonFile("""{}""")
val parsed = JsonUtils.fromPackageJson(invalidJson)
assertThat(parsed).isNotNull()
assertThat(parsed?.version).isNull()
}
@Test
fun fromReactNativePackageJson_withValidJson_parsesJsonCorrectly() {
val validJson =
createJsonFile(
"""
{
"version": "1000.0.0"
}
"""
.trimIndent()
)
val parsed = JsonUtils.fromPackageJson(validJson)!!
assertThat("1000.0.0").isEqualTo(parsed.version)
}
@Test
fun fromAutolinkingConfigJson_withInvalidJson_returnsNull() {
val invalidJson = createJsonFile("""¯\_(ツ)_/¯""")
assertThat(JsonUtils.fromAutolinkingConfigJson(invalidJson)).isNull()
}
@Test
fun fromAutolinkingConfigJson_withSimpleJson_returnsIt() {
val validJson =
createJsonFile(
"""
{
"reactNativeVersion": "1000.0.0"
}
"""
.trimIndent()
)
val parsed = JsonUtils.fromAutolinkingConfigJson(validJson)!!
assertThat("1000.0.0").isEqualTo(parsed.reactNativeVersion)
}
@Test
fun fromAutolinkingConfigJson_withProjectSpecified_canParseIt() {
val validJson =
createJsonFile(
"""
{
"reactNativeVersion": "1000.0.0",
"project": {
"ios": {
"sourceDir": "./packages/rn-tester",
"xcodeProject": {
"name": "RNTesterPods.xcworkspace",
"isWorkspace": true
},
"automaticPodsInstallation": false
},
"android": {
"sourceDir": "./packages/rn-tester",
"appName": "RN-Tester",
"packageName": "com.facebook.react.uiapp",
"applicationId": "com.facebook.react.uiapp",
"mainActivity": ".RNTesterActivity",
"watchModeCommandParams": [
"--mode HermesDebug"
],
"dependencyConfiguration": "implementation"
}
}
}
"""
.trimIndent()
)
val parsed = JsonUtils.fromAutolinkingConfigJson(validJson)!!
assertThat("./packages/rn-tester").isEqualTo(parsed.project!!.android!!.sourceDir)
assertThat("RN-Tester").isEqualTo(parsed.project!!.android!!.appName)
assertThat("com.facebook.react.uiapp").isEqualTo(parsed.project!!.android!!.packageName)
assertThat("com.facebook.react.uiapp").isEqualTo(parsed.project!!.android!!.applicationId)
assertThat(".RNTesterActivity").isEqualTo(parsed.project!!.android!!.mainActivity)
assertThat("--mode HermesDebug")
.isEqualTo(parsed.project!!.android!!.watchModeCommandParams!![0])
assertThat("implementation").isEqualTo(parsed.project!!.android!!.dependencyConfiguration)
}
@Test
fun fromAutolinkingConfigJson_withInfoLogs_sanitizeAndParseIt() {
@Suppress("JsonStandardCompliance")
val validJson =
createJsonFile(
"""
> AwesomeProject@0.0.1 npx
> rnc-cli config
{
"reactNativeVersion": "1000.0.0",
"project": {
"ios": {
"sourceDir": "./packages/rn-tester",
"xcodeProject": {
"name": "RNTesterPods.xcworkspace",
"isWorkspace": true
},
"automaticPodsInstallation": false
},
"android": {
"sourceDir": "./packages/rn-tester",
"appName": "RN-Tester",
"packageName": "com.facebook.react.uiapp",
"applicationId": "com.facebook.react.uiapp",
"mainActivity": ".RNTesterActivity",
"watchModeCommandParams": [
"--mode HermesDebug"
],
"dependencyConfiguration": "implementation"
}
}
}
"""
.trimIndent()
)
val parsed = JsonUtils.fromAutolinkingConfigJson(validJson)!!
assertThat("./packages/rn-tester").isEqualTo(parsed.project!!.android!!.sourceDir)
assertThat("RN-Tester").isEqualTo(parsed.project!!.android!!.appName)
assertThat("com.facebook.react.uiapp").isEqualTo(parsed.project!!.android!!.packageName)
assertThat("com.facebook.react.uiapp").isEqualTo(parsed.project!!.android!!.applicationId)
assertThat(".RNTesterActivity").isEqualTo(parsed.project!!.android!!.mainActivity)
assertThat("--mode HermesDebug")
.isEqualTo(parsed.project!!.android!!.watchModeCommandParams!![0])
assertThat("implementation").isEqualTo(parsed.project!!.android!!.dependencyConfiguration)
}
@Test
fun fromAutolinkingConfigJson_withDependenciesSpecified_canParseIt() {
val validJson =
createJsonFile(
"""
{
"reactNativeVersion": "1000.0.0",
"dependencies": {
"@react-native/oss-library-example": {
"root": "./node_modules/@react-native/oss-library-example",
"name": "@react-native/oss-library-example",
"platforms": {
"ios": {
"podspecPath": "./node_modules/@react-native/oss-library-example/OSSLibraryExample.podspec",
"version": "0.0.1",
"configurations": [],
"scriptPhases": []
},
"android": {
"sourceDir": "./node_modules/@react-native/oss-library-example/android",
"packageImportPath": "import com.facebook.react.osslibraryexample.OSSLibraryExamplePackage;",
"packageInstance": "new OSSLibraryExamplePackage()",
"buildTypes": ["staging", "debug", "release"],
"libraryName": "OSSLibraryExampleSpec",
"componentDescriptors": [
"SampleNativeComponentComponentDescriptor"
],
"cmakeListsPath": "./node_modules/@react-native/oss-library-example/android/build/generated/source/codegen/jni/CMakeLists.txt",
"cxxModuleCMakeListsModuleName": null,
"cxxModuleCMakeListsPath": null,
"cxxModuleHeaderName": null,
"dependencyConfiguration": "implementation",
"isPureCxxDependency": false
}
}
}
}
}
"""
.trimIndent()
)
val parsed = JsonUtils.fromAutolinkingConfigJson(validJson)!!
assertThat("./node_modules/@react-native/oss-library-example")
.isEqualTo(parsed.dependencies!!["@react-native/oss-library-example"]!!.root)
assertThat("@react-native/oss-library-example")
.isEqualTo(parsed.dependencies!!["@react-native/oss-library-example"]!!.name)
assertThat("react-native_oss-library-example")
.isEqualTo(parsed.dependencies!!["@react-native/oss-library-example"]!!.nameCleansed)
assertThat("./node_modules/@react-native/oss-library-example/android")
.isEqualTo(
parsed.dependencies!!["@react-native/oss-library-example"]!!
.platforms!!
.android!!
.sourceDir
)
assertThat("import com.facebook.react.osslibraryexample.OSSLibraryExamplePackage;")
.isEqualTo(
parsed.dependencies!!["@react-native/oss-library-example"]!!
.platforms!!
.android!!
.packageImportPath
)
assertThat("new OSSLibraryExamplePackage()")
.isEqualTo(
parsed.dependencies!!["@react-native/oss-library-example"]!!
.platforms!!
.android!!
.packageInstance
)
assertThat(listOf("staging", "debug", "release"))
.isEqualTo(
parsed.dependencies!!["@react-native/oss-library-example"]!!
.platforms!!
.android!!
.buildTypes
)
assertThat("OSSLibraryExampleSpec")
.isEqualTo(
parsed.dependencies!!["@react-native/oss-library-example"]!!
.platforms!!
.android!!
.libraryName
)
assertThat(listOf("SampleNativeComponentComponentDescriptor"))
.isEqualTo(
parsed.dependencies!!["@react-native/oss-library-example"]!!
.platforms!!
.android!!
.componentDescriptors
)
assertThat(
"./node_modules/@react-native/oss-library-example/android/build/generated/source/codegen/jni/CMakeLists.txt"
)
.isEqualTo(
parsed.dependencies!!["@react-native/oss-library-example"]!!
.platforms!!
.android!!
.cmakeListsPath
)
assertThat(
parsed.dependencies!!["@react-native/oss-library-example"]!!
.platforms!!
.android!!
.cxxModuleHeaderName
)
.isNull()
assertThat(
parsed.dependencies!!["@react-native/oss-library-example"]!!
.platforms!!
.android!!
.cxxModuleCMakeListsPath
)
.isNull()
assertThat(
parsed.dependencies!!["@react-native/oss-library-example"]!!
.platforms!!
.android!!
.cxxModuleCMakeListsModuleName
)
.isNull()
assertThat("implementation")
.isEqualTo(
parsed.dependencies!!["@react-native/oss-library-example"]!!
.platforms!!
.android!!
.dependencyConfiguration
)
assertThat(
parsed.dependencies!!["@react-native/oss-library-example"]!!
.platforms!!
.android!!
.isPureCxxDependency!!
)
.isFalse()
}
private fun createJsonFile(@Language("JSON") input: String) =
tempFolder.newFile().apply { writeText(input) }
}

View File

@@ -0,0 +1,82 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.utils
import com.facebook.react.utils.KotlinStdlibCompatUtils.capitalizeCompat
import com.facebook.react.utils.KotlinStdlibCompatUtils.lowercaseCompat
import com.facebook.react.utils.KotlinStdlibCompatUtils.toBooleanStrictOrNullCompat
import org.assertj.core.api.Assertions.assertThat
import org.junit.Test
class KotlinStdlibCompatUtilsTest {
@Test
fun lowercaseCompat_withEmptyString() {
assertThat("".lowercaseCompat()).isEqualTo("")
}
@Test
fun lowercaseCompat_withLowercaseString() {
assertThat("frodo".lowercaseCompat()).isEqualTo("frodo")
}
@Test
fun lowercaseCompat_withTitlecaseString() {
assertThat("Frodo".lowercaseCompat()).isEqualTo("frodo")
}
@Test
fun lowercaseCompat_withUppercaseString() {
assertThat("FRODO".lowercaseCompat()).isEqualTo("frodo")
}
@Test
fun capitalizeCompat_withEmptyString() {
assertThat("".capitalizeCompat()).isEqualTo("")
}
@Test
fun capitalizeCompat_withLowercaseString() {
assertThat("bilbo".capitalizeCompat()).isEqualTo("Bilbo")
}
@Test
fun capitalizeCompat_withTitlecaseString() {
assertThat("Bilbo".capitalizeCompat()).isEqualTo("Bilbo")
}
@Test
fun capitalizeCompat_withUppercaseString() {
assertThat("BILBO".capitalizeCompat()).isEqualTo("BILBO")
}
@Test
fun toBooleanStrictOrNullCompat_withEmptyString() {
assertThat("".toBooleanStrictOrNullCompat()).isNull()
}
@Test
fun toBooleanStrictOrNullCompat_withfalse() {
assertThat("false".toBooleanStrictOrNullCompat()).isFalse()
}
@Test
fun toBooleanStrictOrNullCompat_withCapitalTrue_returnsNull() {
assertThat("True".toBooleanStrictOrNullCompat()).isNull()
}
@Test
fun toBooleanStrictOrNullCompat_withCapitalFalse_returnsNull() {
assertThat("False".toBooleanStrictOrNullCompat()).isNull()
}
@Test
fun toBooleanStrictOrNullCompat_withRandomInput_returnsNull() {
assertThat("maybe".toBooleanStrictOrNullCompat()).isNull()
}
}

View File

@@ -0,0 +1,87 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.utils
import com.facebook.react.tests.OS
import com.facebook.react.tests.OsRule
import com.facebook.react.tests.WithOs
import com.facebook.react.utils.Os.cliPath
import com.facebook.react.utils.Os.unixifyPath
import org.assertj.core.api.Assertions.assertThat
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
class OsTest {
@get:Rule val osRule = OsRule()
@get:Rule val tempFolder = TemporaryFolder()
@Test
@WithOs(OS.LINUX, "amd64")
fun onLinuxAmd64_checksOsCorrectly() {
assertThat(Os.isWindows()).isFalse()
assertThat(Os.isMac()).isFalse()
assertThat(Os.isLinuxAmd64()).isTrue()
}
@Test
@WithOs(OS.MAC)
fun onMac_checksOsCorrectly() {
assertThat(Os.isWindows()).isFalse()
assertThat(Os.isMac()).isTrue()
assertThat(Os.isLinuxAmd64()).isFalse()
}
@Test
@WithOs(OS.WIN)
fun isWindows_onWindows_returnsTrue() {
assertThat(Os.isWindows()).isTrue()
assertThat(Os.isMac()).isFalse()
assertThat(Os.isLinuxAmd64()).isFalse()
}
@Test
fun unixifyPath_withAUnixPath_doesNothing() {
val aUnixPath = "/just/a/unix/path.sh"
assertThat(aUnixPath).isEqualTo(aUnixPath.unixifyPath())
}
@Test
fun unixifyPath_withAWindowsPath_convertsItCorrectly() {
val aWindowsPath = "D:\\just\\a\\windows\\path\\"
assertThat("/D/just/a/windows/path/").isEqualTo(aWindowsPath.unixifyPath())
}
@Test
@WithOs(OS.WIN)
fun cliPath_onWindows_returnsRelativePath() {
val tempFile = tempFolder.newFile("test.txt").apply { createNewFile() }
assertThat(tempFile.relativeTo(tempFolder.root).path)
.isEqualTo(tempFile.cliPath(tempFolder.root))
}
@Test
@WithOs(OS.LINUX)
fun cliPath_onLinux_returnsAbsolutePath() {
val tempFile = tempFolder.newFile("test.txt").apply { createNewFile() }
assertThat(tempFile.absolutePath).isEqualTo(tempFile.cliPath(tempFolder.root))
}
@Test
@WithOs(OS.MAC)
fun cliPath_onMac_returnsAbsolutePath() {
val tempFile = tempFolder.newFile("test.txt").apply { createNewFile() }
assertThat(tempFile.absolutePath).isEqualTo(tempFile.cliPath(tempFolder.root))
}
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.utils
import com.facebook.react.tests.OS
import com.facebook.react.tests.OsRule
import com.facebook.react.tests.WithOs
import org.assertj.core.api.Assertions.assertThat
import org.junit.Rule
import org.junit.Test
class TaskUtilsTest {
@get:Rule val osRule = OsRule()
@Test
fun windowsAwareCommandLine_withEmptyInput_isEmpty() {
assertThat(windowsAwareCommandLine().isEmpty()).isTrue()
}
@Test
fun windowsAwareCommandLine_withList_isEqualAsVararg() {
assertThat(windowsAwareCommandLine(listOf("a", "b", "c")))
.isEqualTo(windowsAwareCommandLine("a", "b", "c"))
}
@Test
@WithOs(OS.MAC)
fun windowsAwareCommandLine_onMac_returnsTheList() {
assertThat(listOf("a", "b", "c")).isEqualTo(windowsAwareCommandLine("a", "b", "c"))
}
@Test
@WithOs(OS.LINUX)
fun windowsAwareCommandLine_onLinux_returnsTheList() {
assertThat(listOf("a", "b", "c")).isEqualTo(windowsAwareCommandLine("a", "b", "c"))
}
@Test
@WithOs(OS.WIN)
fun windowsAwareCommandLine_onWindows_prependsCmd() {
assertThat(listOf("cmd", "/c", "a", "b", "c")).isEqualTo(windowsAwareCommandLine("a", "b", "c"))
}
@Test
@WithOs(OS.MAC)
fun windowsAwareBashCommandLine_onMac_returnsTheList() {
assertThat(listOf("a", "b", "c"))
.isEqualTo(windowsAwareBashCommandLine("a", "b", "c", bashWindowsHome = "abc"))
}
@Test
@WithOs(OS.LINUX)
fun windowsAwareBashCommandLine_onLinux_returnsTheList() {
assertThat(listOf("a", "b", "c")).isEqualTo(windowsAwareBashCommandLine("a", "b", "c"))
}
@Test
@WithOs(OS.WIN)
fun windowsAwareBashCommandLine_onWindows_prependsBash() {
assertThat(listOf("bash", "-c", "a", "b", "c"))
.isEqualTo(windowsAwareBashCommandLine("a", "b", "c"))
}
@Test
@WithOs(OS.WIN)
fun windowsAwareBashCommandLine_onWindows_prependsCustomBashPath() {
assertThat(listOf("/custom/bash", "-c", "a", "b", "c"))
.isEqualTo(windowsAwareBashCommandLine("a", "b", "c", bashWindowsHome = "/custom/bash"))
}
}