Skip to content

Commit 51e6d40

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

5 files changed

Lines changed: 24 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 3 chars for "..."
17+
if (budget <= 0) return str.slice(0, maxLength - 3) + "..."
18+
const truncated = str.slice(0, budget)
19+
const lastSpace = truncated.lastIndexOf(" ")
20+
if (lastSpace > 0) return truncated.slice(0, lastSpace) + "..."
21+
return truncated + "..."
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+/).length
3134
}

src/task-manager.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,20 +52,24 @@ 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+
Object.assign(task, changes)
63+
return true
6464
}
6565

66-
// TODO: implement — return all tasks sorted by the given field
67-
// priority sort order: high > medium > low
6866
sortBy(field: "priority" | "createdAt" | "status"): Task[] {
69-
throw new Error("not implemented")
67+
const priorityOrder: Record<string, number> = { high: 0, medium: 1, low: 2 }
68+
return Array.from(this.tasks.values()).sort((a, b) => {
69+
if (field === "priority") return priorityOrder[a.priority] - priorityOrder[b.priority]
70+
if (field === "createdAt") return a.createdAt.getTime() - b.createdAt.getTime()
71+
// status: alphabetical
72+
return a.status.localeCompare(b.status)
73+
})
7074
}
7175
}

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,63}$/.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)