Skip to content

Commit 855491c

Browse files
authored
Merge pull request #319 from bitfireAT/ical4j-3to4
Merge ical4j-3to4 into main branch
2 parents ee3e63b + 70837ab commit 855491c

137 files changed

Lines changed: 5316 additions & 4178 deletions

File tree

Some content is hidden

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

gradle/libs.versions.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ androidx-test-runner = "1.7.0"
88
dokka = "2.2.0"
99
ezvcard = "0.12.2"
1010
guava = "33.5.0-android"
11-
# noinspection NewerVersionAvailable
12-
ical4j = "3.2.19" # final version; update to 4.x will require much work
11+
ical4j = "4.2.5"
1312
junit = "4.13.2"
1413
kotlin = "2.3.20"
1514
kotlinx-coroutines-test = "1.10.2"

lib/build.gradle.kts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,4 +148,12 @@ dependencies {
148148
testImplementation(libs.kotlin.coroutines.test)
149149
testImplementation(libs.mockk)
150150
testImplementation(libs.roboelectric)
151-
}
151+
}
152+
153+
tasks.withType<Test>().configureEach {
154+
options {
155+
// Prevent Robolectric from instrumenting ical4j classes to avoid problems with registering
156+
// ical4j's ZoneRulesProviderImpl more than once with Java's ZoneRulesProvider.
157+
systemProperty("org.robolectric.packagesToNotAcquire", "net.fortuna.ical4j")
158+
}
159+
}

lib/consumer-rules.pro

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,6 @@
1010
-dontwarn org.codehaus.groovy.**
1111
-dontwarn org.jparsec.**
1212

13-
# keep to be used by ical4j
14-
-keep class at.bitfire.ical4android.AndroidCompatTimeZoneRegistry { *; }
15-
-keep class at.bitfire.ical4android.AndroidCompatTimeZoneRegistry$Factory { *; }
16-
1713
# keep all vCard properties/parameters (used via reflection)
1814
-keep class ezvcard.io.scribe.** { *; }
1915
-keep class ezvcard.property.** { *; }

lib/src/androidTest/kotlin/at/bitfire/ical4android/AndroidCompatTimeZoneRegistryTest.kt

Lines changed: 0 additions & 100 deletions
This file was deleted.

lib/src/androidTest/kotlin/at/bitfire/ical4android/AndroidTimeZonesTest.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ package at.bitfire.ical4android
99
import net.fortuna.ical4j.model.TimeZoneRegistryFactory
1010
import org.junit.Assert
1111
import org.junit.Assert.assertNotNull
12+
import org.junit.Ignore
1213
import org.junit.Test
1314
import java.time.ZoneId
1415
import java.time.format.TextStyle

lib/src/androidTest/kotlin/at/bitfire/ical4android/DmfsStyleProvidersTaskTest.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
package at.bitfire.ical4android
88

