Skip to content

Commit fae1a7a

Browse files
Burgynclaude
andcommitted
Refactor TpFileParser to context-based parsing pattern
Introduce TpParsingContext to align TpFileParser with the project's convention where parsers accept a context and return void, storing results in the context (matching IHttpRequestParser/ILineParser pattern). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 01b72d8 commit fae1a7a

5 files changed

Lines changed: 67 additions & 31 deletions

File tree

src/TeaPie.DotnetTool/CompileScriptCommand.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,11 @@ private async Task<int> CompileTpScripts(string path, Settings settings)
4646

4747
var content = File.ReadAllText(path);
4848
var parser = new TpFileParser();
49+
var parsingContext = new TpParsingContext(content, Path.GetFileNameWithoutExtension(path));
4950

50-
List<TpTestCaseDefinition> definitions;
5151
try
5252
{
53-
definitions = parser.Parse(content, Path.GetFileNameWithoutExtension(path));
53+
parser.Parse(parsingContext);
5454
}
5555
catch (Exception ex)
5656
{
@@ -60,7 +60,7 @@ private async Task<int> CompileTpScripts(string path, Settings settings)
6060

6161
var overallSuccess = true;
6262

63-
foreach (var def in definitions)
63+
foreach (var def in parsingContext.Definitions)
6464
{
6565
AnsiConsole.MarkupLine($"\n[bold]Test case:[/] [white]'{def.Name.EscapeMarkup()}'[/]");
6666

src/TeaPie/StructureExploration/BaseStructureExplorer.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,12 @@ protected void ExploreTpFile(
9595
var content = System.IO.File.ReadAllText(tpFilePath);
9696
var fallbackName = Path.GetFileNameWithoutExtension(tpFilePath);
9797

98-
var definitions = _tpFileParser.Parse(content, fallbackName);
98+
var parsingContext = new TpParsingContext(content, fallbackName);
99+
_tpFileParser.Parse(parsingContext);
99100

100101
var relativePath = GetRelativePath(currentFolder, Path.GetFileName(tpFilePath));
101102

102-
foreach (var definition in definitions)
103+
foreach (var definition in parsingContext.Definitions)
103104
{
104105
var requestFileObj = new InternalFile(tpFilePath, relativePath, currentFolder);
105106
var testCase = new TestCase(requestFileObj)

src/TeaPie/TestCases/TpFileParser.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,23 @@ internal class TpFileParser
77
private static readonly string[] LineSeparators = [Constants.WindowsEndOfLine, Constants.UnixEndOfLine];
88

99
/// <summary>
10-
/// Parses the content of a <c>.tp</c> file into a list of test case definitions.
10+
/// Parses the content of a <c>.tp</c> file and stores the resulting
11+
/// test case definitions in <see cref="TpParsingContext.Definitions"/>.
1112
/// </summary>
12-
/// <param name="content">Full text content of the <c>.tp</c> file.</param>
13-
/// <param name="fallbackName">
14-
/// Name used when the file contains no explicit <c>--- TESTCASE</c> marker
15-
/// (i.e. single implicit test case).
13+
/// <param name="context">
14+
/// Parsing context that carries the input content and receives the parsed definitions.
1615
/// </param>
17-
public List<TpTestCaseDefinition> Parse(string content, string fallbackName)
16+
public void Parse(TpParsingContext context)
1817
{
19-
ArgumentNullException.ThrowIfNull(content);
20-
ArgumentException.ThrowIfNullOrWhiteSpace(fallbackName);
18+
ArgumentNullException.ThrowIfNull(context);
2119

22-
var lines = content.Split(LineSeparators, StringSplitOptions.None);
20+
var lines = context.Content.Split(LineSeparators, StringSplitOptions.None);
2321

24-
return HasTestCaseMarker(lines)
25-
? ParseExplicitTestCases(lines, fallbackName)
26-
: [ParseImplicitTestCase(lines, fallbackName)];
22+
var definitions = HasTestCaseMarker(lines)
23+
? ParseExplicitTestCases(lines, context.FallbackName)
24+
: [ParseImplicitTestCase(lines, context.FallbackName)];
25+
26+
context.Definitions.AddRange(definitions);
2727
}
2828

2929
private static bool HasTestCaseMarker(string[] lines)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
namespace TeaPie.TestCases;
2+
3+
internal class TpParsingContext(string content, string fallbackName)
4+
{
5+
public string Content { get; } = content ?? throw new ArgumentNullException(nameof(content));
6+
public string FallbackName { get; } = !string.IsNullOrWhiteSpace(fallbackName)
7+
? fallbackName
8+
: throw new ArgumentException("Value cannot be null or whitespace.", nameof(fallbackName));
9+
10+
public List<TpTestCaseDefinition> Definitions { get; } = [];
11+
}

tests/TeaPie.Tests/TestCases/TpFileParserShould.cs

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ public void ParseSingleTestCaseWithAllSections()
2828
--- END
2929
""";
3030

31-
var result = _parser.Parse(content, "fallback");
31+
var context = new TpParsingContext(content, "fallback");
32+
_parser.Parse(context);
33+
var result = context.Definitions;
3234

3335
Single(result);
3436
var def = result[0];
@@ -53,7 +55,9 @@ public void ParseSingleTestCaseWithHttpOnly()
5355
--- END
5456
""";
5557

56-
var result = _parser.Parse(content, "fallback");
58+
var context = new TpParsingContext(content, "fallback");
59+
_parser.Parse(context);
60+
var result = context.Definitions;
5761

5862
Single(result);
5963
var def = result[0];
@@ -89,7 +93,9 @@ public void ParseMultipleTestCasesFromOneFile()
8993
--- END
9094
""";
9195

92-
var result = _parser.Parse(content, "fallback");
96+
var context = new TpParsingContext(content, "fallback");
97+
_parser.Parse(context);
98+
var result = context.Definitions;
9399

94100
Equal(2, result.Count);
95101

@@ -115,7 +121,9 @@ public void ParseImplicitSingleTestCaseWithoutTestCaseMarker()
115121
tp.Test("ok", () => Equal(200, tp.Response.StatusCode()));
116122
""";
117123

118-
var result = _parser.Parse(content, "My Implicit Test");
124+
var context = new TpParsingContext(content, "My Implicit Test");
125+
_parser.Parse(context);
126+
var result = context.Definitions;
119127

120128
Single(result);
121129
var def = result[0];
@@ -139,7 +147,7 @@ public void ThrowWhenHttpSectionIsMissing()
139147
--- END
140148
""";
141149

142-
var ex = Throws<InvalidOperationException>(() => _parser.Parse(content, "fallback"));
150+
var ex = Throws<InvalidOperationException>(() => _parser.Parse(new TpParsingContext(content, "fallback")));
143151
Contains("Bad Test", ex.Message);
144152
Contains(TpConstants.HttpMarker, ex.Message);
145153
}
@@ -156,7 +164,9 @@ public void UseFallbackNameWhenSingleTestCaseMarkerHasNoName()
156164
--- END
157165
""";
158166

159-
var result = _parser.Parse(content, "My Fallback Name");
167+
var context = new TpParsingContext(content, "My Fallback Name");
168+
_parser.Parse(context);
169+
var result = context.Definitions;
160170

161171
Single(result);
162172
Equal("My Fallback Name", result[0].Name);
@@ -181,7 +191,7 @@ public void ThrowWhenMultipleTestCasesHaveNamelessMarker()
181191
--- END
182192
""";
183193

184-
var ex = Throws<InvalidOperationException>(() => _parser.Parse(content, "fallback"));
194+
var ex = Throws<InvalidOperationException>(() => _parser.Parse(new TpParsingContext(content, "fallback")));
185195
Contains(TpConstants.TestCaseMarker, ex.Message);
186196
}
187197

@@ -201,7 +211,9 @@ public void HandleEmptyInitAndTestSections()
201211
--- END
202212
""";
203213

204-
var result = _parser.Parse(content, "fallback");
214+
var context = new TpParsingContext(content, "fallback");
215+
_parser.Parse(context);
216+
var result = context.Definitions;
205217

206218
Single(result);
207219
var def = result[0];
@@ -229,7 +241,9 @@ public void PreserveFormattingOfHttpSection()
229241
"",
230242
"--- END");
231243

232-
var result = _parser.Parse(content, "fallback");
244+
var context = new TpParsingContext(content, "fallback");
245+
_parser.Parse(context);
246+
var result = context.Definitions;
233247

234248
Single(result);
235249
Contains(httpBody, result[0].HttpContent);
@@ -251,7 +265,9 @@ public void ParseCaseInsensitiveSectionMarkers()
251265
--- end
252266
""";
253267

254-
var result = _parser.Parse(content, "fallback");
268+
var context = new TpParsingContext(content, "fallback");
269+
_parser.Parse(context);
270+
var result = context.Definitions;
255271

256272
Single(result);
257273
Equal("Case Insensitive", result[0].Name);
@@ -293,7 +309,9 @@ public void ParseThreeTestCasesWithVariousConfigurations()
293309
--- END
294310
""";
295311

296-
var result = _parser.Parse(content, "fallback");
312+
var context = new TpParsingContext(content, "fallback");
313+
_parser.Parse(context);
314+
var result = context.Definitions;
297315

298316
Equal(3, result.Count);
299317

@@ -327,7 +345,9 @@ public void ParseMarkersWithNoSpaceAfterDashes()
327345
"",
328346
"---END");
329347

330-
var result = _parser.Parse(content, "fallback");
348+
var context = new TpParsingContext(content, "fallback");
349+
_parser.Parse(context);
350+
var result = context.Definitions;
331351

332352
Single(result);
333353
Equal("No Space Test", result[0].Name);
@@ -355,7 +375,9 @@ public void ParseMarkersWithExtraSpacesAfterDashes()
355375
"",
356376
"--- END");
357377

358-
var result = _parser.Parse(content, "fallback");
378+
var context = new TpParsingContext(content, "fallback");
379+
_parser.Parse(context);
380+
var result = context.Definitions;
359381

360382
Single(result);
361383
Equal("Extra Spaces", result[0].Name);
@@ -385,7 +407,9 @@ public void ParseMultipleRequestsInHttpSection()
385407
--- END
386408
""";
387409

388-
var result = _parser.Parse(content, "fallback");
410+
var context = new TpParsingContext(content, "fallback");
411+
_parser.Parse(context);
412+
var result = context.Definitions;
389413

390414
Single(result);
391415
Contains("FirstRequest", result[0].HttpContent);

0 commit comments

Comments
 (0)