dima.avdeev
9 months ago
86 changed files with 1680 additions and 894 deletions
@ -1,7 +1,16 @@
|
||||
[versions] |
||||
kotlinx-coroutines = "1.8.0-RC" |
||||
kotlinx-coroutines = "1.7.3" |
||||
androidx-appcompat = "1.6.1" |
||||
androidx-activity-compose = "1.8.2" |
||||
androidx-test = "1.5.0" |
||||
androidx-compose = "1.6.0" |
||||
|
||||
[libraries] |
||||
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" } |
||||
kotlinx-coroutines-swing = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-swing", version.ref = "kotlinx-coroutines" } |
||||
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinx-coroutines" } |
||||
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinx-coroutines" } |
||||
androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" } |
||||
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity-compose" } |
||||
androidx-test-core = { module = "androidx.test:core", version.ref = "androidx-test" } |
||||
androidx-compose-ui-test = { module = "androidx.compose.ui:ui-test", version.ref = "androidx-compose" } |
||||
androidx-compose-ui-test-manifest = { module = "androidx.compose.ui:ui-test-manifest", version.ref = "androidx-compose" } |
||||
androidx-compose-ui-test-junit4 = { module = "androidx.compose.ui:ui-test-junit4", version.ref = "androidx-compose" } |
@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME |
||||
distributionPath=wrapper/dists |
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip |
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip |
||||
zipStoreBase=GRADLE_USER_HOME |
||||
zipStorePath=wrapper/dists |
||||
|
@ -0,0 +1 @@
|
||||
Android platform |
Binary file not shown.
@ -1,13 +1,12 @@
|
||||
<resources> |
||||
<string name="app_name">Compose Resources App</string> |
||||
<string name="hello">😊 Hello world!</string> |
||||
<string name="multi_line">Lorem ipsum dolor sit amet, |
||||
consectetur adipiscing elit. |
||||
Donec eget turpis ac sem ultricies consequat.</string> |
||||
<string name="str_template">Hello, %1$s! You have %2$d new messages.</string> |
||||
<string name="multi_line">Lorem ipsum dolor sit amet,\nconsectetur adipiscing elit. |
||||
Donec eget turpis ac sem ultricies consequat.</string> |
||||
<string name="str_template">Hello, %1$s!\nYou have %2$d new messages.</string> |
||||
<string-array name="str_arr"> |
||||
<item>item 1</item> |
||||
<item>item 2</item> |
||||
<item>item 3</item> |
||||
<item>item \u2605</item> |
||||
<item>item \u2318</item> |
||||
<item>item \u00BD</item> |
||||
</string-array> |
||||
</resources> |
||||
|
@ -0,0 +1 @@
|
||||
Desktop platform |
@ -0,0 +1 @@
|
||||
iOS platform |
@ -0,0 +1 @@
|
||||
JS platform |
@ -0,0 +1 @@
|
||||
macOS platform |
@ -0,0 +1 @@
|
||||
WasmJS platform |
@ -1,169 +0,0 @@
|
||||
package org.jetbrains.compose.resources |
||||
|
||||
import androidx.compose.foundation.Image |
||||
import androidx.compose.material3.Text |
||||
import androidx.compose.runtime.* |
||||
import androidx.compose.ui.test.ExperimentalTestApi |
||||
import androidx.compose.ui.test.runComposeUiTest |
||||
import kotlinx.coroutines.flow.MutableStateFlow |
||||
import org.junit.Assert.assertEquals |
||||
import org.junit.Before |
||||
import org.junit.Test |
||||
import kotlin.test.assertEquals |
||||
import kotlin.test.assertFailsWith |
||||
|
||||
@OptIn(ExperimentalTestApi::class, ExperimentalResourceApi::class, InternalResourceApi::class) |
||||
class ComposeResourceTest { |
||||
|
||||
@Before |
||||
fun dropCaches() { |
||||
dropStringsCache() |
||||
dropImageCache() |
||||
} |
||||
|
||||
@Before |
||||
fun configureTestEnvironment() { |
||||
getResourceEnvironment = ::getTestEnvironment |
||||
} |
||||
|
||||
@Test |
||||
fun testCountRecompositions() = runComposeUiTest { |
||||
runBlockingTest { |
||||
val imagePathFlow = MutableStateFlow(DrawableResource("1.png")) |
||||
val recompositionsCounter = RecompositionsCounter() |
||||
setContent { |
||||
CompositionLocalProvider(LocalComposeEnvironment provides TestComposeEnvironment) { |
||||
val res by imagePathFlow.collectAsState() |
||||
val imgRes = imageResource(res) |
||||
recompositionsCounter.content { |
||||
Image(bitmap = imgRes, contentDescription = null) |
||||
} |
||||
} |
||||
} |
||||
awaitIdle() |
||||
imagePathFlow.emit(DrawableResource("2.png")) |
||||
awaitIdle() |
||||
assertEquals(2, recompositionsCounter.count) |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
fun testImageResourceCache() = runComposeUiTest { |
||||
runBlockingTest { |
||||
val testResourceReader = TestResourceReader() |
||||
val imagePathFlow = MutableStateFlow(DrawableResource("1.png")) |
||||
setContent { |
||||
CompositionLocalProvider( |
||||
LocalResourceReader provides testResourceReader, |
||||
LocalComposeEnvironment provides TestComposeEnvironment |
||||
) { |
||||
val res by imagePathFlow.collectAsState() |
||||
Image(painterResource(res), null) |
||||
} |
||||
} |
||||
awaitIdle() |
||||
imagePathFlow.emit(DrawableResource("2.png")) |
||||
awaitIdle() |
||||
imagePathFlow.emit(DrawableResource("1.png")) |
||||
awaitIdle() |
||||
|
||||
assertEquals( |
||||
expected = listOf("1.png", "2.png"), //no second read of 1.png |
||||
actual = testResourceReader.readPaths |
||||
) |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
fun testStringResourceCache() = runComposeUiTest { |
||||
runBlockingTest { |
||||
val testResourceReader = TestResourceReader() |
||||
val stringIdFlow = MutableStateFlow(TestStringResource("app_name")) |
||||
setContent { |
||||
CompositionLocalProvider( |
||||
LocalResourceReader provides testResourceReader, |
||||
LocalComposeEnvironment provides TestComposeEnvironment |
||||
) { |
||||
val res by stringIdFlow.collectAsState() |
||||
Text(stringResource(res)) |
||||
Text(stringArrayResource(TestStringResource("str_arr")).joinToString()) |
||||
} |
||||
} |
||||
awaitIdle() |
||||
stringIdFlow.emit(TestStringResource("hello")) |
||||
awaitIdle() |
||||
stringIdFlow.emit(TestStringResource("app_name")) |
||||
awaitIdle() |
||||
|
||||
assertEquals( |
||||
expected = listOf("strings.xml"), //just one string.xml read |
||||
actual = testResourceReader.readPaths |
||||
) |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
fun testReadStringResource() = runComposeUiTest { |
||||
runBlockingTest { |
||||
setContent { |
||||
CompositionLocalProvider(LocalComposeEnvironment provides TestComposeEnvironment) { |
||||
assertEquals( |
||||
"Compose Resources App", |
||||
stringResource(TestStringResource("app_name")) |
||||
) |
||||
assertEquals( |
||||
"Hello, test-name! You have 42 new messages.", |
||||
stringResource(TestStringResource("str_template"), "test-name", 42) |
||||
) |
||||
assertEquals( |
||||
listOf("item 1", "item 2", "item 3"), |
||||
stringArrayResource(TestStringResource("str_arr")) |
||||
) |
||||
} |
||||
} |
||||
awaitIdle() |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
fun testLoadStringResource() = runBlockingTest { |
||||
kotlin.test.assertEquals("Compose Resources App", getString(TestStringResource("app_name"))) |
||||
kotlin.test.assertEquals( |
||||
"Hello, test-name! You have 42 new messages.", |
||||
getString(TestStringResource("str_template"), "test-name", 42) |
||||
) |
||||
kotlin.test.assertEquals(listOf("item 1", "item 2", "item 3"), getStringArray(TestStringResource("str_arr"))) |
||||
} |
||||
|
||||
@Test |
||||
fun testMissingResource() = runBlockingTest { |
||||
assertFailsWith<MissingResourceException> { |
||||
readResourceBytes("missing.png") |
||||
} |
||||
val error = assertFailsWith<IllegalStateException> { |
||||
getString(TestStringResource("unknown_id")) |
||||
} |
||||
kotlin.test.assertEquals("String ID=`unknown_id` is not found!", error.message) |
||||
} |
||||
|
||||
@Test |
||||
fun testReadFileResource() = runBlockingTest { |
||||
val bytes = readResourceBytes("strings.xml") |
||||
kotlin.test.assertEquals( |
||||
""" |
||||
<resources> |
||||
<string name="app_name">Compose Resources App</string> |
||||
<string name="hello">😊 Hello world!</string> |
||||
<string name="str_template">Hello, %1${'$'}s! You have %2${'$'}d new messages.</string> |
||||
<string-array name="str_arr"> |
||||
<item>item 1</item> |
||||
<item>item 2</item> |
||||
<item>item 3</item> |
||||
</string-array> |
||||
</resources> |
||||
|
||||
""".trimIndent(), |
||||
bytes.decodeToString() |
||||
) |
||||
} |
||||
} |
@ -0,0 +1,18 @@
|
||||
package org.jetbrains.compose.resources |
||||
|
||||
import java.io.File |
||||
|
||||
private object AndroidResourceReader |
||||
|
||||
@OptIn(ExperimentalResourceApi::class) |
||||
@InternalResourceApi |
||||
actual suspend fun readResourceBytes(path: String): ByteArray { |
||||
val classLoader = Thread.currentThread().contextClassLoader ?: AndroidResourceReader.javaClass.classLoader |
||||
val resource = classLoader.getResourceAsStream(path) ?: run { |
||||
//try to find a font in the android assets |
||||
if (File(path).parentFile?.name.orEmpty() == "font") { |
||||
classLoader.getResourceAsStream("assets/$path") |
||||
} else null |
||||
} ?: throw MissingResourceException(path) |
||||
return resource.readBytes() |
||||
} |
@ -1,12 +0,0 @@
|
||||
package org.jetbrains.compose.resources |
||||
|
||||
import kotlinx.coroutines.CoroutineScope |
||||
import kotlinx.coroutines.runBlocking |
||||
|
||||
|
||||
actual typealias TestReturnType = Unit |
||||
|
||||
actual fun runBlockingTest(block: suspend CoroutineScope.() -> Unit): TestReturnType { |
||||
return runBlocking { block() } |
||||
} |
||||
|
@ -0,0 +1,156 @@
|
||||
package org.jetbrains.compose.resources |
||||
|
||||
import androidx.compose.foundation.Image |
||||
import androidx.compose.material3.Text |
||||
import androidx.compose.runtime.* |
||||
import androidx.compose.ui.test.ExperimentalTestApi |
||||
import androidx.compose.ui.test.runComposeUiTest |
||||
import kotlinx.coroutines.test.runTest |
||||
import kotlin.test.* |
||||
|
||||
@OptIn(ExperimentalTestApi::class, ExperimentalResourceApi::class, InternalResourceApi::class) |
||||
class ComposeResourceTest { |
||||
|
||||
init { |
||||
dropStringsCache() |
||||
dropImageCache() |
||||
getResourceEnvironment = ::getTestEnvironment |
||||
} |
||||
|
||||
@Test |
||||
fun testCountRecompositions() = runComposeUiTest { |
||||
var res by mutableStateOf(DrawableResource("1.png")) |
||||
val recompositionsCounter = RecompositionsCounter() |
||||
setContent { |
||||
CompositionLocalProvider(LocalComposeEnvironment provides TestComposeEnvironment) { |
||||
val imgRes = imageResource(res) |
||||
recompositionsCounter.content { |
||||
Image(bitmap = imgRes, contentDescription = null) |
||||
} |
||||
} |
||||
} |
||||
waitForIdle() |
||||
res = DrawableResource("2.png") |
||||
waitForIdle() |
||||
assertEquals(2, recompositionsCounter.count) |
||||
} |
||||
|
||||
@Test |
||||
fun testImageResourceCache() = runComposeUiTest { |
||||
val testResourceReader = TestResourceReader() |
||||
var res by mutableStateOf(DrawableResource("1.png")) |
||||
setContent { |
||||
CompositionLocalProvider( |
||||
LocalResourceReader provides testResourceReader, |
||||
LocalComposeEnvironment provides TestComposeEnvironment |
||||
) { |
||||
Image(painterResource(res), null) |
||||
} |
||||
} |
||||
waitForIdle() |
||||
res = DrawableResource("2.png") |
||||
waitForIdle() |
||||
res = DrawableResource("1.png") |
||||
waitForIdle() |
||||
|
||||
assertEquals( |
||||
expected = listOf("1.png", "2.png"), //no second read of 1.png |
||||
actual = testResourceReader.readPaths |
||||
) |
||||
} |
||||
|
||||
@Test |
||||
fun testStringResourceCache() = runComposeUiTest { |
||||
val testResourceReader = TestResourceReader() |
||||
var res by mutableStateOf(TestStringResource("app_name")) |
||||
var str = "" |
||||
setContent { |
||||
CompositionLocalProvider( |
||||
LocalResourceReader provides testResourceReader, |
||||
LocalComposeEnvironment provides TestComposeEnvironment |
||||
) { |
||||
str = stringResource(res) |
||||
Text(str) |
||||
Text(stringArrayResource(TestStringResource("str_arr")).joinToString()) |
||||
} |
||||
} |
||||
waitForIdle() |
||||
assertEquals(str, "Compose Resources App") |
||||
res = TestStringResource("hello") |
||||
waitForIdle() |
||||
assertEquals(str, "\uD83D\uDE0A Hello world!") |
||||
res = TestStringResource("app_name") |
||||
waitForIdle() |
||||
assertEquals(str, "Compose Resources App") |
||||
|
||||
assertEquals( |
||||
expected = listOf("strings.xml"), //just one string.xml read |
||||
actual = testResourceReader.readPaths |
||||
) |
||||
} |
||||
|
||||
@Test |
||||
fun testReadStringResource() = runComposeUiTest { |
||||
var app_name = "" |
||||
var accentuated_characters = "" |
||||
var str_template = "" |
||||
var str_arr = emptyList<String>() |
||||
setContent { |
||||
CompositionLocalProvider(LocalComposeEnvironment provides TestComposeEnvironment) { |
||||
app_name = stringResource(TestStringResource("app_name")) |
||||
accentuated_characters = stringResource(TestStringResource("accentuated_characters")) |
||||
str_template = stringResource(TestStringResource("str_template"), "test-name", 42) |
||||
str_arr = stringArrayResource(TestStringResource("str_arr")) |
||||
} |
||||
} |
||||
waitForIdle() |
||||
|
||||
assertEquals("Compose Resources App", app_name) |
||||
assertEquals("Créer une table", accentuated_characters) |
||||
assertEquals("Hello, test-name! You have 42 new messages.", str_template) |
||||
assertEquals(listOf("item 1", "item 2", "item 3"), str_arr) |
||||
} |
||||
|
||||
@Test |
||||
fun testLoadStringResource() = runTest { |
||||
assertEquals("Compose Resources App", getString(TestStringResource("app_name"))) |
||||
assertEquals( |
||||
"Hello, test-name! You have 42 new messages.", |
||||
getString(TestStringResource("str_template"), "test-name", 42) |
||||
) |
||||
assertEquals(listOf("item 1", "item 2", "item 3"), getStringArray(TestStringResource("str_arr"))) |
||||
} |
||||
|
||||
@Test |
||||
fun testMissingResource() = runTest { |
||||
assertFailsWith<MissingResourceException> { |
||||
readResourceBytes("missing.png") |
||||
} |
||||
val error = assertFailsWith<IllegalStateException> { |
||||
getString(TestStringResource("unknown_id")) |
||||
} |
||||
assertEquals("String ID=`unknown_id` is not found!", error.message) |
||||
} |
||||
|
||||
@Test |
||||
fun testReadFileResource() = runTest { |
||||
val bytes = readResourceBytes("strings.xml") |
||||
assertEquals( |
||||
""" |
||||
<resources> |
||||
<string name="app_name">Compose Resources App</string> |
||||
<string name="hello">😊 Hello world!</string> |
||||
<string name="accentuated_characters">Créer une table</string> |
||||
<string name="str_template">Hello, %1${'$'}s! You have %2${'$'}d new messages.</string> |
||||
<string-array name="str_arr"> |
||||
<item>item 1</item> |
||||
<item>item 2</item> |
||||
<item>item 3</item> |
||||
</string-array> |
||||
</resources> |
||||
|
||||
""".trimIndent(), |
||||
bytes.decodeToString() |
||||
) |
||||
} |
||||
} |
@ -1,169 +0,0 @@
|
||||
package org.jetbrains.compose.resources |
||||
|
||||
import androidx.compose.foundation.Image |
||||
import androidx.compose.material3.Text |
||||
import androidx.compose.runtime.* |
||||
import androidx.compose.ui.test.ExperimentalTestApi |
||||
import androidx.compose.ui.test.runComposeUiTest |
||||
import kotlinx.coroutines.flow.MutableStateFlow |
||||
import org.junit.Assert.assertEquals |
||||
import org.junit.Before |
||||
import org.junit.Test |
||||
import kotlin.test.assertEquals |
||||
import kotlin.test.assertFailsWith |
||||
|
||||
@OptIn(ExperimentalTestApi::class, ExperimentalResourceApi::class, InternalResourceApi::class) |
||||
class ComposeResourceTest { |
||||
|
||||
@Before |
||||
fun dropCaches() { |
||||
dropStringsCache() |
||||
dropImageCache() |
||||
} |
||||
|
||||
@Before |
||||
fun configureTestEnvironment() { |
||||
getResourceEnvironment = ::getTestEnvironment |
||||
} |
||||
|
||||
@Test |
||||
fun testCountRecompositions() = runComposeUiTest { |
||||
runBlockingTest { |
||||
val imagePathFlow = MutableStateFlow(DrawableResource("1.png")) |
||||
val recompositionsCounter = RecompositionsCounter() |
||||
setContent { |
||||
CompositionLocalProvider(LocalComposeEnvironment provides TestComposeEnvironment) { |
||||
val res by imagePathFlow.collectAsState() |
||||
val imgRes = imageResource(res) |
||||
recompositionsCounter.content { |
||||
Image(bitmap = imgRes, contentDescription = null) |
||||
} |
||||
} |
||||
} |
||||
awaitIdle() |
||||
imagePathFlow.emit(DrawableResource("2.png")) |
||||
awaitIdle() |
||||
assertEquals(2, recompositionsCounter.count) |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
fun testImageResourceCache() = runComposeUiTest { |
||||
runBlockingTest { |
||||
val testResourceReader = TestResourceReader() |
||||
val imagePathFlow = MutableStateFlow(DrawableResource("1.png")) |
||||
setContent { |
||||
CompositionLocalProvider( |
||||
LocalResourceReader provides testResourceReader, |
||||
LocalComposeEnvironment provides TestComposeEnvironment |
||||
) { |
||||
val res by imagePathFlow.collectAsState() |
||||
Image(painterResource(res), null) |
||||
} |
||||
} |
||||
awaitIdle() |
||||
imagePathFlow.emit(DrawableResource("2.png")) |
||||
awaitIdle() |
||||
imagePathFlow.emit(DrawableResource("1.png")) |
||||
awaitIdle() |
||||
|
||||
assertEquals( |
||||
expected = listOf("1.png", "2.png"), //no second read of 1.png |
||||
actual = testResourceReader.readPaths |
||||
) |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
fun testStringResourceCache() = runComposeUiTest { |
||||
runBlockingTest { |
||||
val testResourceReader = TestResourceReader() |
||||
val stringIdFlow = MutableStateFlow(TestStringResource("app_name")) |
||||
setContent { |
||||
CompositionLocalProvider( |
||||
LocalResourceReader provides testResourceReader, |
||||
LocalComposeEnvironment provides TestComposeEnvironment |
||||
) { |
||||
val res by stringIdFlow.collectAsState() |
||||
Text(stringResource(res)) |
||||
Text(stringArrayResource(TestStringResource("str_arr")).joinToString()) |
||||
} |
||||
} |
||||
awaitIdle() |
||||
stringIdFlow.emit(TestStringResource("hello")) |
||||
awaitIdle() |
||||
stringIdFlow.emit(TestStringResource("app_name")) |
||||
awaitIdle() |
||||
|
||||
assertEquals( |
||||
expected = listOf("strings.xml"), //just one string.xml read |
||||
actual = testResourceReader.readPaths |
||||
) |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
fun testReadStringResource() = runComposeUiTest { |
||||
runBlockingTest { |
||||
setContent { |
||||
CompositionLocalProvider(LocalComposeEnvironment provides TestComposeEnvironment) { |
||||
assertEquals( |
||||
"Compose Resources App", |
||||
stringResource(TestStringResource("app_name")) |
||||
) |
||||
assertEquals( |
||||
"Hello, test-name! You have 42 new messages.", |
||||
stringResource(TestStringResource("str_template"), "test-name", 42) |
||||
) |
||||
assertEquals( |
||||
listOf("item 1", "item 2", "item 3"), |
||||
stringArrayResource(TestStringResource("str_arr")) |
||||
) |
||||
} |
||||
} |
||||
awaitIdle() |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
fun testLoadStringResource() = runBlockingTest { |
||||
kotlin.test.assertEquals("Compose Resources App", getString(TestStringResource("app_name"))) |
||||
kotlin.test.assertEquals( |
||||
"Hello, test-name! You have 42 new messages.", |
||||
getString(TestStringResource("str_template"), "test-name", 42) |
||||
) |
||||
kotlin.test.assertEquals(listOf("item 1", "item 2", "item 3"), getStringArray(TestStringResource("str_arr"))) |
||||
} |
||||
|
||||
@Test |
||||
fun testMissingResource() = runBlockingTest { |
||||
assertFailsWith<MissingResourceException> { |
||||
readResourceBytes("missing.png") |
||||
} |
||||
val error = assertFailsWith<IllegalStateException> { |
||||
getString(TestStringResource("unknown_id")) |
||||
} |
||||
kotlin.test.assertEquals("String ID=`unknown_id` is not found!", error.message) |
||||
} |
||||
|
||||
@Test |
||||
fun testReadFileResource() = runBlockingTest { |
||||
val bytes = readResourceBytes("strings.xml") |
||||
kotlin.test.assertEquals( |
||||
""" |
||||
<resources> |
||||
<string name="app_name">Compose Resources App</string> |
||||
<string name="hello">😊 Hello world!</string> |
||||
<string name="str_template">Hello, %1${'$'}s! You have %2${'$'}d new messages.</string> |
||||
<string-array name="str_arr"> |
||||
<item>item 1</item> |
||||
<item>item 2</item> |
||||
<item>item 3</item> |
||||
</string-array> |
||||
</resources> |
||||
|
||||
""".trimIndent(), |
||||
bytes.decodeToString() |
||||
) |
||||
} |
||||
} |
@ -1,7 +0,0 @@
|
||||
package org.jetbrains.compose.resources |
||||
|
||||
import kotlinx.coroutines.* |
||||
|
||||
actual typealias TestReturnType = Any |
||||
actual fun runBlockingTest(block: suspend CoroutineScope.() -> Unit): TestReturnType = |
||||
TODO("Implement if necessary. We focus on k/wasm target for now") |
@ -1,17 +0,0 @@
|
||||
package org.jetbrains.compose.resources |
||||
|
||||
import kotlinx.coroutines.* |
||||
import kotlinx.coroutines.test.runTest |
||||
|
||||
@JsFun("() => ''") |
||||
private external fun jsRef(): JsAny |
||||
|
||||
|
||||
actual typealias TestReturnType = Any |
||||
/** |
||||
* Runs the [block] in a coroutine. |
||||
*/ |
||||
actual fun runBlockingTest(block: suspend CoroutineScope.() -> Unit): TestReturnType = MainScope().promise { |
||||
block() |
||||
jsRef() |
||||
} |
@ -1,5 +1,8 @@
|
||||
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 |
||||
android.useAndroidX=true |
||||
android.enableJetifier=true |
||||
kotlin.code.style=official |
||||
compose.version=1.0.0 |
||||
org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8 -Dkotlin.daemon.jvm.options\="-Xmx2048M" |
||||
org.gradle.caching=true |
||||
org.gradle.configuration-cache=true |
||||
|
||||
compose.version=1.5.11 |
||||
kotlin.version=1.9.21 |
||||
|
||||
kotlin.code.style=official |
@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<verification-metadata xmlns="https://schema.gradle.org/dependency-verification" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://schema.gradle.org/dependency-verification https://schema.gradle.org/dependency-verification/dependency-verification-1.3.xsd"> |
||||
<configuration> |
||||
<verify-metadata>true</verify-metadata> |
||||
<verify-signatures>true</verify-signatures> |
||||
<ignored-keys> |
||||
<ignored-key id="4A3DA032DA2BBE01" reason="vlcj key is not certified with a trusted signature"/> |
||||
</ignored-keys> |
||||
<trusted-keys> |
||||
<trusted-key id="1BD97A6A154E7810EE0BC832E2F38302C8075E3D" group="org.gradle.kotlin" name="gradle-kotlin-dsl-plugins" version="4.2.1"/> |
||||
<trusted-key id="20723A6399BC060154283B37CFAE163B64AC9189" group="^org[.]jetbrains($|([.].*))" regex="true"/> |
||||
<trusted-key id="2E3A1AFFE42B5F53AF19F780BCF4173966770193" group="org.jetbrains" name="annotations" version="13.0"/> |
||||
<trusted-key id="33FD4BFD33554634053D73C0C2148900BCD3C2AF" group="org.jetbrains" name="annotations" version="23.0.0"/> |
||||
<trusted-key id="6F538074CCEBF35F28AF9B066A0975F8B1127B83" group="org.jetbrains.kotlin"/> |
||||
<trusted-key id="8756C4F765C9AC3CB6B85D62379CE192D401AB61" group="org.jetbrains.intellij.deps" name="trove4j" version="1.0.20200330"/> |
||||
<trusted-key id="E7DC75FC24FB3C8DFE8086AD3D5839A2262CBBFB" group="org.jetbrains.kotlinx"/> |
||||
<trusted-key id="FA7929F83AD44C4590F6CC6815C71C0A4E0B8EDD" group="net.java.dev.jna"/> |
||||
</trusted-keys> |
||||
</configuration> |
||||
<components> |
||||
<component group="org.gradle.kotlin.kotlin-dsl" name="org.gradle.kotlin.kotlin-dsl.gradle.plugin" version="4.2.1"> |
||||
<artifact name="org.gradle.kotlin.kotlin-dsl.gradle.plugin-4.2.1.pom"> |
||||
<sha256 value="311ff9eca17b0f6c9cc8104ebb88c73d38a4985a0488b01670bc2be09e5a2320" origin="Generated by Gradle" reason="Artifact is not signed"/> |
||||
</artifact> |
||||
</component> |
||||
<component group="org.jetbrains.compose" name="compose-gradle-plugin" version="1.5.11"> |
||||
<artifact name="compose-gradle-plugin-1.5.11.jar"> |
||||
<ignored-keys> |
||||
<ignored-key id="20723A6399BC060154283B37CFAE163B64AC9189" reason="PGP verification failed"/> |
||||
</ignored-keys> |
||||
<sha256 value="d54be424f035dd452f2317b56ed54e0080135bed1936fc84f7371f59b9e9edea" origin="Generated by Gradle" reason="PGP signature verification failed!"/> |
||||
</artifact> |
||||
<artifact name="compose-gradle-plugin-1.5.11.module"> |
||||
<ignored-keys> |
||||
<ignored-key id="20723A6399BC060154283B37CFAE163B64AC9189" reason="PGP verification failed"/> |
||||
</ignored-keys> |
||||
<sha256 value="e74b7aedc30d01e7b8e3d53280b5a67e168b3cd44632e340f094560e8364c7f5" origin="Generated by Gradle" reason="PGP signature verification failed!"/> |
||||
</artifact> |
||||
</component> |
||||
<component group="org.jetbrains.compose" name="org.jetbrains.compose.gradle.plugin" version="1.5.11"> |
||||
<artifact name="org.jetbrains.compose.gradle.plugin-1.5.11.pom"> |
||||
<sha256 value="0915dc92e751288db3b6ced9b24d4c786f940e68a1d7fff4a0ce151d5f19fbc4" origin="Generated by Gradle" reason="Artifact is not signed"/> |
||||
</artifact> |
||||
</component> |
||||
<component group="org.jetbrains.kotlin.multiplatform" name="org.jetbrains.kotlin.multiplatform.gradle.plugin" version="1.9.21"> |
||||
<artifact name="org.jetbrains.kotlin.multiplatform.gradle.plugin-1.9.21.pom"> |
||||
<sha256 value="4c7095d560a1c73dcff7b4d4d3b58a3ba5e895d10075f8fde24b7d6b300d6856" origin="Generated by Gradle" reason="Artifact is not signed"/> |
||||
</artifact> |
||||
</component> |
||||
<component group="uk.co.caprica" name="vlcj" version="4.8.2"> |
||||
<artifact name="vlcj-4.8.2.jar"> |
||||
<sha256 value="304d585e780be8765baa4fa83b376c21920789f9e570aecf888912d40eedabb5" origin="Generated by Gradle" reason="A key couldn't be downloaded"/> |
||||
</artifact> |
||||
<artifact name="vlcj-4.8.2.pom"> |
||||
<sha256 value="ef72f58a845a737e948b015213db48b69f9c5137f73b507cfd978e545c5b2009" origin="Generated by Gradle" reason="A key couldn't be downloaded"/> |
||||
</artifact> |
||||
</component> |
||||
<component group="uk.co.caprica" name="vlcj-natives" version="4.8.1"> |
||||
<artifact name="vlcj-natives-4.8.1.jar"> |
||||
<sha256 value="f47cef91dfdf335611b6d11945c9d1794e85811b3884c1fd31f9ed76ab19da50" origin="Generated by Gradle" reason="A key couldn't be downloaded"/> |
||||
</artifact> |
||||
<artifact name="vlcj-natives-4.8.1.pom"> |
||||
<sha256 value="a676774073e4ee3d782e47129679877f7d7c0ae72e9dd4b04025d56672292edc" origin="Generated by Gradle" reason="A key couldn't be downloaded"/> |
||||
</artifact> |
||||
</component> |
||||
</components> |
||||
</verification-metadata> |
@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME |
||||
distributionPath=wrapper/dists |
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip |
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip |
||||
zipStoreBase=GRADLE_USER_HOME |
||||
zipStorePath=wrapper/dists |
||||
|
@ -1,2 +1,22 @@
|
||||
pluginManagement { |
||||
repositories { |
||||
google() |
||||
gradlePluginPortal() |
||||
mavenCentral() |
||||
} |
||||
|
||||
plugins { |
||||
kotlin("multiplatform").version(extra["kotlin.version"] as String) |
||||
id("org.jetbrains.compose").version(extra["compose.version"] as String) |
||||
} |
||||
} |
||||
|
||||
dependencyResolutionManagement { |
||||
repositories { |
||||
google() |
||||
mavenCentral() |
||||
} |
||||
} |
||||
|
||||
include(":VideoPlayer:library") |
||||
include(":VideoPlayer:demo") |
@ -1,42 +0,0 @@
|
||||
package org.jetbrains.compose.resources |
||||
|
||||
import com.android.build.api.variant.AndroidComponentsExtension |
||||
import com.android.build.gradle.BaseExtension |
||||
import com.android.build.gradle.tasks.MergeSourceSetFolders |
||||
import org.gradle.api.Project |
||||
import org.gradle.api.provider.Provider |
||||
import org.gradle.api.tasks.Copy |
||||
import org.gradle.api.tasks.SourceSet |
||||
import org.jetbrains.compose.internal.utils.registerTask |
||||
import java.io.File |
||||
|
||||
internal fun Project.configureAndroidResources( |
||||
commonResourcesDir: Provider<File>, |
||||
androidFontsDir: Provider<File>, |
||||
onlyIfProvider: Provider<Boolean> |
||||
) { |
||||
val androidExtension = project.extensions.findByName("android") as? BaseExtension ?: return |
||||
val androidComponents = project.extensions.findByType(AndroidComponentsExtension::class.java) ?: return |
||||
|
||||
val androidMainSourceSet = androidExtension.sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME) |
||||
androidMainSourceSet.resources.srcDir(commonResourcesDir) |
||||
androidMainSourceSet.assets.srcDir(androidFontsDir) |
||||
|
||||
val copyFonts = registerTask<Copy>("copyFontsToAndroidAssets") { |
||||
includeEmptyDirs = false |
||||
from(commonResourcesDir) |
||||
include("**/font*/*") |
||||
into(androidFontsDir) |
||||
onlyIf { onlyIfProvider.get() } |
||||
} |
||||
androidComponents.onVariants { variant -> |
||||
variant.sources?.assets?.addGeneratedSourceDirectory( |
||||
taskProvider = copyFonts, |
||||
wiredWith = { |
||||
objects.directoryProperty().fileProvider( |
||||
copyFonts.map { t -> t.destinationDir } |
||||
) |
||||
} |
||||
) |
||||
} |
||||
} |
@ -0,0 +1 @@
|
||||
android.useAndroidX=true |
@ -0,0 +1,25 @@
|
||||
plugins { |
||||
kotlin("multiplatform") |
||||
id("org.jetbrains.compose") |
||||
id("com.github.gmazzo.buildconfig") |
||||
} |
||||
|
||||
group = "app.group" |
||||
|
||||
kotlin { |
||||
jvm() |
||||
|
||||
sourceSets { |
||||
commonMain { |
||||
dependencies { |
||||
implementation(compose.runtime) |
||||
implementation(compose.material) |
||||
implementation(compose.components.resources) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
buildConfig { |
||||
buildConfigField(String::class.java, "str", "") |
||||
} |
@ -0,0 +1,9 @@
|
||||
import androidx.compose.material.Text |
||||
import androidx.compose.runtime.Composable |
||||
import app.group.empty_res.generated.resources.Res |
||||
|
||||
@Composable |
||||
fun App() { |
||||
val res = Res |
||||
Text("text") |
||||
} |
@ -0,0 +1,4 @@
|
||||
plugins { |
||||
kotlin("multiplatform").apply(false) |
||||
id("org.jetbrains.compose").apply(false) |
||||
} |
@ -0,0 +1 @@
|
||||
org.gradle.jvmargs=-Xmx8096M |
@ -0,0 +1,24 @@
|
||||
rootProject.name = "bundled_kp" |
||||
include(":app") |
||||
pluginManagement { |
||||
repositories { |
||||
mavenLocal() |
||||
gradlePluginPortal() |
||||
google() |
||||
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") |
||||
} |
||||
plugins { |
||||
id("org.jetbrains.kotlin.multiplatform").version("KOTLIN_VERSION_PLACEHOLDER") |
||||
id("org.jetbrains.compose").version("COMPOSE_GRADLE_PLUGIN_VERSION_PLACEHOLDER") |
||||
id("com.github.gmazzo.buildconfig").version("5.3.5") |
||||
} |
||||
} |
||||
dependencyResolutionManagement { |
||||
repositories { |
||||
mavenLocal() |
||||
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") |
||||
mavenCentral() |
||||
gradlePluginPortal() |
||||
google() |
||||
} |
||||
} |
@ -1,2 +1,3 @@
|
||||
org.gradle.jvmargs=-Xmx8096M |
||||
android.useAndroidX=true |
||||
android.useAndroidX=true |
||||
org.jetbrains.compose.experimental.jscanvas.enabled=true |
Binary file not shown.
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<manifest> |
||||
<application/> |
||||
</manifest> |
@ -0,0 +1,36 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:width="600dp" |
||||
android:height="600dp" |
||||
android:viewportWidth="600" |
||||
android:viewportHeight="600"> |
||||
<path |
||||
android:pathData="M301.21,418.53C300.97,418.54 300.73,418.56 300.49,418.56C297.09,418.59 293.74,417.72 290.79,416.05L222.6,377.54C220.63,376.43 219,374.82 217.85,372.88C216.7,370.94 216.09,368.73 216.07,366.47L216.07,288.16C216.06,287.32 216.09,286.49 216.17,285.67C216.38,283.54 216.91,281.5 217.71,279.6L199.29,268.27L177.74,256.19C175.72,260.43 174.73,265.23 174.78,270.22L174.79,387.05C174.85,393.89 178.57,400.2 184.53,403.56L286.26,461.02C290.67,463.51 295.66,464.8 300.73,464.76C300.91,464.76 301.09,464.74 301.27,464.74C301.24,449.84 301.22,439.23 301.22,439.23L301.21,418.53Z" |
||||
android:fillColor="#041619" |
||||
android:fillType="nonZero"/> |
||||
<path |
||||
android:pathData="M409.45,242.91L312.64,188.23C303.64,183.15 292.58,183.26 283.68,188.51L187.92,245C183.31,247.73 179.93,251.62 177.75,256.17L177.74,256.19L199.29,268.27L217.71,279.6C217.83,279.32 217.92,279.02 218.05,278.74C218.24,278.36 218.43,277.98 218.64,277.62C219.06,276.88 219.52,276.18 220.04,275.51C221.37,273.8 223.01,272.35 224.87,271.25L289.06,233.39C290.42,232.59 291.87,231.96 293.39,231.51C295.53,230.87 297.77,230.6 300,230.72C302.98,230.88 305.88,231.73 308.47,233.2L373.37,269.85C375.54,271.08 377.49,272.68 379.13,274.57C379.68,275.19 380.18,275.85 380.65,276.53C380.86,276.84 381.05,277.15 381.24,277.47L397.79,266.39L420.34,252.93L420.31,252.88C417.55,248.8 413.77,245.35 409.45,242.91Z" |
||||
android:fillColor="#37BF6E" |
||||
android:fillType="nonZero"/> |
||||
<path |
||||
android:pathData="M381.24,277.47C381.51,277.92 381.77,278.38 382.01,278.84C382.21,279.24 382.39,279.65 382.57,280.06C382.91,280.88 383.19,281.73 383.41,282.59C383.74,283.88 383.92,285.21 383.93,286.57L383.93,361.1C383.96,363.95 383.35,366.77 382.16,369.36C381.93,369.86 381.69,370.35 381.42,370.83C379.75,373.79 377.32,376.27 374.39,378L310.2,415.87C307.47,417.48 304.38,418.39 301.21,418.53L301.22,439.23C301.22,439.23 301.24,449.84 301.27,464.74C306.1,464.61 310.91,463.3 315.21,460.75L410.98,404.25C419.88,399 425.31,389.37 425.22,379.03L425.22,267.85C425.17,262.48 423.34,257.34 420.34,252.93L397.79,266.39L381.24,277.47Z" |
||||
android:fillColor="#3870B2" |
||||
android:fillType="nonZero"/> |
||||
<path |
||||
android:pathData="M177.75,256.17C179.93,251.62 183.31,247.73 187.92,245L283.68,188.51C292.58,183.26 303.64,183.15 312.64,188.23L409.45,242.91C413.77,245.35 417.55,248.8 420.31,252.88L420.34,252.93L498.59,206.19C494.03,199.46 487.79,193.78 480.67,189.75L320.86,99.49C306.01,91.1 287.75,91.27 273.07,99.95L114.99,193.2C107.39,197.69 101.81,204.11 98.21,211.63L177.74,256.19L177.75,256.17ZM301.27,464.74C301.09,464.74 300.91,464.76 300.73,464.76C295.66,464.8 290.67,463.51 286.26,461.02L184.53,403.56C178.57,400.2 174.85,393.89 174.79,387.05L174.78,270.22C174.73,265.23 175.72,260.43 177.74,256.19L98.21,211.63C94.86,218.63 93.23,226.58 93.31,234.82L93.31,427.67C93.42,438.97 99.54,449.37 109.4,454.92L277.31,549.77C284.6,553.88 292.84,556.01 301.2,555.94L301.2,555.8C301.39,543.78 301.33,495.26 301.27,464.74Z" |
||||
android:strokeWidth="10" |
||||
android:fillColor="#00000000" |
||||
android:strokeColor="#083042" |
||||
android:fillType="nonZero"/> |
||||
<path |
||||
android:pathData="M498.59,206.19L420.34,252.93C423.34,257.34 425.17,262.48 425.22,267.85L425.22,379.03C425.31,389.37 419.88,399 410.98,404.25L315.21,460.75C310.91,463.3 306.1,464.61 301.27,464.74C301.33,495.26 301.39,543.78 301.2,555.8L301.2,555.94C309.48,555.87 317.74,553.68 325.11,549.32L483.18,456.06C497.87,447.39 506.85,431.49 506.69,414.43L506.69,230.91C506.6,222.02 503.57,213.5 498.59,206.19Z" |
||||
android:strokeWidth="10" |
||||
android:fillColor="#00000000" |
||||
android:strokeColor="#083042" |
||||
android:fillType="nonZero"/> |
||||
<path |
||||
android:pathData="M301.2,555.94C292.84,556.01 284.6,553.88 277.31,549.76L109.4,454.92C99.54,449.37 93.42,438.97 93.31,427.67L93.31,234.82C93.23,226.58 94.86,218.63 98.21,211.63C101.81,204.11 107.39,197.69 114.99,193.2L273.07,99.95C287.75,91.27 306.01,91.1 320.86,99.49L480.67,189.75C487.79,193.78 494.03,199.46 498.59,206.19C503.57,213.5 506.6,222.02 506.69,230.91L506.69,414.43C506.85,431.49 497.87,447.39 483.18,456.06L325.11,549.32C317.74,553.68 309.48,555.87 301.2,555.94Z" |
||||
android:strokeWidth="10" |
||||
android:fillColor="#00000000" |
||||
android:strokeColor="#083042" |
||||
android:fillType="nonZero"/> |
||||
</vector> |
Loading…
Reference in new issue