Skip to content

Commit 75db760

Browse files
ci(test): WiP Test
Signed-off-by: Andy Scherzinger <[email protected]>
1 parent 89291a0 commit 75db760

File tree

6 files changed

+2623
-27
lines changed

6 files changed

+2623
-27
lines changed

build.gradle

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ buildscript {
99
ext {
1010
daggerVersion = "2.57.1"
1111
kotlinVersion = "2.2.20"
12+
jUnitVersion = "4.13.2"
13+
androidXTestVersion = "1.3.0"
14+
androidXEspressoTestVersion = "3.7.0"
15+
mockkVersion = "1.14.5"
16+
mockitoVersion = "5.20.0"
17+
mockitoKotlinVersion = "6.0.0"
1218
}
1319
}
1420

core/build.gradle

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,15 @@ dependencies {
4141
implementation 'androidx.core:core-ktx:1.16.0'
4242
implementation 'androidx.appcompat:appcompat:1.7.1'
4343
implementation 'com.google.android.material:material:1.13.0'
44-
testImplementation 'junit:junit:4.13.2'
45-
androidTestImplementation 'androidx.test.ext:junit:1.3.0'
46-
androidTestImplementation 'androidx.test.espresso:espresso-core:3.7.0'
44+
45+
testImplementation "junit:junit:$jUnitVersion"
46+
testImplementation 'androidx.test:core:1.7.0'
47+
testImplementation 'org.robolectric:robolectric:4.16'
48+
testImplementation "org.mockito:mockito-core:$mockitoVersion"
49+
testImplementation "org.mockito.kotlin:mockito-kotlin:$mockitoKotlinVersion"
50+
testImplementation "io.mockk:mockk:$mockkVersion"
51+
androidTestImplementation "androidx.test.ext:junit:$androidXTestVersion"
52+
androidTestImplementation "androidx.test.espresso:espresso-core:$androidXEspressoTestVersion"
4753
}
4854

