Files
connectai/tests/wikiSave.test.ts
T
koriweb 47b3b9f93a v2.2.299~307: 아키텍처 수렴 + 채팅 정리 + 벤치마킹 강화 + Claude 구독 엔진
- v2.2.299 아키텍처 수렴: coreChat 통일(엔진 휴리스틱 3벌 제거), 기업 모드
  검색 오케스트레이터 승격, lib/execUtil(실행 래퍼 6곳·Python 탐지 3벌 단일화),
  lib/kstSchedule(워처 4개 nowInKst 통합), estimateTokens 통합, 설정 접근 규칙 명문화
- v2.2.300 채팅 화면 정리: LiveReasoningFilter(스트리밍 중 <think>/Harmony 추론
  토큰 단위 차단), 확신도·검토요청 footer 기본 숨김(계산·Reflection 은 유지)
- v2.2.301 문맥·의도 이해: [답변 전 이해 원칙] 상시 주입, 워크플로우 의도 브리핑,
  Report QA 루프(규칙 레지스트리+실측치+회귀 게이트, 블로그_v3 개념 이식)
- v2.2.302 /benchmark 비즈니스 렌즈(가격·수익·운영)+빌드 프롬프트 모드+QA 연계
- v2.2.303 handoff 모드(측정치 무손실 인수인계 문서)+/claude(Claude Code 터미널 위임)
- v2.2.304 이식성: 지식 경로 두뇌-상대 규약(pickWikiDir 상대 해석), 이사 체크리스트
- v2.2.305 Claude 구독 엔진: claude: 프로바이더(CLI 위임, 모델 드롭다운 자동 노출,
  coreChat 지원 — 워크플로우·QA도 구독 모델 가능)
- v2.2.306 Tone Guard: AI 상투어 금지 레지스트리(상담사 화법 실사례 8종+대조 예시)
- v2.2.307 /benchmark 레이아웃 골격(sectionRoles 결정론 분석, 롤링 배너 즉답),
  파트별 실패 격리, 합성 타임아웃 120→300초

검증: tsc 무오류 + jest 888 통과 + esbuild 정상

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 21:02:15 +09:00

86 lines
3.5 KiB
TypeScript

/**
* v2.2.273 — 지식 문서 로컬 저장 (순수 로직: 파일명 안전화 + 저장 폴더 우선순위).
*/
import * as path from 'path';
import { sanitizeWikiFileName, pickWikiDir } from '../src/features/datacollect/wikiSave';
describe('sanitizeWikiFileName', () => {
test('금지 문자 치환 + .md 보장', () => {
const f = sanitizeWikiFileName('회의록 a/b:c*d?e<f>g|h 2026-07-03');
expect(f).not.toMatch(/[\\/:*?"<>|]/);
expect(f.endsWith('.md')).toBe(true);
expect(f).toContain('회의록');
});
test('빈 제목 → untitled, 120자 캡', () => {
expect(sanitizeWikiFileName('')).toMatch(/^untitled_\d+\.md$/);
expect(sanitizeWikiFileName('가'.repeat(300)).length).toBeLessThanOrEqual(124);
});
test('.md 중복 방지', () => {
expect(sanitizeWikiFileName('문서.md')).toBe('문서.md');
});
});
describe('pickWikiDir — 저장 폴더 우선순위', () => {
const abs = path.resolve('E:/커스텀/위키');
test('① 설정 절대경로 최우선', () => {
const r = pickWikiDir(abs, 'E:/brain', 'E:/ws');
expect(r).toEqual({ dir: abs, label: '설정 폴더' });
});
test('② 설정 없으면 두뇌/Datacollect_Wiki', () => {
const r = pickWikiDir('', 'E:/brain', 'E:/ws');
expect(r!.label).toBe('두뇌');
expect(r!.dir).toBe(path.join('E:/brain', 'Datacollect_Wiki'));
});
test('③ 두뇌 없으면 워크스페이스/.astra/wiki', () => {
const r = pickWikiDir('', '', 'E:/ws');
expect(r!.label).toBe('워크스페이스');
expect(r!.dir).toBe(path.join('E:/ws', '.astra', 'wiki'));
});
test('[v2.2.304] 상대경로 설정은 두뇌 루트 기준으로 해석 (이식성)', () => {
const r = pickWikiDir('상대/경로', '/brain', null);
expect(r!.label).toBe('설정 폴더(두뇌 기준)');
expect(r!.dir.replace(/\\/g, '/')).toContain('/brain/상대/경로');
});
test('[v2.2.304] ../ 상대경로로 두뇌 밖 형제 폴더도 지정 가능', () => {
const r = pickWikiDir('../../Premium/자료', '/Wiki/10_Wiki/Topics', null);
expect(r!.dir.replace(/\\/g, '/')).toBe('/Wiki/Premium/자료');
});
test('상대경로인데 두뇌도 없으면 다음 후보(워크스페이스)로', () => {
const r = pickWikiDir('상대/경로', '', '/ws');
expect(r!.label).toBe('워크스페이스');
});
test('④ 전부 없으면 null', () => {
expect(pickWikiDir('', '', null)).toBeNull();
});
});
describe('pickWikiDir — 이메일 지식 문서 별도 관리 (kind=email)', () => {
test('기본 폴더가 Email_Wiki 로 분리 — 일반(Datacollect_Wiki)과 다름', () => {
const email = pickWikiDir('', 'E:/brain', 'E:/ws', 'email');
const general = pickWikiDir('', 'E:/brain', 'E:/ws', 'general');
expect(email!.dir).toBe(path.join('E:/brain', 'Email_Wiki'));
expect(general!.dir).toBe(path.join('E:/brain', 'Datacollect_Wiki'));
expect(email!.dir).not.toBe(general!.dir);
});
test('이메일 전용 설정 경로가 최우선', () => {
const abs = path.resolve('E:/이메일위키');
const r = pickWikiDir(abs, 'E:/brain', 'E:/ws', 'email');
expect(r).toEqual({ dir: abs, label: '설정 폴더' });
});
test('두뇌 없으면 워크스페이스 .astra/wiki/email', () => {
const r = pickWikiDir('', '', 'E:/ws', 'email');
expect(r!.dir).toBe(path.join('E:/ws', '.astra', 'wiki', 'email'));
});
});