Skip to content

Commit 5a52067

Browse files
authored
Update tests - Add materialize/dematerialize (hoc081098#30)
* Update tests * fix * fix * fix * fix tests * fix tests * fix tests * fix tests
1 parent 1229b7c commit 5a52067

29 files changed

+981
-235
lines changed

.github/workflows/build.yml

+21-14
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,19 @@
1-
# This is a basic workflow to help you get started with Actions
2-
31
name: CI
42

5-
# Controls when the action will run.
63
on:
7-
# Triggers the workflow on push or pull request events but only for the master branch
84
push:
95
branches: [ master ]
106
pull_request:
117
branches: [ master ]
12-
13-
# Allows you to run this workflow manually from the Actions tab
148
workflow_dispatch:
159

16-
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
1710
jobs:
18-
# This workflow contains a single job called "build"
1911
build:
2012
strategy:
2113
matrix:
22-
os: [macOS-latest, windows-latest, ubuntu-latest]
23-
24-
# The type of runner that the job will run on
14+
os: [ macOS-latest ]
2515
runs-on: ${{matrix.os}}
26-
27-
# Steps represent a sequence of tasks that will be executed as part of the job
2816
steps:
29-
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
3017
- uses: actions/checkout@v2
3118

3219
- name: Validate gradle wrapper
@@ -48,8 +35,28 @@ jobs:
4835
restore-keys: |
4936
${{ runner.os }}-${{ github.job }}-
5037
38+
- name: Cache konan
39+
uses: actions/cache@v2
40+
with:
41+
path: |
42+
~/.konan/cache
43+
~/.konan/dependencies
44+
~/.konan/kotlin-native-macos*
45+
~/.konan/kotlin-native-mingw*
46+
~/.konan/kotlin-native-prebuilt-macos*
47+
key: ${{ runner.os }}-konan-${{ hashFiles('**/*.gradle*') }}
48+
restore-keys: |
49+
${{ runner.os }}-konan-
50+
5151
- name: Make gradlew executable
5252
run: chmod +x ./gradlew
5353

5454
- name: Build
5555
run: ./gradlew build --stacktrace
56+
57+
- name: Upload test report artifact
58+
if: ${{ failure() }}
59+
uses: actions/upload-artifact@v2
60+
with:
61+
name: test-report
62+
path: build/reports/tests/allTests/

.github/workflows/publish-release.yml

+14-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: Publish Release
22

33
on:
44
release:
5-
types: [published]
5+
types: [ published ]
66

77
jobs:
88
publish:
@@ -34,6 +34,19 @@ jobs:
3434
restore-keys: |
3535
${{ runner.os }}-${{ github.job }}-
3636
37+
- name: Cache konan
38+
uses: actions/cache@v2
39+
with:
40+
path: |
41+
~/.konan/cache
42+
~/.konan/dependencies
43+
~/.konan/kotlin-native-macos*
44+
~/.konan/kotlin-native-mingw*
45+
~/.konan/kotlin-native-prebuilt-macos*
46+
key: ${{ runner.os }}-konan-${{ hashFiles('**/*.gradle*') }}
47+
restore-keys: |
48+
${{ runner.os }}-konan-
49+
3750
- name: Make gradlew executable
3851
run: chmod +x ./gradlew
3952

.github/workflows/publish-snapshot.yml

+13
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,19 @@ jobs:
3333
restore-keys: |
3434
${{ runner.os }}-${{ github.job }}-
3535
36+
- name: Cache konan
37+
uses: actions/cache@v2
38+
with:
39+
path: |
40+
~/.konan/cache
41+
~/.konan/dependencies
42+
~/.konan/kotlin-native-macos*
43+
~/.konan/kotlin-native-mingw*
44+
~/.konan/kotlin-native-prebuilt-macos*
45+
key: ${{ runner.os }}-konan-${{ hashFiles('**/*.gradle*') }}
46+
restore-keys: |
47+
${{ runner.os }}-konan-
48+
3649
- name: Make gradlew executable
3750
run: chmod +x ./gradlew
3851

.idea/misc.xml

+8-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build.gradle.kts

+35-24
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType
33

44
plugins {
55
kotlin("multiplatform") version "1.5.31"
6-
jacoco
7-
id("com.diffplug.spotless") version "5.17.0"
6+
id("com.diffplug.spotless") version "5.17.1"
87
id("maven-publish")
98
id("com.vanniktech.maven.publish") version "0.18.0"
109
}
@@ -15,20 +14,11 @@ version = "0.0.7-SNAPSHOT"
1514
repositories {
1615
google()
1716
mavenCentral()
18-
}
19-
20-
jacoco {
21-
toolVersion = "0.8.6"
22-
}
23-
24-
tasks.withType<JacocoReport> {
25-
reports {
26-
xml.isEnabled = true
27-
}
28-
dependsOn(tasks.withType<Test>())
17+
gradlePluginPortal()
2918
}
3019

3120
val kotlinCoroutinesVersion = "1.5.2"
21+
val ktlintVersion = "0.43.0"
3222

3323
kotlin {
3424
explicitApi()
@@ -37,10 +27,6 @@ kotlin {
3727
compilations.all {
3828
kotlinOptions.jvmTarget = "1.8"
3929
}
40-
testRuns["test"].executionTask.configure {
41-
useJUnit()
42-
finalizedBy(tasks.withType<JacocoReport>())
43-
}
4430
}
4531
js(BOTH) {
4632
compilations.all {
@@ -82,7 +68,6 @@ kotlin {
8268
watchosX64()
8369
watchosX86()
8470

85-
8671
sourceSets {
8772
val commonMain by getting {
8873
dependencies {
@@ -93,18 +78,22 @@ kotlin {
9378
dependencies {
9479
implementation(kotlin("test-common"))
9580
implementation(kotlin("test-annotations-common"))
96-
implementation("app.cash.turbine:turbine:0.6.1")
81+
implementation("org.jetbrains.kotlinx:atomicfu:0.16.3")
9782
}
9883
}
99-
val jvmMain by getting
84+
val jvmMain by getting {
85+
dependsOn(commonMain)
86+
}
10087
val jvmTest by getting {
10188
dependsOn(commonTest)
10289

10390
dependencies {
10491
implementation(kotlin("test-junit"))
10592
}
10693
}
107-
val jsMain by getting
94+
val jsMain by getting {
95+
dependsOn(commonMain)
96+
}
10897
val jsTest by getting {
10998
dependencies {
11099
implementation(kotlin("test-js"))
@@ -113,6 +102,13 @@ kotlin {
113102

114103
val nativeMain by creating {
115104
dependsOn(commonMain)
105+
dependencies {
106+
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinCoroutinesVersion") {
107+
version {
108+
strictly(kotlinCoroutinesVersion)
109+
}
110+
}
111+
}
116112
}
117113
val nativeTest by creating {
118114
dependsOn(commonTest)
@@ -162,17 +158,32 @@ spotless {
162158
kotlin {
163159
target("**/*.kt")
164160

165-
ktlint("0.37.2").userData(
161+
ktlint(ktlintVersion).userData(
166162
mapOf(
167163
// TODO this should all come from editorconfig https://github.com/diffplug/spotless/issues/142
168164
"indent_size" to "2",
169-
"kotlin_imports_layout" to "ascii",
165+
"ij_kotlin_imports_layout" to "*",
170166
)
171167
)
168+
169+
trimTrailingWhitespace()
170+
indentWithSpaces()
171+
endWithNewline()
172172
}
173173

174174
kotlinGradle {
175175
target("**/*.kts")
176+
177+
ktlint(ktlintVersion).userData(
178+
mapOf(
179+
"indent_size" to "4",
180+
"ij_kotlin_imports_layout" to "*",
181+
)
182+
)
183+
184+
trimTrailingWhitespace()
185+
indentWithSpaces()
186+
endWithNewline()
176187
}
177188
}
178189

@@ -182,4 +193,4 @@ allprojects {
182193
sonatypeHost = com.vanniktech.maven.publish.SonatypeHost.S01
183194
}
184195
}
185-
}
196+
}

settings.gradle.kts

-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11

22
rootProject.name = "FlowExt"
3-
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.hoc081098.flowext
2+
3+
import kotlinx.coroutines.flow.FlowCollector
4+
5+
internal class ClosedException(val owner: FlowCollector<*>) :
6+
Exception("Flow was aborted, no more elements needed")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.hoc081098.flowext
2+
3+
public sealed interface Event<out T> {
4+
public data class Value<out T>(public val value: T) : Event<T> {
5+
override fun toString(): String = "Event.Value($value)"
6+
}
7+
8+
public data class Error(public val throwable: Throwable) : Event<Nothing> {
9+
override fun toString(): String = "Event.Error($throwable)"
10+
}
11+
12+
public object Complete : Event<Nothing> {
13+
override fun toString(): String = "Event.Complete"
14+
}
15+
}
16+
17+
public fun <T, R> Event<T>.map(transform: (T) -> R): Event<R> = when (this) {
18+
Event.Complete -> Event.Complete
19+
is Event.Error -> this
20+
is Event.Value -> Event.Value(transform(value))
21+
}
22+
23+
public fun <T> Event<T>.valueOrNull(): T? = when (this) {
24+
Event.Complete -> null
25+
is Event.Error -> null
26+
is Event.Value -> value
27+
}
28+
29+
public fun <T> Event<T>.valueOrThrow(): T = when (this) {
30+
Event.Complete -> throw NoSuchElementException("$this has no value!")
31+
is Event.Error -> throw throwable
32+
is Event.Value -> value
33+
}
34+
35+
public fun <T> Event<T>.throwableOrNull(): Throwable? = when (this) {
36+
Event.Complete -> null
37+
is Event.Error -> throwable
38+
is Event.Value -> null
39+
}
40+
41+
public fun <T> Event<T>.throwableOrThrow(): Throwable = when (this) {
42+
Event.Complete -> throw NoSuchElementException("$this has no throwable!")
43+
is Event.Error -> throwable
44+
is Event.Value -> throw NoSuchElementException("$this has no throwable!")
45+
}

src/commonMain/kotlin/com/hoc081098/flowext/interval.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package com.hoc081098.flowext
22

3-
import kotlin.time.Duration
4-
import kotlin.time.ExperimentalTime
53
import kotlinx.coroutines.delay
64
import kotlinx.coroutines.flow.Flow
75
import kotlinx.coroutines.flow.flow
6+
import kotlin.time.Duration
7+
import kotlin.time.ExperimentalTime
88

99
@ExperimentalTime
1010
public fun interval(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.hoc081098.flowext
2+
3+
import kotlinx.coroutines.flow.Flow
4+
import kotlinx.coroutines.flow.catch
5+
import kotlinx.coroutines.flow.collect
6+
import kotlinx.coroutines.flow.flow
7+
import kotlinx.coroutines.flow.map
8+
import kotlinx.coroutines.flow.onCompletion
9+
10+
public fun <T> Flow<T>.materialize(): Flow<Event<T>> = map<T, Event<T>> { Event.Value(it) }
11+
.onCompletion { if (it === null) emit(Event.Complete) }
12+
.catch { emit(Event.Error(it)) }
13+
14+
public fun <T> Flow<Event<T>>.dematerialize(): Flow<T> = flow {
15+
try {
16+
collect {
17+
when (it) {
18+
Event.Complete -> throw ClosedException(this)
19+
is Event.Error -> throw it.throwable
20+
is Event.Value -> emit(it.value)
21+
}
22+
}
23+
} catch (e: ClosedException) {
24+
if (e.owner !== this) throw e
25+
}
26+
}

src/commonMain/kotlin/com/hoc081098/flowext/takeUntil.kt

-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import kotlinx.coroutines.CoroutineStart
44
import kotlinx.coroutines.ExperimentalCoroutinesApi
55
import kotlinx.coroutines.coroutineScope
66
import kotlinx.coroutines.flow.Flow
7-
import kotlinx.coroutines.flow.FlowCollector
87
import kotlinx.coroutines.flow.collect
98
import kotlinx.coroutines.flow.flow
109
import kotlinx.coroutines.flow.take
@@ -32,5 +31,3 @@ public fun <T, R> Flow<T>.takeUntil(notifier: Flow<R>): Flow<T> = flow {
3231
if (e.owner !== this) throw e
3332
}
3433
}
35-
36-
private class ClosedException(val owner: FlowCollector<*>) : Exception("Flow was aborted, no more elements needed")

src/commonMain/kotlin/com/hoc081098/flowext/timer.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package com.hoc081098.flowext
22

3-
import kotlin.time.Duration
4-
import kotlin.time.ExperimentalTime
53
import kotlinx.coroutines.delay
64
import kotlinx.coroutines.flow.Flow
75
import kotlinx.coroutines.flow.flow
6+
import kotlin.time.Duration
7+
import kotlin.time.ExperimentalTime
88

99
/**
1010
* Creates a [Flow] that will wait for a specified time, before emitting the [value].

0 commit comments

Comments
 (0)