fix: simplify date-only due labels
This commit is contained in:
@@ -24,26 +24,44 @@ describe('TaskDueDisplay', () => {
|
||||
expect(host.innerHTML).toBe('<!--v-if-->')
|
||||
})
|
||||
|
||||
it('renders semantic canonical time with absolute and relative copy', async () => {
|
||||
const { host } = await mountDue({ dueAt: '2026-09-10', dueHasTime: false, completed: false, nowMs })
|
||||
const root = host.querySelector('.task-due')!
|
||||
const time = root.querySelector('time')!
|
||||
expect(root.classList.contains('task-due--neutral')).toBe(true)
|
||||
expect(time.getAttribute('datetime')).toBe('2026-09-10')
|
||||
expect(time.textContent).toContain('9月10日')
|
||||
expect(time.textContent).toContain('今天')
|
||||
expect(time.getAttribute('title')).toBe(time.getAttribute('aria-label'))
|
||||
expect(time.getAttribute('title')).toContain('2026年9月10日')
|
||||
expect(root.querySelector('svg')).toBeNull()
|
||||
it('renders date-only visual text without an absolute date or explanatory prefixes', async () => {
|
||||
const cases = [
|
||||
{ dueAt: '2026-09-12', text: '2天', state: 'neutral', explanation: '还有2天' },
|
||||
{ dueAt: '2026-09-08', text: '2天', state: 'overdue', explanation: '已过期2天' },
|
||||
{ dueAt: '2026-09-10', text: '今天', state: 'neutral', explanation: '今天' },
|
||||
] as const
|
||||
for (const item of cases) {
|
||||
const { host } = await mountDue({ dueAt: item.dueAt, dueHasTime: false, completed: false, nowMs })
|
||||
const root = host.querySelector('.task-due')!
|
||||
const time = root.querySelector('time')!
|
||||
expect(root.classList.contains(`task-due--${item.state}`)).toBe(true)
|
||||
expect(time.textContent?.trim()).toBe(item.text)
|
||||
expect(time.textContent).not.toMatch(/2026|9月|还有|已过期/)
|
||||
expect(time.getAttribute('datetime')).toBe(item.dueAt)
|
||||
expect(time.getAttribute('title')).toBe(time.getAttribute('aria-label'))
|
||||
expect(time.getAttribute('title')).toContain(`2026年9月${Number(item.dueAt.slice(8))}日`)
|
||||
expect(time.getAttribute('title')).toContain(item.explanation)
|
||||
}
|
||||
})
|
||||
|
||||
it('distinguishes incomplete overdue and completed neutral states', async () => {
|
||||
const overdue = await mountDue({ dueAt: '2026-09-09', dueHasTime: false, completed: false, nowMs })
|
||||
expect(overdue.host.querySelector('.task-due--overdue')).not.toBeNull()
|
||||
it('keeps completed date-only deadlines neutral and visually minimal', async () => {
|
||||
const completed = await mountDue({ dueAt: '2026-09-09', dueHasTime: false, completed: true, nowMs })
|
||||
expect(completed.host.querySelector('.task-due--completed')).not.toBeNull()
|
||||
expect(completed.host.querySelector('.task-due--overdue')).toBeNull()
|
||||
expect(completed.host.textContent).toContain('已完成(原定1天前)')
|
||||
const root = completed.host.querySelector('.task-due')!
|
||||
const time = root.querySelector('time')!
|
||||
expect(root.classList.contains('task-due--completed')).toBe(true)
|
||||
expect(root.classList.contains('task-due--overdue')).toBe(false)
|
||||
expect(time.textContent?.trim()).toBe('已完成')
|
||||
expect(time.textContent).not.toMatch(/2026|9月|已过期|还有/)
|
||||
expect(time.getAttribute('title')).toContain('截止日期:2026年9月9日')
|
||||
expect(time.getAttribute('title')).toContain('已完成(原定1天前)')
|
||||
})
|
||||
|
||||
it('keeps timed task absolute and relative visual copy unchanged', async () => {
|
||||
const dueAt = new Date(nowMs + 2 * 60 * 60_000).toISOString()
|
||||
const { host } = await mountDue({ dueAt, dueHasTime: true, completed: false, nowMs })
|
||||
const time = host.querySelector('time')!
|
||||
expect(time.querySelector('.task-due__absolute')?.textContent).toMatch(/^9月10日 \d{2}:\d{2}$/)
|
||||
expect(time.querySelector('.task-due__relative')?.textContent).toBe('还有2小时')
|
||||
})
|
||||
|
||||
it('reacts when the shared nowMs prop advances', async () => {
|
||||
|
||||
@@ -13,15 +13,15 @@ const presentation = computed(() => getTaskDuePresentation(props))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span v-if="presentation" class="task-due" :class="`task-due--${presentation.state}`">
|
||||
<span v-if="presentation" class="task-due" :class="[`task-due--${presentation.state}`, { 'task-due--timed': dueHasTime }]">
|
||||
<time
|
||||
class="task-due__text"
|
||||
:datetime="presentation.datetime"
|
||||
:title="presentation.fullText"
|
||||
:aria-label="presentation.fullText"
|
||||
>
|
||||
<span class="task-due__absolute">{{ presentation.absoluteText }}</span>
|
||||
<span class="task-due__separator" aria-hidden="true"> · </span>
|
||||
<span v-if="dueHasTime" class="task-due__absolute">{{ presentation.absoluteText }}</span>
|
||||
<span v-if="dueHasTime" class="task-due__separator" aria-hidden="true"> · </span>
|
||||
<span class="task-due__relative">{{ presentation.relativeText }}</span>
|
||||
</time>
|
||||
</span>
|
||||
|
||||
Reference in New Issue
Block a user