Skip to content

Commit 5ee6974

Browse files
Merge pull request #27 from amanshuraikwar/theme-data-testss
Theme data testss
2 parents 86e463e + 39770bd commit 5ee6974

12 files changed

Lines changed: 269 additions & 51 deletions

File tree

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: Theme Data Tests
2+
3+
on:
4+
workflow_dispatch:
5+
pull_request:
6+
branches:
7+
- trunk
8+
9+
jobs:
10+
web-build-html-js:
11+
runs-on: macos-11
12+
steps:
13+
- name: Checkout
14+
uses: actions/checkout@v2.3.1
15+
16+
- name: Set up JDK 11
17+
uses: actions/setup-java@v1
18+
with:
19+
java-version: 11
20+
21+
- name: Theme Data Tests
22+
run: |
23+
cd project-files/Portfolio
24+

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
# My Portfolio
22

3+
<p align="center">
4+
5+
![](https://github.com/amanshuraikwar/amanshuraikwar.github.io/actions/workflows/build-web-html-js.yml/badge.svg?branch=trunk)
6+
&nbsp; &nbsp; &nbsp; &nbsp;
7+
![](https://github.com/amanshuraikwar/amanshuraikwar.github.io/actions/workflows/main.yml/badge.svg?branch=trunk)
8+
&nbsp; &nbsp; &nbsp; &nbsp;
9+
![](https://github.com/amanshuraikwar/amanshuraikwar.github.io/actions/workflows/theme-data-tests.yml/badge.svg?branch=trunk)
10+
</p>
11+
12+
13+
14+
15+
316
This is my portfolio. It is a KMM project which runs on Web, Android, iOS.
417

518
The business logic is written in Kotlin.

project-files/Portfolio/shared/build.gradle.kts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
21
import io.github.amanshuraikwar.nxtbuz.buildSrc.Libs
2+
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
33

44
plugins {
55
kotlin("multiplatform")
@@ -13,12 +13,12 @@ version = "1.0"
1313
kotlin {
1414
android()
1515

16-
val iosTarget: (String, KotlinNativeTarget.() -> Unit) -> KotlinNativeTarget =
17-
if (System.getenv("SDK_NAME")?.startsWith("iphoneos") == true)
18-
::iosArm64
19-
else
20-
::iosX64
21-
16+
val iosTarget: (String, KotlinNativeTarget.() -> Unit) -> KotlinNativeTarget = when {
17+
System.getenv("SDK_NAME")?.startsWith("iphoneos") == true -> ::iosArm64
18+
System.getenv("NATIVE_ARCH")
19+
?.startsWith("arm") == true -> ::iosSimulatorArm64 // available to KT 1.5.30
20+
else -> ::iosX64
21+
}
2222
iosTarget("ios") {}
2323

2424
cocoapods {
@@ -33,7 +33,7 @@ kotlin {
3333
useCommonJs()
3434
browser()
3535
}
36-
36+
3737
sourceSets {
3838
val commonMain by getting {
3939
dependencies {
@@ -56,8 +56,7 @@ kotlin {
5656
}
5757
val commonTest by getting {
5858
dependencies {
59-
implementation(kotlin("test-common"))
60-
implementation(kotlin("test-annotations-common"))
59+
implementation(kotlin("test"))
6160
implementation(Libs.Ktor.clientMock)
6261
}
6362
}
@@ -86,7 +85,6 @@ kotlin {
8685
val jsTest by getting {
8786
dependencies {
8887
implementation(kotlin("test-js"))
89-
// implementation("org.jetbrains.kotlin:kotlin-test-js")
9088
}
9189
}
9290
}
Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,5 @@
11
package io.github.amanshuraikwar.portfolio
22

3-
import kotlinx.coroutines.CoroutineScope
4-
import kotlinx.coroutines.runBlocking
5-
6-
actual fun runTest(block: suspend CoroutineScope.() -> Unit) = runBlocking { block() }
7-
8-
actual annotation class JsName actual constructor(
9-
actual val name: String
10-
)
11-
123
actual class Platform actual constructor() {
134
actual val platform: String = "Android ${android.os.Build.VERSION.SDK_INT}"
145
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package io.github.amanshuraikwar.portfolio
2+
3+
import kotlinx.coroutines.CoroutineScope
4+
import kotlinx.coroutines.runBlocking
5+
6+
actual fun runTest(block: suspend CoroutineScope.() -> Unit) = runBlocking { block() }
7+
8+
actual annotation class JsName actual constructor(
9+
actual val name: String
10+
)
11+
12+
/** Read the given resource as binary data. */
13+
actual fun readBinaryResource(
14+
resourceName: String
15+
): ByteArray {
16+
return ClassLoader
17+
.getSystemResourceAsStream(resourceName)!!
18+
.readBytes()
19+
}
Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
package io.github.amanshuraikwar.portfolio
22

3-
import kotlinx.coroutines.CoroutineScope
4-
5-
expect fun runTest(block: suspend CoroutineScope.() -> Unit)
6-
expect annotation class JsName constructor(val name: String)
7-
83
expect class Platform() {
94
val platform: String
105
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package io.github.amanshuraikwar.portfolio
2+
3+
import kotlinx.coroutines.CoroutineScope
4+
5+
expect fun runTest(block: suspend CoroutineScope.() -> Unit)
6+
expect annotation class JsName constructor(val name: String)
7+
8+
/** Read the given resource as binary data. */
9+
expect fun readBinaryResource(
10+
resourceName: String
11+
): ByteArray

project-files/Portfolio/shared/src/commonTest/kotlin/io.github.amanshuraikwar.portfolio/ThemeDataTest.kt

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,4 +169,122 @@ class ThemeDataTest {
169169
)
170170
}
171171
}
172+
173+
@Test
174+
@JsName("verifyRemoteJsonColorStringsAreAccurate")
175+
fun `verify remote json color strings are accurate`() {
176+
val portfolioApi = PortfolioApi(
177+
PortfolioApi.createHttpClient(enableNetworkLogs = true)
178+
)
179+
180+
runTest {
181+
assertEquals(
182+
true,
183+
portfolioApi
184+
.getThemeData()
185+
.themes
186+
.fold(true) { acc, cur ->
187+
acc && cur.let {
188+
it.primaryColor.isAccurateColorString()
189+
&& it.onPrimaryColor.isAccurateColorString()
190+
&& it.surfaceColor.isAccurateColorString()
191+
&& it.onSurfaceColor.isAccurateColorString()
192+
&& it.errorColor.isAccurateColorString()
193+
&& it.onErrorColor.isAccurateColorString()
194+
}
195+
}
196+
)
197+
}
198+
}
199+
200+
private fun String.isAccurateColorString(): Boolean {
201+
return matches(Regex("#([A-Fa-f0-9]){8}"))
202+
}
203+
204+
/*
205+
@Test
206+
@JsName("verifyLocalJsonSerializationIsWorking")
207+
fun `verify local json serialization is working`() {
208+
val mockEngine = MockEngine { request ->
209+
if (request.url.toString().endsWith("/theme.json")) {
210+
respond(
211+
content = ByteReadChannel(
212+
readBinaryResource("api/theme.json").toString()
213+
),
214+
status = HttpStatusCode.OK,
215+
headers = headersOf(HttpHeaders.ContentType, "application/json")
216+
)
217+
} else {
218+
respond(content = ByteReadChannel(""))
219+
}
220+
}
221+
222+
val portfolioApi = PortfolioApi(
223+
PortfolioApi.createHttpClient(
224+
engine = mockEngine,
225+
enableNetworkLogs = true
226+
)
227+
)
228+
229+
runTest {
230+
assertEquals(
231+
ThemeDataResponse(
232+
listOf(
233+
ThemeColorsDataResponse(
234+
name = "Dark Salmon",
235+
isDark = true,
236+
primaryColor = "#FFFFCDD2",
237+
onPrimaryColor = "#FF4E342E",
238+
surfaceColor = "#FF212121",
239+
onSurfaceColor = "#FFffffff",
240+
errorColor = "#FFE57373",
241+
onErrorColor = "#FF4E342E",
242+
),
243+
ThemeColorsDataResponse(
244+
name = "Light Blue",
245+
isDark = false,
246+
primaryColor = "#ffEA5C5A",
247+
onPrimaryColor = "#FFffffff",
248+
surfaceColor = "#ffCDECF9",
249+
onSurfaceColor = "#FF030204",
250+
errorColor = "#FFE57373",
251+
onErrorColor = "#FF212121",
252+
),
253+
ThemeColorsDataResponse(
254+
name = "Matt D'av Ella",
255+
isDark = false,
256+
primaryColor = "#ffE35638",
257+
onPrimaryColor = "#FFFADACA",
258+
surfaceColor = "#ffFBF8EC",
259+
onSurfaceColor = "#FF24242C",
260+
errorColor = "#FFE57373",
261+
onErrorColor = "#FF212121",
262+
),
263+
ThemeColorsDataResponse(
264+
name = "Google",
265+
isDark = false,
266+
primaryColor = "#ff4285F4",
267+
onPrimaryColor = "#FFffffff",
268+
surfaceColor = "#ffffffff",
269+
onSurfaceColor = "#FF212121",
270+
errorColor = "#FFE57373",
271+
onErrorColor = "#FF212121",
272+
),
273+
ThemeColorsDataResponse(
274+
name = "Spotify",
275+
isDark = true,
276+
primaryColor = "#ff1FDF64",
277+
onPrimaryColor = "#FF212121",
278+
surfaceColor = "#ff212121",
279+
onSurfaceColor = "#FFFFFFFF",
280+
errorColor = "#FFE57373",
281+
onErrorColor = "#FF212121",
282+
)
283+
)
284+
),
285+
portfolioApi.getThemeData()
286+
)
287+
}
288+
}
289+
*/
172290
}
Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,8 @@
11
package io.github.amanshuraikwar.portfolio
22

3-
import kotlinx.coroutines.CoroutineScope
4-
import kotlinx.coroutines.runBlocking
53
import platform.UIKit.UIDevice
64

7-
actual fun runTest(block: suspend CoroutineScope.() -> Unit) = runBlocking { block() }
8-
9-
actual annotation class JsName actual constructor(
10-
actual val name: String
11-
)
12-
135
actual class Platform actual constructor() {
14-
actual val platform: String = UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion
6+
actual val platform: String =
7+
UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion
158
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package io.github.amanshuraikwar.portfolio
2+
3+
import kotlinx.cinterop.addressOf
4+
import kotlinx.cinterop.usePinned
5+
import kotlinx.coroutines.CoroutineScope
6+
import kotlinx.coroutines.runBlocking
7+
import platform.Foundation.NSBundle
8+
import platform.Foundation.NSData
9+
import platform.Foundation.dataWithContentsOfFile
10+
import platform.posix.memcpy
11+
12+
actual fun runTest(block: suspend CoroutineScope.() -> Unit) = runBlocking { block() }
13+
14+
actual annotation class JsName actual constructor(
15+
actual val name: String
16+
)
17+
18+
/** Read the given resource as binary data. */
19+
actual fun readBinaryResource(
20+
resourceName: String
21+
): ByteArray {
22+
// split based on "." and "/". We want to strip the leading ./ and
23+
// split the extension
24+
val pathParts = resourceName.split("[.|/]".toRegex())
25+
// pathParts looks like
26+
// [, , test_case_input_one, bin]
27+
val path = NSBundle.mainBundle
28+
.pathForResource("resources/${pathParts[2]}", pathParts[3])
29+
val data = NSData.dataWithContentsOfFile(path!!)
30+
return data!!.toByteArray()
31+
}
32+
33+
internal fun NSData.toByteArray(): ByteArray {
34+
return ByteArray(length.toInt()).apply {
35+
usePinned {
36+
memcpy(it.addressOf(0), bytes, length)
37+
}
38+
}
39+
}

0 commit comments

Comments
 (0)