feat(parser): update group parsing to handle special cases and improve regex patterns
feat(parser): enhance details extraction for lessons, including handling of subgroups and room moves feat(timetable): integrate room and teacher retrieval based on week context test(parser): add tests for group parsing with special characters and room move scenarios test(formats): implement tests for various lesson formats and their expected outputs feat(rooms): introduce room management functions for handling moves and week-based plans
This commit is contained in:
117
test/formats.test.js
Normal file
117
test/formats.test.js
Normal file
@@ -0,0 +1,117 @@
|
||||
import { test } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { groupsIn, alternatives, entries, details, leadingTime } from "../server/parser.js";
|
||||
import { roomMoves, weekPlan, onlyPlace } from "../server/rooms.js";
|
||||
import { peopleAndRooms, roomsOn, teachersOn, movedOn } from "../server/directory.js";
|
||||
|
||||
// Cell formats found by the catalog's diagnostics (October 2026).
|
||||
|
||||
test("Группы с направлением в скобках: 24-ИЯ (РА)и-1 … и-6 — разные группы", () => {
|
||||
assert.deepEqual(groupsIn("24-ИЯ (РА)и-1 | 24-ИЯ (РА)и-2 | 24-ИЯ (РА)и-3"), ["24-ИЯ (РА)и-1", "24-ИЯ (РА)и-2", "24-ИЯ (РА)и-3"]);
|
||||
assert.deepEqual(groupsIn("25 ИЯ (РА)и-1"), ["25-ИЯ (РА)и-1"]);
|
||||
assert.deepEqual(groupsIn("24-РГФи-1 26-ИТ-2"), ["24-РГФи-1", "26-ИТ-2"]);
|
||||
});
|
||||
|
||||
test("Перенос аудитории на дату, и с годом: «412н 26.10.2026-333»", () => {
|
||||
assert.deepEqual(roomMoves("Типология (л.) Полякова Г.В. 412н 26.10.2026-333", 2026).moves, [{ date: "2026-10-26", room: "333" }]);
|
||||
assert.deepEqual(roomMoves("Язык (п.з.) Горбач М.Н. 510н\n28.10.2026-504н", 2026).moves, [{ date: "2026-10-28", room: "504Н" }]);
|
||||
assert.deepEqual(roomMoves("ауд. 432 14.10. -ауд. 333", 2026).moves, [{ date: "2026-10-14", room: "333" }]);
|
||||
// The parser keeps the usual room; the move goes to that date only.
|
||||
const lesson = { raw: "Типология (л.) Полякова Г.В. 412н 26.10.2026-333", room: "412н", teacher: "Полякова Г.В." };
|
||||
const entry = peopleAndRooms(lesson, "2026");
|
||||
assert.deepEqual(roomsOn(entry, "2026-10-26"), ["333"]);
|
||||
assert.equal(movedOn(entry, "2026-10-26"), true);
|
||||
assert.deepEqual(roomsOn(entry, "2026-10-19"), ["412Н"]);
|
||||
assert.equal(movedOn(entry, "2026-10-19"), false);
|
||||
});
|
||||
|
||||
test("Строка с аудиторией по неделям продолжает занятие, а не становится новым", () => {
|
||||
const [one, ...rest] = entries("Язык профессионального общения (англ) (п.з.) Шабунина О.А.\n1-9н. 502н\nс 10н -359");
|
||||
assert.equal(rest.length, 0);
|
||||
assert.equal(details(one.main).subject, "Язык профессионального общения (англ)");
|
||||
assert.deepEqual(one.plan, [
|
||||
{ weeks: [[1, 9]], color: null, rooms: ["502Н"], teachers: [] },
|
||||
{ weeks: [[10, null]], color: null, rooms: ["359"], teachers: [] },
|
||||
]);
|
||||
const entry = peopleAndRooms({ raw: one.text, room: "", teacher: "Шабунина О.А.", plan: one.plan }, "2026");
|
||||
assert.deepEqual(roomsOn(entry, "2026-10-20", { n: 8, color: "green" }), ["502Н"]);
|
||||
assert.deepEqual(roomsOn(entry, "2026-11-03", { n: 10, color: "green" }), ["359"]);
|
||||
});
|
||||
|
||||
test("Преподаватель по неделям и аудитория по цвету недели", () => {
|
||||
const teachers = weekPlan("2-9н.-Клос О.Ю., 10-14н.-Конторов В.Э. 319Д");
|
||||
// The room at the end is the room of both parts.
|
||||
assert.deepEqual(teachers, [
|
||||
{ weeks: [[2, 9]], color: null, rooms: ["319Д"], teachers: ["Клос О.Ю."] },
|
||||
{ weeks: [[10, 14]], color: null, rooms: ["319Д"], teachers: ["Конторов В.Э."] },
|
||||
]);
|
||||
const entry = peopleAndRooms({ raw: "2-14н. История литературы (п.з.)\n2-9н.-Клос О.Ю., 10-14н.-Конторов В.Э. 319Д", room: "", teacher: "", plan: teachers }, "2026");
|
||||
assert.deepEqual(teachersOn(entry, { n: 3, color: "white" }), ["Клос О.Ю."]);
|
||||
assert.deepEqual(teachersOn(entry, { n: 12, color: "green" }), ["Конторов В.Э."]);
|
||||
|
||||
const [lesson] = entries("с 10н. Дискурсивная практика (рус) (п.з.) Булах А.С.\nбел.н.504н/зел.н.524н");
|
||||
const byColor = peopleAndRooms({ raw: lesson.text, room: "", teacher: "", plan: lesson.plan }, "2026");
|
||||
assert.deepEqual(roomsOn(byColor, "2026-11-10", { n: 11, color: "white" }), ["504Н"]);
|
||||
assert.deepEqual(roomsOn(byColor, "2026-11-17", { n: 12, color: "green" }), ["524Н"]);
|
||||
assert.equal(onlyPlace("1-9н. 502н"), true);
|
||||
assert.equal(onlyPlace("13,15 н. РБ (л.з) Сивацкий Д.С.209н"), false);
|
||||
});
|
||||
|
||||
test("Строка с видом и неделями без предмета — тот же предмет в другие недели", () => {
|
||||
const list = entries("2-6н. Потребительское право (л.) Савицкая К.Д. ауд. А1-06\n7,9,11н. – (п.з.) Савицкая К.Д. ауд. А1-06 8,12,14н. – (п.з.) Савицкая К.Д. ауд. А1-06");
|
||||
assert.deepEqual(list.map((e) => [details(e.main).condition, details(e.main).subject, details(e.main).type]), [
|
||||
["2-6н.", "Потребительское право", "Лекция"],
|
||||
["7,9,11н.", "Потребительское право", "Практика"],
|
||||
["8,12,14н.", "Потребительское право", "Практика"],
|
||||
]);
|
||||
assert.equal(details(list[0].main).room, "А1-06");
|
||||
});
|
||||
|
||||
test("Дисциплины по выбору: заголовок, предмет перед неделями, виды по неделям", () => {
|
||||
const read = (raw) => entries(raw).map((e) => ((d) => `${d.condition} ${d.subject} · ${d.type}`)(details(e.main)));
|
||||
assert.deepEqual(read("Дисциплины по выбору: 1-16 н. Логика (л./п.з.) Магалинский И.В. ауд. С0-05\nСоциология 1-10 н. (л.) Шидловский С.О. 11-16 н. (п.з.) Лапацуева А.С.С0-03"), [
|
||||
"1-16 н. Логика · Лекция и практика",
|
||||
"1-10 н. Социология · Лекция",
|
||||
"11-16 н. Социология · Практика",
|
||||
]);
|
||||
assert.deepEqual(read("Дисциплина по выбору: Социология ауд. С0-03\n1-10 н. (л.) Шидловский С.О.\n11-18 н. (п.з.) Лапацуева А.С."), [
|
||||
"1-10 н. Социология · Лекция",
|
||||
"11-18 н. Социология · Практика",
|
||||
]);
|
||||
assert.deepEqual(read("Дисциплина сцециализации: 4-14 н. Преступления в сфере информационных технологий (л.) Чижик Е.В. ауд. В0-05"), [
|
||||
"4-14 н. Преступления в сфере информационных технологий · Лекция",
|
||||
]);
|
||||
assert.deepEqual(read("1-11н. - л., 12-14 – п.з. Защита населения Дмитриченко Н.С. ауд. 210м/к"), [
|
||||
"1-11н. Защита населения · Лекция",
|
||||
"12-14н. Защита населения · Практика",
|
||||
]);
|
||||
});
|
||||
|
||||
test("Время в начале ячейки: интервал с дефисом, заголовок со временем", () => {
|
||||
assert.deepEqual(leadingTime("17:00-17:20-информационный час-Клос О.Ю. 319Д").starts, ["17:00"]);
|
||||
assert.equal(leadingTime("17:00-17:20-информационный час").end, "17:20");
|
||||
assert.deepEqual(alternatives("18.35+20.10 Новополоцк:\n1-5 н. Судебно-следственная психология (л.) Колесникова Е.В. ауд. 246"), [
|
||||
"18.35+20.10 1-5 н. Судебно-следственная психология (л.) Колесникова Е.В. ауд. 246",
|
||||
]);
|
||||
});
|
||||
|
||||
test("Подгруппа в тексте ячейки, точка вместо занятия, заголовок заглавными", () => {
|
||||
const own = details("12н.2п/гр. Экономика организаций (л.з.) Лисиченок Е.П. ауд.331");
|
||||
assert.equal(own.subject, "Экономика организаций");
|
||||
assert.equal(own.ownSubgroup, 2);
|
||||
assert.deepEqual(entries("."), []);
|
||||
assert.equal(details("ВВЕДЕНИЕ В ВЫСШЕЕ ОБРАЗОВАНИЕ\nг. Полоцк, Полоцкий коллегиум\n26-ГЕО, 26-ИТ-1 Ректорский вход\n26-ИТ-2, 26-СТ обзорная экскурсия").subject, "ВВЕДЕНИЕ В ВЫСШЕЕ ОБРАЗОВАНИЕ");
|
||||
// A two-line subject stays whole.
|
||||
assert.equal(details("Интеллектуальная собственность - драйвер инновационного развития\nна пространстве Евразии").subject.includes("Евразии"), true);
|
||||
});
|
||||
|
||||
test("Старое имя разделённой группы: понятная ошибка, другое написание — та же группа", async () => {
|
||||
const { timetable } = await import("../server/timetable.js");
|
||||
const schedule = { groups: ["24-ИЯ (РА)и-1", "24-ИЯ (РА)и-2"], lessons: [], notes: [], period: "Осенний семестр", source: {} };
|
||||
const file = { id: "doc", name: "24-ИЯ (РА)и-1_24-ИЯ (РА)и-2.docx" };
|
||||
assert.throws(
|
||||
() => timetable({ file, schedule, calendar: null, group: "24-ИЯ(РА)", from: "2026-10-19" }),
|
||||
(e) => e.code === "group_not_found" && /разделена: 24-ИЯ \(РА\)и-1, 24-ИЯ \(РА\)и-2/.test(e.message),
|
||||
);
|
||||
assert.equal(timetable({ file, schedule, calendar: null, group: "24-ИЯ(РА)и-1", from: "2026-10-19" }).group, "24-ИЯ (РА)и-1");
|
||||
});
|
||||
@@ -120,7 +120,7 @@ test("Даты практики в заголовке группы не стан
|
||||
["23-ТТиИ"],
|
||||
);
|
||||
assert.deepEqual(groupsIn("25-ИЯ(РА) 23 ИНС-1 24ДОи"), [
|
||||
"25-ИЯ(РА)",
|
||||
"25-ИЯ (РА)",
|
||||
"23-ИНС-1",
|
||||
"24-ДОи",
|
||||
]);
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
вт 13:40–15:05 | каждую неделю, нижняя строка | Информатика | Лекция | 362 | Василевский А.В. | 26-ПГС-1,26-ПГС-2
|
||||
вт 15:20–16:45 | каждую неделю | Химия | Лабораторная | | Аврамёнок А.Н. | 26-ПГС-1,26-ПГС-1/п2
|
||||
вт 15:20–16:45 | каждую неделю, верхняя строка | Начертательная геометрия, инженерная и машинная графика | Практика | 543н | Малаховская В.В. | 26-ПГС-1,26-ПГС-1/п1
|
||||
вт 15:20–16:45 | нед. 13-17 | Иванов В.П. ауд.403 | Занятие | 403 | Иванов В.П. | 26-ПГС-1,26-ПГС-1/п2
|
||||
пн 10:05–11:30 | каждую неделю | История белорусской государственности | Лекция | 432 | Кордюкевич О.Г. | 26-ПГС-1,26-ПГС-2
|
||||
пн 11:45–13:10 | каждую неделю, верхняя строка | История белорусской государственности | Практика | 425 | Кордюкевич О.Г. | 26-ПГС-1
|
||||
пн 11:45–13:10 | каждую неделю, верхняя строка | Физика | Практика | 337н | Солдатенко П.Н. | 26-ПГС-2
|
||||
@@ -17,7 +16,6 @@
|
||||
пн 15:20–16:45 | каждую неделю | Начертательная геометрия, инженерная и машинная графика | Практика | 543н | Малаховская В.В. | 26-ПГС-2,26-ПГС-2/п2
|
||||
пн 15:20–16:45 | каждую неделю | Химия | Лабораторная | | Аврамёнок А.Н. | 26-ПГС-1,26-ПГС-1/п1
|
||||
пн 15:20–16:45 | каждую неделю, нижняя строка | Инженерная геодезия | Лабораторная | 325н | Шевелев И.П. | 26-ПГС-1,26-ПГС-1/п3
|
||||
пн 15:20–16:45 | нед. 13-17 | Иванов В.П. ауд.403 | Занятие | 403 | Иванов В.П. | 26-ПГС-1,26-ПГС-1/п1
|
||||
пт 10:05–11:30 | каждую неделю, верхняя строка | Иностранный язык | Практика | 541н | Каменная В.А. | 26-ПГС-1,26-ПГС-1/п1
|
||||
пт 10:05–11:30 | каждую неделю, верхняя строка | Начертательная геометрия, инженерная и машинная графика | Практика | 543н | Малаховская В.В. | 26-ПГС-1,26-ПГС-1/п2
|
||||
пт 10:05–11:30 | каждую неделю, верхняя строка | Физика | Лабораторная | 205н | Сивацкий Д.С. | 26-ПГС-2,26-ПГС-2/п1
|
||||
|
||||
Reference in New Issue
Block a user