@sylix/coworker 2.0.10 → 2.0.12

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 (178) hide show
  1. package/dist/commands/slash/config.d.ts.map +1 -1
  2. package/dist/commands/slash/config.js +23 -5
  3. package/dist/commands/slash/config.js.map +1 -1
  4. package/dist/commands/slash/todo.js +1 -1
  5. package/dist/commands/slash/todo.js.map +1 -1
  6. package/dist/core/CoWorkerAgent.d.ts.map +1 -1
  7. package/dist/core/CoWorkerAgent.js +6 -3
  8. package/dist/core/CoWorkerAgent.js.map +1 -1
  9. package/dist/permissions/PermissionInterceptor.js +1 -1
  10. package/dist/permissions/PermissionInterceptor.js.map +1 -1
  11. package/dist/skills/defaults/accessibility/screen-reader-testing.md +545 -0
  12. package/dist/skills/defaults/accessibility/wcag-audit-patterns.md +555 -0
  13. package/dist/skills/defaults/ai-ml/rag.md +276 -0
  14. package/dist/skills/defaults/backend-development/api-design-principles.md +528 -0
  15. package/dist/skills/defaults/backend-development/api-design.md +285 -0
  16. package/dist/skills/defaults/backend-development/architecture-patterns.md +494 -0
  17. package/dist/skills/defaults/backend-development/async-python.md +237 -0
  18. package/dist/skills/defaults/backend-development/auth-implementation-patterns.md +638 -0
  19. package/dist/skills/defaults/backend-development/bazel-build-optimization.md +387 -0
  20. package/dist/skills/defaults/backend-development/billing-automation/SKILL.md +566 -0
  21. package/dist/skills/defaults/backend-development/code-review-excellence.md +538 -0
  22. package/dist/skills/defaults/backend-development/cqrs-implementation.md +554 -0
  23. package/dist/skills/defaults/backend-development/database-design.md +305 -0
  24. package/dist/skills/defaults/backend-development/debugging-strategies.md +536 -0
  25. package/dist/skills/defaults/backend-development/e2e-testing-patterns.md +544 -0
  26. package/dist/skills/defaults/backend-development/error-handling-patterns.md +641 -0
  27. package/dist/skills/defaults/backend-development/fastapi-templates.md +559 -0
  28. package/dist/skills/defaults/backend-development/fastapi.md +309 -0
  29. package/dist/skills/defaults/backend-development/git-advanced-workflows.md +405 -0
  30. package/dist/skills/defaults/backend-development/microservices-patterns.md +595 -0
  31. package/dist/skills/defaults/backend-development/microservices.md +284 -0
  32. package/dist/skills/defaults/backend-development/monorepo-management.md +623 -0
  33. package/dist/skills/defaults/backend-development/nodejs-backend-patterns.md +1048 -0
  34. package/dist/skills/defaults/backend-development/nx-workspace-patterns.md +457 -0
  35. package/dist/skills/defaults/backend-development/paypal-integration/SKILL.md +478 -0
  36. package/dist/skills/defaults/backend-development/pci-compliance/SKILL.md +480 -0
  37. package/dist/skills/defaults/backend-development/python-anti-patterns.md +349 -0
  38. package/dist/skills/defaults/backend-development/python-background-jobs.md +364 -0
  39. package/dist/skills/defaults/backend-development/python-code-style.md +360 -0
  40. package/dist/skills/defaults/backend-development/python-configuration.md +368 -0
  41. package/dist/skills/defaults/backend-development/python-design-patterns.md +296 -0
  42. package/dist/skills/defaults/backend-development/python-error-handling.md +323 -0
  43. package/dist/skills/defaults/backend-development/python-packaging.md +887 -0
  44. package/dist/skills/defaults/backend-development/python-performance-optimization.md +874 -0
  45. package/dist/skills/defaults/backend-development/python-project-structure.md +252 -0
  46. package/dist/skills/defaults/backend-development/python-resilience.md +376 -0
  47. package/dist/skills/defaults/backend-development/python-resource-management.md +421 -0
  48. package/dist/skills/defaults/backend-development/python-type-safety.md +428 -0
  49. package/dist/skills/defaults/backend-development/sql-optimization-patterns.md +509 -0
  50. package/dist/skills/defaults/backend-development/stripe-integration/SKILL.md +522 -0
  51. package/dist/skills/defaults/backend-development/turborepo-caching.md +376 -0
  52. package/dist/skills/defaults/blockchain/defi-protocol-templates.md +430 -0
  53. package/dist/skills/defaults/blockchain/nft-standards.md +364 -0
  54. package/dist/skills/defaults/blockchain/solidity-security.md +514 -0
  55. package/dist/skills/defaults/blockchain/web3-testing.md +360 -0
  56. package/dist/skills/defaults/business/competitive-landscape/SKILL.md +527 -0
  57. package/dist/skills/defaults/business/market-sizing-analysis/SKILL.md +451 -0
  58. package/dist/skills/defaults/business/startup-financial-modeling/SKILL.md +494 -0
  59. package/dist/skills/defaults/business/startup-metrics-framework/SKILL.md +564 -0
  60. package/dist/skills/defaults/business/team-composition-analysis.md +437 -0
  61. package/dist/skills/defaults/compliance/employment-contract-templates/SKILL.md +527 -0
  62. package/dist/skills/defaults/compliance/gdpr-data-handling/SKILL.md +630 -0
  63. package/dist/skills/defaults/data-engineering/airflow-dag-patterns.md +436 -0
  64. package/dist/skills/defaults/data-engineering/airflow.md +519 -0
  65. package/dist/skills/defaults/data-engineering/data-quality.md +583 -0
  66. package/dist/skills/defaults/data-engineering/dbt-transformation-patterns.md +482 -0
  67. package/dist/skills/defaults/data-engineering/dbt.md +556 -0
  68. package/dist/skills/defaults/data-engineering/ml-pipeline-workflow/SKILL.md +247 -0
  69. package/dist/skills/defaults/data-engineering/spark-optimization.md +348 -0
  70. package/dist/skills/defaults/data-engineering/spark.md +411 -0
  71. package/dist/skills/defaults/database/postgresql.md +202 -0
  72. package/dist/skills/defaults/debugging/systematic-debugging.md +249 -0
  73. package/dist/skills/defaults/devops/architecture-decision-records.md +448 -0
  74. package/dist/skills/defaults/devops/changelog-automation.md +580 -0
  75. package/dist/skills/defaults/devops/cicd.md +314 -0
  76. package/dist/skills/defaults/devops/cloud.md +263 -0
  77. package/dist/skills/defaults/devops/code-review-excellence.md +299 -0
  78. package/dist/skills/defaults/devops/cost-optimization.md +295 -0
  79. package/dist/skills/defaults/devops/deployment-pipeline-design.md +356 -0
  80. package/dist/skills/defaults/devops/docker.md +281 -0
  81. package/dist/skills/defaults/devops/git-workflows.md +205 -0
  82. package/dist/skills/defaults/devops/github-actions.md +311 -0
  83. package/dist/skills/defaults/devops/gitlab-ci-patterns.md +266 -0
  84. package/dist/skills/defaults/devops/hybrid-cloud-networking.md +241 -0
  85. package/dist/skills/defaults/devops/istio-traffic-management.md +327 -0
  86. package/dist/skills/defaults/devops/kubernetes.md +339 -0
  87. package/dist/skills/defaults/devops/linkerd-patterns.md +311 -0
  88. package/dist/skills/defaults/devops/multi-cloud-architecture.md +181 -0
  89. package/dist/skills/defaults/devops/observability.md +243 -0
  90. package/dist/skills/defaults/devops/openapi-spec-generation.md +1024 -0
  91. package/dist/skills/defaults/devops/postmortem-writing.md +396 -0
  92. package/dist/skills/defaults/devops/prometheus-configuration.md +265 -0
  93. package/dist/skills/defaults/devops/secrets-management.md +341 -0
  94. package/dist/skills/defaults/devops/service-mesh-observability.md +385 -0
  95. package/dist/skills/defaults/devops/terraform-module-library.md +244 -0
  96. package/dist/skills/defaults/finance/backtesting-frameworks/SKILL.md +663 -0
  97. package/dist/skills/defaults/finance/risk-metrics-calculation/SKILL.md +557 -0
  98. package/dist/skills/defaults/frontend/accessibility-compliance.md +420 -0
  99. package/dist/skills/defaults/frontend/design-system-patterns.md +337 -0
  100. package/dist/skills/defaults/frontend/interaction-design.md +327 -0
  101. package/dist/skills/defaults/frontend/javascript.md +311 -0
  102. package/dist/skills/defaults/frontend/modern-javascript-patterns.md +927 -0
  103. package/dist/skills/defaults/frontend/react-native-design.md +440 -0
  104. package/dist/skills/defaults/frontend/react.md +345 -0
  105. package/dist/skills/defaults/frontend/responsive-design.md +472 -0
  106. package/dist/skills/defaults/frontend/tailwind-design-system.md +337 -0
  107. package/dist/skills/defaults/frontend/typescript-advanced-types.md +724 -0
  108. package/dist/skills/defaults/frontend/typescript.md +334 -0
  109. package/dist/skills/defaults/frontend/visual-design-foundations.md +326 -0
  110. package/dist/skills/defaults/frontend/web-component-design.md +279 -0
  111. package/dist/skills/defaults/game-development/godot-gdscript-patterns.md +188 -0
  112. package/dist/skills/defaults/game-development/unity-ecs-patterns.md +594 -0
  113. package/dist/skills/defaults/kubernetes/gitops-workflow.md +285 -0
  114. package/dist/skills/defaults/kubernetes/gitops.md +280 -0
  115. package/dist/skills/defaults/kubernetes/helm-chart-scaffolding.md +553 -0
  116. package/dist/skills/defaults/kubernetes/helm.md +343 -0
  117. package/dist/skills/defaults/kubernetes/k8s-manifest-generator.md +501 -0
  118. package/dist/skills/defaults/kubernetes/k8s-security-policies.md +342 -0
  119. package/dist/skills/defaults/kubernetes/manifests.md +330 -0
  120. package/dist/skills/defaults/kubernetes/security.md +337 -0
  121. package/dist/skills/defaults/llm-application/embedding-strategies.md +608 -0
  122. package/dist/skills/defaults/llm-application/hybrid-search-implementation.md +570 -0
  123. package/dist/skills/defaults/llm-application/hybrid-search.md +570 -0
  124. package/dist/skills/defaults/llm-application/langchain-architecture.md +666 -0
  125. package/dist/skills/defaults/llm-application/langchain.md +259 -0
  126. package/dist/skills/defaults/llm-application/llm-evaluation.md +695 -0
  127. package/dist/skills/defaults/llm-application/prompt-engineering-patterns.md +449 -0
  128. package/dist/skills/defaults/llm-application/prompt-engineering.md +219 -0
  129. package/dist/skills/defaults/llm-application/rag-implementation.md +434 -0
  130. package/dist/skills/defaults/llm-application/similarity-search-patterns.md +560 -0
  131. package/dist/skills/defaults/llm-application/similarity-search.md +560 -0
  132. package/dist/skills/defaults/llm-application/vector-index-tuning.md +523 -0
  133. package/dist/skills/defaults/mobile/mobile-android-design.md +440 -0
  134. package/dist/skills/defaults/mobile/mobile-ios-design.md +266 -0
  135. package/dist/skills/defaults/monitoring/distributed-tracing.md +436 -0
  136. package/dist/skills/defaults/monitoring/grafana-dashboards.md +370 -0
  137. package/dist/skills/defaults/monitoring/prometheus-configuration.md +379 -0
  138. package/dist/skills/defaults/monitoring/slo-implementation.md +323 -0
  139. package/dist/skills/defaults/refactoring/code-refactoring.md +349 -0
  140. package/dist/skills/defaults/security/anti-reversing-techniques/SKILL.md +559 -0
  141. package/dist/skills/defaults/security/auditor.md +168 -0
  142. package/dist/skills/defaults/security/binary-analysis-patterns/SKILL.md +438 -0
  143. package/dist/skills/defaults/security/memory-forensics/SKILL.md +483 -0
  144. package/dist/skills/defaults/security/mtls-configuration.md +349 -0
  145. package/dist/skills/defaults/security/protocol-reverse-engineering/SKILL.md +520 -0
  146. package/dist/skills/defaults/security/sast-configuration.md +182 -0
  147. package/dist/skills/defaults/security/security.md +313 -0
  148. package/dist/skills/defaults/security/stride-analysis.md +273 -0
  149. package/dist/skills/defaults/security/threat-mitigation-mapping.md +290 -0
  150. package/dist/skills/defaults/systems/bash-defensive-patterns/SKILL.md +539 -0
  151. package/dist/skills/defaults/systems/bats-testing-patterns/SKILL.md +631 -0
  152. package/dist/skills/defaults/systems/go-concurrency-patterns.md +657 -0
  153. package/dist/skills/defaults/systems/memory-safety-patterns.md +605 -0
  154. package/dist/skills/defaults/systems/rust-async-patterns.md +519 -0
  155. package/dist/skills/defaults/systems/shellcheck-configuration/SKILL.md +456 -0
  156. package/dist/skills/defaults/team-collaboration/multi-reviewer-patterns.md +126 -0
  157. package/dist/skills/defaults/team-collaboration/parallel-feature-development.md +151 -0
  158. package/dist/skills/defaults/testing/javascript-testing-patterns.md +1021 -0
  159. package/dist/skills/defaults/testing/python-testing-patterns.md +351 -0
  160. package/dist/skills/defaults/testing/testing.md +332 -0
  161. package/dist/skills/defaults/workflows/context-driven-development.md +384 -0
  162. package/dist/skills/defaults/workflows/track-management.md +592 -0
  163. package/dist/skills/defaults/workflows/workflow-patterns.md +622 -0
  164. package/dist/skills/index.d.ts +11 -0
  165. package/dist/skills/index.d.ts.map +1 -0
  166. package/dist/skills/index.js +129 -0
  167. package/dist/skills/index.js.map +1 -0
  168. package/dist/utils/character.js +6 -9
  169. package/dist/utils/character.js.map +1 -1
  170. package/dist/utils/contextManager.js +3 -7
  171. package/dist/utils/contextManager.js.map +1 -1
  172. package/dist/utils/inputbar.d.ts.map +1 -1
  173. package/dist/utils/inputbar.js +8 -1
  174. package/dist/utils/inputbar.js.map +1 -1
  175. package/dist/utils/output.d.ts.map +1 -1
  176. package/dist/utils/output.js +3 -35
  177. package/dist/utils/output.js.map +1 -1
  178. package/package.json +1 -1
