forked from agzam/vyatsu-schedule
feat(remote): add streaming TeachersParser
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
package agzam.vyatsu
|
||||
|
||||
import agzam.vyatsu.data.remote.GroupsParser
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
|
||||
class GroupsPipelineMemoryTest {
|
||||
|
||||
@Test
|
||||
fun streamingUnderSmallHeap() {
|
||||
val fixture = checkNotNull(javaClass.getResourceAsStream("/groups.html")) {
|
||||
"Fixture groups.html not found in src/test/resources"
|
||||
}
|
||||
val result = fixture.use(GroupsParser::parseStream)
|
||||
assertTrue(result.groups.size > 400)
|
||||
assertTrue(result.groups.any { it.id == "26981" && it.name.contains("ПОДб-1701-08-00") })
|
||||
assertTrue(result.dateRanges.size > 400)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package agzam.vyatsu
|
||||
|
||||
import agzam.vyatsu.data.remote.TeachersParser
|
||||
import agzam.vyatsu.domain.model.DateRange
|
||||
import agzam.vyatsu.domain.model.Season
|
||||
import java.io.InputStream
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
|
||||
class TeachersPipelineMemoryTest {
|
||||
|
||||
private fun fixture(): InputStream =
|
||||
checkNotNull(javaClass.getResourceAsStream("/teacher.html")) {
|
||||
"Fixture teacher.html not found in src/test/resources"
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parsesDepartmentsAndFaculties() {
|
||||
val result = fixture().use(TeachersParser::parseStream)
|
||||
assertTrue("expected >=4 departments", result.departments.size >= 4)
|
||||
|
||||
val ids = result.departments.map { it.departmentId }.toSet()
|
||||
assertEquals(setOf("11111", "22222", "33333", "44444"), ids)
|
||||
|
||||
val names = result.departments.map { it.name }
|
||||
assertTrue(
|
||||
"nested tags must be stripped from kafPeriod names",
|
||||
names.contains("Кафедра технологий и конструирования машин и аппаратов")
|
||||
)
|
||||
|
||||
val avt = result.departments.first { it.departmentId == "11111" }
|
||||
assertTrue("faculty must be mapped via shortname", avt.faculty.contains("ФАВТ"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun chunkBoundarySafe() {
|
||||
val full = fixture().use(TeachersParser::parseStream)
|
||||
val limited = limitReads(fixture(), 64).use(TeachersParser::parseStream)
|
||||
assertEquals(full, limited)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun seasonAndRanges() {
|
||||
val result = fixture().use(TeachersParser::parseStream)
|
||||
|
||||
val hasAutumn = result.dateRanges.values.any { it[Season.AUTUMN]?.isNotEmpty() == true }
|
||||
val hasSpring = result.dateRanges.values.any { it[Season.SPRING]?.isNotEmpty() == true }
|
||||
assertTrue("AUTUMN season must be present", hasAutumn)
|
||||
assertTrue("SPRING season must be present", hasSpring)
|
||||
|
||||
val autumn = result.dateRanges["11111"]?.get(Season.AUTUMN).orEmpty()
|
||||
assertTrue(
|
||||
"DateRange must be parsed from URL groups",
|
||||
autumn.contains(DateRange("01092026", "13092026"))
|
||||
)
|
||||
assertTrue(
|
||||
"second AUTUMN range must be present",
|
||||
autumn.contains(DateRange("14092026", "27092026"))
|
||||
)
|
||||
|
||||
val spring = result.dateRanges["44444"]?.get(Season.SPRING).orEmpty()
|
||||
assertTrue(
|
||||
"SPRING DateRange must be parsed from URL groups",
|
||||
spring.contains(DateRange("02022026", "27022026"))
|
||||
)
|
||||
}
|
||||
|
||||
private fun limitReads(input: InputStream, maxBytes: Int): InputStream =
|
||||
object : InputStream() {
|
||||
override fun read(): Int = input.read()
|
||||
|
||||
override fun read(b: ByteArray, off: Int, len: Int): Int =
|
||||
input.read(b, off, minOf(len, maxBytes))
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,90 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="content-language" content="ru">
|
||||
<title>Расписание занятий преподавателей - Официальный сайт ВятГУ</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="headerEduPrograms">
|
||||
<div class="block-content">
|
||||
<h2>Планируемое расписание занятий преподавателей</h2>
|
||||
<div class="fak_name" data-fak_id="fak_avt_41"><span>Факультет автоматики</span> и вычислительной техники (ОРУ)</div>
|
||||
<div class="block-content" id="fak_avt_41" style="display: none;">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div
|
||||
class="kafPeriod"
|
||||
data-kaf_period_id="111111"
|
||||
>
|
||||
Кафедра алгоритмов и программ </div>
|
||||
<div
|
||||
class="listPeriod"
|
||||
id="listPeriod_111111"
|
||||
style="display: none;"
|
||||
>
|
||||
<a target="_blank" href="/reports/schedule/prepod/11111_1_01092026_13092026.html">с 01 09 2026 по 13 09 2026</a>
|
||||
<br/>
|
||||
<a target="_blank" href="/reports/schedule/prepod/11111_1_14092026_27092026.html">с 14 09 2026 по 27 09 2026</a>
|
||||
<br/>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div
|
||||
class="kafPeriod"
|
||||
data-kaf_period_id="222221"
|
||||
>
|
||||
Кафедра <b>технологий и конструирования</b> машин и аппаратов </div>
|
||||
<div
|
||||
class="listPeriod"
|
||||
id="listPeriod_222221"
|
||||
style="display: none;"
|
||||
>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="fak_name" data-fak_id="fak_phil_21"><b>Философский</b> факультет</div>
|
||||
<div class="block-content" id="fak_phil_21" style="display: none;">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="kafPeriod" data-kaf_period_id="333331">
|
||||
Кафедра философии </div>
|
||||
<div
|
||||
class="listPeriod"
|
||||
id="listPeriod_333331"
|
||||
style="display: none;"
|
||||
>
|
||||
<a target="_blank" href="/reports/schedule/prepod/33333_1_01092026_13092026.html">с 01 09 2026 по 13 09 2026</a>
|
||||
<br/>
|
||||
<a target="_blank" href="/reports/schedule/prepod/33333_1_14092026_27092026.html">с 14 09 2026 по 27 09 2026</a>
|
||||
<br/>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div
|
||||
class="kafPeriod"
|
||||
data-kaf_period_id="444441"
|
||||
>
|
||||
Кафедра логики и методологии науки </div>
|
||||
<div
|
||||
class="listPeriod"
|
||||
id="listPeriod_444441"
|
||||
style="display: none;"
|
||||
>
|
||||
<a target="_blank" href="/reports/schedule/prepod/44444_2_02022026_27022026.html">с 02 02 2027 по 27 02 2026</a>
|
||||
<br/>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user