spec_forge 0.5.0 → 0.7.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 (116) hide show
  1. checksums.yaml +4 -4
  2. data/.standard.yml +3 -3
  3. data/CHANGELOG.md +217 -2
  4. data/README.md +162 -25
  5. data/flake.lock +3 -3
  6. data/flake.nix +11 -5
  7. data/lib/spec_forge/attribute/chainable.rb +208 -20
  8. data/lib/spec_forge/attribute/factory.rb +92 -15
  9. data/lib/spec_forge/attribute/faker.rb +62 -13
  10. data/lib/spec_forge/attribute/global.rb +96 -0
  11. data/lib/spec_forge/attribute/literal.rb +15 -2
  12. data/lib/spec_forge/attribute/matcher.rb +186 -11
  13. data/lib/spec_forge/attribute/parameterized.rb +45 -12
  14. data/lib/spec_forge/attribute/regex.rb +55 -5
  15. data/lib/spec_forge/attribute/resolvable.rb +48 -5
  16. data/lib/spec_forge/attribute/resolvable_array.rb +62 -4
  17. data/lib/spec_forge/attribute/resolvable_hash.rb +62 -4
  18. data/lib/spec_forge/attribute/store.rb +65 -0
  19. data/lib/spec_forge/attribute/transform.rb +33 -5
  20. data/lib/spec_forge/attribute/variable.rb +37 -6
  21. data/lib/spec_forge/attribute.rb +166 -66
  22. data/lib/spec_forge/backtrace_formatter.rb +26 -3
  23. data/lib/spec_forge/callbacks.rb +88 -0
  24. data/lib/spec_forge/cli/actions.rb +27 -0
  25. data/lib/spec_forge/cli/command.rb +78 -24
  26. data/lib/spec_forge/cli/docs/generate.rb +72 -0
  27. data/lib/spec_forge/cli/docs.rb +92 -0
  28. data/lib/spec_forge/cli/init.rb +51 -9
  29. data/lib/spec_forge/cli/new.rb +67 -6
  30. data/lib/spec_forge/cli/run.rb +32 -4
  31. data/lib/spec_forge/cli/serve.rb +155 -0
  32. data/lib/spec_forge/cli.rb +26 -7
  33. data/lib/spec_forge/configuration.rb +96 -24
  34. data/lib/spec_forge/context/callbacks.rb +91 -0
  35. data/lib/spec_forge/context/global.rb +72 -0
  36. data/lib/spec_forge/context/store.rb +131 -0
  37. data/lib/spec_forge/context/variables.rb +91 -0
  38. data/lib/spec_forge/context.rb +36 -0
  39. data/lib/spec_forge/core_ext/array.rb +27 -0
  40. data/lib/spec_forge/core_ext/rspec.rb +22 -4
  41. data/lib/spec_forge/documentation/builder.rb +383 -0
  42. data/lib/spec_forge/documentation/document/operation.rb +47 -0
  43. data/lib/spec_forge/documentation/document/parameter.rb +22 -0
  44. data/lib/spec_forge/documentation/document/request_body.rb +24 -0
  45. data/lib/spec_forge/documentation/document/response.rb +39 -0
  46. data/lib/spec_forge/documentation/document/response_body.rb +27 -0
  47. data/lib/spec_forge/documentation/document.rb +48 -0
  48. data/lib/spec_forge/documentation/generators/base.rb +81 -0
  49. data/lib/spec_forge/documentation/generators/openapi/base.rb +100 -0
  50. data/lib/spec_forge/documentation/generators/openapi/error_formatter.rb +149 -0
  51. data/lib/spec_forge/documentation/generators/openapi/v3_0.rb +65 -0
  52. data/lib/spec_forge/documentation/generators/openapi.rb +59 -0
  53. data/lib/spec_forge/documentation/generators.rb +17 -0
  54. data/lib/spec_forge/documentation/loader/cache.rb +138 -0
  55. data/lib/spec_forge/documentation/loader.rb +159 -0
  56. data/lib/spec_forge/documentation/openapi/base.rb +33 -0
  57. data/lib/spec_forge/documentation/openapi/v3_0/example.rb +44 -0
  58. data/lib/spec_forge/documentation/openapi/v3_0/media_type.rb +42 -0
  59. data/lib/spec_forge/documentation/openapi/v3_0/operation.rb +175 -0
  60. data/lib/spec_forge/documentation/openapi/v3_0/response.rb +65 -0
  61. data/lib/spec_forge/documentation/openapi/v3_0/schema.rb +80 -0
  62. data/lib/spec_forge/documentation/openapi/v3_0/tag.rb +71 -0
  63. data/lib/spec_forge/documentation/openapi.rb +23 -0
  64. data/lib/spec_forge/documentation.rb +27 -0
  65. data/lib/spec_forge/error.rb +284 -113
  66. data/lib/spec_forge/factory.rb +35 -16
  67. data/lib/spec_forge/filter.rb +86 -0
  68. data/lib/spec_forge/forge.rb +171 -0
  69. data/lib/spec_forge/http/backend.rb +101 -29
  70. data/lib/spec_forge/http/client.rb +23 -13
  71. data/lib/spec_forge/http/request.rb +85 -62
  72. data/lib/spec_forge/http/verb.rb +79 -0
  73. data/lib/spec_forge/http.rb +105 -0
  74. data/lib/spec_forge/loader.rb +244 -0
  75. data/lib/spec_forge/matchers.rb +130 -0
  76. data/lib/spec_forge/normalizer/default.rb +51 -0
  77. data/lib/spec_forge/normalizer/definition.rb +248 -0
  78. data/lib/spec_forge/normalizer/validators.rb +99 -0
  79. data/lib/spec_forge/normalizer.rb +486 -115
  80. data/lib/spec_forge/normalizers/_shared.yml +74 -0
  81. data/lib/spec_forge/normalizers/configuration.yml +23 -0
  82. data/lib/spec_forge/normalizers/constraint.yml +8 -0
  83. data/lib/spec_forge/normalizers/expectation.yml +47 -0
  84. data/lib/spec_forge/normalizers/factory.yml +12 -0
  85. data/lib/spec_forge/normalizers/factory_reference.yml +15 -0
  86. data/lib/spec_forge/normalizers/global_context.yml +28 -0
  87. data/lib/spec_forge/normalizers/spec.yml +50 -0
  88. data/lib/spec_forge/runner/adapter.rb +183 -0
  89. data/lib/spec_forge/runner/callbacks.rb +246 -0
  90. data/lib/spec_forge/runner/debug_proxy.rb +213 -0
  91. data/lib/spec_forge/runner/listener.rb +54 -0
  92. data/lib/spec_forge/runner/metadata.rb +58 -0
  93. data/lib/spec_forge/runner/state.rb +98 -0
  94. data/lib/spec_forge/runner.rb +50 -125
  95. data/lib/spec_forge/spec/expectation/constraint.rb +100 -21
  96. data/lib/spec_forge/spec/expectation.rb +47 -51
  97. data/lib/spec_forge/spec.rb +50 -108
  98. data/lib/spec_forge/type.rb +36 -4
  99. data/lib/spec_forge/version.rb +4 -1
  100. data/lib/spec_forge.rb +168 -76
  101. data/lib/templates/openapi.yml.tt +22 -0
  102. data/lib/templates/redoc.html.tt +28 -0
  103. data/lib/templates/swagger.html.tt +59 -0
  104. metadata +109 -16
  105. data/lib/spec_forge/normalizer/configuration.rb +0 -77
  106. data/lib/spec_forge/normalizer/constraint.rb +0 -47
  107. data/lib/spec_forge/normalizer/expectation.rb +0 -86
  108. data/lib/spec_forge/normalizer/factory.rb +0 -65
  109. data/lib/spec_forge/normalizer/factory_reference.rb +0 -71
  110. data/lib/spec_forge/normalizer/spec.rb +0 -74
  111. data/spec_forge/factories/user.yml +0 -4
  112. data/spec_forge/forge_helper.rb +0 -48
  113. data/spec_forge/specs/users.yml +0 -65
  114. /data/lib/templates/{forge_helper.tt → forge_helper.rb.tt} +0 -0
  115. /data/lib/templates/{new_factory.tt → new_factory.yml.tt} +0 -0
  116. /data/lib/templates/{new_spec.tt → new_spec.yml.tt} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2f51faa712bafdcb48e3940273ec494eb3f39e43c0d122ff0a6f97e425026438
