Skip to content

Commit 5435ee4

Browse files
Merge pull request #772 from nextcloud/test-wip
Add date formatter tests
2 parents 8426233 + 38bb443 commit 5435ee4

File tree

7 files changed

+2570
-28
lines changed

7 files changed

+2570
-28
lines changed

.github/workflows/testing.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
2+
# SPDX-License-Identifier: MIT
3+
4+
name: Android Tests
5+
6+
on:
7+
pull_request:
8+
push:
9+
branches: [ main, stable-* ]
10+
11+
permissions:
12+
contents: read
13+
14+
jobs:
15+
validation:
16+
name: Validate Gradle Wrapper
17+
runs-on: ubuntu-latest
18+
steps:
19+
- name: Checkout
20+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
21+
- uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
22+
with:
23+
distribution: 'temurin'
24+
java-version: '17'
25+
check-latest: true
26+
cache: 'gradle'
27+
- name: Validate Gradle Wrapper
28+
uses: gradle/actions/wrapper-validation@ed408507eac070d1f99cc633dbcf757c94c7933a # v4.4.3
29+
30+
test:
31+
name: Unit tests
32+
runs-on: ubuntu-latest
33+
steps:
34+
- name: Checkout
35+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
36+
- uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
37+
with:
38+
distribution: 'temurin'
39+
java-version: '17'
40+
check-latest: true
41+
cache: 'gradle'
42+
- name: Unit tests
43+
run: bash ./gradlew test --stacktrace --no-configuration-cache

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: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ android {
2121
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
2222
}
2323

24+
testOptions {
25+
unitTests {
26+
includeAndroidResources = true
27+
}
28+
}
29+
2430
compileOptions {
2531
sourceCompatibility JavaVersion.VERSION_17
2632
targetCompatibility JavaVersion.VERSION_17
@@ -41,9 +47,15 @@ dependencies {
4147
implementation 'androidx.core:core-ktx:1.16.0'
4248
implementation 'androidx.appcompat:appcompat:1.7.1'
4349
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'
50+
51+
testImplementation "junit:junit:$jUnitVersion"
52+
testImplementation 'androidx.test:core:1.7.0'
53+
testImplementation 'org.robolectric:robolectric:4.16'
54+
testImplementation "org.mockito:mockito-core:$mockitoVersion"
55+
testImplementation "org.mockito.kotlin:mockito-kotlin:$mockitoKotlinVersion"
56+
testImplementation "io.mockk:mockk:$mockkVersion"
57+
androidTestImplementation "androidx.test.ext:junit:$androidXTestVersion"
58+
androidTestImplementation "androidx.test.espresso:espresso-core:$androidXEspressoTestVersion"
4759
}
4860

4961
afterEvaluate {

core/src/main/java/com/nextcloud/android/common/core/utils/DateFormatter.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
/**
1+
/*
22
* Nextcloud Android Common Library
33
*
44
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
55
* SPDX-License-Identifier: MIT
66
*/
7+
78
package com.nextcloud.android.common.core.utils
89

910
import android.content.Context
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
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+
10+
import android.content.Context
11+
import android.os.Build
12+
import androidx.test.core.app.ApplicationProvider
13+
import com.nextcloud.android.common.core.R
14+
import org.junit.Assert.assertEquals
15+
import org.junit.Before
16+
import org.junit.Test
17+
import org.junit.runner.RunWith
18+
import org.robolectric.RobolectricTestRunner
19+
import org.robolectric.annotation.Config
20+
import java.text.SimpleDateFormat
21+
import java.util.Calendar
22+
import java.util.Locale
23+
24+
/**
25+
* DateFormatter tests checking the different formats relative/absolute date formatting.
26+
*/
27+
@RunWith(RobolectricTestRunner::class)
28+
@Config(sdk = [Build.VERSION_CODES.Q])
29+
class DateFormatterTest {
30+
private lateinit var dateFormatter: DateFormatter
31+
private lateinit var context: Context
32+
33+
@Before
34+
fun setUp() {
35+
context = ApplicationProvider.getApplicationContext()
36+
// Force a specific locale to make tests independent of the test environment's locale
37+
val config = context.resources.configuration
38+
config.setLocale(Locale.US)
39+
val localizedContext = context.createConfigurationContext(config)
40+
dateFormatter = DateFormatter(localizedContext)
41+
}
42+
43+
@Test
44+
fun `Test 'now' formatting`() {
45+
val calendar = Calendar.getInstance()
46+
val formattedDate = dateFormatter.getConditionallyRelativeFormattedTimeSpan(calendar)
47+
val expected = context.getString(R.string.date_formatting_now)
48+
assertEquals(expected, formattedDate)
49+
}
50+
51+
@Test
52+
fun `Test relative minutes formatting`() {
53+
val calendar = Calendar.getInstance()
54+
calendar.add(Calendar.MINUTE, -5)
55+
val formattedDate = dateFormatter.getConditionallyRelativeFormattedTimeSpan(calendar)
56+
val expected = context.getString(R.string.date_formatting_relative_minutes, 5)
57+
assertEquals(expected, formattedDate)
58+
}
59+
60+
@Test
61+
fun `Test relative hours formatting`() {
62+
val calendar = Calendar.getInstance()
63+
calendar.add(Calendar.HOUR, -3)
64+
val formattedDate = dateFormatter.getConditionallyRelativeFormattedTimeSpan(calendar)
65+
val expected = context.resources.getQuantityString(R.plurals.date_formatting_relative_hours, 3, 3)
66+
assertEquals(expected, formattedDate)
67+
}
68+
69+
@Test
70+
fun `Test day of the week formatting`() {
71+
val calendar = Calendar.getInstance()
72+
calendar.add(Calendar.DAY_OF_YEAR, -4)
73+
val sdf = SimpleDateFormat("EEE", Locale.US)
74+
val expected = sdf.format(calendar.time)
75+
val formattedDate = dateFormatter.getConditionallyRelativeFormattedTimeSpan(calendar)
76+
assertEquals(expected, formattedDate)
77+
}
78+
79+
@Test
80+
fun `Test month and day formatting`() {
81+
val calendar = Calendar.getInstance()
82+
calendar.add(Calendar.DAY_OF_YEAR, -100)
83+
val sdf = SimpleDateFormat("MMM d", Locale.US)
84+
val expected = sdf.format(calendar.time)
85+
val formattedDate = dateFormatter.getConditionallyRelativeFormattedTimeSpan(calendar)
86+
assertEquals(expected, formattedDate)
87+
}
88+
89+
@Test
90+
fun `Test full date formatting`() {
91+
val calendar = Calendar.getInstance()
92+
calendar.add(Calendar.YEAR, -2)
93+
val sdf = SimpleDateFormat("MMM d, yyyy", Locale.US)
94+
val expected = sdf.format(calendar.time)
95+
val formattedDate = dateFormatter.getConditionallyRelativeFormattedTimeSpan(calendar)
96+
assertEquals(expected, formattedDate)
97+
}
98+
}

0 commit comments

Comments
 (0)