Skip to content

Commit 7c09eb8

Browse files
committed
refactor textUtilities tests
1 parent 13353da commit 7c09eb8

File tree

5 files changed

+98
-41
lines changed

5 files changed

+98
-41
lines changed

packages/core/src/amazonq/commons/controllers/contentController.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,13 @@ import {
1515
getIndentedCode,
1616
getSelectionFromRange,
1717
} from '../../../shared/utilities/textDocumentUtilities'
18-
import { extractFileAndCodeSelectionFromMessage, fs, getErrorMsg, ToolkitError } from '../../../shared'
18+
import {
19+
extractFileAndCodeSelectionFromMessage,
20+
formatTextWithIndent,
21+
fs,
22+
getErrorMsg,
23+
ToolkitError,
24+
} from '../../../shared'
1925

2026
export class ContentProvider implements vscode.TextDocumentContentProvider {
2127
constructor(private uri: vscode.Uri) {}
@@ -49,14 +55,7 @@ export class EditorContentController {
4955
if (indent.trim().length !== 0) {
5056
indent = ' '.repeat(indent.length - indent.trimStart().length)
5157
}
52-
let textWithIndent = ''
53-
text.split('\n').forEach((line, index) => {
54-
if (index === 0) {
55-
textWithIndent += line
56-
} else {
57-
textWithIndent += '\n' + indent + line
58-
}
59-
})
58+
const textWithIndent = formatTextWithIndent(text, indent)
6059
editor
6160
.edit((editBuilder) => {
6261
editBuilder.insert(cursorStart, textWithIndent)

packages/core/src/amazonq/commons/diff.ts

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import * as vscode from 'vscode'
77
import { fs } from '../../shared'
8-
import { diffLines } from 'diff'
8+
import { Change, diffLines } from 'diff'
99

1010
export async function openDiff(leftPath: string, rightPath: string, tabId: string, scheme: string) {
1111
const { left, right } = await getFileDiffUris(leftPath, rightPath, tabId, scheme)
@@ -42,21 +42,30 @@ export async function computeDiff(leftPath: string, rightPath: string, tabId: st
4242
ignoreWhitespace: true,
4343
})
4444

45-
let charsAdded = 0
46-
let charsRemoved = 0
47-
let linesAdded = 0
48-
let linesRemoved = 0
49-
changes.forEach((change) => {
50-
const lines = change.value.split('\n')
51-
const charCount = lines.reduce((sum, line) => sum + line.length, 0)
52-
const lineCount = change.count ?? lines.length - 1 // ignoring end-of-file empty line
53-
if (change.added) {
54-
charsAdded += charCount
55-
linesAdded += lineCount
56-
} else if (change.removed) {
57-
charsRemoved += charCount
58-
linesRemoved += lineCount
59-
}
60-
})
61-
return { changes, charsAdded, linesAdded, charsRemoved, linesRemoved }
45+
interface Result {
46+
charsAdded: number
47+
linesAdded: number
48+
charsRemoved: number
49+
linesRemoved: number
50+
}
51+
52+
const changeDetails = changes.reduce(
53+
(curResult: Result, change: Change) => {
54+
const lines = change.value.split('\n')
55+
const charCount = lines.reduce((sum, line) => sum + line.length, 0)
56+
const lineCount = change.count ?? lines.length - 1 // ignoring end-of-file empty line
57+
58+
if (change.added) {
59+
curResult.charsAdded += charCount
60+
curResult.linesAdded += lineCount
61+
} else if (change.removed) {
62+
curResult.charsRemoved += charCount
63+
curResult.linesRemoved += lineCount
64+
}
65+
return curResult
66+
},
67+
{ charsAdded: 0, linesAdded: 0, charsRemoved: 0, linesRemoved: 0 }
68+
)
69+
70+
return { changes, ...changeDetails }
6271
}

packages/core/src/shared/utilities/collectionUtils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -346,13 +346,13 @@ export function inspect(obj: any, opt?: { depth: number }): string {
346346
export function stripUndefined<T extends Record<string, any>>(
347347
obj: T
348348
): asserts obj is { [P in keyof T]-?: NonNullable<T[P]> } {
349-
Object.keys(obj).forEach((key) => {
349+
for (const key of Object.keys(obj)) {
350350
if (obj[key] === undefined) {
351351
delete obj[key]
352352
} else if (typeof obj[key] === 'object') {
353353
stripUndefined(obj[key])
354354
}
355-
})
355+
}
356356
}
357357

358358
export function isAsyncIterable(obj: any): obj is AsyncIterable<unknown> {

packages/core/src/shared/utilities/textUtilities.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,3 +274,8 @@ export function extractFileAndCodeSelectionFromMessage(message: any) {
274274
const selection = message?.context?.focusAreaContext?.selectionInsideExtendedCodeBlock as vscode.Selection
275275
return { filePath, selection }
276276
}
277+
278+
export function formatTextWithIndent(text: string, indent: string): string {
279+
// TODO: shouldn't this trim the resulting string?
280+
return text.split('\n').reduce((prev, curr) => (prev === '' ? prev + curr : prev + '\n' + indent + curr))
281+
}

packages/core/src/test/shared/utilities/textUtilities.test.ts

Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import {
1313
sanitizeFilename,
1414
toSnakeCase,
1515
undefinedIfEmpty,
16+
formatTextWithIndent,
17+
formatTextWithIndent2,
1618
} from '../../../shared/utilities/textUtilities'
1719

1820
describe('textUtilities', async function () {
@@ -131,21 +133,35 @@ describe('toSnakeCase', function () {
131133
})
132134
})
133135

136+
interface TestCase<Input, Output> {
137+
input: Input
138+
params?: any[]
139+
output: Output
140+
case: string
141+
}
142+
143+
function generateTestCases<Input, Output>(
144+
cases: TestCase<Input, Output>[],
145+
f: (t: Input, ...p: any[]) => Output
146+
): void {
147+
for (const c of cases) {
148+
it(c.case, function () {
149+
assert.strictEqual(c.params ? f(c.input, ...c.params) : f(c.input), c.output)
150+
})
151+
}
152+
}
153+
134154
describe('sanitizeFilename', function () {
135-
const cases: { input: string; output: string; case: string; replaceString?: string }[] = [
155+
const cases = [
136156
{ input: 'foo🤷', output: 'foo_', case: 'removes emojis' },
137157
{ input: 'foo/zub', output: 'foo_zub', case: 'replaces slash with underscore' },
138158
{ input: 'foo zub', output: 'foo_zub', case: 'replaces space with underscore' },
139-
{ input: 'foo:bar', output: 'fooXbar', replaceString: 'X', case: 'replaces dot with replaceString' },
159+
{ input: 'foo:bar', output: 'fooXbar', params: ['X'], case: 'replaces dot with replaceString' },
140160
{ input: 'foo🤷bar/zu b.txt', output: 'foo_bar_zu_b.txt', case: 'docstring example' },
141161
{ input: 'foo.txt', output: 'foo.txt', case: 'keeps dot' },
142162
{ input: 'züb', output: 'züb', case: 'keeps special chars' },
143163
]
144-
cases.forEach((testCase) => {
145-
it(testCase.case, function () {
146-
assert.strictEqual(sanitizeFilename(testCase.input, testCase.replaceString), testCase.output)
147-
})
148-
})
164+
generateTestCases(cases, sanitizeFilename)
149165
})
150166

151167
describe('undefinedIfEmpty', function () {
@@ -157,9 +173,37 @@ describe('undefinedIfEmpty', function () {
157173
{ input: ' foo ', output: ' foo ', case: 'return original str without trim' },
158174
]
159175

160-
cases.forEach((testCases) => {
161-
it(testCases.case, function () {
162-
assert.strictEqual(undefinedIfEmpty(testCases.input), testCases.output)
163-
})
164-
})
176+
generateTestCases(cases, undefinedIfEmpty)
177+
})
178+
179+
describe('formatStringWithIndent', function () {
180+
const cases = [
181+
{ input: 'foo', output: 'foo', params: [' '], case: 'return str if input is not multiline' },
182+
{
183+
input: 'foo\nbar',
184+
output: 'foo\n bar',
185+
params: [' '],
186+
case: 'return str with indent if input is multiline',
187+
},
188+
{
189+
input: 'foo\n\nbar',
190+
output: 'foo\n \n bar',
191+
params: [' '],
192+
case: 'return str with indent if input is multiline with empty line',
193+
},
194+
{
195+
input: 'foo\nbar\nfoo\nbar\n',
196+
output: 'foo\n bar\n foo\n bar\n ',
197+
params: [' '],
198+
case: 'return str with indent if input is multiline with empty line at the end',
199+
},
200+
{
201+
input: 'foo\nbar\nfoo\nbar\n',
202+
output: 'foo\nbar\nfoo\nbar\n',
203+
params: [''],
204+
case: 'returns original string with empty indent',
205+
},
206+
]
207+
208+
generateTestCases(cases, formatTextWithIndent)
165209
})

0 commit comments

Comments
 (0)