4
- data.tar.gz: fe5cf7dff0a44cf5cfc466189fb38c3ed66da21637e18ebcdb44e31f9f6a8b73
3
+ metadata.gz: 7f8c38cb9ff50cb02ee74171a4d571ac411807b1dcce43edab0f28a757269b2f
4
+ data.tar.gz: 1595911a7a84d7712ddcc5bf0e2a08c0c30afce995ac02bb1372c1ae29ca7db0
5
5
  SHA512:
6
- metadata.gz: be068681e3c2ce8b2f62fa21ae03281d40b34c19e190acce4f90796dd526197b6ae54cc6edaa04d6715e347a67e2c193e2b99b0e16e45b47b3183915001790f3
7
- data.tar.gz: 644f2c1a49d3ed45a201cb53d731176a418c134679f324ef96f331427481643b2744bd6c27c0f326df32c1db751c412137ad209a3f0b0ce3add9cc68eb6a660e
6
+ metadata.gz: 731ff8f0cc847010f38caab823c7d30c0d3d7083d4ea53de6ac46c19929c2c31ce698db787303c706ae6ee517dea396ef5ceb220732dd172050967404dd102af
7
+ data.tar.gz: 1a24dd8f84528427e30d105c4e358ca226b699e79a68a9ac2eb5385a974abb2acb27f8c8a3751e8c69a70001ef8d2ef3938ab06f9c81f1f041325b1b038923e1
data/.standard.yml CHANGED
@@ -2,6 +2,6 @@
2
2
  # https://github.com/standardrb/standard
