@
feat(chemistry-8): перестройка раздела intro под эталон учебников (SPA-движок) По замечанию: учебник не соответствовал структуре/наполнению других учебников. Перестроено по контракту глав физики (para-selector SPA + движок задач): - chem8_engine.js — общий движок: para-selector, ленивая сборка §, makeCard, тренажёр задач (числовой ввод + MCQ, nav-dots, score), sidebar-шпаргалка с XP, уровни/достижения, серверная синхронизация прогресса, тема. Конфиг — CHEM8_CFG. - chem8-textbook.css — фреймворк-CSS: layout+sidebar, hero, psel-карточки, para-hero (9 градиентов), карточки теории, def/remember/insight, тренажёр, mcq, флагман-карточки, виджеты, ach-popup (amber-палитра). - chem8_intro_widgets.js — виджеты § (карта элементов, Mr, порция, Авогадро, M+объём) и флагманы (треугольник n–m–M, калькулятор газа, балансировщик, пошаговый решатель) на chem8_svg.js. - chemistry_8_intro.html — перестроен: PARAS, build_p1..p9+pr1+final, POOLS (38 задач), SIDEBARS, TIPS. Богатая анатомия § как в физике. Тесты: 23/23 (юнит + jsdom-виджеты + полностраничный jsdom SPA — para-selector, активный §, монтаж виджетов, тренажёр, без ошибок скриптов). Ассеты отдаются 200. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> @
This commit is contained in:
@@ -101,27 +101,42 @@ test('хаб chemistry_8_hub.html существует и ссылается н
|
||||
assert.ok(hub.includes('/api/textbooks/chemistry-8/children'), 'грузит детей');
|
||||
});
|
||||
|
||||
test('каждая глава существует и задаёт свой _TB_SLUG', () => {
|
||||
test('каждая глава существует, ссылается на хаб и подключает chem8', () => {
|
||||
for (const ch of CHILDREN) {
|
||||
const html = fs.readFileSync(path.join(TB, ch.file), 'utf8');
|
||||
assert.ok(html.includes("const _TB_SLUG = '" + ch.slug + "'"), ch.file + ' slug');
|
||||
assert.ok(html.includes('/textbook/chemistry-8"'), ch.file + ' ссылка назад в хаб');
|
||||
assert.ok(html.includes('/js/chem8_svg.js'), ch.file + ' подключает chem8_svg');
|
||||
assert.ok(html.includes('/js/biochem-core.js'), ch.file + ' подключает biochem-core');
|
||||
if (ch.slug === 'chemistry-8-intro') {
|
||||
// intro перестроен на движок (SPA): slug задаётся через CHEM8_CFG
|
||||
assert.ok(html.includes("slug:'chemistry-8-intro'"), 'intro slug в CHEM8_CFG');
|
||||
assert.ok(html.includes('/js/chem8_engine.js'), 'intro подключает движок');
|
||||
} else {
|
||||
assert.ok(html.includes("const _TB_SLUG = '" + ch.slug + "'"), ch.file + ' slug (каркас)');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('Phase 1 — раздел intro наполнен (9 § + ПР1 + босс)', () => {
|
||||
test('Phase 1 — раздел intro перестроен на движок (SPA, эталон)', () => {
|
||||
const html = fs.readFileSync(path.join(TB, 'chemistry_8_intro.html'), 'utf8');
|
||||
for (let i = 1; i <= 9; i++) assert.ok(html.includes('id="p' + i + '"'), '§' + i + ' секция');
|
||||
assert.ok(html.includes('id="pr1"'), 'ПР1');
|
||||
assert.ok(html.includes('id="boss"'), 'босс раздела');
|
||||
assert.ok(html.includes('id="mt-mount"'), 'треугольник n–m–M');
|
||||
assert.ok(html.includes('id="bal-mount"'), 'балансировщик');
|
||||
assert.ok(html.includes("READ_IDS = ['p1','p2','p3','p4','p5','p6','p7','p8','p9']"), '9 читаемых § для прогресса');
|
||||
assert.ok(html.includes('id="psel-grid"'), 'para-selector');
|
||||
for (let i = 1; i <= 9; i++) assert.ok(html.includes('id="sec-p' + i + '"'), '§' + i + ' секция');
|
||||
assert.ok(html.includes('id="sec-pr1"'), 'ПР1 секция');
|
||||
assert.ok(html.includes('id="sec-final1"'), 'финал-секция');
|
||||
assert.ok(html.includes('window.POOLS'), 'тренажёр задач (POOLS)');
|
||||
assert.ok(html.includes('window.BUILDERS'), 'builders §');
|
||||
assert.ok(html.includes('function build_p6'), 'build_p6 (треугольник)');
|
||||
assert.ok(html.includes('/css/chem8-textbook.css'), 'фреймворк-CSS');
|
||||
assert.ok(html.includes('/js/chem8_intro_widgets.js'), 'виджеты раздела');
|
||||
assert.ok(!html.includes('Раздел в разработке'), 'баннер-заглушка убран');
|
||||
});
|
||||
|
||||
test('chem8_engine.js и виджеты — валидный синтаксис', () => {
|
||||
const eng = fs.readFileSync(path.join(ROOT, 'frontend', 'js', 'chem8_engine.js'), 'utf8');
|
||||
const wid = fs.readFileSync(path.join(ROOT, 'frontend', 'js', 'chem8_intro_widgets.js'), 'utf8');
|
||||
assert.doesNotThrow(() => new Function(eng), 'движок парсится');
|
||||
assert.doesNotThrow(() => new Function(wid), 'виджеты парсятся');
|
||||
});
|
||||
|
||||
test('Phase 1 — ответы босса согласованы с molarMass', () => {
|
||||
// значения в боссе intro должны совпадать с движком
|
||||
assert.equal(C.molarMass('H2SO4'), 98); // задача 1
|
||||
|
||||
Reference in New Issue
Block a user