Skip to content

Commit 2c532f4

Browse files
authored
Unit Testing (#208)
* Unit Testing | Patch 1 * Unit Testing | Patch 2 * Unit Testing | Patch 3 * Unit Testing | Patch 4 * Unit Testing | Patch 5 * Unit Testing | Patch 6 * Unit Testing | Patch 7 * Unit Testing | Patch 8 * Unit Testing | Patch 9 * Unit Testing | Patch 10 * Unit Testing | Patch 11 * Unit Testing | Patch 12 * Unit Testing | Patch 13 * Unit Testing | Patch 14 * Unit Testing | Patch 15 * Unit Testing | Patch 16 * Unit Testing | Patch 17 * Unit Testing | Patch 18 * Unit Testing | Patch 19 * Unit Testing | Patch 20 * Unit Testing | Patch 21 * Unit Testing | Patch 22 * Unit Testing | Patch 23 * Unit Testing | Patch 24 * Unit Testing | Patch 24 * Unit Testing | Patch 25 * Unit Testing | Patch 26 * Unit Testing | Patch 27 * Unit Testing | Patch 28 * Unit Testing | Patch 29 * Unit Testing | Patch 30 * Unit Testing | Patch 31 * Unit Testing | Patch 32 * Unit Testing | Patch 33 * Unit Testing | Patch 34 * Unit Testing | Patch 35 * Unit Testing | Patch 36 * Unit Testing | Patch 37 * Unit Testing | Patch 38 * Unit Testing | Patch 39 * Unit Testing | Patch 40 * Unit Testing | Patch 41 * Unit Testing | Patch 42 * Unit Testing | Patch 43 * Unit Testing | Patch 44 * Unit Testing | Patch 45 * Unit Testing | Patch 46 * Unit Testing | Patch 47 * Unit Testing | Patch 48
1 parent a1edcc7 commit 2c532f4

File tree

255 files changed

+17376
-199
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

255 files changed

+17376
-199
lines changed

.github/workflows/android_test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@ jobs:
2323
run: chmod +x ./gradlew
2424

2525
- name: Run Tests with Gradle
26-
run: ./gradlew test
26+
run: ./gradlew clean testDebugUnitTest

app/src/main/java/com/shifthackz/aisdv1/app/di/ProvidersModule.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import com.shifthackz.aisdv1.core.common.appbuild.BuildVersion
77
import com.shifthackz.aisdv1.core.common.file.FileProviderDescriptor
88
import com.shifthackz.aisdv1.core.common.links.LinksProvider
99
import com.shifthackz.aisdv1.core.common.schedulers.SchedulersProvider
10+
import com.shifthackz.aisdv1.core.common.time.TimeProvider
1011
import com.shifthackz.aisdv1.domain.entity.ServerSource
1112
import com.shifthackz.aisdv1.domain.feature.auth.AuthorizationCredentials
1213
import com.shifthackz.aisdv1.domain.feature.auth.AuthorizationStore
@@ -24,6 +25,7 @@ import io.reactivex.rxjava3.core.Scheduler
2425
import io.reactivex.rxjava3.schedulers.Schedulers
2526
import org.koin.android.ext.koin.androidApplication
2627
import org.koin.dsl.module
28+
import java.util.Date
2729
import java.util.concurrent.Executor
2830
import java.util.concurrent.Executors
2931

@@ -134,6 +136,14 @@ val providersModule = module {
134136
}
135137
}
136138

