-
Notifications
You must be signed in to change notification settings - Fork 51
Expand file tree
/
Copy pathsql-analyze-tool.test.ts
More file actions
172 lines (156 loc) · 5.34 KB
/
sql-analyze-tool.test.ts
File metadata and controls
172 lines (156 loc) · 5.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/**
* Tests for SqlAnalyzeTool title construction and formatAnalysis output.
*
* These test the formatting logic patterns used in sql-analyze.ts.
* Since formatAnalysis is not exported, we replicate its logic here —
* same approach as tool-formatters.test.ts. This means these tests
* will not catch changes to the real function unless the test copy
* is also updated. This is an accepted tradeoff in this codebase.
*/
import { describe, test, expect } from "bun:test"
describe("SqlAnalyzeTool: title construction", () => {
// Replicates the title template from sql-analyze.ts execute() line 25
function buildTitle(result: { error?: string; issue_count: number; confidence: string }) {
return `Analyze: ${result.error ? "PARSE ERROR" : `${result.issue_count} issue${result.issue_count !== 1 ? "s" : ""}`} [${result.confidence}]`
}
test("zero issues shows '0 issues'", () => {
expect(buildTitle({ issue_count: 0, confidence: "high" })).toBe("Analyze: 0 issues [high]")
})
test("one issue shows singular '1 issue'", () => {
expect(buildTitle({ issue_count: 1, confidence: "high" })).toBe("Analyze: 1 issue [high]")
})
test("multiple issues shows plural", () => {
expect(buildTitle({ issue_count: 5, confidence: "medium" })).toBe("Analyze: 5 issues [medium]")
})
test("error present shows PARSE ERROR", () => {
expect(buildTitle({ error: "syntax error", issue_count: 0, confidence: "low" })).toBe(
"Analyze: PARSE ERROR [low]",
)
})
})
describe("SqlAnalyzeTool: formatAnalysis output", () => {
// Replicates formatAnalysis() from sql-analyze.ts lines 45-70
function formatAnalysis(result: {
error?: string
issues: Array<{
type: string
severity: string
message: string
recommendation: string
location?: string
confidence: string
}>
issue_count: number
confidence: string
confidence_factors: string[]
}): string {
if (result.error) return `Analysis failed: ${result.error}`
if (result.issues.length === 0) return "No anti-patterns or issues detected."
const lines: string[] = [
`Found ${result.issue_count} issue${result.issue_count !== 1 ? "s" : ""} (confidence: ${result.confidence}):`,
]
if (result.confidence_factors.length > 0) {
lines.push(` Note: ${result.confidence_factors.join("; ")}`)
}
lines.push("")
for (const issue of result.issues) {
const loc = issue.location ? ` \u2014 ${issue.location}` : ""
const conf = issue.confidence !== "high" ? ` [${issue.confidence} confidence]` : ""
lines.push(` [${issue.severity.toUpperCase()}] ${issue.type}${conf}`)
lines.push(` ${issue.message}${loc}`)
lines.push(` \u2192 ${issue.recommendation}`)
lines.push("")
}
return lines.join("\n")
}
test("error result returns failure message", () => {
const output = formatAnalysis({
error: "parse error at line 5",
issues: [],
issue_count: 0,
confidence: "low",
confidence_factors: [],
})
expect(output).toBe("Analysis failed: parse error at line 5")
})
test("zero issues returns clean message", () => {
const output = formatAnalysis({
issues: [],
issue_count: 0,
confidence: "high",
confidence_factors: [],
})
expect(output).toBe("No anti-patterns or issues detected.")
})
test("issues are formatted with severity, type, location", () => {
const output = formatAnalysis({
issues: [
{
type: "lint",
severity: "warning",
message: "SELECT * detected",
recommendation: "Use explicit columns",
location: "line 1",
confidence: "high",
},
],
issue_count: 1,
confidence: "high",
confidence_factors: ["lint"],
})
expect(output).toContain("[WARNING] lint")
expect(output).toContain("SELECT * detected \u2014 line 1")
expect(output).toContain("\u2192 Use explicit columns")
})
test("non-high confidence issues show confidence tag", () => {
const output = formatAnalysis({
issues: [
{
type: "semantic",
severity: "info",
message: "Possible unused join",
recommendation: "Review join necessity",
confidence: "medium",
},
],
issue_count: 1,
confidence: "medium",
confidence_factors: ["semantics"],
})
expect(output).toContain("[medium confidence]")
})
test("high confidence issues omit confidence tag", () => {
const output = formatAnalysis({
issues: [
{
type: "safety",
severity: "high",
message: "SQL injection risk",
recommendation: "Use parameterized queries",
confidence: "high",
},
],
issue_count: 1,
confidence: "high",
confidence_factors: ["safety"],
})
expect(output).not.toContain("[high confidence]")
})
test("confidence factors are listed in Note line", () => {
const output = formatAnalysis({
issues: [
{
type: "lint",
severity: "warning",
message: "Missing LIMIT",
recommendation: "Add LIMIT clause",
confidence: "high",
},
],
issue_count: 1,
confidence: "high",
confidence_factors: ["lint", "semantics", "safety"],
})
expect(output).toContain("Note: lint; semantics; safety")
})
})