@@ -0,0 +1,631 @@
1
+ ---
2
+ name: bats-testing-patterns
3
+ description: Master Bash Automated Testing System (Bats) for comprehensive shell script testing. Use when writing tests for shell scripts, CI/CD pipelines, or requiring test-driven development of shell utilities.
4
+ ---
5
+
6
+ # Bats Testing Patterns
7
+
8
+ Comprehensive guidance for writing comprehensive unit tests for shell scripts using Bats (Bash Automated Testing System), including test patterns, fixtures, and best practices for production-grade shell testing.
9
+
10
+ ## When to Use This Skill
11
+
12
+ - Writing unit tests for shell scripts
13
+ - Implementing test-driven development (TDD) for scripts
14
+ - Setting up automated testing in CI/CD pipelines
15
+ - Testing edge cases and error conditions
16
+ - Validating behavior across different shell environments
17
+ - Building maintainable test suites for scripts
18
+ - Creating fixtures for complex test scenarios
19
+ - Testing multiple shell dialects (bash, sh, dash)
20
+
21
+ ## Bats Fundamentals
22
+
23
+ ### What is Bats?
24
+
25
+ Bats (Bash Automated Testing System) is a TAP (Test Anything Protocol) compliant testing framework for shell scripts that provides:
26
+
27
+ - Simple, natural test syntax
28
+ - TAP output format compatible with CI systems
29
+ - Fixtures and setup/teardown support
30
+ - Assertion helpers
31
+ - Parallel test execution
32
+
33
+ ### Installation
34
+
35
+ ```bash
36
+ # macOS with Homebrew
37
+ brew install bats-core
38
+
39
+ # Ubuntu/Debian
40
+ git clone https://github.com/bats-core/bats-core.git
41
+ cd bats-core
42
+ ./install.sh /usr/local
43
+
44
+ # From npm (Node.js)
45
+ npm install --global bats
46
+
47
+ # Verify installation
48
+ bats --version
49
+ ```
50
+
51
+ ### File Structure
52
+
53
+ ```
54
+ project/
55
+ ├── bin/
56
+ │ ├── script.sh
57
+ │ └── helper.sh
58
+ ├── tests/
59
+ │ ├── test_script.bats
60
+ │ ├── test_helper.sh
61
+ │ ├── fixtures/
62
+ │ │ ├── input.txt
63
+ │ │ └── expected_output.txt
64
+ │ └── helpers/
65
+ │ └── mocks.bash
66
+ └── README.md
67
+ ```
68
+
69
+ ## Basic Test Structure
70
+
71
+ ### Simple Test File
72
+
73
+ ```bash
74
+ #!/usr/bin/env bats
75
+
76
+ # Load test helper if present
77
+ load test_helper
78
+
79
+ # Setup runs before each test
80
+ setup() {
81
+ export TMPDIR=$(mktemp -d)
82
+ }
83
+
84
+ # Teardown runs after each test
85
+ teardown() {
86
+ rm -rf "$TMPDIR"
87
+ }
88
+
89
+ # Test: simple assertion
90
+ @test "Function returns 0 on success" {
91
+ run my_function "input"
92
+ [ "$status" -eq 0 ]
93
+ }
94
+
95
+ # Test: output verification
96
+ @test "Function outputs correct result" {
97
+ run my_function "test"
98
+ [ "$output" = "expected output" ]
99
+ }
100
+
101
+ # Test: error handling
102
+ @test "Function returns 1 on missing argument" {
103
+ run my_function
104
+ [ "$status" -eq 1 ]
105
+ }
106
+ ```
107
+
108
+ ## Assertion Patterns
109
+
110
+ ### Exit Code Assertions
111
+
112
+ ```bash
113
+ #!/usr/bin/env bats
114
+
115
+ @test "Command succeeds" {
116
+ run true
117
+ [ "$status" -eq 0 ]
118
+ }
119
+
120
+ @test "Command fails as expected" {
121
+ run false
122
+ [ "$status" -ne 0 ]
123
+ }
124
+
125
+ @test "Command returns specific exit code" {
126
+ run my_function --invalid
127
+ [ "$status" -eq 127 ]
128
+ }
129
+
130
+ @test "Can capture command result" {
131
+ run echo "hello"
132
+ [ $status -eq 0 ]
133
+ [ "$output" = "hello" ]
134
+ }
135
+ ```
136
+
137
+ ### Output Assertions
138
+
139
+ ```bash
140
+ #!/usr/bin/env bats
141
+
142
+ @test "Output matches string" {
143
+ result=$(echo "hello world")
144
+ [ "$result" = "hello world" ]
145
+ }
146
+
147
+ @test "Output contains substring" {
148
+ result=$(echo "hello world")
149
+ [[ "$result" == *"world"* ]]
150
+ }
151
+
152
+ @test "Output matches pattern" {
153
+ result=$(date +%Y)
154
+ [[ "$result" =~ ^[0-9]{4}$ ]]
155
+ }
156
+
157
+ @test "Multi-line output" {
158
+ run printf "line1\nline2\nline3"
159
+ [ "$output" = "line1
160
+ line2
161
+ line3" ]
162
+ }
163
+
164
+ @test "Lines variable contains output" {
165
+ run printf "line1\nline2\nline3"
166
+ [ "${lines[0]}" = "line1" ]
167
+ [ "${lines[1]}" = "line2" ]
168
+ [ "${lines[2]}" = "line3" ]
169
+ }
170
+ ```
171
+
172
+ ### File Assertions
173
+
174
+ ```bash
175
+ #!/usr/bin/env bats
176
+
177
+ @test "File is created" {
178
+ [ ! -f "$TMPDIR/output.txt" ]
179
+ my_function > "$TMPDIR/output.txt"
180
+ [ -f "$TMPDIR/output.txt" ]
181
+ }
182
+
183
+ @test "File contents match expected" {
184
+ my_function > "$TMPDIR/output.txt"
185
+ [ "$(cat "$TMPDIR/output.txt")" = "expected content" ]
186
+ }
187
+
188
+ @test "File is readable" {
189
+ touch "$TMPDIR/test.txt"
190
+ [ -r "$TMPDIR/test.txt" ]
191
+ }
192
+
193
+ @test "File has correct permissions" {
194
+ touch "$TMPDIR/test.txt"
195
+ chmod 644 "$TMPDIR/test.txt"
196
+ [ "$(stat -f %OLp "$TMPDIR/test.txt")" = "644" ]
197
+ }
198
+
199
+ @test "File size is correct" {
200
+ echo -n "12345" > "$TMPDIR/test.txt"
201
+ [ "$(wc -c < "$TMPDIR/test.txt")" -eq 5 ]
202
+ }
203
+ ```
204
+
205
+ ## Setup and Teardown Patterns
206
+
207
+ ### Basic Setup and Teardown
208
+
209
+ ```bash
210
+ #!/usr/bin/env bats
211
+
212
+ setup() {
213
+ # Create test directory
214
+ TEST_DIR=$(mktemp -d)
215
+ export TEST_DIR
216
+
217
+ # Source script under test
218
+ source "${BATS_TEST_DIRNAME}/../bin/script.sh"
219
+ }
220
+
221
+ teardown() {
222
+ # Clean up temporary directory
223
+ rm -rf "$TEST_DIR"
224
+ }
225
+
226
+ @test "Test using TEST_DIR" {
227
+ touch "$TEST_DIR/file.txt"
228
+ [ -f "$TEST_DIR/file.txt" ]
229
+ }
230
+ ```
231
+
232
+ ### Setup with Resources
233
+
234
+ ```bash
235
+ #!/usr/bin/env bats
236
+
237
+ setup() {
238
+ # Create directory structure
239
+ mkdir -p "$TMPDIR/data/input"
240
+ mkdir -p "$TMPDIR/data/output"
241
+
242
+ # Create test fixtures
243
+ echo "line1" > "$TMPDIR/data/input/file1.txt"
244
+ echo "line2" > "$TMPDIR/data/input/file2.txt"
245
+
246
+ # Initialize environment
247
+ export DATA_DIR="$TMPDIR/data"
248
+ export INPUT_DIR="$DATA_DIR/input"
249
+ export OUTPUT_DIR="$DATA_DIR/output"
250
+ }
251
+
252
+ teardown() {
253
+ rm -rf "$TMPDIR/data"
254
+ }
255
+
256
+ @test "Processes input files" {
257
+ run my_process_script "$INPUT_DIR" "$OUTPUT_DIR"
258
+ [ "$status" -eq 0 ]
259
+ [ -f "$OUTPUT_DIR/file1.txt" ]
260
+ }
261
+ ```
262
+
263
+ ### Global Setup/Teardown
264
+
265
+ ```bash
266
+ #!/usr/bin/env bats
267
+
268
+ # Load shared setup from test_helper.sh
269
+ load test_helper
270
+
271
+ # setup_file runs once before all tests
272
+ setup_file() {
273
+ export SHARED_RESOURCE=$(mktemp -d)
274
+ echo "Expensive setup" > "$SHARED_RESOURCE/data.txt"
275
+ }
276
+
277
+ # teardown_file runs once after all tests
278
+ teardown_file() {
279
+ rm -rf "$SHARED_RESOURCE"
280
+ }
281
+
282
+ @test "First test uses shared resource" {
283
+ [ -f "$SHARED_RESOURCE/data.txt" ]
284
+ }
285
+
286
+ @test "Second test uses shared resource" {
287
+ [ -d "$SHARED_RESOURCE" ]
288
+ }
289
+ ```
290
+
291
+ ## Mocking and Stubbing Patterns
292
+
293
+ ### Function Mocking
294
+
295
+ ```bash
296
+ #!/usr/bin/env bats
297
+
298
+ # Mock external command
299
+ my_external_tool() {
300
+ echo "mocked output"
301
+ return 0
302
+ }
303
+
304
+ @test "Function uses mocked tool" {
305
+ export -f my_external_tool
306
+ run my_function
307
+ [[ "$output" == *"mocked output"* ]]
308
+ }
309
+ ```
310
+
311
+ ### Command Stubbing
312
+
313
+ ```bash
314
+ #!/usr/bin/env bats
315
+
316
+ setup() {
317
+ # Create stub directory
318
+ STUBS_DIR="$TMPDIR/stubs"
319
+ mkdir -p "$STUBS_DIR"
320
+
321
+ # Add to PATH
322
+ export PATH="$STUBS_DIR:$PATH"
323
+ }
324
+
325
+ create_stub() {
326
+ local cmd="$1"
327
+ local output="$2"
328
+ local code="${3:-0}"
329
+
330
+ cat > "$STUBS_DIR/$cmd" <<EOF
331
+ #!/bin/bash
332
+ echo "$output"
333
+ exit $code
334
+ EOF
335
+ chmod +x "$STUBS_DIR/$cmd"
336
+ }
337
+
338
+ @test "Function works with stubbed curl" {
339
+ create_stub curl "{ \"status\": \"ok\" }" 0
340
+ run my_api_function
341
+ [ "$status" -eq 0 ]
342
+ }
343
+ ```
344
+
345
+ ### Variable Stubbing
346
+
347
+ ```bash
348
+ #!/usr/bin/env bats
349
+
350
+ @test "Function handles environment override" {
351
+ export MY_SETTING="override_value"
352
+ run my_function
353
+ [ "$status" -eq 0 ]
354
+ [[ "$output" == *"override_value"* ]]
355
+ }
356
+
357
+ @test "Function uses default when var unset" {
358
+ unset MY_SETTING
359
+ run my_function
360
+ [ "$status" -eq 0 ]
361
+ [[ "$output" == *"default"* ]]
362
+ }
363
+ ```
364
+
365
+ ## Fixture Management
366
+
367
+ ### Using Fixture Files
368
+
369
+ ```bash
370
+ #!/usr/bin/env bats
371
+
372
+ # Fixture directory: tests/fixtures/
373
+
374
+ setup() {
375
+ FIXTURES_DIR="${BATS_TEST_DIRNAME}/fixtures"
376
+ WORK_DIR=$(mktemp -d)
377
+ export WORK_DIR
378
+ }
379
+
380
+ teardown() {
381
+ rm -rf "$WORK_DIR"
382
+ }
383
+
384
+ @test "Process fixture file" {
385
+ # Copy fixture to work directory
386
+ cp "$FIXTURES_DIR/input.txt" "$WORK_DIR/input.txt"
387
+
388
+ # Run function
389
+ run my_process_function "$WORK_DIR/input.txt"
390
+
391
+ # Compare output
392
+ diff "$WORK_DIR/output.txt" "$FIXTURES_DIR/expected_output.txt"
393
+ }
394
+ ```
395
+
396
+ ### Dynamic Fixture Generation
397
+
398
+ ```bash
399
+ #!/usr/bin/env bats
400
+
401
+ generate_fixture() {
402
+ local lines="$1"
403
+ local file="$2"
404
+
405
+ for i in $(seq 1 "$lines"); do
406
+ echo "Line $i content" >> "$file"
407
+ done
408
+ }
409
+
410
+ @test "Handle large input file" {
411
+ generate_fixture 1000 "$TMPDIR/large.txt"
412
+ run my_function "$TMPDIR/large.txt"
413
+ [ "$status" -eq 0 ]
414
+ [ "$(wc -l < "$TMPDIR/large.txt")" -eq 1000 ]
415
+ }
416
+ ```
417
+
418
+ ## Advanced Patterns
419
+
420
+ ### Testing Error Conditions
421
+
422
+ ```bash
423
+ #!/usr/bin/env bats
424
+
425
+ @test "Function fails with missing file" {
426
+ run my_function "/nonexistent/file.txt"
427
+ [ "$status" -ne 0 ]
428
+ [[ "$output" == *"not found"* ]]
429
+ }
430
+
431
+ @test "Function fails with invalid input" {
432
+ run my_function ""
433
+ [ "$status" -ne 0 ]
434
+ }
435
+
436
+ @test "Function fails with permission denied" {
437
+ touch "$TMPDIR/readonly.txt"
438
+ chmod 000 "$TMPDIR/readonly.txt"
439
+ run my_function "$TMPDIR/readonly.txt"
440
+ [ "$status" -ne 0 ]
441
+ chmod 644 "$TMPDIR/readonly.txt" # Cleanup
442
+ }
443
+
444
+ @test "Function provides helpful error message" {
445
+ run my_function --invalid-option
446
+ [ "$status" -ne 0 ]
447
+ [[ "$output" == *"Usage:"* ]]
448
+ }
449
+ ```
450
+
451
+ ### Testing with Dependencies
452
+
453
+ ```bash
454
+ #!/usr/bin/env bats
455
+
456
+ setup() {
457
+ # Check for required tools
458
+ if ! command -v jq &>/dev/null; then
459
+ skip "jq is not installed"
460
+ fi
461
+
462
+ export SCRIPT="${BATS_TEST_DIRNAME}/../bin/script.sh"
463
+ }
464
+
465
+ @test "JSON parsing works" {
466
+ skip_if ! command -v jq &>/dev/null
467
+ run my_json_parser '{"key": "value"}'
468
+ [ "$status" -eq 0 ]
469
+ }
470
+ ```
471
+
472
+ ### Testing Shell Compatibility
473
+
474
+ ```bash
475
+ #!/usr/bin/env bats
476
+
477
+ @test "Script works in bash" {
478
+ bash "${BATS_TEST_DIRNAME}/../bin/script.sh" arg1
479
+ }
480
+
481
+ @test "Script works in sh (POSIX)" {
482
+ sh "${BATS_TEST_DIRNAME}/../bin/script.sh" arg1
483
+ }
484
+
485
+ @test "Script works in dash" {
486
+ if command -v dash &>/dev/null; then
487
+ dash "${BATS_TEST_DIRNAME}/../bin/script.sh" arg1
488
+ else
489
+ skip "dash not installed"
490
+ fi
491
+ }
492
+ ```
493
+
494
+ ### Parallel Execution
495
+
496
+ ```bash
497
+ #!/usr/bin/env bats
498
+
499
+ @test "Multiple independent operations" {
500
+ run bash -c 'for i in {1..10}; do
501
+ my_operation "$i" &
502
+ done
503
+ wait'
504
+ [ "$status" -eq 0 ]
505
+ }
506
+
507
+ @test "Concurrent file operations" {
508
+ for i in {1..5}; do
509
+ my_function "$TMPDIR/file$i" &
510
+ done
511
+ wait
512
+ [ -f "$TMPDIR/file1" ]
513
+ [ -f "$TMPDIR/file5" ]
514
+ }
515
+ ```
516
+
517
+ ## Test Helper Pattern
518
+
519
+ ### test_helper.sh
520
+
521
+ ```bash
522
+ #!/usr/bin/env bash
523
+
524
+ # Source script under test
525
+ export SCRIPT_DIR="${BATS_TEST_DIRNAME%/*}/bin"
526
+
527
+ # Common test utilities
528
+ assert_file_exists() {
529
+ if [ ! -f "$1" ]; then
530
+ echo "Expected file to exist: $1"
531
+ return 1
532
+ fi
533
+ }
534
+
535
+ assert_file_equals() {
536
+ local file="$1"
537
+ local expected="$2"
538
+
539
+ if [ ! -f "$file" ]; then
540
+ echo "File does not exist: $file"
541
+ return 1
542
+ fi
543
+
544
+ local actual=$(cat "$file")
545
+ if [ "$actual" != "$expected" ]; then
546
+ echo "File contents do not match"
547
+ echo "Expected: $expected"
548
+ echo "Actual: $actual"
549
+ return 1
550
+ fi
551
+ }
552
+
553
+ # Create temporary test directory
554
+ setup_test_dir() {
555
+ export TEST_DIR=$(mktemp -d)
556
+ }
557
+
558
+ cleanup_test_dir() {
559
+ rm -rf "$TEST_DIR"
560
+ }
561
+ ```
562
+
563
+ ## Integration with CI/CD
564
+
565
+ ### GitHub Actions Workflow
566
+
567
+ ```yaml
568
+ name: Tests
569
+
570
+ on: [push, pull_request]
571
+
572
+ jobs:
573
+ test:
574
+ runs-on: ubuntu-latest
575
+
576
+ steps:
577
+ - uses: actions/checkout@v3
578
+
579
+ - name: Install Bats
580
+ run: |
581
+ npm install --global bats
582
+
583
+ - name: Run Tests
584
+ run: |
585
+ bats tests/*.bats
586
+
587
+ - name: Run Tests with Tap Reporter
588
+ run: |
589
+ bats tests/*.bats --tap | tee test_output.tap
590
+ ```
591
+
592
+ ### Makefile Integration
593
+
594
+ ```makefile
595
+ .PHONY: test test-verbose test-tap
596
+
597
+ test:
598
+ bats tests/*.bats
599
+
600
+ test-verbose:
601
+ bats tests/*.bats --verbose
602
+
603
+ test-tap:
604
+ bats tests/*.bats --tap
605
+
606
+ test-parallel:
607
+ bats tests/*.bats --parallel 4
608
+
609
+ coverage: test
610
+ # Optional: Generate coverage reports
611
+ ```
612
+
613
+ ## Best Practices
614
+
615
+ 1. **Test one thing per test** - Single responsibility principle
616
+ 2. **Use descriptive test names** - Clearly states what is being tested
617
+ 3. **Clean up after tests** - Always remove temporary files in teardown
618
+ 4. **Test both success and failure paths** - Don't just test happy path
619
+ 5. **Mock external dependencies** - Isolate unit under test
620
+ 6. **Use fixtures for complex data** - Makes tests more readable
621
+ 7. **Run tests in CI/CD** - Catch regressions early
622
+ 8. **Test across shell dialects** - Ensure portability
623
+ 9. **Keep tests fast** - Run in parallel when possible
624
+ 10. **Document complex test setup** - Explain unusual patterns
625
+
626
+ ## Resources
627
+
628
+ - **Bats GitHub**: https://github.com/bats-core/bats-core
629
+ - **Bats Documentation**: https://bats-core.readthedocs.io/
630
+ - **TAP Protocol**: https://testanything.org/
631
+ - **Test-Driven Development**: https://en.wikipedia.org/wiki/Test-driven_development