@grimoire-cc/cli 0.13.3 → 0.15.0

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.
Files changed (92) hide show
  1. package/dist/bin.js +15 -5
  2. package/dist/bin.js.map +1 -1
  3. package/dist/commands/agent-paths.d.ts +11 -0
  4. package/dist/commands/agent-paths.d.ts.map +1 -0
  5. package/dist/commands/agent-paths.js +69 -0
  6. package/dist/commands/agent-paths.js.map +1 -0
  7. package/dist/commands/agent-skills.d.ts +10 -0
  8. package/dist/commands/agent-skills.d.ts.map +1 -0
  9. package/dist/commands/agent-skills.js +159 -0
  10. package/dist/commands/agent-skills.js.map +1 -0
  11. package/dist/commands/config.d.ts +7 -0
  12. package/dist/commands/config.d.ts.map +1 -0
  13. package/dist/commands/config.js +62 -0
  14. package/dist/commands/config.js.map +1 -0
  15. package/dist/commands/list.d.ts.map +1 -1
  16. package/dist/commands/list.js +237 -75
  17. package/dist/commands/list.js.map +1 -1
  18. package/dist/commands/update.d.ts +1 -2
  19. package/dist/commands/update.d.ts.map +1 -1
  20. package/dist/commands/update.js +18 -0
  21. package/dist/commands/update.js.map +1 -1
  22. package/dist/enforce.d.ts +9 -9
  23. package/dist/enforce.d.ts.map +1 -1
  24. package/dist/enforce.js +56 -23
  25. package/dist/enforce.js.map +1 -1
  26. package/dist/frontmatter.d.ts +16 -0
  27. package/dist/frontmatter.d.ts.map +1 -0
  28. package/dist/frontmatter.js +74 -0
  29. package/dist/frontmatter.js.map +1 -0
  30. package/dist/grimoire-config.d.ts +6 -0
  31. package/dist/grimoire-config.d.ts.map +1 -0
  32. package/dist/grimoire-config.js +23 -0
  33. package/dist/grimoire-config.js.map +1 -0
  34. package/dist/prompt.d.ts.map +1 -1
  35. package/dist/prompt.js +13 -8
  36. package/dist/prompt.js.map +1 -1
  37. package/dist/remove.d.ts +4 -0
  38. package/dist/remove.d.ts.map +1 -1
  39. package/dist/remove.js +8 -0
  40. package/dist/remove.js.map +1 -1
  41. package/dist/resolve.d.ts.map +1 -1
  42. package/dist/resolve.js +12 -5
  43. package/dist/resolve.js.map +1 -1
  44. package/dist/setup.d.ts.map +1 -1
  45. package/dist/setup.js +45 -2
  46. package/dist/setup.js.map +1 -1
  47. package/dist/summary.d.ts.map +1 -1
  48. package/dist/summary.js +9 -0
  49. package/dist/summary.js.map +1 -1
  50. package/package.json +1 -1
  51. package/packs/dev-pack/agents/grimoire.tdd-specialist.md +194 -27
  52. package/packs/dev-pack/grimoire.json +0 -38
  53. package/packs/dev-pack/skills/grimoire.conventional-commit/SKILL.md +69 -65
  54. package/packs/dotnet-pack/agents/grimoire.csharp-coder.md +110 -113
  55. package/packs/dotnet-pack/grimoire.json +23 -5
  56. package/packs/dotnet-pack/skills/grimoire.unit-testing-dotnet/SKILL.md +252 -0
  57. package/packs/{dev-pack/skills/grimoire.tdd-specialist → dotnet-pack/skills/grimoire.unit-testing-dotnet}/reference/anti-patterns.md +78 -0
  58. package/packs/dotnet-pack/skills/grimoire.unit-testing-dotnet/reference/tdd-workflow-patterns.md +259 -0
  59. package/packs/frontend-pack/agents/grimoire.angular-coder.md +193 -0
  60. package/packs/frontend-pack/grimoire.json +7 -0
  61. package/packs/go-pack/grimoire.json +19 -0
  62. package/packs/go-pack/skills/grimoire.unit-testing-go/SKILL.md +256 -0
  63. package/packs/go-pack/skills/grimoire.unit-testing-go/reference/anti-patterns.md +244 -0
  64. package/packs/go-pack/skills/grimoire.unit-testing-go/reference/tdd-workflow-patterns.md +259 -0
  65. package/packs/python-pack/grimoire.json +19 -0
  66. package/packs/python-pack/skills/grimoire.unit-testing-python/SKILL.md +239 -0
  67. package/packs/python-pack/skills/grimoire.unit-testing-python/reference/anti-patterns.md +244 -0
  68. package/packs/python-pack/skills/grimoire.unit-testing-python/reference/tdd-workflow-patterns.md +259 -0
  69. package/packs/rust-pack/grimoire.json +29 -0
  70. package/packs/rust-pack/skills/grimoire.unit-testing-rust/SKILL.md +243 -0
  71. package/packs/rust-pack/skills/grimoire.unit-testing-rust/reference/anti-patterns.md +244 -0
  72. package/packs/rust-pack/skills/grimoire.unit-testing-rust/reference/tdd-workflow-patterns.md +259 -0
  73. package/packs/ts-pack/agents/grimoire.typescript-coder.md +36 -1
  74. package/packs/ts-pack/grimoire.json +27 -1
  75. package/packs/ts-pack/skills/grimoire.unit-testing-typescript/SKILL.md +255 -0
  76. package/packs/ts-pack/skills/grimoire.unit-testing-typescript/reference/anti-patterns.md +244 -0
  77. package/packs/ts-pack/skills/grimoire.unit-testing-typescript/reference/tdd-workflow-patterns.md +259 -0
  78. package/dist/commands/enforce-agent.d.ts +0 -5
  79. package/dist/commands/enforce-agent.d.ts.map +0 -1
  80. package/dist/commands/enforce-agent.js +0 -94
  81. package/dist/commands/enforce-agent.js.map +0 -1
  82. package/packs/dev-pack/skills/grimoire.tdd-specialist/SKILL.md +0 -248
  83. package/packs/dev-pack/skills/grimoire.tdd-specialist/reference/language-frameworks.md +0 -388
  84. package/packs/dev-pack/skills/grimoire.tdd-specialist/reference/tdd-workflow-patterns.md +0 -135
  85. package/packs/dotnet-pack/skills/grimoire.dotnet-unit-testing/SKILL.md +0 -293
  86. package/packs/dotnet-pack/skills/grimoire.dotnet-unit-testing/reference/anti-patterns.md +0 -329
  87. package/packs/dotnet-pack/skills/grimoire.dotnet-unit-testing/reference/framework-guidelines.md +0 -361
  88. package/packs/dotnet-pack/skills/grimoire.dotnet-unit-testing/reference/parameterized-testing.md +0 -378
  89. package/packs/dotnet-pack/skills/grimoire.dotnet-unit-testing/reference/test-organization.md +0 -476
  90. package/packs/dotnet-pack/skills/grimoire.dotnet-unit-testing/reference/test-performance.md +0 -576
  91. package/packs/dotnet-pack/skills/grimoire.dotnet-unit-testing/templates/tunit-template.md +0 -438
  92. package/packs/dotnet-pack/skills/grimoire.dotnet-unit-testing/templates/xunit-template.md +0 -303