3
3
  ruby_version: 3.3
4
4
  ignore:
5
- - ".direnv/**/*"
6
- - "vendor/**/*"
7
- - "spec/integration/**/*"
5
+ - ".direnv/**/*"
6
+ - "vendor/**/*"
7
+ - "spec/integration/vendor/**/*"
data/CHANGELOG.md CHANGED
@@ -15,14 +15,227 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
15
15
  ### Removed
16
16
  -->
17
17
 
18
- ## [Unreleased]
18
+ ## [0.7.0] - 12025-06-22
19
19
 
20
20
  ### Added
21
21
 
22
+ #### 🚀 Documentation-First Architecture
23
+ **The Big Picture**: SpecForge now generates OpenAPI documentation from your tests automatically!
24
+
25
+ - **Primary Documentation Workflow**: New `docs` command (now the default!) generates OpenAPI specs from test execution
26
+ - Smart caching system with `--fresh` flag for forced regeneration
27
+ - Multiple output formats: YAML (default) or JSON via `--format`
28
+ - Custom output paths with `--output` option
29
+ - Built-in OpenAPI 3.0.4 validation with detailed, helpful error messages
30
+ - Optional validation skip with `--skip-validation` for faster iterations
31
+
32
+ - **Live Documentation Server**: `spec_forge serve` command for immediate feedback
33
+ - Local web server with Swagger UI (default) or Redoc (`--ui redoc`)
34
+ - Configurable port with `--port` (defaults to 8080)
35
+ - Auto-generated HTML templates for both UI options
36
+ - Perfect for development and API review workflows
37
+
38
+ - **Flexible Configuration System**:
39
+ - Directory-based config: `config/components/`, `config/paths/`, etc.
40
+ - Template-based initialization with sensible defaults
41
+ - Enhanced YAML merging with `$ref` support
42
+ - Full OpenAPI customization through configuration files
43
+
44
+ #### 🧪 Enhanced Testing Capabilities
45
+
46
+ - **HTTP Header Testing**: Comprehensive header validation
47
+ ```yaml
48
+ headers:
49
+ Content-Type: "application/json"
50
+ X-Request-ID: /^[0-9a-f-]{36}$/
51
+ Cache-Control:
52
+ matcher.and:
53
+ - matcher.include: "max-age="
54
+ - matcher.include: "private"
55
+ ```
56
+
57
+ - **Flexible Store System**: Store anything, access everything
58
+ - OpenStruct-based entries for maximum flexibility
59
+ - Custom data via callbacks (config, metadata, computed values)
60
+ - Same familiar `store.id.attribute` syntax
61
+ - Perfect for complex test scenarios and feature flags
62
+
63
+ - **Documentation Control**: Fine-grained control over what gets documented
64
+ - New `documentation: true/false` attribute for specs and expectations
65
+ - Exclude test-only scenarios from API docs while keeping functionality
66
+
67
+ #### ⚙️ Architecture Improvements
68
+
69
+ - **YAML-Driven Normalizers**: Configuration over code
70
+ - Structure definitions in `lib/spec_forge/normalizers/*.yml`
71
+ - Powerful `reference:` system for reusable components
72
+ - Wildcard support (`*`) for catch-all schemas
73
+ - Centralized validation logic in dedicated module
74
+
75
+ - **Enhanced CLI Experience**:
76
+ - Improved `init` command with `--skip-openapi` and `--skip-factories` flags
77
+ - Better help text and examples throughout
78
+ - Clearer error messages with actionable context
79
+
80
+ - **Developer Utilities**:
81
+ - `Array#to_merged_h` for cleaner hash merging
82
+ - Unified `.normalize!(input, using:)` API across normalizers
83
+ - Separated test preparation (`Runner.prepare`) from execution
84
+
22
85
  ### Changed
