feat: show task due distance
This commit is contained in:
@@ -8,6 +8,40 @@ const mvpPanel = readFileSync('src/MvpPanel.vue', 'utf8')
|
||||
const countdownPanel = readFileSync('src/CountdownPanel.vue', 'utf8')
|
||||
const floatingAdd = readFileSync('src/components/FloatingAddButton.vue', 'utf8')
|
||||
const completedFilterPill = readFileSync('src/components/CompletedFilterPill.vue', 'utf8')
|
||||
const taskDueDisplay = readFileSync('src/components/TaskDueDisplay.vue', 'utf8')
|
||||
|
||||
describe('unified task due display', () => {
|
||||
it('uses the shared display for overdue, ordinary parent, and child task rows', () => {
|
||||
expect(app).toContain("import TaskDueDisplay from './components/TaskDueDisplay.vue'")
|
||||
expect(app.match(/<TaskDueDisplay/g)).toHaveLength(4)
|
||||
expect(app).toContain(':due-at="node.task.due_at"')
|
||||
expect(app).toContain(':due-at="subtask.due_at"')
|
||||
expect(app).not.toContain('formatDue(')
|
||||
expect(app).not.toContain('overdue-badge')
|
||||
expect(taskDueDisplay).not.toMatch(/setInterval|setTimeout/)
|
||||
})
|
||||
|
||||
it('keeps overdue parent subtasks interactive without duplicating ordinary rows', () => {
|
||||
const overdue = app.slice(app.indexOf('<section v-if="overdueTaskTree.length"'), app.indexOf('<h3 id="today-tasks"'))
|
||||
expect(overdue).toContain('v-for="subtask in node.subtasks"')
|
||||
expect(overdue).toContain('@click.stop="toggle(subtask)"')
|
||||
expect(overdue).toContain('@click="selectTaskUnlessSwiped(subtask)"')
|
||||
expect(overdue).not.toContain('class="drag-handle task-drag-handle"')
|
||||
expect(overdue).not.toContain('startTaskReorder(subtask, $event)')
|
||||
expect(overdue.match(/v-for="subtask in node.subtasks"/g)).toHaveLength(1)
|
||||
expect(overdue).not.toContain('swipe-bg')
|
||||
})
|
||||
|
||||
it('uses semantic due colors and preserves task content and action tracks', () => {
|
||||
expect(css).toContain('.task-due--overdue{color:var(--danger)}')
|
||||
expect(css).toContain('.task-due--neutral,.task-due--completed{color:var(--muted)}')
|
||||
expect(css).toContain('.task-main{border:0;background:transparent;flex:1;min-width:0;')
|
||||
expect(css).toContain('.icon,.ghost{min-width:44px;min-height:44px;')
|
||||
expect(css).toContain('@media(max-width:930px){.task-main .meta{display:flex;flex-wrap:wrap;')
|
||||
expect(css).not.toContain('.overdue-task .meta')
|
||||
expect(css).not.toContain('.overdue-badge')
|
||||
})
|
||||
})
|
||||
|
||||
describe('mobile navigation styles', () => {
|
||||
it('renames the bottom More tab to a direct Settings tab', () => {
|
||||
@@ -351,11 +385,22 @@ describe('task and habit row decoration', () => {
|
||||
expect(mvpPanel.match(/'--reorder-y': `\$\{habitReorder\?\.id === h\.id \? habitReorder\.offsetY : 0\}px`/g)?.length).toBe(1)
|
||||
})
|
||||
|
||||
it('exposes complete task titles on every ellipsized parent and child title node', () => {
|
||||
expect(app.match(/<strong :title="node\.task\.title">\{\{node\.task\.title\}\}<\/strong>/g)).toHaveLength(2)
|
||||
expect(app.match(/<strong :title="subtask\.title">\{\{subtask\.title\}\}<\/strong>/g)).toHaveLength(2)
|
||||
expect(app).not.toContain('<strong>{{node.task.title}}</strong>')
|
||||
expect(app).not.toContain('<strong>{{subtask.title}}</strong>')
|
||||
})
|
||||
|
||||
it('keeps the Trash restore action at least 44px tall', () => {
|
||||
expect(css).toMatch(/\.restore\{[^}]*min-height:44px/)
|
||||
})
|
||||
|
||||
it('supports pointer dragging for desktop task and subtask completion', () => {
|
||||
expect(app.match(/@pointerdown="startTaskPointer/g)?.length).toBe(2)
|
||||
expect(app.match(/@pointermove="moveTaskPointer/g)?.length).toBe(2)
|
||||
expect(app.match(/@pointerup="finishTaskPointer/g)?.length).toBe(2)
|
||||
expect(app.match(/@pointercancel="cancelTaskPointer/g)?.length).toBe(2)
|
||||
expect(app.match(/@pointerdown="startTaskPointer/g)?.length).toBe(3)
|
||||
expect(app.match(/@pointermove="moveTaskPointer/g)?.length).toBe(3)
|
||||
expect(app.match(/@pointerup="finishTaskPointer/g)?.length).toBe(3)
|
||||
expect(app.match(/@pointercancel="cancelTaskPointer/g)?.length).toBe(3)
|
||||
})
|
||||
|
||||
it('supports pointer dragging for desktop habit rows in Today and Habits views', () => {
|
||||
@@ -400,7 +445,7 @@ describe('task and habit row decoration', () => {
|
||||
expect(app).not.toContain('class="sr-only" :aria-label="node.task.completed')
|
||||
expect(app).not.toContain('class="sr-only" :aria-label="subtask.completed')
|
||||
expect(app).toContain('class="task-check"')
|
||||
expect(app.match(/class="task-check"/g)?.length).toBe(3)
|
||||
expect(app.match(/class="task-check"/g)?.length).toBe(4)
|
||||
expect(app).toContain('class="task-check-mark"')
|
||||
expect(css).toContain('.task-check{')
|
||||
expect(css).toContain('.task-check-mark{')
|
||||
|
||||
Reference in New Issue
Block a user