test: 引入测试框架,初步实现标签过滤方法的测试用例

This commit is contained in:
Ted 2025-06-27 08:54:37 +08:00
parent 5cb2e3f199
commit 50eead39bc
4 changed files with 4252 additions and 49 deletions

6
jest.config.js Normal file
View file

@ -0,0 +1,6 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testMatch: ['**/test/**/*.test.ts'],
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
};

4137
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -6,13 +6,16 @@
"scripts": {
"dev": "node esbuild.config.mjs",
"build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production",
"version": "node version-bump.mjs && git add manifest.json versions.json"
"version": "node version-bump.mjs && git add manifest.json versions.json",
"test": "jest"
},
"keywords": [],
"author": "ratiger",
"license": "GPL-3.0-only",
"devDependencies": {
"@types/node": "^16.11.6",
"@jest/types": "^30.0.1",
"@types/jest": "^30.0.0",
"@types/node": "^16.18.126",
"@types/react": "^19.1.2",
"@types/react-calendar-heatmap": "^1.9.0",
"@types/react-dom": "^19.1.2",
@ -20,7 +23,9 @@
"@typescript-eslint/parser": "5.29.0",
"builtin-modules": "3.3.0",
"esbuild": "0.17.3",
"obsidian": "latest",
"jest": "^30.0.2",
"obsidian": "^1.8.7",
"ts-jest": "^29.4.0",
"tslib": "2.4.0",
"typescript": "4.7.4"
},

147
test/TagFilter.test.ts Normal file
View file

