Skip to content

Commit 78f1f6f

Browse files
authored
Move validation classes, make them non-static and adapt tests (#37)
1 parent a9ac952 commit 78f1f6f

File tree

13 files changed

+92
-57
lines changed

13 files changed

+92
-57
lines changed

lib/src/main/kotlin/at/bitfire/ical4android/Event.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ data class Event(
243243
get() = Logger.getLogger(Event::class.java.name)
244244

245245
/**
246-
* Parses an iCalendar resource, applies [at.bitfire.ical4android.validation.ICalPreprocessor]
246+
* Parses an iCalendar resource, applies [at.bitfire.synctools.icalendar.validation.ICalPreprocessor]
247247
* and [EventValidator] to increase compatibility and extracts the VEVENTs.
248248
*
249249
* @param reader where the iCalendar is read from

lib/src/main/kotlin/at/bitfire/ical4android/ICalendar.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
package at.bitfire.ical4android
88

99
import at.bitfire.ical4android.ICalendar.Companion.CALENDAR_NAME
10-
import at.bitfire.ical4android.validation.ICalPreprocessor
1110
import at.bitfire.synctools.BuildConfig
1211
import at.bitfire.synctools.exception.InvalidRemoteResourceException
1312
import at.bitfire.synctools.icalendar.ICalendarParser
13+
import at.bitfire.synctools.icalendar.validation.ICalPreprocessor
1414
import net.fortuna.ical4j.data.CalendarBuilder
1515
import net.fortuna.ical4j.data.ParserException
1616
import net.fortuna.ical4j.model.Calendar

lib/src/main/kotlin/at/bitfire/ical4android/Task.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ data class Task(
100100
get() = Logger.getLogger(Task::class.java.name)
101101

102102
/**
103-
* Parses an iCalendar resource, applies [at.bitfire.ical4android.validation.ICalPreprocessor] to increase compatibility
103+
* Parses an iCalendar resource, applies [at.bitfire.synctools.icalendar.validation.ICalPreprocessor] to increase compatibility
104104
* and extracts the VTODOs.
105105
*
106106
* @param reader where the iCalendar is taken from

lib/src/main/kotlin/at/bitfire/synctools/icalendar/ICalendarParser.kt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77
package at.bitfire.synctools.icalendar
88

9-
import at.bitfire.ical4android.validation.ICalPreprocessor
109
import at.bitfire.synctools.exception.InvalidRemoteResourceException
10+
import at.bitfire.synctools.icalendar.validation.ICalPreprocessor
1111
import net.fortuna.ical4j.data.CalendarBuilder
1212
import net.fortuna.ical4j.data.CalendarParserFactory
1313
import net.fortuna.ical4j.data.ContentHandlerContext
@@ -20,8 +20,12 @@ import java.util.logging.Logger
2020

2121
/**
2222
* Custom iCalendar parser that applies error correction using [ICalPreprocessor].
23+
*
24+
* @param preprocessor pre-processor to use
2325
*/
24-
class ICalendarParser {
26+
class ICalendarParser(
27+
private val preprocessor: ICalPreprocessor = ICalPreprocessor()
28+
) {
2529

2630
private val logger
2731
get() = Logger.getLogger(javaClass.name)
@@ -39,7 +43,7 @@ class ICalendarParser {
3943
*/
4044
fun parse(reader: Reader): Calendar {
4145
// preprocess stream to work around problems that prevent parsing and thus can't be fixed later
42-
val preprocessed = ICalPreprocessor.preprocessStream(reader)
46+
val preprocessed = preprocessor.preprocessStream(reader)
4347

4448
// parse stream, ignoring invalid properties (if possible)
4549
val calendar: Calendar
@@ -57,7 +61,7 @@ class ICalendarParser {
5761

5862
// Pre-process calendar for increased compatibility (fixes some common errors)
5963
try {
60-
ICalPreprocessor.preprocessCalendar(calendar)
64+
preprocessor.preprocessCalendar(calendar)
6165
} catch (e: Exception) {
6266
logger.log(Level.WARNING, "Couldn't pre-process iCalendar", e)
6367
}

lib/src/main/kotlin/at/bitfire/ical4android/validation/FixInvalidDayOffsetPreprocessor.kt renamed to lib/src/main/kotlin/at/bitfire/synctools/icalendar/validation/FixInvalidDayOffsetPreprocessor.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
* SPDX-License-Identifier: GPL-3.0-or-later
55
*/
66

7-
package at.bitfire.ical4android.validation
7+
package at.bitfire.synctools.icalendar.validation
88

99
/**
1010
* Fixes durations with day offsets with the 'T' prefix.
1111
* See also https://github.com/bitfireAT/ical4android/issues/77
1212
*/
13-
object FixInvalidDayOffsetPreprocessor : StreamPreprocessor() {
13+
class FixInvalidDayOffsetPreprocessor : StreamPreprocessor() {
1414

1515
override fun regexpForProblem() = Regex(
1616
// Examples:

lib/src/main/kotlin/at/bitfire/ical4android/validation/FixInvalidUtcOffsetPreprocessor.kt renamed to lib/src/main/kotlin/at/bitfire/synctools/icalendar/validation/FixInvalidUtcOffsetPreprocessor.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@
44
* SPDX-License-Identifier: GPL-3.0-or-later
55
*/
66

7-
package at.bitfire.ical4android.validation
7+
package at.bitfire.synctools.icalendar.validation
88

9-
import at.bitfire.ical4android.validation.FixInvalidUtcOffsetPreprocessor.TZOFFSET_REGEXP
109
import java.util.logging.Level
1110
import java.util.logging.Logger
1211

@@ -17,7 +16,7 @@ import java.util.logging.Logger
1716
* Rewrites values of all TZOFFSETFROM and TZOFFSETTO properties which match [TZOFFSET_REGEXP]
1817
* so that an hour value of 00 is inserted.
1918
*/
20-
object FixInvalidUtcOffsetPreprocessor: StreamPreprocessor() {
19+
class FixInvalidUtcOffsetPreprocessor: StreamPreprocessor() {
2120

2221
private val logger
2322
get() = Logger.getLogger(javaClass.name)

lib/src/main/kotlin/at/bitfire/ical4android/validation/ICalPreprocessor.kt renamed to lib/src/main/kotlin/at/bitfire/synctools/icalendar/validation/ICalPreprocessor.kt

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
* SPDX-License-Identifier: GPL-3.0-or-later
55
*/
66

7-
package at.bitfire.ical4android.validation
7+
package at.bitfire.synctools.icalendar.validation
88

9+
import androidx.annotation.VisibleForTesting
910
import net.fortuna.ical4j.model.Calendar
1011
import net.fortuna.ical4j.model.Property
1112
import net.fortuna.ical4j.transform.rfc5545.CreatedPropertyRule
@@ -24,7 +25,7 @@ import java.util.logging.Logger
2425
* (like "W. Europe Standard Time" to an Android-friendly name like "Europe/Vienna")
2526
*
2627
*/
27-
object ICalPreprocessor {
28+
class ICalPreprocessor {
2829

2930
private val propertyRules = arrayOf(
3031
CreatedPropertyRule(), // make sure CREATED is UTC
@@ -33,9 +34,10 @@ object ICalPreprocessor {
3334
DateListPropertyRule() // ... by the ical4j VTIMEZONE with the same TZID!
3435
)
3536

36-
private val streamPreprocessors = arrayOf(
37-
FixInvalidUtcOffsetPreprocessor, // fix things like TZOFFSET(FROM,TO):+5730
38-
FixInvalidDayOffsetPreprocessor // fix things like DURATION:PT2D
37+
@VisibleForTesting
38+
internal val streamPreprocessors = arrayOf(
39+
FixInvalidUtcOffsetPreprocessor(), // fix things like TZOFFSET(FROM,TO):+5730
40+
FixInvalidDayOffsetPreprocessor() // fix things like DURATION:PT2D
3941
)
4042

4143
/**

lib/src/main/kotlin/at/bitfire/ical4android/validation/StreamPreprocessor.kt renamed to lib/src/main/kotlin/at/bitfire/synctools/icalendar/validation/StreamPreprocessor.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* SPDX-License-Identifier: GPL-3.0-or-later
55
*/
66

7-
package at.bitfire.ical4android.validation
7+
package at.bitfire.synctools.icalendar.validation
88

99
import java.io.IOException
1010
import java.io.Reader

lib/src/test/kotlin/at/bitfire/synctools/icalendar/ICalendarParserTest.kt

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,38 +6,54 @@
66

77
package at.bitfire.synctools.icalendar
88

9-
import at.bitfire.ical4android.validation.ICalPreprocessor
109
import at.bitfire.synctools.exception.InvalidRemoteResourceException
10+
import at.bitfire.synctools.icalendar.validation.ICalPreprocessor
11+
import io.mockk.every
12+
import io.mockk.impl.annotations.InjectMockKs
13+
import io.mockk.impl.annotations.RelaxedMockK
1114
import io.mockk.junit4.MockKRule
12-
import io.mockk.mockkObject
15+
import io.mockk.slot
1316
import io.mockk.verify
17+
import org.junit.Before
1418
import org.junit.Rule
1519
import org.junit.Test
20+
import java.io.Reader
1621
import java.io.StringReader
1722

1823
class ICalendarParserTest {
1924

2025
@get:Rule
2126
val mockkRule = MockKRule(this)
2227

28+
@RelaxedMockK
29+
lateinit var preprocessor: ICalPreprocessor
30+
31+
@InjectMockKs
32+
lateinit var parser: ICalendarParser
33+
34+
@Before
35+
fun setUp() {
36+
val reader = slot<Reader>()
37+
every { preprocessor.preprocessStream(capture(reader)) } answers { reader.captured }
38+
}
39+
40+
2341
@Test
2442
fun testParse_AppliesPreProcessing() {
25-
mockkObject(ICalPreprocessor)
26-
2743
val reader = StringReader(
2844
"BEGIN:VCALENDAR\r\n" +
2945
"BEGIN:VEVENT\r\n" +
3046
"END:VEVENT\r\n" +
3147
"END:VCALENDAR\r\n"
3248
)
33-
val cal = ICalendarParser().parse(reader)
49+
val cal = parser.parse(reader)
3450

3551
verify(exactly = 1) {
3652
// verify preprocessing was applied to stream
37-
ICalPreprocessor.preprocessStream(any())
53+
preprocessor.preprocessStream(any())
3854

3955
// verify preprocessing was applied to resulting calendar
40-
ICalPreprocessor.preprocessCalendar(cal)
56+
preprocessor.preprocessCalendar(cal)
4157
}
4258
}
4359

@@ -50,13 +66,14 @@ class ICalendarParserTest {
5066
"END:VEVENT\r\n" +
5167
"END:VCALENDAR\r\n"
5268
)
53-
ICalendarParser().parse(reader)
69+
parser.parse(reader)
70+
// no exception called
5471
}
5572

5673
@Test(expected = InvalidRemoteResourceException::class)
5774
fun testParse_ThrowsExceptionOnInvalidInput() {
5875
val reader = StringReader("invalid")
59-
ICalendarParser().parse(reader)
76+
parser.parse(reader)
6077
}
6178

6279
}

lib/src/test/kotlin/at/bitfire/ical4android/validation/FixInvalidDayOffsetPreprocessorTest.kt renamed to lib/src/test/kotlin/at/bitfire/synctools/icalendar/validation/FixInvalidDayOffsetPreprocessorTest.kt

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* SPDX-License-Identifier: GPL-3.0-or-later
55
*/
66

7-
package at.bitfire.ical4android.validation
7+
package at.bitfire.synctools.icalendar.validation
88

99
import org.junit.Assert.assertEquals
1010
import org.junit.Assert.assertFalse
@@ -13,17 +13,19 @@ import org.junit.Test
1313
import java.time.Duration
1414

1515
class FixInvalidDayOffsetPreprocessorTest {
16+
17+
private val processor = FixInvalidDayOffsetPreprocessor()
1618

1719
/**
18-
* Calls [FixInvalidDayOffsetPreprocessor.fixString] and asserts the result is equal to [expected].
20+
* Calls `processor.fixString` and asserts the result is equal to [expected].
1921
*
2022
* @param expected The expected result
2123
* @param testValue The value to test
2224
* @param parseDuration If `true`, [Duration.parse] is called on the fixed value to make sure it's a valid duration
2325
*/
2426
private fun assertFixedEquals(expected: String, testValue: String, parseDuration: Boolean = true) {
2527
// Fix the duration string
26-
val fixed = FixInvalidDayOffsetPreprocessor.fixString(testValue)
28+
val fixed = processor.fixString(testValue)
2729

2830
// Test the duration can now be parsed
2931
if (parseDuration)
@@ -40,7 +42,7 @@ class FixInvalidDayOffsetPreprocessorTest {
4042
fun test_FixString_NoOccurrence() {
4143
assertEquals(
4244
"Some String",
43-
FixInvalidDayOffsetPreprocessor.fixString("Some String"),
45+
processor.fixString("Some String"),
4446
)
4547
}
4648

@@ -99,14 +101,14 @@ class FixInvalidDayOffsetPreprocessorTest {
99101

100102
@Test
101103
fun test_RegexpForProblem_DayOffsetTo_Invalid() {
102-
val regex = FixInvalidDayOffsetPreprocessor.regexpForProblem()
104+
val regex = processor.regexpForProblem()
103105
assertTrue(regex.matches("DURATION:PT2D"))
104106
assertTrue(regex.matches("TRIGGER:PT1D"))
105107
}
106108

107109
@Test
108110
fun test_RegexpForProblem_DayOffsetTo_Valid() {
109-
val regex = FixInvalidDayOffsetPreprocessor.regexpForProblem()
111+
val regex = processor.regexpForProblem()
110112
assertFalse(regex.matches("DURATION:-PT12H"))
111113
assertFalse(regex.matches("TRIGGER:-PT15M"))
112114
}

0 commit comments

Comments
 (0)