@aicgen/aicgen 1.0.0-beta.1

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 (287) hide show
  1. package/.claude/agents/architecture-reviewer.md +88 -0
  2. package/.claude/agents/guideline-checker.md +73 -0
  3. package/.claude/agents/security-auditor.md +108 -0
  4. package/.claude/guidelines/api-design.md +645 -0
  5. package/.claude/guidelines/architecture.md +2503 -0
  6. package/.claude/guidelines/best-practices.md +618 -0
  7. package/.claude/guidelines/code-style.md +304 -0
  8. package/.claude/guidelines/design-patterns.md +573 -0
  9. package/.claude/guidelines/devops.md +226 -0
  10. package/.claude/guidelines/error-handling.md +413 -0
  11. package/.claude/guidelines/language.md +782 -0
  12. package/.claude/guidelines/performance.md +706 -0
  13. package/.claude/guidelines/security.md +583 -0
  14. package/.claude/guidelines/testing.md +568 -0
  15. package/.claude/settings.json +98 -0
  16. package/.claude/settings.local.json +8 -0
  17. package/.env.example +23 -0
  18. package/.eslintrc.json +28 -0
  19. package/.github/workflows/release.yml +180 -0
  20. package/.github/workflows/test.yml +81 -0
  21. package/.gitmodules +3 -0
  22. package/.vs/ProjectSettings.json +3 -0
  23. package/.vs/VSWorkspaceState.json +16 -0
  24. package/.vs/aicgen.slnx/FileContentIndex/5f0ce2a3-fd68-4863-9e23-e428cf1794e3.vsidx +0 -0
  25. package/.vs/aicgen.slnx/v18/.wsuo +0 -0
  26. package/.vs/aicgen.slnx/v18/DocumentLayout.json +54 -0
  27. package/.vs/slnx.sqlite +0 -0
  28. package/AGENTS.md +121 -0
  29. package/CLAUDE.md +36 -0
  30. package/CONTRIBUTING.md +821 -0
  31. package/LICENSE +21 -0
  32. package/README.md +199 -0
  33. package/assets/icon.svg +34 -0
  34. package/assets/logo.svg +41 -0
  35. package/bun.lock +848 -0
  36. package/data/LICENSE +21 -0
  37. package/data/README.md +203 -0
  38. package/data/api/basics.md +292 -0
  39. package/data/api/index.md +8 -0
  40. package/data/api/pagination.md +142 -0
  41. package/data/api/rest.md +137 -0
  42. package/data/api/versioning.md +60 -0
  43. package/data/architecture/clean-architecture/index.md +7 -0
  44. package/data/architecture/clean-architecture/layers.md +111 -0
  45. package/data/architecture/ddd/index.md +8 -0
  46. package/data/architecture/ddd/strategic.md +89 -0
  47. package/data/architecture/ddd/tactical.md +132 -0
  48. package/data/architecture/event-driven/index.md +7 -0
  49. package/data/architecture/event-driven/messaging.md +242 -0
  50. package/data/architecture/event-driven/patterns.md +129 -0
  51. package/data/architecture/feature-toggles/index.md +7 -0
  52. package/data/architecture/feature-toggles/patterns.md +73 -0
  53. package/data/architecture/gui/index.md +7 -0
  54. package/data/architecture/gui/patterns.md +132 -0
  55. package/data/architecture/hexagonal/ports-adapters.md +132 -0
  56. package/data/architecture/index.md +12 -0
  57. package/data/architecture/layered/index.md +7 -0
  58. package/data/architecture/layered/layers.md +100 -0
  59. package/data/architecture/microservices/api-gateway.md +56 -0
  60. package/data/architecture/microservices/boundaries.md +80 -0
  61. package/data/architecture/microservices/communication.md +97 -0
  62. package/data/architecture/microservices/data.md +92 -0
  63. package/data/architecture/microservices/index.md +11 -0
  64. package/data/architecture/microservices/resilience.md +111 -0
  65. package/data/architecture/modular-monolith/boundaries.md +133 -0
  66. package/data/architecture/modular-monolith/structure.md +131 -0
  67. package/data/architecture/serverless/best-practices.md +322 -0
  68. package/data/architecture/serverless/index.md +7 -0
  69. package/data/architecture/serverless/patterns.md +80 -0
  70. package/data/architecture/solid/index.md +7 -0
  71. package/data/architecture/solid/principles.md +187 -0
  72. package/data/database/basics.md +365 -0
  73. package/data/database/design-patterns.md +68 -0
  74. package/data/database/index.md +8 -0
  75. package/data/database/indexing.md +136 -0
  76. package/data/database/nosql.md +223 -0
  77. package/data/database/schema.md +137 -0
  78. package/data/devops/ci-cd.md +66 -0
  79. package/data/devops/index.md +8 -0
  80. package/data/devops/observability.md +73 -0
  81. package/data/devops/practices.md +77 -0
  82. package/data/error-handling/basics.md +222 -0
  83. package/data/error-handling/index.md +7 -0
  84. package/data/error-handling/strategy.md +185 -0
  85. package/data/guideline-mappings.yml +1077 -0
  86. package/data/index.md +3 -0
  87. package/data/language/csharp/basics.md +210 -0
  88. package/data/language/csharp/testing.md +252 -0
  89. package/data/language/go/basics.md +158 -0
  90. package/data/language/go/testing.md +192 -0
  91. package/data/language/index.md +14 -0
  92. package/data/language/java/basics.md +184 -0
  93. package/data/language/java/testing.md +273 -0
  94. package/data/language/javascript/basics.md +217 -0
  95. package/data/language/javascript/testing.md +269 -0
  96. package/data/language/python/async.md +100 -0
  97. package/data/language/python/basics.md +100 -0
  98. package/data/language/python/index.md +10 -0
  99. package/data/language/python/testing.md +125 -0
  100. package/data/language/python/types.md +99 -0
  101. package/data/language/ruby/basics.md +227 -0
  102. package/data/language/ruby/testing.md +267 -0
  103. package/data/language/rust/basics.md +175 -0
  104. package/data/language/rust/testing.md +219 -0
  105. package/data/language/typescript/async.md +103 -0
  106. package/data/language/typescript/basics.md +87 -0
  107. package/data/language/typescript/config.md +95 -0
  108. package/data/language/typescript/error-handling.md +98 -0
  109. package/data/language/typescript/generics.md +85 -0
  110. package/data/language/typescript/index.md +14 -0
  111. package/data/language/typescript/interfaces-types.md +83 -0
  112. package/data/language/typescript/performance.md +103 -0
  113. package/data/language/typescript/testing.md +98 -0
  114. package/data/patterns/base-patterns.md +105 -0
  115. package/data/patterns/concurrency.md +87 -0
  116. package/data/patterns/data-access.md +83 -0
  117. package/data/patterns/distribution.md +86 -0
  118. package/data/patterns/domain-logic.md +81 -0
  119. package/data/patterns/gof.md +109 -0
  120. package/data/patterns/index.md +12 -0
  121. package/data/performance/async.md +148 -0
  122. package/data/performance/basics.md +324 -0
  123. package/data/performance/caching-strategies.md +68 -0
  124. package/data/performance/caching.md +152 -0
  125. package/data/performance/index.md +8 -0
  126. package/data/practices/code-review.md +52 -0
  127. package/data/practices/documentation.md +260 -0
  128. package/data/practices/index.md +11 -0
  129. package/data/practices/planning.md +142 -0
  130. package/data/practices/refactoring.md +91 -0
  131. package/data/practices/version-control.md +55 -0
  132. package/data/security/auth-jwt.md +159 -0
  133. package/data/security/headers.md +143 -0
  134. package/data/security/index.md +10 -0
  135. package/data/security/injection.md +119 -0
  136. package/data/security/secrets.md +148 -0
  137. package/data/style/index.md +8 -0
  138. package/data/style/naming.md +136 -0
  139. package/data/style/organization.md +162 -0
  140. package/data/templates/agents/architecture-reviewer.md +88 -0
  141. package/data/templates/agents/guideline-checker.md +73 -0
  142. package/data/templates/agents/security-auditor.md +108 -0
  143. package/data/templates/antigravity/rules/architecture.md.hbs +5 -0
  144. package/data/templates/antigravity/rules/code-style.md.hbs +5 -0
  145. package/data/templates/antigravity/rules/language.md.hbs +5 -0
  146. package/data/templates/antigravity/rules/performance.md.hbs +5 -0
  147. package/data/templates/antigravity/rules/security.md.hbs +5 -0
  148. package/data/templates/antigravity/rules/testing.md.hbs +5 -0
  149. package/data/templates/antigravity/workflows/add-documentation.md.hbs +23 -0
  150. package/data/templates/antigravity/workflows/generate-integration-tests.md.hbs +17 -0
  151. package/data/templates/antigravity/workflows/generate-unit-tests.md.hbs +20 -0
  152. package/data/templates/antigravity/workflows/performance-audit.md.hbs +24 -0
  153. package/data/templates/antigravity/workflows/refactor-extract-module.md.hbs +17 -0
  154. package/data/templates/antigravity/workflows/security-audit.md.hbs +20 -0
  155. package/data/templates/hooks/formatting.json +26 -0
  156. package/data/templates/hooks/security.json +35 -0
  157. package/data/templates/hooks/testing.json +17 -0
  158. package/data/testing/basics.md +151 -0
  159. package/data/testing/index.md +9 -0
  160. package/data/testing/integration.md +159 -0
  161. package/data/testing/unit-fundamentals.md +128 -0
  162. package/data/testing/unit-mocking.md +116 -0
  163. package/data/version.json +49 -0
  164. package/dist/commands/init.d.ts +8 -0
  165. package/dist/commands/init.d.ts.map +1 -0
  166. package/dist/commands/init.js +46 -0
  167. package/dist/commands/init.js.map +1 -0
  168. package/dist/config/profiles.d.ts +4 -0
  169. package/dist/config/profiles.d.ts.map +1 -0
  170. package/dist/config/profiles.js +30 -0
  171. package/dist/config/profiles.js.map +1 -0
  172. package/dist/config/settings.d.ts +7 -0
  173. package/dist/config/settings.d.ts.map +1 -0
  174. package/dist/config/settings.js +7 -0
  175. package/dist/config/settings.js.map +1 -0
  176. package/dist/index.d.ts +3 -0
  177. package/dist/index.d.ts.map +1 -0
  178. package/dist/index.js +58489 -0
  179. package/dist/index.js.map +1 -0
  180. package/dist/models/guideline.d.ts +15 -0
  181. package/dist/models/guideline.d.ts.map +1 -0
  182. package/dist/models/guideline.js +2 -0
  183. package/dist/models/guideline.js.map +1 -0
  184. package/dist/models/preference.d.ts +9 -0
  185. package/dist/models/preference.d.ts.map +1 -0
  186. package/dist/models/preference.js +2 -0
  187. package/dist/models/preference.js.map +1 -0
  188. package/dist/models/profile.d.ts +9 -0
  189. package/dist/models/profile.d.ts.map +1 -0
  190. package/dist/models/profile.js +2 -0
  191. package/dist/models/profile.js.map +1 -0
  192. package/dist/models/project.d.ts +13 -0
  193. package/dist/models/project.d.ts.map +1 -0
  194. package/dist/models/project.js +2 -0
  195. package/dist/models/project.js.map +1 -0
  196. package/dist/services/ai/anthropic.d.ts +7 -0
  197. package/dist/services/ai/anthropic.d.ts.map +1 -0
  198. package/dist/services/ai/anthropic.js +39 -0
  199. package/dist/services/ai/anthropic.js.map +1 -0
  200. package/dist/services/generator.d.ts +2 -0
  201. package/dist/services/generator.d.ts.map +1 -0
  202. package/dist/services/generator.js +4 -0
  203. package/dist/services/generator.js.map +1 -0
  204. package/dist/services/learner.d.ts +2 -0
  205. package/dist/services/learner.d.ts.map +1 -0
  206. package/dist/services/learner.js +4 -0
  207. package/dist/services/learner.js.map +1 -0
  208. package/dist/services/scanner.d.ts +3 -0
  209. package/dist/services/scanner.d.ts.map +1 -0
  210. package/dist/services/scanner.js +54 -0
  211. package/dist/services/scanner.js.map +1 -0
  212. package/dist/utils/errors.d.ts +15 -0
  213. package/dist/utils/errors.d.ts.map +1 -0
  214. package/dist/utils/errors.js +27 -0
  215. package/dist/utils/errors.js.map +1 -0
  216. package/dist/utils/file.d.ts +7 -0
  217. package/dist/utils/file.d.ts.map +1 -0
  218. package/dist/utils/file.js +32 -0
  219. package/dist/utils/file.js.map +1 -0
  220. package/dist/utils/logger.d.ts +6 -0
  221. package/dist/utils/logger.d.ts.map +1 -0
  222. package/dist/utils/logger.js +17 -0
  223. package/dist/utils/logger.js.map +1 -0
  224. package/dist/utils/path.d.ts +6 -0
  225. package/dist/utils/path.d.ts.map +1 -0
  226. package/dist/utils/path.js +14 -0
  227. package/dist/utils/path.js.map +1 -0
  228. package/docs/planning/memory-lane.md +83 -0
  229. package/package.json +64 -0
  230. package/packaging/linux/aicgen.spec +23 -0
  231. package/packaging/linux/control +9 -0
  232. package/packaging/macos/scripts/postinstall +12 -0
  233. package/packaging/windows/setup.nsi +92 -0
  234. package/planning/BRANDING-SUMMARY.md +194 -0
  235. package/planning/BRANDING.md +174 -0
  236. package/planning/BUILD.md +186 -0
  237. package/planning/CHUNK-IMPLEMENTATION-PLAN.md +87 -0
  238. package/planning/CHUNK-TAXONOMY.md +375 -0
  239. package/planning/CHUNKS-COMPLETE.md +382 -0
  240. package/planning/DESIGN.md +313 -0
  241. package/planning/DYNAMIC-GUIDELINES-DESIGN.md +265 -0
  242. package/planning/ENTERPRISE-UX-COMPLETE.md +281 -0
  243. package/planning/IMPLEMENTATION-PLAN.md +20 -0
  244. package/planning/PHASE1-COMPLETE.md +211 -0
  245. package/planning/PHASE2-COMPLETE.md +350 -0
  246. package/planning/PHASE3-COMPLETE.md +399 -0
  247. package/planning/PHASE4-COMPLETE.md +361 -0
  248. package/planning/PHASE4.5-CHUNKS.md +462 -0
  249. package/planning/STRUCTURE.md +170 -0
  250. package/scripts/add-categories.ts +87 -0
  251. package/scripts/build-binary.ts +46 -0
  252. package/scripts/embed-data.ts +105 -0
  253. package/scripts/generate-version.ts +150 -0
  254. package/scripts/test-decompress.ts +27 -0
  255. package/scripts/test-extract.ts +31 -0
  256. package/src/__tests__/services/assistant-file-writer.test.ts +400 -0
  257. package/src/__tests__/services/guideline-loader.test.ts +281 -0
  258. package/src/__tests__/services/tarball-extraction.test.ts +125 -0
  259. package/src/commands/add-guideline.ts +296 -0
  260. package/src/commands/clear.ts +61 -0
  261. package/src/commands/guideline-selector.ts +123 -0
  262. package/src/commands/init.ts +645 -0
  263. package/src/commands/quick-add.ts +586 -0
  264. package/src/commands/remove-guideline.ts +152 -0
  265. package/src/commands/stats.ts +49 -0
  266. package/src/commands/update.ts +240 -0
  267. package/src/config.ts +82 -0
  268. package/src/embedded-data.ts +1492 -0
  269. package/src/index.ts +67 -0
  270. package/src/models/profile.ts +24 -0
  271. package/src/models/project.ts +43 -0
  272. package/src/services/assistant-file-writer.ts +612 -0
  273. package/src/services/config-generator.ts +150 -0
  274. package/src/services/config-manager.ts +70 -0
  275. package/src/services/data-source.ts +248 -0
  276. package/src/services/first-run-init.ts +148 -0
  277. package/src/services/guideline-loader.ts +311 -0
  278. package/src/services/hook-generator.ts +178 -0
  279. package/src/services/subagent-generator.ts +310 -0
  280. package/src/utils/banner.ts +66 -0
  281. package/src/utils/errors.ts +27 -0
  282. package/src/utils/file.ts +67 -0
  283. package/src/utils/formatting.ts +172 -0
  284. package/src/utils/logger.ts +89 -0
  285. package/src/utils/path.ts +17 -0
  286. package/src/utils/wizard-state.ts +132 -0
  287. package/tsconfig.json +25 -0