23
86
 
87
+ #### 🎯 User Experience Overhaul
88
+
89
+ - **New Default Behavior**: `spec_forge` without arguments now shows help instead of running tests
90
+ - **Breaking Change**: Use `spec_forge docs` for documentation or `spec_forge run` for test-only execution
91
+ - Safer default that guides users to the right command for their needs
92
+
93
+ - **Streamlined Commands**:
94
+ - Better command organization and help text
95
+ - Consistent flag naming across commands
96
+ - Enhanced error handling with helpful suggestions
97
+
98
+ #### 🏗️ Internal Refactoring
99
+
100
+ - **Normalizer Architecture**: YAML-based instead of class-heavy approach
101
+ - Consolidated shared definitions in `_shared.yml`
102
+ - Easier maintenance and extension
103
+ - Better error context with attribute path tracking
104
+
105
+ - **Test Execution Pipeline**:
106
+ - Clean separation between test preparation and execution
107
+ - Enhanced RSpec adapter pattern
108
+ - Better reusability for documentation generation
109
+
110
+ - **HTTP & Store Improvements**:
111
+ - Automatic header value string conversion
112
+ - Simplified store entry structure with OpenStruct flexibility
113
+ - Enhanced request/response handling
114
+
24
115
  ### Removed
25
116
 