139+
single<TimeProvider> {
140+
object : TimeProvider {
141+
override fun nanoTime(): Long = System.nanoTime()
142+
override fun currentTimeMillis(): Long = System.currentTimeMillis()
143+
override fun currentDate(): Date = Date()
144+
}
145+
}
146+
137147
single<FileProviderDescriptor> {
138148
object : FileProviderDescriptor {
139149
override val providerPath: String = "${androidApplication().packageName}.fileprovider"

core/common/src/main/java/com/shifthackz/aisdv1/core/common/extensions/StringExtensions.kt

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,6 @@ package com.shifthackz.aisdv1.core.common.extensions
33
private const val PROTOCOL_DELIMITER = "://"
44
private const val PROTOCOL_HOLDER = "[[_PROTOCOL_]]"
55

6-
fun String.withoutUrlProtocol(): String {
7-
if (!this.contains(PROTOCOL_DELIMITER)) return this
8-
val decomposed = this.split(PROTOCOL_DELIMITER)
9-
if (decomposed.size < 2) return this
10-
return decomposed.last()
11-
}
12-
136
fun String.fixUrlSlashes(): String = this
147
.replace(PROTOCOL_DELIMITER, PROTOCOL_HOLDER)
158
.replace(Regex("/{2,}"), "/")
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.shifthackz.aisdv1.core.common.time
2+
3+
import java.util.Date
4+
5+
interface TimeProvider {
6+
fun nanoTime(): Long
7+
fun currentTimeMillis(): Long
8+
fun currentDate(): Date
9+
}

domain/src/test/java/com/shifthackz/aisdv1/domain/entity/AppVersionTest.kt renamed to core/common/src/test/java/com/shifthackz/aisdv1/core/common/appbuild/BuildVersionTest.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
package com.shifthackz.aisdv1.domain.entity
1+
package com.shifthackz.aisdv1.core.common.appbuild
22

3-
import com.shifthackz.aisdv1.core.common.appbuild.BuildVersion
43
import org.junit.Assert
54
import org.junit.Test
65

7-
class AppVersionTest {
6+
class BuildVersionTest {
87

98
@Test
109
fun `Parse 1_0_0, expected success`() {
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.shifthackz.aisdv1.core.common.extensions
2+
3+
import org.junit.Assert
4+
import org.junit.Test
5+
import java.util.Date
6+
7+
class DateExtensionsTest {
8+
9+
companion object {
10+
private val date = Date(894333955000) // 1998-05-05 05:05:55
11+
}
12+
13+
@Test
14+
fun `given date 05_05_1998, then getRawDay, expected 5`() {
15+
val expected = 5
16+
val actual = date.getRawDay()
17+
Assert.assertEquals(expected, actual)
18+
}
19+
20+
@Test
21+
fun `given date 05_05_1998, then getRawMonth, expected 5`() {
22+
val expected = 5
23+
val actual = date.getRawMonth()
24+
Assert.assertEquals(expected, actual)
25+
}
26+
27+
@Test
28+
fun `given date 05_05_1998, then getRawYear, expected 1998`() {
29+
val expected = 1998
30+
val actual = date.getRawYear()
31+
Assert.assertEquals(expected, actual)
32+
}
33+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.shifthackz.aisdv1.core.common.extensions
2+
3+
import org.junit.Assert
4+
import org.junit.Test
5+
6+
class KotlinExtensionsTest {
7+
8+
@Test
9+
fun `given TestClass with null value, then applyIf with true predicate, expected test value changed`() {
10+
class TestClass {
11+
var testValue: String? = null
12+
}
13+
14+
val instance = TestClass()
15+
val predicate = true
16+
instance.applyIf(predicate) {
17+
testValue = "5598"
18+
}
19+
20+
val expected = "5598"
21+
val actual = instance.testValue
22+
Assert.assertEquals(expected, actual)
23+
}
24+
25+
@Test
26+
fun `given TestClass with null value, then applyIf with false predicate, expected test value NOT changed`() {
27+
class TestClass {
28+
var testValue: String? = null
29+
}
30+
31+
val instance = TestClass()
32+
val predicate = false
33+
instance.applyIf(predicate) {
34+
testValue = "5598"
35+
}
36+
37+
val expected = null
38+
val actual = instance.testValue
39+
Assert.assertEquals(expected, actual)
40+
}
41+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.shifthackz.aisdv1.core.common.math
2+
3+
import org.junit.Assert
4+
import org.junit.Test
5+
6+
class MathUtilsTest {
7+
8+
@Test
9+
fun `given Double with 8 fraction digits, then roundTo(2), expected Double with 2 fraction digits`() {
10+
val value = 55.98238462
11+
val expected = 55.98.toString()
12+
val actual = value.roundTo(2).toString()
13+
Assert.assertEquals(expected, actual)
14+
}
15+
16+
@Test
17+
fun `given Float with 6 fraction digits, then roundTo(2), expected Float with 2 fraction digits`() {
18+
val value = 55.982384f
19+
val expected = 55.98f.toString()
20+
val actual = value.roundTo(2).toString()
21+
Assert.assertEquals(expected, actual)
22+
}
23+
}

core/validation/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@ android {
1212
dependencies {
1313
implementation di.koinCore
1414
implementation reactive.rxkotlin
15+
testImplementation test.junit
16+
testImplementation test.mockk
1517
}

core/validation/src/main/java/com/shifthackz/aisdv1/core/validation/horde/CommonStringValidator.kt renamed to core/validation/src/main/java/com/shifthackz/aisdv1/core/validation/common/CommonStringValidator.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.shifthackz.aisdv1.core.validation.horde
1+
package com.shifthackz.aisdv1.core.validation.common
22

33
import com.shifthackz.aisdv1.core.validation.ValidationResult
44

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.shifthackz.aisdv1.core.validation.horde
1+
package com.shifthackz.aisdv1.core.validation.common
22

33
import com.shifthackz.aisdv1.core.validation.ValidationResult
44

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package com.shifthackz.aisdv1.core.validation.di
22

3+
import com.shifthackz.aisdv1.core.validation.common.CommonStringValidator
4+
import com.shifthackz.aisdv1.core.validation.common.CommonStringValidatorImpl
35
import com.shifthackz.aisdv1.core.validation.dimension.DimensionValidator
46
import com.shifthackz.aisdv1.core.validation.dimension.DimensionValidatorImpl
5-
import com.shifthackz.aisdv1.core.validation.horde.CommonStringValidator
6-
import com.shifthackz.aisdv1.core.validation.horde.CommonStringValidatorImpl
77
import com.shifthackz.aisdv1.core.validation.url.UrlValidator
88
import com.shifthackz.aisdv1.core.validation.url.UrlValidatorImpl
99
import org.koin.core.module.dsl.factoryOf
@@ -13,7 +13,7 @@ import org.koin.dsl.module
1313
val validatorsModule = module {
1414
// !!! Do not use [factoryOf] for DimensionValidatorImpl, it has 2 default Ints in constructor
1515
factory<DimensionValidator> { DimensionValidatorImpl() }
16+
factory<UrlValidator> { UrlValidatorImpl() }
1617

17-
factoryOf(::UrlValidatorImpl) bind UrlValidator::class
1818
factoryOf(::CommonStringValidatorImpl) bind CommonStringValidator::class
1919
}

core/validation/src/main/java/com/shifthackz/aisdv1/core/validation/url/UrlValidatorImpl.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ import android.util.Patterns
44
import android.webkit.URLUtil
55
import com.shifthackz.aisdv1.core.validation.ValidationResult
66
import java.net.URI
7+
import java.util.regex.Pattern
78

8-
internal class UrlValidatorImpl : UrlValidator {
9+
internal class UrlValidatorImpl(
10+
private val webUrlPattern: Pattern = Patterns.WEB_URL,
11+
) : UrlValidator {
912

1013
override operator fun invoke(input: String?): ValidationResult<UrlValidator.Error> = when {
1114
input == null -> ValidationResult(
@@ -32,7 +35,7 @@ internal class UrlValidatorImpl : UrlValidator {
3235
isValid = false,
3336
validationError = UrlValidator.Error.Invalid,
3437
)
35-
!Patterns.WEB_URL.matcher(input).matches() -> ValidationResult(
38+
!webUrlPattern.matcher(input).matches() -> ValidationResult(
3639
isValid = false,
3740
validationError = UrlValidator.Error.Invalid,
3841
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package com.shifthackz.aisdv1.core.validation.common
2+
3+
import com.shifthackz.aisdv1.core.validation.ValidationResult
4+
import org.junit.Assert
5+
import org.junit.Test
6+
7+
class CommonStringValidatorImplTest {
8+
9+
private val validator = CommonStringValidatorImpl()
10+
11+
@Test
12+
fun `given input is null, expected not valid with Empty error`() {
13+
val expected = ValidationResult<CommonStringValidator.Error>(
14+
isValid = false,
15+
validationError = CommonStringValidator.Error.Empty,
16+
)
17+
val actual = validator(null)
18+
Assert.assertEquals(expected, actual)
19+
}
20+
21+
@Test
22+
fun `given input is empty, expected not valid with Empty error`() {
23+
val expected = ValidationResult<CommonStringValidator.Error>(
24+
isValid = false,
25+
validationError = CommonStringValidator.Error.Empty,
26+
)
27+
val actual = validator("")
28+
Assert.assertEquals(expected, actual)
29+
}
30+
31+
@Test
32+
fun `given input is blank, expected not valid with Empty error`() {
33+
val expected = ValidationResult<CommonStringValidator.Error>(
34+
isValid = false,
35+
validationError = CommonStringValidator.Error.Empty,
36+
)
37+
val actual = validator(" ")
38+
Assert.assertEquals(expected, actual)
39+
}
40+
41+
@Test
42+
fun `given input is non empty string, expected valid`() {
43+
val expected = ValidationResult<CommonStringValidator.Error>(true)
44+
val actual = validator("5598 is my favorite")
45+
Assert.assertEquals(expected, actual)
46+
}
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package com.shifthackz.aisdv1.core.validation.dimension
2+
3+
import com.shifthackz.aisdv1.core.validation.ValidationResult
4+
import org.junit.Assert
5+
import org.junit.Test
6+
7+
class DimensionValidatorImplTest {
8+
9+
private val validator = DimensionValidatorImpl(MIN, MAX)
10+
11+
@Test
12+
fun `given input is null, expected not valid with Empty error`() {
13+
val expected = ValidationResult<DimensionValidator.Error>(
14+
isValid = false,
15+
validationError = DimensionValidator.Error.Empty,
16+
)
17+
val actual = validator(null)
18+
Assert.assertEquals(expected, actual)
19+
}
20+
21+
@Test
22+
fun `given input is empty, expected not valid with Empty error`() {
23+
val expected = ValidationResult<DimensionValidator.Error>(
24+
isValid = false,
25+
validationError = DimensionValidator.Error.Empty,
26+
)
27+
val actual = validator("")
28+
Assert.assertEquals(expected, actual)
29+
}
30+
31+
@Test
32+
fun `given input is unparsable to int, expected not valid with Unexpected error`() {
33+
val expected = ValidationResult<DimensionValidator.Error>(
34+
isValid = false,
35+
validationError = DimensionValidator.Error.Unexpected,
36+
)
37+
val actual = validator("5598❤")
38+
Assert.assertEquals(expected, actual)
39+
}
40+
41+
@Test
42+
fun `given input is less than minimum allowed value, expected not valid with LessThanMinimum error`() {
43+
val expected = ValidationResult<DimensionValidator.Error>(
44+
isValid = false,
45+
validationError = DimensionValidator.Error.LessThanMinimum(MIN),
46+
)
47+
val actual = validator("55")
48+
Assert.assertEquals(expected, actual)
49+
}
50+
51+
@Test
52+
fun `given input is bigger than maximum allowed value, expected not valid with BiggerThanMaximum error`() {
53+
val expected = ValidationResult<DimensionValidator.Error>(
54+
isValid = false,
55+
validationError = DimensionValidator.Error.BiggerThanMaximum(MAX),
56+
)
57+
val actual = validator("5598")
58+
Assert.assertEquals(expected, actual)
59+
}
60+
61+
@Test
62+
fun `given input is valid parsable int value, expected valid`() {
63+
val expected = ValidationResult<DimensionValidator.Error>(true)
64+
val actual = validator("1024")
65+
Assert.assertEquals(expected, actual)
66+
}
67+
68+
companion object {
69+
private const val MIN = 64
70+
private const val MAX = 2048
71+
}
72+
}

0 commit comments

Comments
 (0)