@@ -1,378 +0,0 @@
1
- # Parameterized Testing
2
-
3
- Comprehensive guide to parameterized testing in xUnit and TUnit.
4
-
5
- ## Table of Contents
6
-
7
- - [When to Use Each Data Source](#when-to-use-each-data-source)
8
- - [xUnit Parameterized Testing](#xunit-parameterized-testing)
9
- - [InlineData](#xunit-inlinedata)
10
- - [MemberData](#xunit-memberdata)
11
- - [ClassData](#xunit-classdata)
12
- - [TUnit Parameterized Testing](#tunit-parameterized-testing)
13
- - [Arguments](#tunit-arguments)
14
- - [MethodDataSource](#tunit-methoddatasource)
15
- - [ClassDataSource](#tunit-classdatasource)
16
- - [Matrix Testing](#tunit-matrix-testing)
17
- - [Best Practices](#best-practices)
18
-
19
- ---
20
-
21
- ## When to Use Each Data Source
22
-
23
- | Data Source | Use When | xUnit | TUnit |
24
- | ------------- | ---------- | ------- | ------- |
25
- | **Inline** | Few simple values (primitives, strings) | `[InlineData]` | `[Arguments]` |
26
- | **Method** | Computed data, shared within same class | `[MemberData]` | `[MethodDataSource]` |
27
- | **Class** | Reusable data across multiple test classes | `[ClassData]` | `[ClassDataSource]` |
28
- | **Matrix** | Test all combinations of inputs | Manual | `[Matrix]` (built-in) |
29
-
30
- ---
31
-
32
- ## xUnit Parameterized Testing
33
-
34
- ### xUnit InlineData
35
-
36
- For simple primitive values:
37
-
38
- ```csharp
39
- [Theory]
40
- [InlineData("", false)]
41
- [InlineData("test@example.com", true)]
42
- [InlineData("invalid", false)]
43
- [InlineData("user@domain.co.uk", true)]
44
- public void IsValidEmail_WithVariousInputs_ReturnsExpected(string email, bool expected)
45
- {
46
- var result = _sut.IsValidEmail(email);
47
- Assert.Equal(expected, result);
48
- }
49
- ```
50
-
51
- ### xUnit MemberData
52
-
53
- For computed or complex data from methods in the same class:
54
-
55
- ```csharp
56
- [Theory]
57
- [MemberData(nameof(GetDiscountTestCases))]
58
- public void CalculateDiscount_WithVariousOrders_ReturnsExpectedDiscount(
59
- Order order, decimal expectedDiscount, string scenario)
60
- {
61
- // Arrange & Act
62
- var result = _sut.CalculateDiscount(order);
63
-
64
- // Assert
65
- Assert.Equal(expectedDiscount, result);
66
- }
67
-
68
- public static IEnumerable<object[]> GetDiscountTestCases()
69
- {
70
- yield return new object[]
71
- {
72
- new Order { Total = 50m },
73
- 0m,
74
- "No discount under $100"
75
- };
76
- yield return new object[]
77
- {
78
- new Order { Total = 100m },
79
- 10m,
80
- "10% discount at $100"
81
- };
82
- yield return new object[]
83
- {
84
- new Order { Total = 500m, IsPremiumCustomer = true },
85
- 100m,
86
- "20% discount for premium over $500"
87
- };
88
- }
89
- ```
90
-
91
- **Referencing data from another class:**
92
-
93
- ```csharp
94
- [Theory]
95
- [MemberData(nameof(OrderTestData.ValidOrders), MemberType = typeof(OrderTestData))]
96
- public async Task ProcessOrder_WithValidOrder_Succeeds(Order order) { }
97
-
98
- public static class OrderTestData
99
- {
100
- public static IEnumerable<object[]> ValidOrders => new[]
101
- {
102
- new object[] { CreateStandardOrder() },
103
- new object[] { CreatePremiumOrder() },
104
- new object[] { CreateBulkOrder() }
105
- };
106
- }
107
- ```
108
-
109
- ### xUnit ClassData
110
-
111
- For reusable test data across multiple test classes:
112
-
113
- ```csharp
114
- // Define reusable test data class
115
- public class ValidEmailTestData : IEnumerable<object[]>
116
- {
117
- public IEnumerator<object[]> GetEnumerator()
118
- {
119
- yield return new object[] { "test@example.com" };
120
- yield return new object[] { "user.name@domain.co.uk" };
121
- yield return new object[] { "user+tag@example.org" };
122
- }
123
-
124
- IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
125
- }
126
-
127
- public class InvalidEmailTestData : IEnumerable<object[]>
128
- {
129
- public IEnumerator<object[]> GetEnumerator()
130
- {
131
- yield return new object[] { "" };
132
- yield return new object[] { "notanemail" };
133
- yield return new object[] { "@nodomain.com" };
134
- yield return new object[] { "spaces in@email.com" };
135
- }
136
-
137
- IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
138
- }
139
-
140
- // Use in multiple test classes
141
- public class EmailValidatorTests
142
- {
143
- [Theory]
144
- [ClassData(typeof(ValidEmailTestData))]
145
- public void IsValid_WithValidEmail_ReturnsTrue(string email)
146
- {
147
- Assert.True(_sut.IsValid(email));
148
- }
149
-
150
- [Theory]
151
- [ClassData(typeof(InvalidEmailTestData))]
152
- public void IsValid_WithInvalidEmail_ReturnsFalse(string email)
153
- {
154
- Assert.False(_sut.IsValid(email));
155
- }
156
- }
157
-
158
- public class EmailServiceTests
159
- {
160
- [Theory]
161
- [ClassData(typeof(ValidEmailTestData))]
162
- public async Task SendEmail_WithValidAddress_Succeeds(string email)
163
- {
164
- // Reusing same test data in different test class
165
- var result = await _sut.SendAsync(email, "Subject", "Body");
166
- Assert.True(result.Success);
167
- }
168
- }
169
- ```
170
-
171
- ---
172
-
173
- ## TUnit Parameterized Testing
174
-
175
- ### TUnit Arguments
176
-
177
- For simple values (equivalent to xUnit's InlineData):
178
-
179
- ```csharp
180
- [Test]
181
- [Arguments("", false)]
182
- [Arguments("test@example.com", true)]
183
- [Arguments("invalid", false)]
184
- [Arguments("user@domain.co.uk", true)]
185
- public async Task IsValidEmail_WithVariousInputs_ReturnsExpected(string email, bool expected)
186
- {
187
- var result = _sut.IsValidEmail(email);
188
- await Assert.That(result).IsEqualTo(expected);
189
- }
190
- ```
191
-
192
- ### TUnit MethodDataSource
193
-
194
- For computed data (equivalent to xUnit's MemberData):
195
-
196
- ```csharp
197
- [Test]
198
- [MethodDataSource(nameof(GetDiscountTestCases))]
199
- public async Task CalculateDiscount_WithVariousOrders_ReturnsExpectedDiscount(
200
- Order order, decimal expectedDiscount, string scenario)
201
- {
202
- var result = _sut.CalculateDiscount(order);
203
- await Assert.That(result).IsEqualTo(expectedDiscount);
204
- }
205
-
206
- // TUnit supports tuples for cleaner syntax
207
- public static IEnumerable<(Order Order, decimal ExpectedDiscount, string Scenario)> GetDiscountTestCases()
208
- {
209
- yield return (
210
- new Order { Total = 50m },
211
- 0m,
212
- "No discount under $100"
213
- );
214
- yield return (
215
- new Order { Total = 100m },
216
- 10m,
217
- "10% discount at $100"
218
- );
219
- yield return (
220
- new Order { Total = 500m, IsPremiumCustomer = true },
221
- 100m,
222
- "20% discount for premium over $500"
223
- );
224
- }
225
- ```
226
-
227
- ### TUnit ClassDataSource
228
-
229
- For reusable data across test classes:
230
-
231
- ```csharp
232
- // Define reusable test data source
233
- public class ValidEmailDataSource : DataSourceGeneratorAttribute<string>
234
- {
235
- public override IEnumerable<string> GenerateDataSources(DataGeneratorMetadata metadata)
236
- {
237
- yield return "test@example.com";
238
- yield return "user.name@domain.co.uk";
239
- yield return "user+tag@example.org";
240
- }
241
- }
242
-
243
- public class InvalidEmailDataSource : DataSourceGeneratorAttribute<string>
244
- {
245
- public override IEnumerable<string> GenerateDataSources(DataGeneratorMetadata metadata)
246
- {
247
- yield return "";
248
- yield return "notanemail";
249
- yield return "@nodomain.com";
250
- yield return "spaces in@email.com";
251
- }
252
- }
253
-
254
- // Use in tests
255
- public class EmailValidatorTests
256
- {
257
- [Test]
258
- [ValidEmailDataSource]
259
- public async Task IsValid_WithValidEmail_ReturnsTrue(string email)
260
- {
261
- await Assert.That(_sut.IsValid(email)).IsTrue();
262
- }
263
-
264
- [Test]
265
- [InvalidEmailDataSource]
266
- public async Task IsValid_WithInvalidEmail_ReturnsFalse(string email)
267
- {
268
- await Assert.That(_sut.IsValid(email)).IsFalse();
269
- }
270
- }
271
- ```
272
-
273
- ### TUnit Matrix Testing
274
-
275
- TUnit's unique feature for combinatorial testing:
276
-
277
- ```csharp
278
- // Test all combinations automatically
279
- // This generates 3 × 2 × 2 = 12 test cases
280
- [Test]
281
- [Matrix("Small", "Medium", "Large")]
282
- [Matrix("Standard", "Express")]
283
- [Matrix(true, false)]
284
- public async Task CalculateShipping_MatrixTest_ReturnsValidPrice(
285
- string size, string shippingMethod, bool isInternational)
286
- {
287
- var result = await _sut.CalculateShippingAsync(size, shippingMethod, isInternational);
288
-
289
- await Assert.That(result).IsGreaterThan(0);
290
- }
291
- ```
292
-
293
- ---
294
-
295
- ## Best Practices
296
-
297
- ### 1. Include Scenario Descriptions
298
-
299
- ```csharp
300
- // xUnit - Add description as last parameter
301
- [Theory]
302
- [InlineData(100, 10, "Standard 10% discount")]
303
- [InlineData(500, 75, "Premium 15% discount")]
304
- [InlineData(50, 0, "No discount under threshold")]
305
- public void CalculateDiscount_Scenarios(decimal total, decimal expected, string scenario)
306
- {
307
- // scenario parameter helps identify which case failed
308
- }
309
-
310
- // TUnit - Use DisplayName
311
- [Test]
312
- [Arguments("", false, DisplayName = "Empty string should be invalid")]
313
- [Arguments("test@example.com", true, DisplayName = "Standard email should be valid")]
314
- public async Task IsValidEmail_WithDisplayNames(string email, bool expected)
315
- {
316
- await Assert.That(_sut.IsValid(email)).IsEqualTo(expected);
317
- }
318
- ```
319
-
320
- ### 2. Group Related Test Data
321
-
322
- ```csharp
323
- public static class OrderTestData
324
- {
325
- public static IEnumerable<object[]> ValidOrders => new[]
326
- {
327
- new object[] { CreateStandardOrder() },
328
- new object[] { CreatePremiumOrder() },
329
- new object[] { CreateBulkOrder() }
330
- };
331
-
332
- public static IEnumerable<object[]> InvalidOrders => new[]
333
- {
334
- new object[] { CreateEmptyOrder() },
335
- new object[] { CreateNegativeQuantityOrder() },
336
- new object[] { CreateExpiredOrder() }
337
- };
338
- }
339
- ```
340
-
341
- ### 3. Test Boundary Conditions
342
-
343
- ```csharp
344
- [Theory]
345
- [InlineData(int.MinValue)] // Minimum boundary
346
- [InlineData(-1)] // Just below zero
347
- [InlineData(0)] // Zero boundary
348
- [InlineData(1)] // Just above zero
349
- [InlineData(int.MaxValue)] // Maximum boundary
350
- public void ProcessValue_WithBoundaryValues_HandlesCorrectly(int value)
351
- {
352
- // Test behavior at boundaries
353
- }
354
- ```
355
-
356
- ### 4. Avoid Too Many Parameters
357
-
358
- ```csharp
359
- // BAD: Too many parameters, hard to read
360
- [Theory]
361
- [InlineData("John", "Doe", 25, "john@test.com", "123 Main St", "NYC", "NY", "10001", true)]
362
- public void CreateUser_TooManyParams(string first, string last, int age, ...) { }
363
-
364
- // GOOD: Use a test data object
365
- [Theory]
366
- [MemberData(nameof(GetUserTestCases))]
367
- public void CreateUser_WithTestObject(UserTestCase testCase)
368
- {
369
- var result = _sut.CreateUser(testCase.Input);
370
- Assert.Equal(testCase.ExpectedResult, result.Success);
371
- }
372
-
373
- public record UserTestCase(UserInput Input, bool ExpectedResult, string Scenario);
374
- ```
375
-
376
- ### 5. Keep Test Data Close to Tests
377
-
378
- For data used by only one test class, keep it in the same file. Only extract to separate classes when shared across multiple test files.