117
+ - **Legacy Architecture**: Individual normalizer class files (replaced with YAML config)
118
+
119
+ ---
120
+
121
+ **Migration Notes**:
122
+ - Update any scripts using bare `spec_forge` - now shows help instead of running tests
123
+ - Use `spec_forge docs` for documentation generation or `spec_forge run` for testing
124
+ - Store access patterns remain the same, but internal structure is more flexible
125
+
126
+ ## [0.6.0] - 12025-03-25
127
+
128
+ ### Added
129
+
130
+ - Added new context system for managing shared state between tests
131
+ - Introduced `SpecForge.context` global accessor for accessing test context
132
+ - Created `Context` class with modular components:
133
+ - `Context::Global` for file-level shared variables
134
+ - `Context::Variables` for managing variables with overlay support
135
+ - `Context::Store` for storing the results of the tests
136
+ - Added support for defining and referencing global variables
137
+ ```yaml
138
+ global:
139
+ variables:
140
+ api_version: "v2"
141
+ environment: "test"
142
+
143
+ index_user:
144
+ path: "/{api_version}/users"
145
+ query:
146
+ api_version: "global.variables.api_version"
147
+ ```
148
+ - Added compound matcher support via `matcher.and` for combining multiple matchers
149
+ ```yaml
150
+ email:
151
+ matcher.and:
152
+ - kind_of.string
153
+ - /@/
154
+ - matcher.end_with: ".com"
155
+ ```
156
+ - Added custom RSpec matcher `have_size` for checking an object's size via `matcher.have_size`
157
+ - Added new `Loader` class for improved spec file processing
158
+ - Added new `Filter` class for more flexible test filtering
159
+ - Added normalizer for global context validation
160
+ - Added line number tracking for specs and expectations
161
+ - Added support for defining and referencing callbacks
162
+ ```ruby
163
+ # Configuration level
164
+ SpecForge.configure do |config|
165
+ config.register_callback("callback_name") { |context| }
166
+ # These are aliases
167
+ # config.define_callback("callback_name") { |context| }
168
+ # config.callback("callback_name") { |context| }
169
+ end
170
+
171
+ # Module level (no aliases)
172
+ SpecForge.register_callback("callback_name") { |context| }
173
+ ```
174
+ Once defined, callbacks can be referenced in spec files via the global context
175
+ ```yaml
176
+ global:
177
+ callbacks:
178
+ - before: callback_name
179
+ after: cleanup_database_state
180
+ ```
181
+ - Added support for storing and retrieving test data via the `store_as` directive and `store` attribute
182
+ ```yaml
183
+ create_user:
184
+ path: "/users"
185
+ method: "post"
186
+ expectations:
187
+ - variables:
188
+ name: "John"
189
+ email: "john@example.com"
190
+ store_as: "created_user"
191
+ expect:
192
+ status: 200
193
+
194
+ show_user:
195
+ path: "/users/:id"
196
+ query:
197
+ id: store.created_user.response.id
198
+ - expect:
199
+ status: 200
200
+ ```
201
+ - Added `UndefinedMatcherError` for clearer error messaging when invalid matchers are used
202
+ - Enhanced debugging capabilities with improved DebugProxy methods and store access
203
+ - Added HTTP status descriptions for better error messages
204
+ - Added support for string values in `query`, `body`, and `variables` attributes
205
+ - Added print statement when filtering tests for better visibility
206
+
207
+ ### Changed
208
+
209
+ - Renamed `SpecForge.forge` to `SpecForge.forge_path`
210
+ - Renamed attribute `http_method` to `http_verb` (`http_method` is now an alias)
211
+ - Refactored attribute resolution methods:
212
+ - Renamed `Attribute#resolve` to `#resolved` (memoized version)
213
+ - Renamed `Attribute#resolve_value` to `#resolve` (immediate resolution)
214
+ - Added `Attribute#resolve_as_matcher` for resolving attributes into RSpec matchers
215
+ - Refactored variable resolution to use the new context system
216
+ - Updated `Runner` to properly initialize and manage context between tests
217
+ - Improved error messages with more contextual information about the execution environment
218
+ - Updated YARD comments with better API descriptions and examples
219
+ - Restructured internal architecture for better separation of concerns
220
+ - Moved all error classes under `SpecForge::Error`
221
+ - Fixed issue where nesting expanded matchers (such as `matcher.include`) would cause an error
222
+ - Improved response body validation for hash expectations:
223
+ - Each root-level key is now checked individually for more precise error messages
224
+ - Nested hashes still use the `include` matcher for flexibility
225
+ - Adjusted `Attribute::Matcher` to accept either `matcher` or `matchers` namespace
226
+ - Changed empty array matcher from using `contain_exactly` to `eq([])`
227
+ - Changed empty hash matcher from using `include` to `eq({})`
228
+ - Changed `forge_and` description from "matches all of:" to "match all:"
229
+ - Improved error handling for chainable attributes with better descriptions for various object types
230
+ - Limited error backtrace to 50 lines for cleaner output
231
+ - Enhanced spec loading error messages with more detailed information
232
+ - Improved RSpec example descriptions for better test output
233
+ - Added support for overwriting headers at the request level
234
+
235
+ ## Removed
236
+
237
+ - Removed `Configuration.overlay_options`
238
+
26
239
  ## [0.5.0] - 12025-02-28
27
240
 
28
241
  ### Added
@@ -126,7 +339,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
126
339
 
127
340
  - Initial commit
128
341
 
129
- [unreleased]: https://github.com/itsthedevman/spec_forge/compare/v0.5.0...HEAD
342
+ [unreleased]: https://github.com/itsthedevman/spec_forge/compare/v0.7.0...HEAD
343
+ [0.7.0]: https://github.com/itsthedevman/spec_forge/compare/v0.6.0...v0.7.0
344
+ [0.6.0]: https://github.com/itsthedevman/spec_forge/compare/v0.5.0...v0.6.0
130
345
  [0.5.0]: https://github.com/itsthedevman/spec_forge/compare/v0.4.0...v0.5.0
