camille 1.5.0 → 1.6.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/CHANGELOG.md +6 -0
- data/CLAUDE.md +3 -0
- data/Gemfile.lock +1 -1
- data/README.md +19 -0
- data/lib/camille/testing.rb +51 -0
- data/lib/camille/version.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a6293de3ef709101a5410b308f140bd654e38e81905eefff034eaff831da03d7
|
|
4
|
+
data.tar.gz: d8224fc21dd1c63e7f5a93a65ff6452d841da44c12ef7eccb2a9b713d34211cb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ca46b44d6ee87b156d066e1d9e3736fb74b9c0b1ed2df4634a62bbc879fc23aaa9fb42b4dd6857eda5a47a4968fe8c157b384044da1cda65fd20a45b4071bbc2
|
|
7
|
+
data.tar.gz: 1e52c60928f864586e7361ec0a63419d6763f3f8b6339395157750ffd78a2cd672179aa9028d83db26be79351e68625243c052c6001b1f07f3acac6dc4fbb728
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.6.0
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
* Added `response.data` test helper (require `'camille/testing'`). Validates the response body against the endpoint's response type and returns the snake_case body as a `HashWithIndifferentAccess`. Works with RSpec and Minitest integration / request tests.
|
|
8
|
+
|
|
3
9
|
## 1.5.0
|
|
4
10
|
|
|
5
11
|
### Fixed
|
data/CLAUDE.md
ADDED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -263,6 +263,25 @@ object:
|
|
|
263
263
|
|
|
264
264
|
Everything in `config/camille/types` and `config/camille/schemas` will automatically reload after changes in development environment, just like other files in Rails.
|
|
265
265
|
|
|
266
|
+
### Test helper
|
|
267
|
+
|
|
268
|
+
Camille ships an optional `response.data` helper for Rails integration / request tests. It looks up the endpoint from the current request, validates `response.parsed_body` against the endpoint's response type, and returns the snake_case body as a `HashWithIndifferentAccess` so you can use either string or symbol keys in assertions.
|
|
269
|
+
|
|
270
|
+
In your `rails_helper.rb` (RSpec) or `test_helper.rb` (Minitest):
|
|
271
|
+
|
|
272
|
+
```ruby
|
|
273
|
+
require 'camille/testing'
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Then in a test:
|
|
277
|
+
|
|
278
|
+
```ruby
|
|
279
|
+
get '/products/data'
|
|
280
|
+
expect(response.data[:product][:available_stock]).to eq(1)
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
If the response body fails the type check the helper raises `Camille::Testing::ResponseTypeError`. If the route has no Camille endpoint it raises `Camille::Testing::MissingEndpointError`.
|
|
284
|
+
|
|
266
285
|
## Versioning
|
|
267
286
|
|
|
268
287
|
This project uses [Semantic Versioning](https://semver.org/).
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'action_dispatch'
|
|
2
|
+
|
|
3
|
+
module Camille
|
|
4
|
+
module Testing
|
|
5
|
+
class ResponseTypeError < ::StandardError; end
|
|
6
|
+
class MissingEndpointError < ::StandardError; end
|
|
7
|
+
|
|
8
|
+
module ResponseExtension
|
|
9
|
+
def data
|
|
10
|
+
controller_path = request && request.path_parameters[:controller]
|
|
11
|
+
action = request && request.path_parameters[:action]
|
|
12
|
+
|
|
13
|
+
unless controller_path && action
|
|
14
|
+
raise Camille::Testing::MissingEndpointError,
|
|
15
|
+
"No camille endpoint for this response (request did not match a controller action)."
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
controller_class_name = "#{controller_path.camelize}Controller"
|
|
19
|
+
schema = Camille::Loader.controller_name_to_schema_map[controller_class_name]
|
|
20
|
+
endpoint = schema && schema.endpoints[action.to_sym]
|
|
21
|
+
|
|
22
|
+
unless endpoint
|
|
23
|
+
raise Camille::Testing::MissingEndpointError,
|
|
24
|
+
"No camille endpoint for #{controller_class_name}##{action}."
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
result = endpoint.response_type.check_params(parsed_body)
|
|
28
|
+
if result.type_error?
|
|
29
|
+
io = StringIO.new
|
|
30
|
+
Camille::TypeErrorPrinter.new(result).print(io)
|
|
31
|
+
raise Camille::Testing::ResponseTypeError,
|
|
32
|
+
"\nResponse type check failed.\n#{io.string}"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
deep_indifferent(result.value)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def deep_indifferent value
|
|
41
|
+
case value
|
|
42
|
+
when Hash then value.with_indifferent_access
|
|
43
|
+
when Array then value.map { |v| deep_indifferent(v) }
|
|
44
|
+
else value
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
ActionDispatch::TestResponse.prepend(Camille::Testing::ResponseExtension)
|
data/lib/camille/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: camille
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- merely
|
|
@@ -38,6 +38,7 @@ extra_rdoc_files: []
|
|
|
38
38
|
files:
|
|
39
39
|
- ".rspec"
|
|
40
40
|
- CHANGELOG.md
|
|
41
|
+
- CLAUDE.md
|
|
41
42
|
- Gemfile
|
|
42
43
|
- Gemfile.lock
|
|
43
44
|
- README.md
|
|
@@ -79,6 +80,7 @@ files:
|
|
|
79
80
|
- lib/camille/schema_literal_generator.rb
|
|
80
81
|
- lib/camille/schemas.rb
|
|
81
82
|
- lib/camille/syntax.rb
|
|
83
|
+
- lib/camille/testing.rb
|
|
82
84
|
- lib/camille/type.rb
|
|
83
85
|
- lib/camille/type_error.rb
|
|
84
86
|
- lib/camille/type_error_printer.rb
|