MCPcopy Index your code
hub / github.com/getsentry/XcodeBuildMCP / discoverTestsInFileContent

Function discoverTestsInFileContent

src/utils/swift-test-discovery.ts:137–257  ·  view source on GitHub ↗
(
  targetName: string,
  filePath: string,
  content: string,
)

Source from the content-addressed store, hash-verified

135}
136
137function discoverTestsInFileContent(
138 targetName: string,
139 filePath: string,
140 content: string,
141): DiscoveredTestFile | null {
142 const rawLines = content.split(/\r?\n/);
143 const sanitizerState: SanitizerState = {
144 inBlockComment: false,
145 inMultilineString: false,
146 };
147 const sanitizedLines = rawLines.map((line) => sanitizeLine(line, sanitizerState));
148 const xctestTypes = collectXCTestTypes(sanitizedLines);
149 const tests: DiscoveredTestCase[] = [];
150 const scopeStack: Array<{ typeName?: string; xctestContext: boolean; depth: number }> = [];
151 let braceDepth = 0;
152 let pendingAttributes: string[] = [];
153 let pendingMultilineAttributeIndex: number | null = null;
154 let pendingAttributeParenthesisDepth = 0;
155
156 sanitizedLines.forEach((sanitizedLine, index) => {
157 const lineNumber = index + 1;
158 const line = sanitizedLine.trim();
159
160 while (scopeStack.length > 0 && braceDepth < scopeStack[scopeStack.length - 1].depth) {
161 scopeStack.pop();
162 }
163
164 let consumedAttributeContinuation = false;
165
166 if (line.startsWith('@')) {
167 pendingAttributes.push(line);
168 const parenthesisDepth = countParentheses(line);
169 if (parenthesisDepth > 0) {
170 pendingMultilineAttributeIndex = pendingAttributes.length - 1;
171 pendingAttributeParenthesisDepth = parenthesisDepth;
172 } else {
173 pendingMultilineAttributeIndex = null;
174 pendingAttributeParenthesisDepth = 0;
175 }
176 } else if (pendingMultilineAttributeIndex !== null) {
177 pendingAttributes[pendingMultilineAttributeIndex] =
178 `${pendingAttributes[pendingMultilineAttributeIndex]} ${line}`;
179 pendingAttributeParenthesisDepth += countParentheses(line);
180 consumedAttributeContinuation = true;
181 if (pendingAttributeParenthesisDepth <= 0) {
182 pendingMultilineAttributeIndex = null;
183 pendingAttributeParenthesisDepth = 0;
184 }
185 }
186
187 const typeMatch = line.match(
188 /\b(?:final\s+)?(?:class|struct|actor)\s+([A-Za-z_][A-Za-z0-9_]*)\b(?:\s*:\s*([^{]+))?/,
189 );
190 const extensionMatch = line.match(/\bextension\s+([A-Za-z_][A-Za-z0-9_]*)\b/);
191
192 if (typeMatch && line.includes('{')) {
193 const typeName = typeMatch[1];
194 const inheritanceClause = typeMatch[2] ?? '';

Callers 1

Calls 6

sanitizeLineFunction · 0.85
collectXCTestTypesFunction · 0.85
countParenthesesFunction · 0.85
countBracesFunction · 0.85
formatDisplayNameFunction · 0.85
pushMethod · 0.80

Tested by

no test coverage detected