Skip to content

Commit 17ca072

Browse files
committed
Move ICalPreprocessorInstrumentedTest to unit tests
1 parent 1f7298a commit 17ca072

File tree

2 files changed

+107
-118
lines changed

2 files changed

+107
-118
lines changed

lib/src/androidTest/kotlin/at/bitfire/synctools/icalendar/validation/ICalPreprocessorInstrumentedTest.kt

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

lib/src/test/kotlin/at/bitfire/synctools/icalendar/validation/ICalPreprocessorTest.kt

Lines changed: 107 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
package at.bitfire.synctools.icalendar.validation
88

9+
import com.google.common.io.CharStreams
910
import io.mockk.junit4.MockKRule
1011
import io.mockk.mockkObject
1112
import io.mockk.spyk
@@ -18,7 +19,10 @@ import org.junit.Assert.assertTrue
1819
import org.junit.Rule
1920
import org.junit.Test
2021
import java.io.InputStreamReader
22+
import java.io.Reader
2123
import java.io.StringReader
24+
import java.io.Writer
25+
import java.util.UUID
2226

2327
class ICalPreprocessorTest {
2428

@@ -27,20 +31,6 @@ class ICalPreprocessorTest {
2731

2832
val processor = ICalPreprocessor()
2933

30-
31-
@Test
32-
fun testPreprocessStream_runsApplyPreprocessors() {
33-
val processor = spyk<ICalPreprocessor>()
34-
35-
// readText MUST be called. Otherwise the sequence is never evaluated
36-
// there must be at least one line. Otherwise the sequence is empty
37-
processor.preprocessStream(StringReader("\n")).use { it.readText() }
38-
39-
// verify that applyPreprocessors has been called
40-
verify { processor.applyPreprocessors(any()) }
41-
}
42-
43-
4434
@Test
4535
fun testApplyPreprocessors_appliesStreamProcessors() {
4636
val preprocessors = processor.streamPreprocessors
@@ -59,7 +49,6 @@ class ICalPreprocessorTest {
5949
}
6050
}
6151

62-
6352
@Test
6453
fun testPreprocessCalendar_MsTimeZones() {
6554
javaClass.getResourceAsStream("/events/outlook1.ics").use { stream ->
@@ -73,4 +62,107 @@ class ICalPreprocessorTest {
7362
}
7463
}
7564

65+
@Test
66+
fun testPreprocessStream_runsApplyPreprocessors() {
67+
val processor = spyk<ICalPreprocessor>()
68+
69+
// readText MUST be called. Otherwise the sequence is never evaluated
70+
// there must be at least one line. Otherwise the sequence is empty
71+
processor.preprocessStream(StringReader("\n")).use { it.readText() }
72+
73+
// verify that applyPreprocessors has been called
74+
verify { processor.applyPreprocessors(any()) }
75+
}
76+
77+
@Test
78+
fun testPreprocessStream_LargeFiles() {
79+
val preprocessor = ICalPreprocessor()
80+
val reader = VCalendarReaderGenerator(eventCount = 10_000)
81+
preprocessor.preprocessStream(reader).use { preprocessed ->
82+
// consume preprocessed stream
83+
val start = System.currentTimeMillis()
84+
CharStreams.copy(preprocessed, Writer.nullWriter())
85+
val end = System.currentTimeMillis()
86+
87+
// no exception called
88+
System.err.println("testParse_SuperLargeFiles took ${(end - start) / 1000} seconds")
89+
}
90+
}
91+
92+
93+
/**
94+
* Reader that generates a number of VEVENTs for testing.
95+
*/
96+
private class VCalendarReaderGenerator(val eventCount: Int) : Reader() {
97+
private var stage = 0 // 0 = header, 1 = events, 2 = footer, 3 = done
98+
private var eventIdx = 0
99+
private var current: String? = null
100+
private var pos = 0
101+
102+
override fun reset() {
103+
stage = 0
104+
eventIdx = 0
105+
current = null
106+
pos = 0
107+
}
108+
109+
override fun read(cbuf: CharArray, off: Int, len: Int): Int {
110+
var charsRead = 0
111+
while (charsRead < len) {
112+
if (current == null || pos >= current!!.length) {
113+
current = when (stage) {
114+
0 -> {
115+
stage = 1
116+
"""
117+
BEGIN:VCALENDAR
118+
PRODID:-//xyz Corp//NONSGML PDA Calendar Version 1.0//EN
119+
VERSION:2.0
120+
""".trimIndent() + "\n"
121+
}
122+
1 -> {
123+
if (eventIdx < eventCount) {
124+
val event = """
125+
BEGIN:VEVENT
126+
DTSTAMP:19960704T120000Z
127+
UID:${UUID.randomUUID()}
128+
ORGANIZER:mailto:[email protected]
129+
DTSTART:19960918T143000Z
130+
DTEND:19960920T220000Z
131+
STATUS:CONFIRMED
132+
CATEGORIES:CONFERENCE
133+
SUMMARY:Event $eventIdx
134+
DESCRIPTION:Event $eventIdx description
135+
END:VEVENT
136+
""".trimIndent() + "\n"
137+
eventIdx++
138+
event
139+
} else {
140+
stage = 2
141+
null
142+
}
143+
}
144+
2 -> {
145+
stage = 3
146+
"END:VCALENDAR\n"
147+
}
148+
else -> return if (charsRead == 0) -1 else charsRead
149+
}
150+
pos = 0
151+
if (current == null) continue // move to next stage
152+
}
153+
val charsLeft = current!!.length - pos
154+
val toRead = minOf(len - charsRead, charsLeft)
155+
current!!.toCharArray(pos, pos + toRead).copyInto(cbuf, off + charsRead)
156+
pos += toRead
157+
charsRead += toRead
158+
}
159+
return charsRead
160+
}
161+
162+
override fun close() {
163+
// No resources to release
164+
current = null
165+
}
166+
}
167+
76168
}

0 commit comments

Comments
 (0)