4955
afterEvaluate {
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/**
2+
* Nextcloud Android Common Library
3+
*
4+
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
5+
* SPDX-License-Identifier: MIT
6+
*/
7+
package com.nextcloud.android.common.core.utils
8+
9+
import android.content.Context
10+
import android.content.res.Configuration
11+
import android.content.res.Resources
12+
import android.os.LocaleList
13+
import android.text.format.DateFormat
14+
import com.nextcloud.android.common.core.R
15+
import io.mockk.every
16+
import io.mockk.mockk
17+
import io.mockk.mockkConstructor
18+
import org.junit.Assert.assertEquals
19+
import org.junit.Test
20+
import org.junit.runner.RunWith
21+
import org.mockito.Mock
22+
import org.mockito.MockedStatic
23+
import org.mockito.Mockito.mockStatic
24+
import org.mockito.junit.MockitoJUnitRunner
25+
import org.mockito.kotlin.doReturn
26+
import org.mockito.kotlin.mock
27+
import java.text.SimpleDateFormat
28+
import java.util.Calendar
29+
import java.util.Locale
30+
import kotlin.use
31+
32+
private const val DATE_FORMATTING_NOW = "Now"
33+
34+
@RunWith(MockitoJUnitRunner::class)
35+
class DateFormatterTest {
36+
@Mock
37+
private lateinit var mockContext: Context
38+
39+
@Mock
40+
private lateinit var mockResources: Resources
41+
42+
@Mock
43+
private lateinit var mockConfiguration: Configuration
44+
45+
@Mock
46+
private lateinit var mockLocaleList: LocaleList
47+
48+
@Mock
49+
private lateinit var mockDateFormat: DateFormat
50+
51+
@Test
52+
fun readStringFromContext_LocalizedString() {
53+
val mockContext =
54+
mock<Context> {
55+
on { getString(R.string.date_formatting_now) } doReturn DATE_FORMATTING_NOW
56+
}
57+
58+
val mockResources =
59+
mock<Resources> {
60+
on { mockContext.resources } doReturn mockResources
61+
}
62+
63+
val mockConfiguration =
64+
mock<Configuration> {
65+
on { mockContext.resources.configuration } doReturn mockConfiguration
66+
}
67+
68+
val mockLocaleList =
69+
mock<Configuration> {
70+
on { mockContext.resources.configuration.getLocales() } doReturn mockLocaleList
71+
on {
72+
mockContext.resources.configuration
73+
.getLocales()
74+
.get(0)
75+
} doReturn Locale.US
76+
}
77+
78+
mockStatic(DateFormat::class.java).use { mockedDateFormat ->
79+
mockedDateFormat.`when`<String> { DateFormat.getBestDateTimePattern(Locale.US, "EEE") }.thenReturn("EEE")
80+
mockedDateFormat
81+
.`when`<String> {
82+
DateFormat.getBestDateTimePattern(
83+
Locale.US,
84+
"MMM d"
85+
)
86+
}.thenReturn("MMM d")
87+
mockedDateFormat
88+
.`when`<String> {
89+
DateFormat.getBestDateTimePattern(Locale.US, "MMM d, yyyy")
90+
}.thenReturn("MMM d, yyyy")
91+
92+
// mockkConstructor(SimpleDateFormat::class)
93+
// every { anyConstructed<SimpleDateFormat>() } returns SimpleDateFormat("EEE", Locale.US)
94+
95+
val calendar = Calendar.getInstance()
96+
calendar.set(2025, 6, 17, 8, 35)
97+
98+
val result = DateFormatter(mockContext).getConditionallyRelativeFormattedTimeSpan(calendar)
99+
100+
// ...then the result should be the expected one.
101+
assertEquals(result, "test")
102+
}
103+
}
104+
105+
@Test
106+
fun testMockStaticMethodUsingMockito() {
107+
}
108+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* Nextcloud Android Common Library
3+
*
4+
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
5+
* SPDX-License-Identifier: MIT
6+
*/
7+
8+
package com.nextcloud.android.common.core.utils
9+
import android.content.Context
10+
import android.os.Build
11+
import androidx.test.core.app.ApplicationProvider
12+
import com.nextcloud.android.common.core.R
13+
import org.junit.Assert.assertEquals
14+
import org.junit.Before
15+
import org.junit.Test
16+
import org.junit.runner.RunWith
17+
import org.robolectric.RobolectricTestRunner
18+
import org.robolectric.annotation.Config
19+
import java.text.SimpleDateFormat
20+
import java.util.Calendar
21+
import java.util.Locale
22+
23+
@RunWith(RobolectricTestRunner::class)
24+
@Config(sdk = [Build.VERSION_CODES.Q])
25+
class FormatterTest {
26+
private lateinit var dateFormatter: DateFormatter
27+
private lateinit var context: Context
28+
29+
@Before
30+
fun setUp() {
31+
context = ApplicationProvider.getApplicationContext()
32+
// Force a specific locale to make tests independent of the test environment's locale
33+
val config = context.resources.configuration
34+
config.setLocale(Locale.US)
35+
val localizedContext = context.createConfigurationContext(config)
36+
dateFormatter = DateFormatter(context)
37+
}
38+
39+
@Test
40+
fun `Test 'now' formatting`() {
41+
val calendar = Calendar.getInstance()
42+
val formattedDate = dateFormatter.getConditionallyRelativeFormattedTimeSpan(calendar)
43+
val expected = context.getString(R.string.date_formatting_now)
44+
assertEquals(expected, formattedDate)
45+
}
46+
47+
@Test
48+
fun `Test relative minutes formatting`() {
49+
val calendar = Calendar.getInstance()
50+
calendar.add(Calendar.MINUTE, -5)
51+
val formattedDate = dateFormatter.getConditionallyRelativeFormattedTimeSpan(calendar)
52+
val expected = context.getString(R.string.date_formatting_relative_minutes, 5)
53+
assertEquals(expected, formattedDate)
54+
}
55+
56+
@Test
57+
fun `Test relative hours formatting`() {
58+
val calendar = Calendar.getInstance()
59+
calendar.add(Calendar.HOUR, -3)
60+
val formattedDate = dateFormatter.getConditionallyRelativeFormattedTimeSpan(calendar)
61+
val expected = context.resources.getQuantityString(R.plurals.date_formatting_relative_hours, 3, 3)
62+
assertEquals(expected, formattedDate)
63+
}
64+
65+
@Test
66+
fun `Test day of the week formatting`() {
67+
val calendar = Calendar.getInstance()
68+
calendar.add(Calendar.DAY_OF_YEAR, -4)
69+
val sdf = SimpleDateFormat("EEE", Locale.US)
70+
val expected = sdf.format(calendar.time)
71+
val formattedDate = dateFormatter.getConditionallyRelativeFormattedTimeSpan(calendar)
72+
assertEquals(expected, formattedDate)
73+
}
74+
75+
@Test
76+
fun `Test month and day formatting`() {
77+
val calendar = Calendar.getInstance()
78+
calendar.add(Calendar.DAY_OF_YEAR, -100)
79+
val sdf = SimpleDateFormat("MMM d", Locale.US)
80+
val expected = sdf.format(calendar.time)
81+
val formattedDate = dateFormatter.getConditionallyRelativeFormattedTimeSpan(calendar)
82+
assertEquals(expected, formattedDate)
83+
}
84+
85+
@Test
86+
fun `Test full date formatting`() {
87+
val calendar = Calendar.getInstance()
88+
calendar.add(Calendar.YEAR, -2)
89+
val sdf = SimpleDateFormat("MMM d, yyyy", Locale.US)
90+
val expected = sdf.format(calendar.time)
91+
val formattedDate = dateFormatter.getConditionallyRelativeFormattedTimeSpan(calendar)
92+
assertEquals(expected, formattedDate)
93+
}
94+
}

0 commit comments

Comments
 (0)