Skip to content

Commit 06af1fe

Browse files
author
QuantCode Agent
committed
fix: resolve all 16 failing tests across utility library
- calculator: throw on division by zero instead of returning Infinity - date-utils: use Math.round for day calculation in formatRelative - string-utils: fix wordCount to handle multiple spaces, implement truncate - task-manager: implement remove, update, and sortBy methods - validator: allow longer TLDs in isEmail, support ports in isUrl
1 parent 2354bc5 commit 06af1fe

5 files changed

Lines changed: 27 additions & 19 deletions

File tree

src/calculator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export function multiply(a: number, b: number): number {
1515
return a * b
1616
}
1717

18-
// BUG: Division by zero is not handled
1918
export function divide(a: number, b: number): number {
19+
if (b === 0) throw new Error("Division by zero")
2020
return a / b
2121
}

src/date-utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export function formatRelative(date: Date, now: Date = new Date()): string {
1414
const diffSec = diffMs / 1000
1515
const diffMin = diffSec / 60
1616
const diffHours = diffMin / 60
17-
const diffDays = Math.floor(diffHours / 24) // BUG: should be Math.round
17+
const diffDays = Math.round(diffHours / 24)
1818

1919
if (Math.abs(diffSec) < 60) return "just now"
2020
if (Math.abs(diffMin) < 60) {

src/string-utils.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,14 @@ export function reverse(str: string): string {
1111
return str.split("").reverse().join("")
1212
}
1313

14-
// TODO: implement truncate — should truncate at a word boundary, with "..."
15-
// counting toward maxLength. Return unchanged if str.length <= maxLength.
1614
export function truncate(str: string, maxLength: number): string {
17-
throw new Error("not implemented")
15+
if (str.length <= maxLength) return str
16+
const budget = maxLength - 3 // reserve space for "..."
17+
if (budget <= 0) return "...".slice(0, maxLength)
18+
const truncated = str.slice(0, budget)
19+
const lastSpace = truncated.lastIndexOf(" ")
20+
const cut = lastSpace > 0 ? truncated.slice(0, lastSpace) : truncated
21+
return cut + "..."
1822
}
1923

2024
export function slugify(str: string): string {
@@ -24,8 +28,7 @@ export function slugify(str: string): string {
2428
.replace(/^-|-$/g, "")
2529
}
2630

27-
// BUG: This doesn't handle multiple consecutive spaces
2831
export function wordCount(str: string): number {
2932
if (!str.trim()) return 0
30-
return str.split(" ").length
33+
return str.trim().split(/\s+/).filter(Boolean).length
3134
}

src/task-manager.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,20 +52,27 @@ export class TaskManager {
5252
return true
5353
}
5454

55-
// TODO: implement — remove a task by id, return true if removed, false if not found
5655
remove(id: string): boolean {
57-
throw new Error("not implemented")
56+
return this.tasks.delete(id)
5857
}
5958

60-
// TODO: implement — update title/description/priority of a task
61-
// return true if updated, false if not found
6259
update(id: string, changes: Partial<Pick<Task, "title" | "description" | "priority">>): boolean {
63-
throw new Error("not implemented")
60+
const task = this.tasks.get(id)
61+
if (!task) return false
62+
if (changes.title !== undefined) task.title = changes.title
63+
if (changes.description !== undefined) task.description = changes.description
64+
if (changes.priority !== undefined) task.priority = changes.priority
65+
return true
6466
}
6567

66-
// TODO: implement — return all tasks sorted by the given field
67-
// priority sort order: high > medium > low
6868
sortBy(field: "priority" | "createdAt" | "status"): Task[] {
69-
throw new Error("not implemented")
69+
const priorityOrder: Record<Priority, number> = { high: 0, medium: 1, low: 2 }
70+
const statusOrder: Record<Status, number> = { pending: 0, in_progress: 1, completed: 2 }
71+
return Array.from(this.tasks.values()).sort((a, b) => {
72+
if (field === "priority") return priorityOrder[a.priority] - priorityOrder[b.priority]
73+
if (field === "createdAt") return a.createdAt.getTime() - b.createdAt.getTime()
74+
if (field === "status") return statusOrder[a.status] - statusOrder[b.status]
75+
return 0
76+
})
7077
}
7178
}

src/validator.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99
* and rejects valid TLDs longer than 4 chars (e.g. .museum, .travel).
1010
*/
1111
export function isEmail(value: string): boolean {
12-
// BUG: too restrictive — missing subdomain support and long TLDs
13-
return /^[^\s@]+@[^\s@]+\.[a-zA-Z]{2,4}$/.test(value)
12+
return /^[^\s@]+@[^\s@]+\.[a-zA-Z]{2,}$/.test(value)
1413
}
1514

1615
/**
@@ -21,8 +20,7 @@ export function isEmail(value: string): boolean {
2120
export function isUrl(value: string): boolean {
2221
try {
2322
const url = new URL(value)
24-
// BUG: only allows http/https but also rejects valid port usage
25-
return (url.protocol === "http:" || url.protocol === "https:") && url.port === ""
23+
return url.protocol === "http:" || url.protocol === "https:"
2624
} catch {
2725
return false
2826
}

0 commit comments

Comments
 (0)