Skip to content

Commit ab65438

Browse files
Enhance Scope Management: Introduce ScopeWithTrailingSemicolon class and update related documentation and tests
1 parent 1246dad commit ab65438

6 files changed

Lines changed: 321 additions & 26 deletions

File tree

CLAUDE.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ dotnet test --logger "console;verbosity=detailed"
2525

2626
## Architecture
2727

28-
The library consists of two main classes:
28+
The library consists of three main classes:
2929

3030
1. **`CodeBlocker`** (`CodeBlocker/CodeBlocker.cs`): Wraps `System.CodeDom.Compiler.IndentedTextWriter` to provide simplified code generation with:
3131
- Factory methods (`Create()`, `Create(string indentString)`) that manage `StringWriter` lifecycle
@@ -35,9 +35,14 @@ The library consists of two main classes:
3535

3636
2. **`Scope`** (`CodeBlocker/Scope.cs`): Extends `ktsu.ScopedAction` to provide automatic brace handling:
3737
- On creation: writes `{` and increases indent
38-
- On disposal: decreases indent and writes `};`
38+
- On disposal: decreases indent and writes `}`
3939
- Used with C# `using` statements for clean nested code generation
4040

41+
3. **`ScopeWithTrailingSemicolon`** (`CodeBlocker/Scope.cs`): Variant of `Scope` that appends a semicolon after the closing brace:
42+
- On creation: writes `{` and increases indent
43+
- On disposal: decreases indent and writes `};`
44+
- Useful for C/C++ enum declarations, struct initializers, etc.
45+
4146
## SDK and Dependencies
4247

4348
This project uses:

CodeBlocker.Test/IntegrationTests.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,16 @@ public void ComplexCodeGenerationShouldFormatCorrectly()
4747
"\t{\r\n" +
4848
"\t\tvar x = 1;\r\n" +
4949
"\t\tConsole.WriteLine(x);\r\n" +
50-
"\t};\r\n" +
50+
"\t}\r\n" +
5151
"\r\n" +
5252
"\tpublic void Method2()\r\n" +
5353
"\t{\r\n" +
5454
"\t\tif (true)\r\n" +
5555
"\t\t{\r\n" +
5656
"\t\t\treturn;\r\n" +
57-
"\t\t};\r\n" +
58-
"\t};\r\n" +
59-
"};\r\n";
57+
"\t\t}\r\n" +
58+
"\t}\r\n" +
59+
"}\r\n";
6060

6161
Assert.AreEqual(expected, result);
6262
}
@@ -168,7 +168,7 @@ public void EmptyScopesShouldNotAffectOtherContent()
168168
// Assert
169169

170170
string result = codeBlocker.ToString();
171-
string expected = "before\r\n{\r\n};\r\nafter\r\n";
171+
string expected = "before\r\n{\r\n}\r\nafter\r\n";
172172
Assert.AreEqual(expected, result);
173173
}
174174

@@ -199,8 +199,8 @@ public void MultipleCodeBlockersShouldBeIndependent()
199199
string result1 = codeBlocker1.ToString();
200200
string result2 = codeBlocker2.ToString();
201201

202-
string expected1 = "codeBlocker1 content\r\n{\r\n\tinside scope1\r\n};\r\n";
203-
string expected2 = "codeBlocker2 content\r\n{\r\n\tinside scope2\r\n};\r\n";
202+
string expected1 = "codeBlocker1 content\r\n{\r\n\tinside scope1\r\n}\r\n";
203+
string expected2 = "codeBlocker2 content\r\n{\r\n\tinside scope2\r\n}\r\n";
204204

205205
Assert.AreEqual(expected1, result1);
206206
Assert.AreEqual(expected2, result2);
@@ -305,8 +305,8 @@ public void MixedWriteOperationsWithComplexIndentationShouldFormatCorrectly()
305305
"\tpublic MyClass(string field)\r\n" +
306306
"\t{\r\n" +
307307
"\t\t_field = field ?? throw new ArgumentNullException(nameof(field));\r\n" +
308-
"\t};\r\n" +
309-
"};\r\n";
308+
"\t}\r\n" +
309+
"}\r\n";
310310

311311
Assert.AreEqual(expected, result);
312312
}

CodeBlocker.Test/ScopeTests.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public void DisposeShouldCloseBraceAndDecreaseIndentation()
4646

