新增根 biome.json(v2.5,v2 起原生支持 monorepo,子包自动向上查找):
- formatter: 2 空格缩进、单引号、行宽 100、LF、尾逗号、箭头函数括号
(匹配现有代码风格)
- linter: recommended preset + 项目化裁剪
- useTemplate/useTemplate off(geometry.ts 故意保留字符串拼接,
且测试用精确浮点断言锁定行为)
- noNonNullAssertion off(测试与 DOM 访问里的 ! 是惯用写法)
- noConsole off(4 个 lib 用 console.error/warn 做错误上报)
- CSS 关闭 noDescendingSpecificity/noDuplicateProperties
(手写 CSS 的 fallback 模式)
- useImportType/useNodejsImportProtocol/noUnusedVariables warn
- vcs.useIgnoreFile 自动读 .gitignore;排除 public/target/node_modules/
dist/.dioxus/static + Tailwind 入口 input.css(含 @theme 等 Biome 无法
解析的 at-rules)
首次格式化覆盖 29 个源文件:import 排序、node: 协议、引号/缩进统一,
并修复 index.ts 两处 forEach 回调隐式返回值(useIterableCallbackReturn)。
90 个 vitest 用例全绿,确认无语义改动。
73 lines
2.2 KiB
TypeScript
73 lines
2.2 KiB
TypeScript
/**
|
|
* post-content 测试:钉住代码块 copy 按钮的生成与复制行为。
|
|
* 黑盒驱动:只通过 window.__initPostContent 入口。
|
|
*/
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
import './index';
|
|
|
|
describe('initPostContent', () => {
|
|
beforeEach(() => {
|
|
document.body.innerHTML = '';
|
|
vi.restoreAllMocks();
|
|
vi.useFakeTimers();
|
|
});
|
|
afterEach(() => {
|
|
vi.useRealTimers();
|
|
document.body.innerHTML = '';
|
|
});
|
|
|
|
it('为 pre>code 注入 .copy-code 按钮', () => {
|
|
const root = document.createElement('div');
|
|
root.className = 'post-content';
|
|
root.innerHTML = '<pre><code>console.log(1)</code></pre>';
|
|
document.body.appendChild(root);
|
|
|
|
window.__initPostContent('.post-content');
|
|
|
|
const btn = root.querySelector('pre .copy-code');
|
|
expect(btn).not.toBeNull();
|
|
expect(btn?.textContent).toBe('copy');
|
|
});
|
|
|
|
it('已有 .copy-code 的 pre 不重复注入', () => {
|
|
const root = document.createElement('div');
|
|
root.className = 'post-content';
|
|
root.innerHTML = '<pre><code>x</code><button class="copy-code">copy</button></pre>';
|
|
document.body.appendChild(root);
|
|
|
|
window.__initPostContent('.post-content');
|
|
|
|
const btns = root.querySelectorAll('pre .copy-code');
|
|
expect(btns.length).toBe(1);
|
|
});
|
|
|
|
it('点击按钮调用 clipboard.writeText 并回显 copied!', () => {
|
|
const writeText = vi.fn().mockResolvedValue(undefined);
|
|
Object.defineProperty(navigator, 'clipboard', {
|
|
value: { writeText },
|
|
configurable: true,
|
|
});
|
|
|
|
const root = document.createElement('div');
|
|
root.className = 'post-content';
|
|
root.innerHTML = '<pre><code>hello</code></pre>';
|
|
document.body.appendChild(root);
|
|
|
|
window.__initPostContent('.post-content');
|
|
|
|
const btn = root.querySelector('.copy-code') as HTMLButtonElement;
|
|
btn.click();
|
|
|
|
expect(writeText).toHaveBeenCalledWith('hello');
|
|
expect(btn.textContent).toBe('copied!');
|
|
|
|
// 2 秒后还原回 'copy'
|
|
vi.advanceTimersByTime(2000);
|
|
expect(btn.textContent).toBe('copy');
|
|
});
|
|
|
|
it('selector 未命中时不报错', () => {
|
|
expect(() => window.__initPostContent('.not-exist')).not.toThrow();
|
|
});
|
|
});
|