package/data/index.md ADDED
@@ -0,0 +1,3 @@
1
+ # aicgen Guidelines
2
+
3
+ See [README.md](README.md) for full documentation and contribution guidelines.
@@ -0,0 +1,210 @@
1
+ # C# Fundamentals
2
+
3
+ ## Project Structure
4
+
5
+ ```
6
+ MyProject/
7
+ ├── src/
8
+ │ ├── MyProject.Api/
9
+ │ │ ├── Controllers/
10
+ │ │ ├── Program.cs
11
+ │ │ └── MyProject.Api.csproj
12
+ │ ├── MyProject.Core/
13
+ │ │ ├── Entities/
14
+ │ │ ├── Interfaces/
15
+ │ │ └── Services/
16
+ │ └── MyProject.Infrastructure/
17
+ │ ├── Data/
18
+ │ └── Services/
19
+ ├── tests/
20
+ │ └── MyProject.Tests/
21
+ └── MyProject.sln
22
+ ```
23
+
24
+ ## Naming Conventions
25
+
26
+ ```csharp
27
+ // Classes, interfaces, methods: PascalCase
28
+ public class UserService { }
29
+ public interface IUserRepository { }
30
+ public void CreateUser() { }
31
+
32
+ // Interface prefix: I
33
+ public interface IRepository { }
34
+
35
+ // Private fields: _camelCase
36
+ private readonly IUserRepository _repository;
37
+
38
+ // Parameters, local variables: camelCase
39
+ public User GetUser(string userId) { }
40
+
41
+ // Constants: PascalCase
42
+ public const int MaxRetries = 3;
43
+ ```
44
+
45
+ ## Modern C# Features (10+)
46
+
47
+ ```csharp
48
+ // Records for immutable data
49
+ public record User(string Id, string Email, string Name);
50
+
51
+ // Pattern matching
52
+ var result = obj switch
53
+ {
54
+ User u when u.IsActive => "Active user",
55
+ User u => "Inactive user",
56
+ null => "No user",
57
+ _ => "Unknown"
58
+ };
59
+
60
+ // Null handling
61
+ string? nullableString = GetValue();
62
+ string nonNull = nullableString ?? "default";
63
+ int length = nullableString?.Length ?? 0;
64
+
65
+ // Target-typed new
66
+ List<User> users = new();
67
+ Dictionary<string, int> counts = new();
68
+
69
+ // File-scoped namespaces
70
+ namespace MyProject.Services;
71
+
72
+ public class UserService { }
73
+ ```
74
+
75
+ ## Async/Await
76
+
77
+ ```csharp
78
+ // Async methods return Task
79
+ public async Task<User> GetUserAsync(string id)
80
+ {
81
+ var user = await _repository.FindByIdAsync(id);
82
+ return user ?? throw new NotFoundException(id);
83
+ }
84
+
85
+ // Async enumerable
86
+ public async IAsyncEnumerable<User> GetUsersAsync()
87
+ {
88
+ await foreach (var user in _repository.StreamAsync())
89
+ {
90
+ yield return user;
91
+ }
92
+ }
93
+
94
+ // Cancellation
95
+ public async Task ProcessAsync(CancellationToken ct)
96
+ {
97
+ ct.ThrowIfCancellationRequested();
98
+ await _service.DoWorkAsync(ct);
99
+ }
100
+ ```
101
+
102
+ ## LINQ
103
+
104
+ ```csharp
105
+ // Query syntax
106
+ var activeUsers = from u in users
107
+ where u.IsActive
108
+ orderby u.Name
109
+ select u;
110
+
111
+ // Method syntax (preferred)
112
+ var emails = users
113
+ .Where(u => u.IsActive)
114
+ .OrderBy(u => u.Name)
115
+ .Select(u => u.Email)
116
+ .ToList();
117
+
118
+ // Grouping
119
+ var byDepartment = users
120
+ .GroupBy(u => u.Department)
121
+ .ToDictionary(g => g.Key, g => g.ToList());
122
+ ```
123
+
124
+ ## Exception Handling
125
+
126
+ ```csharp
127
+ // Custom exceptions
128
+ public class NotFoundException : Exception
129
+ {
130
+ public NotFoundException(string id)
131
+ : base($"Entity not found: {id}") { }
132
+ }
133
+
134
+ // Try-catch-finally
135
+ try
136
+ {
137
+ await ProcessAsync();
138
+ }
139
+ catch (NotFoundException ex) when (ex.Message.Contains("user"))
140
+ {
141
+ _logger.LogWarning(ex, "User not found");
142
+ throw;
143
+ }
144
+ catch (Exception ex)
145
+ {
146
+ _logger.LogError(ex, "Unexpected error");
147
+ throw;
148
+ }
149
+ ```
150
+
151
+ ## Dependency Injection
152
+
153
+ ```csharp
154
+ // Service registration
155
+ builder.Services.AddScoped<IUserRepository, UserRepository>();
156
+ builder.Services.AddScoped<IUserService, UserService>();
157
+
158
+ // Constructor injection
159
+ public class UserService : IUserService
160
+ {
161
+ private readonly IUserRepository _repository;
162
+ private readonly ILogger<UserService> _logger;
163
+
164
+ public UserService(IUserRepository repository, ILogger<UserService> logger)
165
+ {
166
+ _repository = repository;
167
+ _logger = logger;
168
+ }
169
+ }
170
+ ```
171
+
172
+ ## Testing (xUnit)
173
+
174
+ ```csharp
175
+ public class UserServiceTests
176
+ {
177
+ private readonly Mock<IUserRepository> _repositoryMock;
178
+ private readonly UserService _sut;
179
+
180
+ public UserServiceTests()
181
+ {
182
+ _repositoryMock = new Mock<IUserRepository>();
183
+ _sut = new UserService(_repositoryMock.Object);
184
+ }
185
+
186
+ [Fact]
187
+ public async Task GetUser_WhenExists_ReturnsUser()
188
+ {
189
+ // Arrange
190
+ var user = new User("1", "test@example.com", "Test");
191
+ _repositoryMock.Setup(r => r.FindByIdAsync("1"))
192
+ .ReturnsAsync(user);
193
+
194
+ // Act
195
+ var result = await _sut.GetUserAsync("1");
196
+
197
+ // Assert
198
+ Assert.Equal("test@example.com", result.Email);
199
+ }
200
+
201
+ [Theory]
202
+ [InlineData("")]
203
+ [InlineData(null)]
204
+ public async Task GetUser_WhenInvalidId_ThrowsArgumentException(string id)
205
+ {
206
+ await Assert.ThrowsAsync<ArgumentException>(
207
+ () => _sut.GetUserAsync(id));
208
+ }
209
+ }
210
+ ```
@@ -0,0 +1,252 @@
1
+ # C# Testing (xUnit)
2
+
3
+ ## Test Structure
4
+
5
+ ```
6
+ MyProject/
7
+ ├── src/
8
+ │ └── MyProject/
9
+ │ └── Services/UserService.cs
10
+ └── tests/
11
+ └── MyProject.Tests/
12
+ └── Services/UserServiceTests.cs
13
+ ```
14
+
15
+ ## Basic Tests
16
+
17
+ ```csharp
18
+ using Xunit;
19
+
20
+ public class UserServiceTests
21
+ {
22
+ private readonly UserService _sut; // System Under Test
23
+
24
+ public UserServiceTests()
25
+ {
26
+ _sut = new UserService();
27
+ }
28
+
29
+ [Fact]
30
+ public void Create_WithValidEmail_ReturnsUser()
31
+ {
32
+ var user = _sut.Create("test@example.com");
33
+
34
+ Assert.NotNull(user);
35
+ Assert.Equal("test@example.com", user.Email);
36
+ }
37
+
38
+ [Fact]
39
+ public void Create_WithInvalidEmail_ThrowsValidationException()
40
+ {
41
+ Assert.Throws<ValidationException>(() => _sut.Create("invalid"));
42
+ }
43
+ }
44
+ ```
45
+
46
+ ## Assertions
47
+
48
+ ```csharp
49
+ // Equality
50
+ Assert.Equal(expected, actual);
51
+ Assert.NotEqual(unexpected, actual);
52
+
53
+ // Boolean
54
+ Assert.True(condition);
55
+ Assert.False(condition);
56
+
57
+ // Null
58
+ Assert.Null(value);
59
+ Assert.NotNull(value);
60
+
61
+ // Collections
62
+ Assert.Empty(collection);
63
+ Assert.NotEmpty(collection);
64
+ Assert.Contains(item, collection);
65
+ Assert.DoesNotContain(item, collection);
66
+ Assert.All(collection, item => Assert.NotNull(item.Name));
67
+
68
+ // Type
69
+ Assert.IsType<User>(result);
70
+ Assert.IsAssignableFrom<IEntity>(result);
71
+
72
+ // Exceptions
73
+ var ex = Assert.Throws<NotFoundException>(() => service.Find("invalid"));
74
+ Assert.Equal("User not found", ex.Message);
75
+ ```
76
+
77
+ ## Theory Tests (Parameterized)
78
+
79
+ ```csharp
80
+ [Theory]
81
+ [InlineData("test@example.com", true)]
82
+ [InlineData("invalid", false)]
83
+ [InlineData("", false)]
84
+ public void IsValidEmail_WithVariousInputs_ReturnsExpected(string email, bool expected)
85
+ {
86
+ var result = _validator.IsValid(email);
87
+ Assert.Equal(expected, result);
88
+ }
89
+
90
+ [Theory]
91
+ [MemberData(nameof(GetTestUsers))]
92
+ public void ProcessUser_WithVariousUsers_ReturnsExpected(User user, string expectedStatus)
93
+ {
94
+ var result = _processor.Process(user);
95
+ Assert.Equal(expectedStatus, result);
96
+ }
97
+
98
+ public static IEnumerable<object[]> GetTestUsers()
99
+ {
100
+ yield return new object[] { new User("active@example.com") { IsActive = true }, "processed" };
101
+ yield return new object[] { new User("inactive@example.com") { IsActive = false }, "skipped" };
102
+ }
103
+ ```
104
+
105
+ ## Test Classes and Collections
106
+
107
+ ```csharp
108
+ // Shared context across tests in a class
109
+ public class UserServiceTests : IClassFixture<DatabaseFixture>
110
+ {
111
+ private readonly DatabaseFixture _fixture;
112
+
113
+ public UserServiceTests(DatabaseFixture fixture)
114
+ {
115
+ _fixture = fixture;
116
+ }
117
+
118
+ [Fact]
119
+ public void Test1() { /* uses _fixture */ }
120
+ }
121
+
122
+ // Shared context across multiple test classes
123
+ [CollectionDefinition("Database")]
124
+ public class DatabaseCollection : ICollectionFixture<DatabaseFixture> { }
125
+
126
+ [Collection("Database")]
127
+ public class UserServiceTests { }
128
+
129
+ [Collection("Database")]
130
+ public class OrderServiceTests { }
131
+ ```
132
+
133
+ ## Mocking with Moq
134
+
135
+ ```csharp
136
+ using Moq;
137
+
138
+ public class UserServiceTests
139
+ {
140
+ private readonly Mock<IUserRepository> _repositoryMock;
141
+ private readonly Mock<ILogger<UserService>> _loggerMock;
142
+ private readonly UserService _sut;
143
+
144
+ public UserServiceTests()
145
+ {
146
+ _repositoryMock = new Mock<IUserRepository>();
147
+ _loggerMock = new Mock<ILogger<UserService>>();
148
+ _sut = new UserService(_repositoryMock.Object, _loggerMock.Object);
149
+ }
150
+
151
+ [Fact]
152
+ public async Task GetUser_WhenExists_ReturnsUser()
153
+ {
154
+ // Arrange
155
+ var user = new User("1", "test@example.com");
156
+ _repositoryMock.Setup(r => r.FindByIdAsync("1"))
157
+ .ReturnsAsync(user);
158
+
159
+ // Act
160
+ var result = await _sut.GetUserAsync("1");
161
+
162
+ // Assert
163
+ Assert.Equal("test@example.com", result.Email);
164
+ _repositoryMock.Verify(r => r.FindByIdAsync("1"), Times.Once);
165
+ }
166
+
167
+ [Fact]
168
+ public async Task GetUser_WhenNotFound_ThrowsNotFoundException()
169
+ {
170
+ _repositoryMock.Setup(r => r.FindByIdAsync(It.IsAny<string>()))
171
+ .ReturnsAsync((User?)null);
172
+
173
+ await Assert.ThrowsAsync<NotFoundException>(
174
+ () => _sut.GetUserAsync("invalid"));
175
+ }
176
+ }
177
+ ```
178
+
179
+ ## Async Testing
180
+
181
+ ```csharp
182
+ [Fact]
183
+ public async Task CreateAsync_WithValidData_ReturnsUser()
184
+ {
185
+ var user = await _sut.CreateAsync("test@example.com");
186
+
187
+ Assert.NotNull(user);
188
+ Assert.Equal("test@example.com", user.Email);
189
+ }
190
+
191
+ [Fact]
192
+ public async Task CreateAsync_WithTimeout_CompletesInTime()
193
+ {
194
+ var task = _sut.CreateAsync("test@example.com");
195
+ var completed = await Task.WhenAny(task, Task.Delay(5000)) == task;
196
+
197
+ Assert.True(completed, "Operation timed out");
198
+ }
199
+ ```
200
+
201
+ ## Test Output
202
+
203
+ ```csharp
204
+ public class UserServiceTests
205
+ {
206
+ private readonly ITestOutputHelper _output;
207
+
208
+ public UserServiceTests(ITestOutputHelper output)
209
+ {
210
+ _output = output;
211
+ }
212
+
213
+ [Fact]
214
+ public void Test_WithLogging()
215
+ {
216
+ _output.WriteLine("Starting test...");
217
+ // test logic
218
+ _output.WriteLine($"Result: {result}");
219
+ }
220
+ }
221
+ ```
222
+
223
+ ## Integration Testing with WebApplicationFactory
224
+
225
+ ```csharp
226
+ public class UserApiTests : IClassFixture<WebApplicationFactory<Program>>
227
+ {
228
+ private readonly HttpClient _client;
229
+
230
+ public UserApiTests(WebApplicationFactory<Program> factory)
231
+ {
232
+ _client = factory.WithWebHostBuilder(builder =>
233
+ {
234
+ builder.ConfigureServices(services =>
235
+ {
236
+ // Replace real services with test doubles
237
+ services.AddScoped<IUserRepository, InMemoryUserRepository>();
238
+ });
239
+ }).CreateClient();
240
+ }
241
+
242
+ [Fact]
243
+ public async Task GetUser_ReturnsUser()
244
+ {
245
+ var response = await _client.GetAsync("/api/users/1");
246
+
247
+ response.EnsureSuccessStatusCode();
248
+ var user = await response.Content.ReadFromJsonAsync<User>();
249
+ Assert.Equal("test@example.com", user?.Email);
250
+ }
251
+ }
252
+ ```
@@ -0,0 +1,158 @@
1
+ # Go Fundamentals
2
+
3
+ ## Project Structure
4
+
5
+ ```
6
+ myproject/
7
+ ├── cmd/
8
+ │ └── myapp/
9
+ │ └── main.go # Application entry point
10
+ ├── internal/ # Private application code
11
+ │ ├── handler/
12
+ │ ├── service/
13
+ │ └── repository/
14
+ ├── pkg/ # Public library code
15
+ ├── go.mod
16
+ └── go.sum
17
+ ```
18
+
19
+ ## Naming Conventions
20
+
21
+ ```go
22
+ // Package names: lowercase, single word
23
+ package user
24
+
25
+ // Exported (public): PascalCase
26
+ func CreateUser() {}
27
+ type UserService struct {}
28
+
29
+ // Unexported (private): camelCase
30
+ func validateEmail() {}
31
+ type userCache struct {}
32
+
33
+ // Interfaces: -er suffix when possible
34
+ type Reader interface {}
35
+ type UserRepository interface {}
36
+
37
+ // Constants: PascalCase for exported
38
+ const MaxRetries = 3
39
+ const defaultTimeout = 30
40
+ ```
41
+
42
+ ## Error Handling
43
+
44
+ ```go
45
+ // Always check errors
46
+ result, err := doSomething()
47
+ if err != nil {
48
+ return fmt.Errorf("failed to do something: %w", err)
49
+ }
50
+
51
+ // Custom errors
52
+ var ErrNotFound = errors.New("not found")
53
+ var ErrInvalidInput = errors.New("invalid input")
54
+
55
+ // Error wrapping for context
56
+ if err != nil {
57
+ return fmt.Errorf("creating user %s: %w", name, err)
58
+ }
59
+
60
+ // Errors.Is and errors.As for checking
61
+ if errors.Is(err, ErrNotFound) {
62
+ // Handle not found
63
+ }
64
+ ```
65
+
66
+ ## Concurrency
67
+
68
+ ```go
69
+ // Goroutines for concurrent work
70
+ go func() {
71
+ // Concurrent task
72
+ }()
73
+
74
+ // Channels for communication
75
+ ch := make(chan int)
76
+ ch <- value // Send
77
+ value := <-ch // Receive
78
+
79
+ // Context for cancellation
80
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
81
+ defer cancel()
82
+
83
+ // sync.WaitGroup for coordination
84
+ var wg sync.WaitGroup
85
+ wg.Add(1)
86
+ go func() {
87
+ defer wg.Done()
88
+ // Work
89
+ }()
90
+ wg.Wait()
91
+ ```
92
+
93
+ ## Testing
94
+
95
+ ```go
96
+ // Test file: user_test.go
97
+ func TestCreateUser(t *testing.T) {
98
+ // Arrange
99
+ svc := NewUserService()
100
+
101
+ // Act
102
+ user, err := svc.Create("test@example.com")
103
+
104
+ // Assert
105
+ if err != nil {
106
+ t.Fatalf("unexpected error: %v", err)
107
+ }
108
+ if user.Email != "test@example.com" {
109
+ t.Errorf("got %s, want test@example.com", user.Email)
110
+ }
111
+ }
112
+
113
+ // Table-driven tests
114
+ func TestValidateEmail(t *testing.T) {
115
+ tests := []struct {
116
+ name string
117
+ email string
118
+ valid bool
119
+ }{
120
+ {"valid", "test@example.com", true},
121
+ {"no at", "invalid", false},
122
+ }
123
+
124
+ for _, tt := range tests {
125
+ t.Run(tt.name, func(t *testing.T) {
126
+ got := ValidateEmail(tt.email)
127
+ if got != tt.valid {
128
+ t.Errorf("ValidateEmail(%q) = %v, want %v", tt.email, got, tt.valid)
129
+ }
130
+ })
131
+ }
132
+ }
133
+ ```
134
+
135
+ ## Common Patterns
136
+
137
+ ```go
138
+ // Functional options
139
+ type Option func(*Config)
140
+
141
+ func WithTimeout(d time.Duration) Option {
142
+ return func(c *Config) { c.Timeout = d }
143
+ }
144
+
145
+ func NewClient(opts ...Option) *Client {
146
+ cfg := defaultConfig()
147
+ for _, opt := range opts {
148
+ opt(&cfg)
149
+ }
150
+ return &Client{config: cfg}
151
+ }
152
+
153
+ // Interface-based design
154
+ type UserRepository interface {
155
+ FindByID(ctx context.Context, id string) (*User, error)
156
+ Save(ctx context.Context, user *User) error
157
+ }
158
+ ```