|
| 1 | +import * as assert from 'assert'; |
| 2 | +import { suite, test } from 'mocha'; |
| 3 | +import { |
| 4 | + TaskStatus, |
| 5 | + EpicStatus, |
| 6 | + TaskFrontmatter, |
| 7 | + EpicFrontmatter, |
| 8 | + TASK_STATUS_VALUES, |
| 9 | + EPIC_STATUS_VALUES, |
| 10 | + isTaskStatus, |
| 11 | + isEpicStatus |
| 12 | +} from '../../types/frontmatter'; |
| 13 | + |
| 14 | +suite('Frontmatter Types Test Suite', () => { |
| 15 | + |
| 16 | + suite('TaskStatus type', () => { |
| 17 | + test('TASK_STATUS_VALUES should contain all valid task statuses', () => { |
| 18 | + assert.strictEqual(TASK_STATUS_VALUES.length, 5, 'Should have 5 status values'); |
| 19 | + assert.ok(TASK_STATUS_VALUES.includes('open'), 'Should include open'); |
| 20 | + assert.ok(TASK_STATUS_VALUES.includes('in_progress'), 'Should include in_progress'); |
| 21 | + assert.ok(TASK_STATUS_VALUES.includes('blocked'), 'Should include blocked'); |
| 22 | + assert.ok(TASK_STATUS_VALUES.includes('completed'), 'Should include completed'); |
| 23 | + assert.ok(TASK_STATUS_VALUES.includes('cancelled'), 'Should include cancelled'); |
| 24 | + }); |
| 25 | + |
| 26 | + test('isTaskStatus should return true for valid statuses', () => { |
| 27 | + assert.strictEqual(isTaskStatus('open'), true); |
| 28 | + assert.strictEqual(isTaskStatus('in_progress'), true); |
| 29 | + assert.strictEqual(isTaskStatus('blocked'), true); |
| 30 | + assert.strictEqual(isTaskStatus('completed'), true); |
| 31 | + assert.strictEqual(isTaskStatus('cancelled'), true); |
| 32 | + }); |
| 33 | + |
| 34 | + test('isTaskStatus should return false for invalid statuses', () => { |
| 35 | + assert.strictEqual(isTaskStatus('invalid'), false); |
| 36 | + assert.strictEqual(isTaskStatus('pending'), false); |
| 37 | + assert.strictEqual(isTaskStatus('done'), false); |
| 38 | + assert.strictEqual(isTaskStatus(''), false); |
| 39 | + assert.strictEqual(isTaskStatus(null), false); |
| 40 | + assert.strictEqual(isTaskStatus(undefined), false); |
| 41 | + assert.strictEqual(isTaskStatus(123), false); |
| 42 | + assert.strictEqual(isTaskStatus({}), false); |
| 43 | + assert.strictEqual(isTaskStatus([]), false); |
| 44 | + }); |
| 45 | + }); |
| 46 | + |
| 47 | + suite('EpicStatus type', () => { |
| 48 | + test('EPIC_STATUS_VALUES should contain all valid epic statuses', () => { |
| 49 | + assert.strictEqual(EPIC_STATUS_VALUES.length, 4, 'Should have 4 status values'); |
| 50 | + assert.ok(EPIC_STATUS_VALUES.includes('backlog'), 'Should include backlog'); |
| 51 | + assert.ok(EPIC_STATUS_VALUES.includes('in_progress'), 'Should include in_progress'); |
| 52 | + assert.ok(EPIC_STATUS_VALUES.includes('completed'), 'Should include completed'); |
| 53 | + assert.ok(EPIC_STATUS_VALUES.includes('cancelled'), 'Should include cancelled'); |
| 54 | + }); |
| 55 | + |
| 56 | + test('isEpicStatus should return true for valid statuses', () => { |
| 57 | + assert.strictEqual(isEpicStatus('backlog'), true); |
| 58 | + assert.strictEqual(isEpicStatus('in_progress'), true); |
| 59 | + assert.strictEqual(isEpicStatus('completed'), true); |
| 60 | + assert.strictEqual(isEpicStatus('cancelled'), true); |
| 61 | + }); |
| 62 | + |
| 63 | + test('isEpicStatus should return false for invalid statuses', () => { |
| 64 | + assert.strictEqual(isEpicStatus('invalid'), false); |
| 65 | + assert.strictEqual(isEpicStatus('open'), false); // open is TaskStatus, not EpicStatus |
| 66 | + assert.strictEqual(isEpicStatus('blocked'), false); // blocked is TaskStatus, not EpicStatus |
| 67 | + assert.strictEqual(isEpicStatus(''), false); |
| 68 | + assert.strictEqual(isEpicStatus(null), false); |
| 69 | + assert.strictEqual(isEpicStatus(undefined), false); |
| 70 | + assert.strictEqual(isEpicStatus(123), false); |
| 71 | + assert.strictEqual(isEpicStatus({}), false); |
| 72 | + }); |
| 73 | + }); |
| 74 | + |
| 75 | + suite('TaskFrontmatter interface', () => { |
| 76 | + test('should allow creation of valid TaskFrontmatter object', () => { |
| 77 | + const taskFrontmatter: TaskFrontmatter = { |
| 78 | + name: 'Initialize extension project with TypeScript + webpack config', |
| 79 | + status: 'open', |
| 80 | + created: '2025-10-04T12:22:30Z', |
| 81 | + updated: '2025-10-04T12:39:29Z', |
| 82 | + github: 'https://github.com/johnproblems/formaltask/issues/2', |
| 83 | + depends_on: [], |
| 84 | + parallel: true, |
| 85 | + conflicts_with: [] |
| 86 | + }; |
| 87 | + |
| 88 | + assert.strictEqual(taskFrontmatter.name, 'Initialize extension project with TypeScript + webpack config'); |
| 89 | + assert.strictEqual(taskFrontmatter.status, 'open'); |
| 90 | + assert.strictEqual(taskFrontmatter.created, '2025-10-04T12:22:30Z'); |
| 91 | + assert.strictEqual(taskFrontmatter.updated, '2025-10-04T12:39:29Z'); |
| 92 | + assert.strictEqual(taskFrontmatter.github, 'https://github.com/johnproblems/formaltask/issues/2'); |
| 93 | + assert.deepStrictEqual(taskFrontmatter.depends_on, []); |
| 94 | + assert.strictEqual(taskFrontmatter.parallel, true); |
| 95 | + assert.deepStrictEqual(taskFrontmatter.conflicts_with, []); |
| 96 | + }); |
| 97 | + |
| 98 | + test('should allow depends_on with string references', () => { |
| 99 | + const taskFrontmatter: TaskFrontmatter = { |
| 100 | + name: 'Configure testing infrastructure', |
| 101 | + status: 'open', |
| 102 | + created: '2025-10-04T12:22:30Z', |
| 103 | + updated: '2025-10-04T12:39:29Z', |
| 104 | + github: 'https://github.com/johnproblems/formaltask/issues/3', |
| 105 | + depends_on: ['Task 2.md'], |
| 106 | + parallel: false, |
| 107 | + conflicts_with: [] |
| 108 | + }; |
| 109 | + |
| 110 | + assert.deepStrictEqual(taskFrontmatter.depends_on, ['Task 2.md']); |
| 111 | + }); |
| 112 | + |
| 113 | + test('should allow depends_on with numeric IDs', () => { |
| 114 | + const taskFrontmatter: TaskFrontmatter = { |
| 115 | + name: 'Create Epic data provider service', |
| 116 | + status: 'open', |
| 117 | + created: '2025-10-04T12:22:30Z', |
| 118 | + updated: '2025-10-04T12:39:29Z', |
| 119 | + github: 'https://github.com/johnproblems/formaltask/issues/10', |
| 120 | + depends_on: [8], |
| 121 | + parallel: false, |
| 122 | + conflicts_with: [] |
| 123 | + }; |
| 124 | + |
| 125 | + assert.deepStrictEqual(taskFrontmatter.depends_on, [8]); |
| 126 | + }); |
| 127 | + |
| 128 | + test('should allow mixed depends_on values', () => { |
| 129 | + const taskFrontmatter: TaskFrontmatter = { |
| 130 | + name: 'Mixed dependencies task', |
| 131 | + status: 'in_progress', |
| 132 | + created: '2025-10-04T12:22:30Z', |
| 133 | + updated: '2025-10-04T12:39:29Z', |
| 134 | + github: 'https://github.com/johnproblems/formaltask/issues/15', |
| 135 | + depends_on: [2, 'Task 3.md', 4], |
| 136 | + parallel: true, |
| 137 | + conflicts_with: [5, 'Task 6.md'] |
| 138 | + }; |
| 139 | + |
| 140 | + assert.deepStrictEqual(taskFrontmatter.depends_on, [2, 'Task 3.md', 4]); |
| 141 | + assert.deepStrictEqual(taskFrontmatter.conflicts_with, [5, 'Task 6.md']); |
| 142 | + }); |
| 143 | + |
| 144 | + test('should allow all valid task statuses', () => { |
| 145 | + const statuses: TaskStatus[] = ['open', 'in_progress', 'blocked', 'completed', 'cancelled']; |
| 146 | + |
| 147 | + for (const status of statuses) { |
| 148 | + const taskFrontmatter: TaskFrontmatter = { |
| 149 | + name: `Task with status ${status}`, |
| 150 | + status: status, |
| 151 | + created: '2025-10-04T12:22:30Z', |
| 152 | + updated: '2025-10-04T12:39:29Z', |
| 153 | + github: 'https://github.com/johnproblems/formaltask/issues/1', |
| 154 | + depends_on: [], |
| 155 | + parallel: true, |
| 156 | + conflicts_with: [] |
| 157 | + }; |
| 158 | + |
| 159 | + assert.strictEqual(taskFrontmatter.status, status); |
| 160 | + } |
| 161 | + }); |
| 162 | + }); |
| 163 | + |
| 164 | + suite('EpicFrontmatter interface', () => { |
| 165 | + test('should allow creation of valid EpicFrontmatter object', () => { |
| 166 | + const epicFrontmatter: EpicFrontmatter = { |
| 167 | + name: 'vscode-extension', |
| 168 | + status: 'backlog', |
| 169 | + created: '2025-10-04T12:11:36Z', |
| 170 | + progress: '0%', |
| 171 | + prd: '.claude/prds/vscode-extension.md', |
| 172 | + github: 'https://github.com/johnproblems/formaltask/issues/1' |
| 173 | + }; |
| 174 | + |
| 175 | + assert.strictEqual(epicFrontmatter.name, 'vscode-extension'); |
| 176 | + assert.strictEqual(epicFrontmatter.status, 'backlog'); |
| 177 | + assert.strictEqual(epicFrontmatter.created, '2025-10-04T12:11:36Z'); |
| 178 | + assert.strictEqual(epicFrontmatter.progress, '0%'); |
| 179 | + assert.strictEqual(epicFrontmatter.prd, '.claude/prds/vscode-extension.md'); |
| 180 | + assert.strictEqual(epicFrontmatter.github, 'https://github.com/johnproblems/formaltask/issues/1'); |
| 181 | + }); |
| 182 | + |
| 183 | + test('should allow all valid epic statuses', () => { |
| 184 | + const statuses: EpicStatus[] = ['backlog', 'in_progress', 'completed', 'cancelled']; |
| 185 | + |
| 186 | + for (const status of statuses) { |
| 187 | + const epicFrontmatter: EpicFrontmatter = { |
| 188 | + name: `Epic with status ${status}`, |
| 189 | + status: status, |
| 190 | + created: '2025-10-04T12:11:36Z', |
| 191 | + progress: '50%', |
| 192 | + prd: '.claude/prds/test.md', |
| 193 | + github: 'https://github.com/johnproblems/formaltask/issues/1' |
| 194 | + }; |
| 195 | + |
| 196 | + assert.strictEqual(epicFrontmatter.status, status); |
| 197 | + } |
| 198 | + }); |
| 199 | + |
| 200 | + test('should handle various progress percentage formats', () => { |
| 201 | + const progressValues = ['0%', '25%', '50%', '75%', '100%']; |
| 202 | + |
| 203 | + for (const progress of progressValues) { |
| 204 | + const epicFrontmatter: EpicFrontmatter = { |
| 205 | + name: 'test-epic', |
| 206 | + status: 'in_progress', |
| 207 | + created: '2025-10-04T12:11:36Z', |
| 208 | + progress: progress, |
| 209 | + prd: '.claude/prds/test.md', |
| 210 | + github: 'https://github.com/johnproblems/formaltask/issues/1' |
| 211 | + }; |
| 212 | + |
| 213 | + assert.strictEqual(epicFrontmatter.progress, progress); |
| 214 | + } |
| 215 | + }); |
| 216 | + }); |
| 217 | +}); |
0 commit comments