const test = require('node:test'); const assert = require('node:assert/strict'); const fs = require('node:fs'); const path = require('node:path'); const { execFileSync } = require('node:child_process'); const root = path.resolve(__dirname, '..', '..'); const read = (file) => fs.readFileSync(path.join(root, file), 'utf8'); test('搜索框与一言小工具只渲染参考主题的一张卡片', () => { const rendered = JSON.parse( execFileSync(process.env.PHP_BINARY || 'php', [path.join(__dirname, 'search-quote-render-harness.php')], { encoding: 'utf8', }) ); // 参考主题这两个小工具忽略 before_widget,卡片由自身输出一次。 assert.doesNotMatch(rendered.search, /jio-widget-shell/); assert.doesNotMatch(rendered.quote, /jio-widget-shell/); // 搜索框:widget-container > .theme-box(承载 20px 底距)+ 标题 + 单张卡片。 assert.equal((rendered.search.match(/class="jio-panel/g) || []).length, 1); assert.match(rendered.search, /
/); assert.match(rendered.search, /class="jio-panel widget-search">
/); assert.equal((rendered.search.match(/class="search-input"/g) || []).length, 1); // 一言:同样的 .theme-box 间距层,卡片自身不带底部边距。 assert.equal((rendered.quote.match(/class="yiyan-box/g) || []).length, 1); assert.match(rendered.quote, /
/); assert.match(rendered.quote, /class="yiyan-box main-bg text-center box-body radius8 main-shadow jio-yiyan" data-jio-yiyan>/); assert.doesNotMatch(rendered.quote, /class="yiyan-box[^"]*theme-box/); assert.match(rendered.quote, /
<\/div>/); }); test('搜索框设置沿用参考主题字段,不再提供自造样式选项', () => { const schema = read('src/WidgetSystem/WidgetSchemas.php'); const renderer = read('src/WidgetSystem/Renderers/GeneralRenderer.php'); const frontend = read('src/WidgetSystem/FrontendRenderer.php'); for (const field of ["'id' => 'show_keywords'", "'id' => 'show_history'", "'id' => 'keywords_title'", "'id' => 'show_input_cat'", "'id' => 'in_cat'", "'id' => 'more_cats'"]) { assert.match(schema, new RegExp(field.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'))); } assert.doesNotMatch(schema, /search_style/); assert.doesNotMatch(renderer, /jio-widget-search/); assert.match(renderer, /function_exists\('jio_get_search_box'\)/); // 与 TOC 一样由内容自带卡片壳,不走通用 .jio-panel 包裹分支。 assert.match(frontend, /\[['"]search['"], ['"]quote['"]\]/); assert.match(frontend, /render_reference_widget\(\$definition, \$instance, \$widget, \$content, true\)/); assert.match(frontend, /bool \$own_card = false/); }); test('文章内一言沿用参考主题的类名组合,不再使用自定义修饰类', () => { const single = read('inc/helpers/jio-single-render.php'); const css = read('assets/css/frontend/single-post/hidden-content.css'); assert.equal((single.match(/'article-yiyan theme-box text-center radius8 main-shadow yiyan-box jio-yiyan'/g) || []).length, 2); assert.match(single, /'yiyan-box main-bg theme-box text-center box-body radius8 main-shadow jio-yiyan'/); assert.doesNotMatch(single, /yiyan--header|yiyan--footer|yiyan--box/); assert.doesNotMatch(css, /yiyan--header|yiyan--footer|yiyan--box/); }); test('遗留的 qv-yiyan.php 渲染请求已移除', () => { const runtime = read('assets/js/runtime/main.js'); assert.doesNotMatch(runtime, /qv-yiyan\.php/); assert.doesNotMatch(runtime, /yiyan_nr\(/); assert.match(read('assets/js/yiyan.js'), /action=jio_yiyan/); });