9+
import android.os.Build
910
import androidx.test.platform.app.InstrumentationRegistry
1011
import at.bitfire.synctools.test.GrantPermissionOrSkipRule
1112
import org.junit.After
@@ -25,7 +26,13 @@ abstract class DmfsStyleProvidersTaskTest(
2526
companion object {
2627
@Parameterized.Parameters(name="{0}")
2728
@JvmStatic
28-
fun taskProviders() = listOf(TaskProvider.ProviderName.OpenTasks,TaskProvider.ProviderName.TasksOrg)
29+
fun taskProviders() = buildList {
30+
add(TaskProvider.ProviderName.OpenTasks)
31+
32+
// tasks.org requires Android 8
33+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
34+
add(TaskProvider.ProviderName.TasksOrg)
35+
}
2936
}
3037

3138
@get:Rule

lib/src/androidTest/kotlin/at/bitfire/ical4android/DmfsTaskTest.kt

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import androidx.core.content.contentValuesOf
1313
import at.bitfire.ical4android.impl.TestTaskList
1414
import at.bitfire.synctools.storage.LocalStorageException
1515
import at.bitfire.synctools.storage.tasks.DmfsTaskList
16-
import net.fortuna.ical4j.model.Date
1716
import net.fortuna.ical4j.model.TimeZoneRegistryFactory
1817
import net.fortuna.ical4j.model.component.VAlarm
1918
import net.fortuna.ical4j.model.parameter.RelType
@@ -31,6 +30,8 @@ import org.junit.Assert.assertFalse
3130
import org.junit.Assert.assertNotNull
3231
import org.junit.Before
3332
import org.junit.Test
33+
import java.time.LocalDate
34+
import java.time.ZonedDateTime
3435

3536
class DmfsTaskTest(
3637
providerName: TaskProvider.ProviderName
@@ -87,18 +88,27 @@ class DmfsTaskTest(
8788
task.summary = "Sample event"
8889
task.description = "Sample event with date/time"
8990
task.location = "Sample location"
90-
task.dtStart = DtStart("20150501T120000", tzVienna)
91-
task.due = Due("20150501T140000", tzVienna)
91+
task.dtStart = DtStart(ZonedDateTime.of(
92+
2015, 5, 1,
93+
12, 0, 0, 0,
94+
tzVienna.toZoneId()
95+
))
96+
task.due = Due(ZonedDateTime.of(
97+
2015, 5, 1,
98+
14, 0, 0, 0,
99+
tzVienna.toZoneId()
100+
))
92101
task.organizer = Organizer("mailto:organizer@example.com")
93102
assertFalse(task.isAllDay())
94103

95104
// extended properties
96105
task.categories.addAll(arrayOf("Cat1", "Cat2"))
97106
task.comment = "A comment"
98107

99-
val sibling = RelatedTo("most-fields2@example.com")
100-
sibling.parameters.add(RelType.SIBLING)
101-
task.relatedTo.add(sibling)
108+
task.relatedTo.add(
109+
RelatedTo("most-fields2@example.com")
110+
.add(RelType.SIBLING)
111+
)
102112

103113
task.unknownProperties += XProperty("X-UNKNOWN-PROP", "Unknown Value")
104114

@@ -133,9 +143,9 @@ class DmfsTaskTest(
133143
val task = Task()
134144
task.uid = "invalidDUE@ical4android.tests"
135145
task.summary = "Task with invalid DUE"
136-
task.dtStart = DtStart(Date("20150102"))
146+
task.dtStart = DtStart(LocalDate.of(2015, 1, 2))
137147

138-
task.due = Due(Date("20150101"))
148+
task.due = Due(LocalDate.of(2015, 1, 1))
139149
DmfsTask(taskList!!, task, "9468a4cf-0d5b-4379-a704-12f1f84100ba", null, 0).add()
140150
}
141151

@@ -144,7 +154,7 @@ class DmfsTaskTest(
144154
val task = Task()
145155
task.uid = "TaskWithManyAlarms"
146156
task.summary = "Task with many alarms"
147-
task.dtStart = DtStart(Date("20150102"))
157+
task.dtStart = DtStart(LocalDate.of(2015, 1, 2))
148158

149159
for (i in 1..1050)
150160
task.alarms += VAlarm(java.time.Duration.ofMinutes(i.toLong()))
@@ -162,7 +172,11 @@ class DmfsTaskTest(
162172
task.summary = "Sample event"
163173
task.description = "Sample event with date/time"
164174
task.location = "Sample location"
165-
task.dtStart = DtStart("20150501T120000", tzVienna)
175+
task.dtStart = DtStart(ZonedDateTime.of(
176+
2015, 5, 1,
177+
12, 0, 0, 0,
178+
tzVienna.toZoneId()
179+
))
166180
assertFalse(task.isAllDay())
167181
val uri = DmfsTask(taskList!!, task, "9468a4cf-0d5b-4379-a704-12f1f84100ba", null, 0).add()
168182
assertNotNull(uri)

lib/src/androidTest/kotlin/at/bitfire/ical4android/JtxICalObjectTest.kt

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import androidx.core.content.pm.PackageInfoCompat
1515
import androidx.test.platform.app.InstrumentationRegistry
1616
import at.bitfire.ical4android.impl.TestJtxCollection
1717
import at.bitfire.ical4android.impl.testProdId
18-
18+
import at.bitfire.synctools.icalendar.ICalendarParser
1919
import at.bitfire.synctools.test.GrantPermissionOrSkipRule
2020
import at.techbee.jtx.JtxContract
2121
import at.techbee.jtx.JtxContract.JtxICalObject
@@ -35,6 +35,8 @@ import org.junit.Rule
3535
import org.junit.Test
3636
import java.io.ByteArrayOutputStream
3737
import java.io.InputStreamReader
38+
import java.io.StringReader
39+
import kotlin.jvm.optionals.getOrNull
3840

3941
class JtxICalObjectTest {
4042

@@ -809,6 +811,7 @@ class JtxICalObjectTest {
809811
@Test fun check_input_equals_output_vtodo_rfc5545_sample() = compare_properties("jtx/vtodo/rfc5545-sample1.ics", null)
810812
@Test fun check_input_equals_output_vtodo_empty_priority() = compare_properties("jtx/vtodo/empty-priority.ics", null)
811813
@Test fun check_input_equals_output_vtodo_latin1() = compare_properties("jtx/vtodo/latin1.ics", null)
814+
@Test fun check_input_equals_output_vtodo_attach() = compare_properties("jtx/vtodo/attach.ics", null)
812815

813816
// VJOURNAL
814817
@Test fun check_input_equals_output_vjournal_default_example() = compare_properties("jtx/vjournal/default-example.ics", null)
@@ -824,6 +827,32 @@ class JtxICalObjectTest {
824827
//@Test fun check_input_equals_output_vjournal_dst_only_vtimezone() = compare_properties("jtx/vjournal/dst-only-vtimezone.ics", null) // includes custom timezones, ignored for now
825828
@Test fun check_input_equals_output_vjournal_all_day() = compare_properties("jtx/vjournal/all-day.ics", null)
826829

830+
831+
@Test
832+
fun fromReader_should_set_recurid_values() {
833+
val ical = """
834+
BEGIN:VCALENDAR
835+
PRODID:irrelevant
836+
VERSION:2.0
837+
BEGIN:VTODO
838+
SUMMARY:Test Task (Exception)
839+
DTSTAMP:20250228T032800Z
840+
DUE;TZID=America/New_York:20250228T130000
841+
RECURRENCE-ID;TZID=America/New_York:20250228T130000
842+
UID:47a23c66-8c1a-4b44-bbe8-ebf33f8cf80f
843+
END:VTODO
844+
END:VCALENDAR
845+
""".trimIndent()
846+
val reader = StringReader(ical)
847+
848+
val iCalObjects = at.bitfire.ical4android.JtxICalObject.fromReader(reader, collection!!)
849+
850+
assertEquals(1, iCalObjects.size)
851+
assertEquals("20250228T130000", iCalObjects.first().recurid)
852+
assertEquals("America/New_York", iCalObjects.first().recuridTimezone)
853+
}
854+
855+
827856
/**
828857
* This function takes a file asserts if the ICalendar is the same before and after processing with getIncomingIcal and getOutgoingIcal
829858
* @param filename the filename to be processed
@@ -837,13 +866,13 @@ class JtxICalObjectTest {
837866
//assertEquals(iCalIn.components[0].getProperty(Component.VTODO), iCalOut.components[0].getProperty(Component.VTODO))
838867

839868
// there should only be one component for VJOURNAL and VTODO!
840-
for(i in 0 until iCalIn.components.size) {
869+
for(i in 0 until iCalIn.componentList.all.size) {
841870

842-
iCalIn.components[i].properties.forEach { inProp ->
871+
iCalIn.componentList.all[i].propertyList.all.forEach { inProp ->
843872

844873
if(inProp.name == "DTSTAMP" || exceptions?.contains(inProp.name) == true)
845874
return@forEach
846-
val outProp = iCalOut.components[i].properties.getProperty<Property>(inProp.name)
875+
val outProp = iCalOut.componentList.all[i].propertyList.getFirst<Property>(inProp.name)?.getOrNull()
847876
assertEquals(inProp, outProp)
848877
}
849878
}
@@ -860,7 +889,7 @@ class JtxICalObjectTest {
860889
val stream = javaClass.classLoader!!.getResourceAsStream(filename)
861890
val reader = InputStreamReader(stream, Charsets.UTF_8)
862891

863-
val iCalIn = ICalendar.fromReader(reader)
892+
val iCalIn = ICalendarParser().parse(reader)
864893

865894
stream.close()
866895
reader.close()
@@ -884,7 +913,7 @@ class JtxICalObjectTest {
884913

885914
iCalObject[0].write(os, testProdId)
886915

887-
val iCalOut = ICalendar.fromReader(os.toByteArray().inputStream().reader())
916+
val iCalOut = ICalendarParser().parse(os.toByteArray().inputStream().reader())
888917

889918
stream.close()
890919
reader.close()

lib/src/androidTest/kotlin/at/bitfire/ical4android/impl/TestCalendar.kt

Lines changed: 0 additions & 36 deletions
This file was deleted.

0 commit comments

Comments
 (0)