@ -0,0 +1,147 @@
import { TagFilter, isOKWithTagFilter } from "../src/models/TagFilter";
describe('测试标签过滤', () => {
test('排除标签', () => {
const filter: TagFilter = { or: [[]], not: ['b'], noTag: 'unlimited' };
const tags = ['a', 'b', 'c'];
expect(isOKWithTagFilter(tags, filter)).toBe(false);
const tags2 = ['a', 'c'];
expect(isOKWithTagFilter(tags2, filter)).toBe(true);
});
test('多级标签排除', () => {
const filter: TagFilter = { or: [[]], not: ['a/b'], noTag: 'unlimited' };
const tags = ['a/b/c'];
expect(isOKWithTagFilter(tags, filter)).toBe(false);
const tags2 = ['a/c'];
expect(isOKWithTagFilter(tags2, filter)).toBe(true);
});
test('或标签组过滤', () => {
const filter: TagFilter = { or: [['a'], ['b', 'c']], not: [], noTag: 'unlimited' };
const tags1 = ['a', 'x'];
expect(isOKWithTagFilter(tags1, filter)).toBe(true);
const tags2 = ['b', 'c', 'y'];
expect(isOKWithTagFilter(tags2, filter)).toBe(true);
const tags3 = ['x', 'y'];
expect(isOKWithTagFilter(tags3, filter)).toBe(false);
});
test('无标签文件过滤 - unlimited', () => {
const filter: TagFilter = { or: [[]], not: [], noTag: 'unlimited' };
const tags: string[] = [];
expect(isOKWithTagFilter(tags, filter)).toBe(true);
const tags2 = ['a'];
expect(isOKWithTagFilter(tags2, filter)).toBe(true);
});
test('无标签文件过滤 - include', () => {
const filter: TagFilter = { or: [[]], not: [], noTag: 'include' };
const tags: string[] = [];
expect(isOKWithTagFilter(tags, filter)).toBe(true);
const tags2 = ['a'];
expect(isOKWithTagFilter(tags2, filter)).toBe(false);
});
test('无标签文件过滤 - exclude', () => {
const filter: TagFilter = { or: [[]], not: [], noTag: 'exclude' };
const tags: string[] = [];
expect(isOKWithTagFilter(tags, filter)).toBe(false);
const tags2 = ['a'];
expect(isOKWithTagFilter(tags2, filter)).toBe(true);
});
test('组合过滤', () => {
const filter: TagFilter = { or: [['a'], ['b', 'c']], not: ['d'], noTag: 'unlimited' };
const tags1 = ['a', 'e'];
expect(isOKWithTagFilter(tags1, filter)).toBe(true);
const tags2 = ['b', 'c', 'e'];
expect(isOKWithTagFilter(tags2, filter)).toBe(true);
const tags3 = ['a', 'd'];
expect(isOKWithTagFilter(tags3, filter)).toBe(false);
const tags4 = ['e', 'f'];
expect(isOKWithTagFilter(tags4, filter)).toBe(false);
});
test('空标签组不影响过滤', () => {
const filter: TagFilter = { or: [[], ['a']], not: [], noTag: 'unlimited' };
const tags = ['a'];
expect(isOKWithTagFilter(tags, filter)).toBe(true);
const filter2: TagFilter = { or: [[], []], not: [], noTag: 'unlimited' };
const tags2 = ['a'];
expect(isOKWithTagFilter(tags2, filter2)).toBe(true);
});
test('包含逻辑与无标签文件', () => {
const filter: TagFilter = { or: [['a']], not: [], noTag: 'include' };
const tags1 = ['a'];
expect(isOKWithTagFilter(tags1, filter)).toBe(true);
const tags2: string[] = [];
expect(isOKWithTagFilter(tags2, filter)).toBe(true);
const filter2: TagFilter = { or: [[]], not: [], noTag: 'include' };
const tags3: string[] = [];
expect(isOKWithTagFilter(tags3, filter2)).toBe(true);
const tags4 = ['a'];
expect(isOKWithTagFilter(tags4, filter2)).toBe(false);
});
test('部分匹配包含', () => {
const filter: TagFilter = { or: [['a']], not: [], noTag: 'unlimited' };
const tags = ['a/b'];
expect(isOKWithTagFilter(tags, filter)).toBe(true);
});
test('多个not标签', () => {
const filter: TagFilter = { or: [[]], not: ['a', 'b'], noTag: 'unlimited' };
expect(isOKWithTagFilter(['a'], filter)).toBe(false);
expect(isOKWithTagFilter(['b'], filter)).toBe(false);
expect(isOKWithTagFilter(['c'], filter)).toBe(true);
});
test('特殊字符标签', () => {
const filter: TagFilter = { or: [['a b']], not: ['c#d'], noTag: 'unlimited' };
expect(isOKWithTagFilter(['a b'], filter)).toBe(true);
expect(isOKWithTagFilter(['c#d'], filter)).toBe(false);
});
test('or组全部为空数组', () => {
const filter1: TagFilter = { or: [[], []], not: [], noTag: 'unlimited' };
expect(isOKWithTagFilter([], filter1)).toBe(true);
expect(isOKWithTagFilter(['a'], filter1)).toBe(true);
const filter2: TagFilter = { or: [[], []], not: [], noTag: 'include' };
expect(isOKWithTagFilter([], filter2)).toBe(true);
expect(isOKWithTagFilter(['a'], filter2)).toBe(false);
const filter3: TagFilter = { or: [[], []], not: [], noTag: 'exclude' };
expect(isOKWithTagFilter([], filter3)).toBe(false);
expect(isOKWithTagFilter(['a'], filter3)).toBe(true);
});
test('多级标签包含逻辑', () => {
const filter: TagFilter = { or: [['a/b']], not: [], noTag: 'unlimited' };
expect(isOKWithTagFilter(['a/b/c'], filter)).toBe(true);
expect(isOKWithTagFilter(['a/c'], filter)).toBe(false);
});
test('混合部分匹配和完全匹配', () => {
const filter: TagFilter = { or: [['a', 'b/c']], not: [], noTag: 'unlimited' };
expect(isOKWithTagFilter(['a/x', 'b/c/d'], filter)).toBe(true);
expect(isOKWithTagFilter(['a', 'b'], filter)).toBe(false);
});
});