131
346
  [0.4.0]: https://github.com/itsthedevman/spec_forge/compare/v0.3.2...v0.4.0
132
347
  [0.3.2]: https://github.com/itsthedevman/spec_forge/compare/v0.3.0...v0.3.2
data/README.md CHANGED
@@ -4,30 +4,84 @@
4
4
  ![Ruby Version](https://img.shields.io/badge/ruby-3.3.7-ruby)
5
5
  [![Tests](https://github.com/itsthedevman/spec_forge/actions/workflows/main.yml/badge.svg)](https://github.com/itsthedevman/spec_forge/actions/workflows/main.yml)
6
6
 
7
- Write API tests in YAML that read like documentation:
7
+ > Note: The code in this repository represents the latest development version with new features and improvements that are being prepared for future releases. For the current stable version, check out [v0.6.0](https://github.com/itsthedevman/spec_forge/releases/tag/v0.6.0) on GitHub releases.
8
+
9
+ Write API tests in YAML that read like documentation and generate OpenAPI specifications:
8
10
 
9
11
  ```yaml
10
- user_profile:
11
- path: /users/1
12
+ show_user:
13
+ path: /users/{id}
14
+ variables:
15
+ expected_status: 200
16
+ user_id: 1
17
+ query:
18
+ id: variables.user_id
12
19
  expectations:
13
20
  - expect:
14
- status: 200
21
+ status: variables.expected_status
15
22
  json:
16
23
  name: kind_of.string
17
- email: /@/
24
+ email:
25
+ matcher.and:
26
+ - kind_of.string
27
+ - /@/
28
+ headers:
29
+ Content-Type: "application/json"
30
+ X-Request-ID: /^[0-9a-f-]{36}$/
18
31
  ```
19
32
 
20
- That's a complete test. No Ruby code, no configuration files, no HTTP client setup - just a clear description of what you're testing. Under the hood, you get all the power of RSpec's matchers, Faker's data generation, and FactoryBot's test objects.
33
+ That's a complete test that validates your API and creates OpenAPI documentation. No Ruby code, no configuration files, no HTTP client setup - just clear, executable specifications.
21
34
 
22
35
  ## Why SpecForge?
23
36
 
24
- SpecForge shines when you need:
37
+ **For Testing:**
38
+
39
+ - **Reduce Boilerplate**: Write tests without repetitive setup code and HTTP configuration
40
+ - **Quick Setup**: Start testing APIs in minutes instead of spending hours on test infrastructure
41
+ - **Clear Syntax**: Tests that everyone can read and understand, regardless of Ruby expertise
42
+
43
+ **For Documentation:**
44
+
45
+ - **OpenAPI Generation**: Generate OpenAPI specifications from your test structure, with full customization through configuration files
46
+ - **Living Documentation**: Your tests ensure the documentation always matches your actual API behavior
47
+ - **Professional Output**: View your API docs in Swagger UI or Redoc with minimal setup
48
+
49
+ **For Teams:**
50
+
51
+ - **Developer & QA Collaboration**: Create specifications that both developers and QA can maintain
52
+ - **Gradual Adoption**: Use alongside your existing test suite, introducing it incrementally where it makes sense
25
53
 
26
- 1. **Living Documentation**: Tests serve as clear, maintainable documentation of your API's expected behavior.
27
- 2. **Power Without Complexity**: Get the benefits of Ruby-based tests (dynamic data, factories, matchers) without writing Ruby code.
28
- 3. **Quick Setup**: Start testing APIs without configuring HTTP clients or writing boilerplate code.
29
- 4. **Gradual Adoption**: Use alongside your existing test suite. Keep complex tests in RSpec while making simple API tests more accessible.
30
- 5. **Accessible API Testing**: Non-developers can write and maintain tests without Ruby knowledge. The YAML syntax reads like documentation.
54
+ ## Key Features
55
+
56
+ - **Automatic Documentation Generation**: Transform tests into OpenAPI specifications with customizable configuration
57
+ - **Live Documentation Server**: Local development server for viewing generated documentation
58
+ - **YAML-Based Tests**: Write clear, declarative tests that read like documentation
59
+ - **RSpec Integration**: Leverage all the power of RSpec matchers and expectations
60
+ - **Header Testing**: Comprehensive HTTP header validation with compound matchers
61
+ - **FactoryBot Integration**: Generate test data with FactoryBot integration
62
+ - **Faker Integration**: Create realistic test data with Faker
63
+ - **Variable System**: Define and reference variables for dynamic test data
64
+ - **Context Storage**: Store API responses and reference them in subsequent tests
65
+ - **Compound Matchers**: Combine multiple validations with `matcher.and` for precise expectations
66
+ - **Global Variables**: Define shared configuration at the file level
67
+ - **Callback System**: Hook into the test lifecycle using Ruby for setup, teardown, and much more!
68
+
69
+ ## Quick Start
70
+
71
+ Get started with SpecForge in 3 commands:
72
+
73
+ ```bash
74
+ # 1. Initialize SpecForge
75
+ spec_forge init
76
+
77
+ # 2. Create your first test
78
+ spec_forge new spec users
79
+
80
+ # 3. View your documentation
81
+ spec_forge serve
82
+ ```
83
+
84
+ Then visit `http://localhost:8080` to see your API documentation!
31
85
 
32
86
  ## When Not to Use SpecForge
33
87
 
@@ -72,12 +126,103 @@ Create your first test:
72
126
  spec_forge new spec users
73
127
  ```
74
128
 
75
- Run your tests:
129
+ Generate documentation (default command):
130
+
131
+ ```bash
132
+ spec_forge
133
+ ```
134
+
135
+ Or start the live documentation server:
136
+
137
+ ```bash
138
+ spec_forge serve
139
+ ```
140
+
141
+ Run tests only (no documentation):
76
142
 
77
143
  ```bash
78
144
  spec_forge run
79
145
  ```
80
146
 
147
+ ## Documentation Workflow
148
+
149
+ SpecForge provides multiple ways to work with your API documentation:
150
+
151
+ ```bash
152
+ # Generate OpenAPI specifications
153
+ spec_forge docs # Smart caching
154
+ spec_forge docs --fresh # Force regeneration
155
+ spec_forge docs --format json # Output as JSON instead of YAML
156
+
157
+ # View documentation in browser
158
+ spec_forge serve # Generate if needed + serve
159
+ spec_forge serve --fresh # Force regeneration + serve
160
+ spec_forge serve --ui redoc # Use Redoc instead
161
+ spec_forge serve --port 3001 # Custom port
162
+
163
+ # Traditional testing
164
+ spec_forge run # Pure testing mode
165
+ spec_forge run users:show_user # Run specific tests
166
+ ```
167
+
168
+ ## Example: Complete User API
169
+
170
+ ```yaml
171
+ # spec_forge/specs/users.yml
172
+ global:
173
+ variables:
174
+ admin_role: "admin"
175
+
176
+ list_users:
177
+ path: /users
178
+ expectations:
179
+ - expect:
180
+ status: 200
181
+ headers:
182
+ Content-Type: "application/json"
183
+ json:
184
+ users:
185
+ matcher.have_size:
186
+ be.greater_than: 0
187
+
188
+ create_user:
189
+ path: /users
190
+ method: POST
191
+ variables:
192
+ username: faker.internet.username
193
+ email: faker.internet.email
194
+ body:
195
+ name: variables.username
196
+ email: variables.email
197
+ role: global.variables.admin_role
198
+ store_as: new_user
199
+ expectations:
200
+ - expect:
201
+ status: 201
202
+ headers:
203
+ Location: /\/users\/\d+/
204
+ json:
205
+ id: kind_of.integer
206
+ name: variables.username
207
+ email: variables.email
208
+ role: global.variables.admin_role
209
+
210
+ show_user:
211
+ path: /users/{id}
212
+ query:
213
+ id: store.new_user.body.id
214
+ expectations:
215
+ - expect:
216
+ status: 200
217
+ json:
218
+ id: store.new_user.body.id
219
+ name: store.new_user.body.name
220
+ email: store.new_user.body.email
221
+ role: global.variables.admin_role
222
+ ```
223
+
224
+ This automatically generates a complete OpenAPI specification with all endpoints, request/response schemas, and examples!
225
+
81
226
  ## Documentation
82
227
 
83
228
  For comprehensive documentation, visit the [SpecForge Wiki](https://github.com/itsthedevman/spec_forge/wiki) which includes:
@@ -85,25 +230,17 @@ For comprehensive documentation, visit the [SpecForge Wiki](https://github.com/i
85
230
  - [Getting Started Guide](https://github.com/itsthedevman/spec_forge/wiki/Getting-Started)
86
231
  - [Configuration Options](https://github.com/itsthedevman/spec_forge/wiki/Configuration)
87
232
  - [Writing Tests](https://github.com/itsthedevman/spec_forge/wiki/Writing-Tests)
233
+ - [Running Tests](https://github.com/itsthedevman/spec_forge/wiki/Running-Tests)
234
+ - [Debugging Guide](https://github.com/itsthedevman/spec_forge/wiki/Debugging)
88
235
  - [Dynamic Features](https://github.com/itsthedevman/spec_forge/wiki/Dynamic-Features)
89
236
  - [Factory Support](https://github.com/itsthedevman/spec_forge/wiki/Factory-Support)
90
237
  - [RSpec Matchers](https://github.com/itsthedevman/spec_forge/wiki/RSpec-Matchers)
91
238
 
92
239
  Also see the [API Documentation](https://itsthedevman.com/docs/spec_forge).
93
240
 
94
- ## Roadmap
95
-
96
- Current development priorities:
97
- - [ ] Negated matchers: `matcher.not`
98
- - [ ] `create_list/build_list` factory strategies
99
- - [ ] `transform.map` support
100
- - [ ] XML/HTML response handling
101
- - [ ] OpenAPI generation from tests
102
- - [x] Array support for `json` expectations
103
- - [x] Support for running individual specs
104
- - [x] Improved error handling
241
+ ## Future Development
105
242
 
106
- Have a feature request? Open an issue on GitHub!
243
+ For the latest development priorities and feature ideas, check out our [Github Project](https://github.com/itsthedevman/spec_forge/projects?query=is%3Aopen). Have a feature request? Open an issue on GitHub!
107
244
 
108
245
  ## Contributing
109
246
 
data/flake.lock CHANGED
@@ -20,11 +20,11 @@
20
20
  },
21
21
  "nixpkgs": {
22
22
  "locked": {
23
- "lastModified": 1737469691,
24
- "narHash": "sha256-nmKOgAU48S41dTPIXAq0AHZSehWUn6ZPrUKijHAMmIk=",
23
+ "lastModified": 1750365781,
24
+ "narHash": "sha256-XE/lFNhz5lsriMm/yjXkvSZz5DfvKJLUjsS6pP8EC50=",
25
25
  "owner": "NixOS",
26
26
  "repo": "nixpkgs",
27
- "rev": "9e4d5190a9482a1fb9d18adf0bdb83c6e506eaab",
27
+ "rev": "08f22084e6085d19bcfb4be30d1ca76ecb96fe54",
28
28
  "type": "github"
29
29
  },
30
30
  "original": {
data/flake.nix CHANGED
@@ -1,21 +1,27 @@
1
1
  {
2
- description = "Ruby 3.4.2 development environment";
2
+ description = "Ruby 3.2 development environment";
3
3
 
4
4
  inputs = {
5
5
  nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
6
6
  flake-utils.url = "github:numtide/flake-utils";
7
7
  };
8
8
 
9
- outputs = { self, nixpkgs, flake-utils }:
10
- flake-utils.lib.eachDefaultSystem (system:
9
+ outputs =
10
+ {
11
+ self,
12
+ nixpkgs,
13
+ flake-utils,
14
+ }:
15
+ flake-utils.lib.eachDefaultSystem (
16
+ system:
11
17
  let
12
18
  pkgs = nixpkgs.legacyPackages.${system};
13
19
  in
14
20
  {
15
21
  devShells.default = pkgs.mkShell {
16
22
  buildInputs = with pkgs; [
17
- (ruby_3_4.override {
18
- jemallocSupport = true;
23
+ (ruby_3_2.override {
24
+ jemallocSupport = false;
19
25
  docSupport = false;
20
26
  })
21
27