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.
- checksums.yaml +4 -4
- data/.standard.yml +3 -3
- data/CHANGELOG.md +217 -2
- data/README.md +162 -25
- data/flake.lock +3 -3
- data/flake.nix +11 -5
- data/lib/spec_forge/attribute/chainable.rb +208 -20
- data/lib/spec_forge/attribute/factory.rb +92 -15
- data/lib/spec_forge/attribute/faker.rb +62 -13
- data/lib/spec_forge/attribute/global.rb +96 -0
- data/lib/spec_forge/attribute/literal.rb +15 -2
- data/lib/spec_forge/attribute/matcher.rb +186 -11
- data/lib/spec_forge/attribute/parameterized.rb +45 -12
- data/lib/spec_forge/attribute/regex.rb +55 -5
- data/lib/spec_forge/attribute/resolvable.rb +48 -5
- data/lib/spec_forge/attribute/resolvable_array.rb +62 -4
- data/lib/spec_forge/attribute/resolvable_hash.rb +62 -4
- data/lib/spec_forge/attribute/store.rb +65 -0
- data/lib/spec_forge/attribute/transform.rb +33 -5
- data/lib/spec_forge/attribute/variable.rb +37 -6
- data/lib/spec_forge/attribute.rb +166 -66
- data/lib/spec_forge/backtrace_formatter.rb +26 -3
- data/lib/spec_forge/callbacks.rb +88 -0
- data/lib/spec_forge/cli/actions.rb +27 -0
- data/lib/spec_forge/cli/command.rb +78 -24
- data/lib/spec_forge/cli/docs/generate.rb +72 -0
- data/lib/spec_forge/cli/docs.rb +92 -0
- data/lib/spec_forge/cli/init.rb +51 -9
- data/lib/spec_forge/cli/new.rb +67 -6
- data/lib/spec_forge/cli/run.rb +32 -4
- data/lib/spec_forge/cli/serve.rb +155 -0
- data/lib/spec_forge/cli.rb +26 -7
- data/lib/spec_forge/configuration.rb +96 -24
- data/lib/spec_forge/context/callbacks.rb +91 -0
- data/lib/spec_forge/context/global.rb +72 -0
- data/lib/spec_forge/context/store.rb +131 -0
- data/lib/spec_forge/context/variables.rb +91 -0
- data/lib/spec_forge/context.rb +36 -0
- data/lib/spec_forge/core_ext/array.rb +27 -0
- data/lib/spec_forge/core_ext/rspec.rb +22 -4
- data/lib/spec_forge/documentation/builder.rb +383 -0
- data/lib/spec_forge/documentation/document/operation.rb +47 -0
- data/lib/spec_forge/documentation/document/parameter.rb +22 -0
- data/lib/spec_forge/documentation/document/request_body.rb +24 -0
- data/lib/spec_forge/documentation/document/response.rb +39 -0
- data/lib/spec_forge/documentation/document/response_body.rb +27 -0
- data/lib/spec_forge/documentation/document.rb +48 -0
- data/lib/spec_forge/documentation/generators/base.rb +81 -0
- data/lib/spec_forge/documentation/generators/openapi/base.rb +100 -0
- data/lib/spec_forge/documentation/generators/openapi/error_formatter.rb +149 -0
- data/lib/spec_forge/documentation/generators/openapi/v3_0.rb +65 -0
- data/lib/spec_forge/documentation/generators/openapi.rb +59 -0
- data/lib/spec_forge/documentation/generators.rb +17 -0
- data/lib/spec_forge/documentation/loader/cache.rb +138 -0
- data/lib/spec_forge/documentation/loader.rb +159 -0
- data/lib/spec_forge/documentation/openapi/base.rb +33 -0
- data/lib/spec_forge/documentation/openapi/v3_0/example.rb +44 -0
- data/lib/spec_forge/documentation/openapi/v3_0/media_type.rb +42 -0
- data/lib/spec_forge/documentation/openapi/v3_0/operation.rb +175 -0
- data/lib/spec_forge/documentation/openapi/v3_0/response.rb +65 -0
- data/lib/spec_forge/documentation/openapi/v3_0/schema.rb +80 -0
- data/lib/spec_forge/documentation/openapi/v3_0/tag.rb +71 -0
- data/lib/spec_forge/documentation/openapi.rb +23 -0
- data/lib/spec_forge/documentation.rb +27 -0
- data/lib/spec_forge/error.rb +284 -113
- data/lib/spec_forge/factory.rb +35 -16
- data/lib/spec_forge/filter.rb +86 -0
- data/lib/spec_forge/forge.rb +171 -0
- data/lib/spec_forge/http/backend.rb +101 -29
- data/lib/spec_forge/http/client.rb +23 -13
- data/lib/spec_forge/http/request.rb +85 -62
- data/lib/spec_forge/http/verb.rb +79 -0
- data/lib/spec_forge/http.rb +105 -0
- data/lib/spec_forge/loader.rb +244 -0
- data/lib/spec_forge/matchers.rb +130 -0
- data/lib/spec_forge/normalizer/default.rb +51 -0
- data/lib/spec_forge/normalizer/definition.rb +248 -0
- data/lib/spec_forge/normalizer/validators.rb +99 -0
- data/lib/spec_forge/normalizer.rb +486 -115
- data/lib/spec_forge/normalizers/_shared.yml +74 -0
- data/lib/spec_forge/normalizers/configuration.yml +23 -0
- data/lib/spec_forge/normalizers/constraint.yml +8 -0
- data/lib/spec_forge/normalizers/expectation.yml +47 -0
- data/lib/spec_forge/normalizers/factory.yml +12 -0
- data/lib/spec_forge/normalizers/factory_reference.yml +15 -0
- data/lib/spec_forge/normalizers/global_context.yml +28 -0
- data/lib/spec_forge/normalizers/spec.yml +50 -0
- data/lib/spec_forge/runner/adapter.rb +183 -0
- data/lib/spec_forge/runner/callbacks.rb +246 -0
- data/lib/spec_forge/runner/debug_proxy.rb +213 -0
- data/lib/spec_forge/runner/listener.rb +54 -0
- data/lib/spec_forge/runner/metadata.rb +58 -0
- data/lib/spec_forge/runner/state.rb +98 -0
- data/lib/spec_forge/runner.rb +50 -125
- data/lib/spec_forge/spec/expectation/constraint.rb +100 -21
- data/lib/spec_forge/spec/expectation.rb +47 -51
- data/lib/spec_forge/spec.rb +50 -108
- data/lib/spec_forge/type.rb +36 -4
- data/lib/spec_forge/version.rb +4 -1
- data/lib/spec_forge.rb +168 -76
- data/lib/templates/openapi.yml.tt +22 -0
- data/lib/templates/redoc.html.tt +28 -0
- data/lib/templates/swagger.html.tt +59 -0
- metadata +109 -16
- data/lib/spec_forge/normalizer/configuration.rb +0 -77
- data/lib/spec_forge/normalizer/constraint.rb +0 -47
- data/lib/spec_forge/normalizer/expectation.rb +0 -86
- data/lib/spec_forge/normalizer/factory.rb +0 -65
- data/lib/spec_forge/normalizer/factory_reference.rb +0 -71
- data/lib/spec_forge/normalizer/spec.rb +0 -74
- data/spec_forge/factories/user.yml +0 -4
- data/spec_forge/forge_helper.rb +0 -48
- data/spec_forge/specs/users.yml +0 -65
- /data/lib/templates/{forge_helper.tt → forge_helper.rb.tt} +0 -0
- /data/lib/templates/{new_factory.tt → new_factory.yml.tt} +0 -0
- /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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f8c38cb9ff50cb02ee74171a4d571ac411807b1dcce43edab0f28a757269b2f
|
4
|
+
data.tar.gz: 1595911a7a84d7712ddcc5bf0e2a08c0c30afce995ac02bb1372c1ae29ca7db0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 731ff8f0cc847010f38caab823c7d30c0d3d7083d4ea53de6ac46c19929c2c31ce698db787303c706ae6ee517dea396ef5ceb220732dd172050967404dd102af
|
7
|
+
data.tar.gz: 1a24dd8f84528427e30d105c4e358ca226b699e79a68a9ac2eb5385a974abb2acb27f8c8a3751e8c69a70001ef8d2ef3938ab06f9c81f1f041325b1b038923e1
|
data/.standard.yml
CHANGED
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
|
-
## [
|
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.
|
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
|

|
5
5
|
[](https://github.com/itsthedevman/spec_forge/actions/workflows/main.yml)
|
6
6
|
|
7
|
-
|
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
|
-
|
11
|
-
path: /users/
|
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:
|
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
|
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
|
-
|
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
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
-
|
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
|
-
##
|
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":
|
24
|
-
"narHash": "sha256-
|
23
|
+
"lastModified": 1750365781,
|
24
|
+
"narHash": "sha256-XE/lFNhz5lsriMm/yjXkvSZz5DfvKJLUjsS6pP8EC50=",
|
25
25
|
"owner": "NixOS",
|
26
26
|
"repo": "nixpkgs",
|
27
|
-
"rev": "
|
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.
|
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 =
|
10
|
-
|
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
|
-
(
|
18
|
-
jemallocSupport =
|
23
|
+
(ruby_3_2.override {
|
24
|
+
jemallocSupport = false;
|
19
25
|
docSupport = false;
|
20
26
|
})
|
21
27
|
|