4747
Assert.AreEqual(initialIndent, codeBlocker.CurrentIndent);
4848
string result = codeBlocker.ToString();
49-
Assert.IsTrue(result.EndsWith("};\r\n", StringComparison.Ordinal), "Result should end with closing brace, semicolon, and newline");
49+
Assert.IsTrue(result.EndsWith("}\r\n", StringComparison.Ordinal), "Result should end with closing brace and newline");
5050
}
5151

5252
[TestMethod]
@@ -66,7 +66,7 @@ public void UsingStatementShouldProperlyOpenAndCloseScope()
6666
// Assert
6767

6868
string result = codeBlocker.ToString();
69-
string expected = "{\r\n\tcontent inside scope\r\n};\r\n";
69+
string expected = "{\r\n\tcontent inside scope\r\n}\r\n";
7070
Assert.AreEqual(expected, result);
7171
}
7272

@@ -92,7 +92,7 @@ public void NestedScopesShouldMaintainProperIndentation()
9292
// Assert
9393

9494
string result = codeBlocker.ToString();
95-
string expected = "{\r\n\tlevel 1\r\n\t{\r\n\t\tlevel 2\r\n\t};\r\n\tback to level 1\r\n};\r\n";
95+
string expected = "{\r\n\tlevel 1\r\n\t{\r\n\t\tlevel 2\r\n\t}\r\n\tback to level 1\r\n}\r\n";
9696
Assert.AreEqual(expected, result);
9797
}
9898

@@ -128,7 +128,7 @@ public void ScopeWithoutContentShouldStillFormatCorrectly()
128128
// Assert
129129

130130
string result = codeBlocker.ToString();
131-
string expected = "{\r\n};\r\n";
131+
string expected = "{\r\n}\r\n";
132132
Assert.AreEqual(expected, result);
133133
}
134134

@@ -154,7 +154,7 @@ public void MultipleSequentialScopesShouldFormatCorrectly()
154154
// Assert
155155

156156
string result = codeBlocker.ToString();
157-
string expected = "{\r\n\tscope 1 content\r\n};\r\n{\r\n\tscope 2 content\r\n};\r\n";
157+
string expected = "{\r\n\tscope 1 content\r\n}\r\n{\r\n\tscope 2 content\r\n}\r\n";
158158
Assert.AreEqual(expected, result);
159159
}
160160

@@ -177,7 +177,7 @@ public void ScopeWithCustomIndentStringShouldWork()
177177
// Assert
178178

179179
string result = codeBlocker.ToString();
180-
string expected = "{\r\n custom indented content\r\n};\r\n";
180+
string expected = "{\r\n custom indented content\r\n}\r\n";
181181
Assert.AreEqual(expected, result);
182182
Assert.AreEqual(customIndent, codeBlocker.IndentString);
183183
}
@@ -268,7 +268,7 @@ public void ScopeWithMixedManualIndentAndScopeIndentShouldWork()
268268
// Note: After manual Outdent within scope, the closing }; will be at the current indent level
269269
// The scope ends at whatever the current indent is when Dispose() is called
270270

271-
string expected = "\t{\r\n\t\tdouble indented\r\n\tsingle indented\r\n};\r\nback to manual indent\r\n";
271+
string expected = "\t{\r\n\t\tdouble indented\r\n\tsingle indented\r\n}\r\nback to manual indent\r\n";
272272
Assert.AreEqual(expected, result);
273273
}
274274

@@ -297,7 +297,7 @@ public void ScopeWithCurrentIndentSetterShouldWork()
297297
Assert.IsTrue(result.Contains("{\r\n", StringComparison.Ordinal), "Result should contain opening brace with newline");
298298
Assert.IsTrue(result.Contains("\t\t\t\t\tlevel 5 content\r\n", StringComparison.Ordinal), "Result should contain content with 5 tabs indentation");
299299

300-
Assert.IsTrue(result.EndsWith("};\r\n", StringComparison.Ordinal), "Result should end with closing brace, semicolon, and newline");
300+
Assert.IsTrue(result.EndsWith("}\r\n", StringComparison.Ordinal), "Result should end with closing brace and newline");
301301
}
302302

303303
[TestMethod]
@@ -347,7 +347,7 @@ public void ScopeWithEmptyCustomIndentStringShouldWork()
347347
// Assert
348348

349349
string result = codeBlocker.ToString();
350-
string expected = "{\r\nno indent\r\n};\r\n";
350+
string expected = "{\r\nno indent\r\n}\r\n";
351351
Assert.AreEqual(expected, result);
352352
}
353353

0 commit comments

Comments
 (0)