Skip to content

Commit c06b0d9

Browse files
Add clean code and TDD guidelines
- Introduced new markdown files for Clean Code, SOLID principles, KISS, DRY, and Test-Driven Development (TDD) practices. - Established rules for code clarity, maintainability, and testing workflows, emphasizing the importance of writing meaningful tests and following design principles. - Included examples in C# to illustrate good and bad practices, enhancing understanding of the guidelines. - Aimed to improve code quality and development efficiency across the project.
1 parent ca9c1c1 commit c06b0d9

2 files changed

Lines changed: 147 additions & 0 deletions

File tree

.cursor/rules/clean-code-solid.mdc

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
---
2+
description: Enforce Clean Code, SOLID, KISS, and DRY in all code changes
3+
alwaysApply: true
4+
---
5+
6+
# Clean Code, SOLID, KISS, and DRY
7+
8+
Follow Robert C. Martin's *Clean Code* and these design principles on every change.
9+
Prefer clarity and maintainability over cleverness.
10+
11+
## Clean Code
12+
13+
- Names must reveal intent; avoid abbreviations and noise (`CalculateCognitiveScore`, not `CalcCS`).
14+
- Functions do one thing, stay short (target ≤ 20 lines), and have few parameters.
15+
- Prefer early returns over deep nesting.
16+
- Comments explain *why*, not *what* — the code should read like prose.
17+
- Fail fast with meaningful exceptions; never swallow errors silently.
18+
19+
```csharp
20+
// ❌ BAD — unclear name, deep nesting, silent failure
21+
public int Proc(object x) {
22+
if (x != null) {
23+
if (x is string s) {
24+
try { return int.Parse(s); } catch { return 0; }
25+
}
26+
}
27+
return 0;
28+
}
29+
30+
// ✅ GOOD — intent-revealing, early return, explicit error
31+
public int ParseScore(string raw) =>
32+
int.TryParse(raw, out var score)
33+
? score
34+
: throw new FormatException($"Invalid score: '{raw}'");
35+
```
36+
37+
## SOLID
38+
39+
- **SRP**: One reason to change per class. Split parsing, reporting, and orchestration.
40+
- **OCP**: Extend via new types or strategies; avoid editing stable code for every variant.
41+
- **LSP**: Subtypes must honor base contracts — no surprise exceptions or narrowed behavior.
42+
- **ISP**: Small, focused interfaces (`ICoverageReader`, not `IAnalysisEverything`).
43+
- **DIP**: Depend on abstractions; inject via constructors, not `new` inside services.
44+
45+
```csharp
46+
// ❌ BAD — concrete dependency, mixed responsibilities
47+
public class ReportService {
48+
public void Run(string path) {
49+
var data = new CoberturaReader().Read(path);
50+
File.WriteAllText("out.json", JsonSerializer.Serialize(data));
51+
}
52+
}
53+
54+
// ✅ GOOD — injected abstraction, single responsibility
55+
public class ReportService(IReportWriter writer, ICoverageReader reader) {
56+
public void Generate(string path) => writer.Write(reader.Read(path));
57+
}
58+
```
59+
60+
## KISS
61+
62+
- Choose the simplest design that satisfies the requirement.
63+
- Do not add abstractions, configuration, or generics without a concrete need.
64+
- Refactor when duplication or complexity appears — not preemptively.
65+
66+
## DRY
67+
68+
- Extract shared logic when the same rule appears twice; do not copy-paste.
69+
- DRY applies to behavior, not coincidental similarity — two similar-looking blocks with different reasons to change should stay separate.
70+
- Prefer existing helpers and project conventions before introducing new utilities.
71+
72+
## Code Smells to Fix
73+
74+
- Long methods or classes → extract focused units.
75+
- Duplicated logic → shared method or type.
76+
- Magic numbers/strings → named constants.
77+
- God classes, feature envy, or shotgun surgery → revisit SRP and DIP.

.cursor/rules/tdd.mdc

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
---
2+
description: Test-driven development workflow and container-based test execution
3+
alwaysApply: true
4+
---
5+
6+
# Test-Driven Development
7+
8+
Follow TDD for new behavior, refactors with behavior changes, and bug fixes.
9+
See also `container-development.mdc` for build and CI commands.
10+
11+
## Red → Green → Refactor
12+
13+
1. **Red** — Write a failing test that describes the desired behavior.
14+
2. **Green** — Write the smallest production change that makes the test pass.
15+
3. **Refactor** — Clean up while keeping tests green.
16+
17+
Do not add production code for untested behavior.
18+
Do not skip the failing-test step to "save time."
19+
20+
## Bug fixes
21+
22+
Reproduce the bug in a test first (as close to real usage as practical), confirm it fails, then fix.
23+
24+
## Writing tests (NUnit)
25+
26+
- Place tests in `*Tests` projects, mirroring production namespaces.
27+
- Name tests by behavior: `MethodName_Scenario_ExpectedResult`.
28+
- Prefer focused tests over large integration suites unless the behavior requires end-to-end coverage.
29+
- Use fixtures under `fixtures/` for sample inputs; keep golden files in `fixtures/reports/golden/`.
30+
31+
```csharp
32+
// ❌ BAD — implementation detail, no clear behavior
33+
[Test]
34+
public void Test1() { ... }
35+
36+
// ✅ GOOD — behavior-focused
37+
[Test]
38+
public void CalculateScores_WhenLinesOfCodeExceedsThreshold_MapsToLowerScore()
39+
{
40+
// arrange → act → assert
41+
}
42+
```
43+
44+
## Run tests in the container
45+
46+
Always run tests through `make` from the repo root.
47+
The Makefile re-executes inside the dev container.
48+
49+
```bash
50+
make test # full suite (Release)
51+
make test-debug # Debug configuration
52+
make coverage # Coverlet report → artifacts/coverage
53+
```
54+
55+
```bash
56+
# ❌ BAD — host SDK, may differ from CI/container
57+
dotnet test CognitiveCodeAnalysis.sln
58+
59+
# ✅ GOOD
60+
make test
61+
```
62+
63+
After each TDD cycle, run the relevant tests before moving on.
64+
Before finishing a feature or fix, run `make test` at minimum; use `make ci` for larger changes.
65+
66+
## When to add tests
67+
68+
- **New behavior** — test first, then implement.
69+
- **Refactor** — existing tests must stay green; add tests only if coverage is missing.
70+
- **Trivial changes** — typos, comments, formatting: no new tests required.

0 commit comments

Comments
 (0)