6dce580846
Feature work on top of the initial organizer: - Videos: .mp4/.mov/.avi/.mkv/.webm/.m4v sorted into output/Movie/YYYY/MM - Profiles: reference-image thumbnail cards via a secure photoai-media:// protocol (serves only registered reference images); per-thumbnail delete; add via click, drag & drop, or paste (Ctrl+V) using webUtils.getPathForFile + a byte-based addReferenceData path for clipboard images - Presets: local person library (max 5) saved to userData; one-click apply into active profiles; reusing stored descriptors (no recompute) - Theme: dark/light with dark default (Tailwind class strategy) - i18n: ko/en table-based localization; first-run onboarding to pick language + theme; English-neutral "Unsorted" folder (was [미정]) - App menu: File/Edit/View/Window/Help, localized; Help opens a detailed, theme-aware user guide window - UI: History block scrolls internally (no whole-window scroll); threshold/concurrency tooltips; generic example name - Settings persisted to userData/settings.json; menu + renderer kept in sync - Docs: NextGen Photo AI feasibility review + Phase 0/1 roadmap All typecheck/tests (12) /build green; boot smoke verified. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
30 lines
1.1 KiB
TypeScript
30 lines
1.1 KiB
TypeScript
import { describe, it, expect } from 'vitest'
|
|
import { buildTargetPath, withCollisionSuffix } from '../src/main/pathBuilder'
|
|
import type { CaptureDate } from '../src/shared/types'
|
|
|
|
const date: CaptureDate = { year: '2024', month: '03', source: 'exif' }
|
|
|
|
describe('buildTargetPath', () => {
|
|
it('인물 매칭 시 /프로필/YYYY/MM/파일명 경로를 만든다', () => {
|
|
const p = buildTargetPath('/out', 'seunghyun', date, '/src/a/photo.jpg')
|
|
expect(p.replace(/\\/g, '/')).toBe('/out/seunghyun/2024/03/photo.jpg')
|
|
})
|
|
|
|
it('미검출(who=null) 시 Unsorted 폴더로 보낸다', () => {
|
|
const p = buildTargetPath('/out', null, date, '/src/photo.png')
|
|
expect(p.replace(/\\/g, '/')).toBe('/out/Unsorted/2024/03/photo.png')
|
|
})
|
|
|
|
it('영상은 Movie/YYYY/MM 폴더로 보낸다', () => {
|
|
const p = buildTargetPath('/out', 'Movie', date, '/src/clip.mp4')
|
|
expect(p.replace(/\\/g, '/')).toBe('/out/Movie/2024/03/clip.mp4')
|
|
})
|
|
})
|
|
|
|
describe('withCollisionSuffix', () => {
|
|
it('확장자 앞에 _N을 붙인다', () => {
|
|
const p = withCollisionSuffix('/out/x/photo.jpg', 2)
|
|
expect(p.replace(/\\/g, '/')).toBe('/out/x/photo_2.jpg')
|
|
})
|
|
})
|