bingocode 1.1.159 → 1.1.161

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bingocode",
3
- "version": "1.1.159",
3
+ "version": "1.1.161",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "claude": "bin/claude-win.cjs",
@@ -0,0 +1,42 @@
1
+ import { describe, it, expect } from "bun:test";
2
+ import { findActualString, normalizeIndentation } from "./utils";
3
+
4
+ describe("findActualString", () => {
5
+ it("exact match works", () => {
6
+ const file = " foo\n bar";
7
+ expect(findActualString(file, " bar")).toBe(" bar");
8
+ });
9
+
10
+ it("tab in file, spaces in search => matches via indent normalization", () => {
11
+ const file = "\t\tfoo\n\t\tbar";
12
+ const result = findActualString(file, " bar"); // model sent spaced ver
13
+ expect(result).toBe("\t\tbar");
14
+ });
15
+
16
+ it("spaces in file, tabs in search => matches via indent normalization", () => {
17
+ const file = " bar"; // 4-space indented file
18
+ const result = findActualString(file, "\tbar"); // model sent tab version
19
+ expect(result).toBe(" bar"); // should return actual content from file
20
+ });
21
+
22
+ it("normalizeIndentation trims leading whitespace", () => {
23
+ expect(normalizeIndentation(" hello")).toBe("hello");
24
+ expect(normalizeIndentation("\t\tfoo\n\t\tbar")).toBe("foo\nbar");
25
+ });
26
+
27
+ it("indent normalization preserves original string content", () => {
28
+ const file = "function test() {\n\tif (true) {\n\t\tconsole.log('hello');\n\t}\n}";
29
+ const search = "function test() {\n if (true) {\n console.log('hello');\n }\n}";
30
+ const result = findActualString(file, search);
31
+ expect(result).toBe(file);
32
+ });
33
+
34
+ it("exact match preferred over indent normalization when both possible", () => {
35
+ // File has tab-indented line
36
+ const file = "\t\tfoo\n\t\tbar";
37
+ const search = "\t\tbar"; // exact match - tab
38
+
39
+ // exact match should win (check via includes returning true first)
40
+ expect(findActualString(file, search)).toBe("\t\tbar");
41
+ });
42
+ });
@@ -92,10 +92,8 @@ export function findActualString(
92
92
  // Try with normalized quotes
93
93
  const normalizedSearch = normalizeQuotes(searchString)
94
94
  const normalizedFile = normalizeQuotes(fileContent)
95
-
96
95
  const searchIndex = normalizedFile.indexOf(normalizedSearch)
97
96
  if (searchIndex !== -1) {
98
- // Find the actual string in the file that matches
99
97
  return fileContent.substring(searchIndex, searchIndex + searchString.length)
100
98
  }
101
99
 
@@ -108,11 +106,26 @@ export function findActualString(
108
106
  }
109
107
 
110
108
  // Try with normalized leading whitespace (tab <-> space)
111
- const normalizedSearch = normalizeIndentation(searchString)
112
- const normalizedFile = normalizeIndentation(fileContent)
113
- const indentIndex = normalizedFile.indexOf(normalizedSearch)
114
- if (indentIndex !== -1) {
115
- return fileContent.substring(indentIndex, indentIndex + searchString.length)
109
+ const indentNormalizedSearch = normalizeIndentation(searchString)
110
+ const indentTrimmedFile = normalizeIndentation(fileContent)
111
+ const matchPoint = indentTrimmedFile.indexOf(indentNormalizedSearch)
112
+ if (matchPoint !== -1) {
113
+ // Leading whitespace normalization is NOT length-preserving,
114
+ // so compute bounds by matching each trimmed line back to its original.
115
+ const origLines = fileContent.split('\n')
116
+ const trimmedLines = indentTrimmedFile.split('\n')
117
+ const searchLines = indentNormalizedSearch.split('\n')
118
+ for (let i = 0; i <= trimmedLines.length - searchLines.length; i++) {
119
+ let k = 0
120
+ while (k < searchLines.length && trimmedLines[i + k] === searchLines[k]) k++
121
+ if (k !== searchLines.length) continue
122
+ let start = 0
123
+ for (let j = 0; j < i; j++) start += origLines[j].length + 1
124
+ let end = start
125
+ for (let j = i; j < i + k; j++) end += origLines[j].length + 1
126
+ return fileContent.substring(start, Math.max(start, end - 1))
127
+ }
128
+ return null
116
129
  }
117
130
 
118
131
  return null