Tests merge #8

Open
vantablackTea wants to merge 12 commits from tests-branch into main
2 changed files with 185 additions and 0 deletions
Showing only changes of commit c6f280ff72 - Show all commits
@@ -0,0 +1,21 @@
package agzam.vyatsu.data.remote.pdf
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class PdfDumpTest {
@Test
fun dumpParsedSchedule() {
val instrumentation = InstrumentationRegistry.getInstrumentation()
val bytes = instrumentation.context.assets.open("schedule.pdf").use { it.readBytes() }
val days = PdfScheduleParser.parse(bytes)
val target = instrumentation.targetContext.getExternalFilesDir(null)!!.resolve("parsed.txt")
target.writeText(days.joinToString(separator = "\n"))
}
}
@@ -0,0 +1,164 @@
package agzam.vyatsu.data.remote.pdf
import agzam.vyatsu.domain.model.Day
import agzam.vyatsu.domain.model.Lesson
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import java.time.LocalDate
import java.time.LocalTime
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class PdfScheduleParserTest {
companion object {
private val days: List<Day> by lazy {
val bytes = InstrumentationRegistry.getInstrumentation().context.assets
.open("schedule.pdf")
.use { it.readBytes() }
PdfScheduleParser.parse(bytes)
}
}
private fun day(date: String): Day = days.first { it.date == LocalDate.parse(date) }
private fun lessons(date: String, start: String): List<Lesson> =
day(date).intervals
.first { it.start == LocalTime.parse(start) }
.lessons
.filter { it.raw.isNotBlank() }
private fun allLessons(date: String): List<Lesson> =
day(date).intervals.flatMap { it.lessons }.filter { it.raw.isNotBlank() }
private fun Lesson.canonical(): String =
listOf(subject, type.name, room, teacher, subgroup).joinToString("|")
@Test
fun parsesWholeTwoWeekPeriod() {
val expectedDates = (0..13L).map { LocalDate.of(2026, 9, 14).plusDays(it) }
assertEquals(expectedDates, days.map { it.date })
}
@Test
fun everyDayHasSevenStandardIntervals() {
val expectedTimes = listOf(
LocalTime.of(8, 20) to LocalTime.of(9, 50),
LocalTime.of(10, 0) to LocalTime.of(11, 30),
LocalTime.of(11, 45) to LocalTime.of(13, 15),
LocalTime.of(14, 0) to LocalTime.of(15, 30),
LocalTime.of(15, 45) to LocalTime.of(17, 15),
LocalTime.of(17, 20) to LocalTime.of(18, 50),
LocalTime.of(18, 55) to LocalTime.of(20, 25)
)
for (day in days) {
assertEquals(day.date.toString(), expectedTimes, day.intervals.map { it.start to it.end })
}
}
@Test
fun emptyDaysHaveNoLessons() {
val emptyDays = listOf("2026-09-14", "2026-09-19", "2026-09-20", "2026-09-26", "2026-09-27")
for (date in emptyDays) {
assertEquals(date, emptyList<Lesson>(), allLessons(date))
}
}
@Test
fun parsesTwoLecturesInOneSlot() {
assertEquals(
listOf(
"Объектно-ориентированный анализ и проектирование|LECTURE|2-202|Преподаватель -.П.|null",
"Разработка Web-приложений|LECTURE|1-236|Преподаватель -.П.|null"
),
lessons("2026-09-15", "10:00").map { it.canonical() }
)
}
@Test
fun parsesThreeLecturesInOneSlot() {
assertEquals(
listOf(
"Инструментальные средства проектирования компонентов вычислительной техники|LECTURE|2-201|Семеновых В.И.|null",
"Предметно-ориентированные автоматизированные информационные системы|LECTURE|1-313|Прозорова Ю.А.|null",
"Сценарное и функциональное программирование|LECTURE|1-311|Преподаватель -.П.|null"
),
lessons("2026-09-15", "11:45").map { it.canonical() }
)
}
@Test
fun parsesLaboratoryWork() {
assertEquals(
listOf(
"Инструментальные средства проектирования компонентов вычислительной техники|LABORATORY|2-201|Семеновых В.И.|null",
"Предметно-ориентированные автоматизированные информационные системы|LABORATORY|1-236|Прозорова Ю.А.|null",
"Сценарное и функциональное программирование|LABORATORY|1-114|Преподаватель -.П.|null"
),
lessons("2026-09-15", "14:00").map { it.canonical() }
)
}
@Test
fun parsesWednesdayLectures() {
assertEquals(
listOf("Введение в архитектуру ЭВМ|LECTURE|1-242|Страбыкин Д.А.|null"),
lessons("2026-09-16", "08:20").map { it.canonical() }
)
assertEquals(
listOf("Теория компиляторов и формальные грамматики|LECTURE|1-242|Мельцов В.Ю.|null"),
lessons("2026-09-16", "10:00").map { it.canonical() }
)
}
@Test
fun parsesPhysicalEducationSubgroups() {
val parsed = lessons("2026-09-17", "11:45").filter { it.room != null }
assertEquals(
listOf(
"Элективные дисциплины (модули) по физической культуре и спорту|PRACTICE|9-115|Трушкова Е.Л.|01 подгруппа",
"Элективные дисциплины (модули) по физической культуре и спорту|PRACTICE|9-301|Салопин О.М.|01 подгруппа",
"Элективные дисциплины (модули) по физической культуре и спорту|PRACTICE|9-301|Салопин О.М.|02 подгруппа"
),
parsed.map { it.canonical() }
)
}
@Test
fun keepsRawTextWhenRoomHasTrailingPunctuation() {
val unparsed = lessons("2026-09-17", "11:45").filter { it.room == null }
assertEquals(2, unparsed.size)
assertTrue(unparsed.any { it.raw.contains("9-209.") })
assertTrue(unparsed.any { it.raw.contains("9-208__") })
}
@Test
fun parsesFridaySubgroupLaboratories() {
assertEquals(
listOf(
"Введение в архитектуру ЭВМ|LABORATORY|1-117|Страбыкин Д.А.|01 подгруппа",
"Введение в архитектуру ЭВМ|LABORATORY|1-117_|Страбыкин Д.А.|02 подгруппа"
),
lessons("2026-09-18", "08:20").map { it.canonical() }
)
}
@Test
fun parsesSecondWeekMondayLaboratories() {
assertEquals(
listOf(
"Теория компиляторов и формальные грамматики|LABORATORY|2-308|Караваева О.В.|01 подгруппа",
"Теория компиляторов и формальные грамматики|LABORATORY|2-308_|Караваева О.В.|02 подгруппа"
),
lessons("2026-09-21", "10:00").map { it.canonical() }
)
}
}