camille 1.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5f58ec63581094cce8faf1d3f9dd3e1909ebe3fb188e8c7ed59c09a74645793b
4
- data.tar.gz: badb42b9b2bb52426060ba9c62544ac6660334784b458360e82594d09ea785d5
3
+ metadata.gz: a6293de3ef709101a5410b308f140bd654e38e81905eefff034eaff831da03d7
4
+ data.tar.gz: d8224fc21dd1c63e7f5a93a65ff6452d841da44c12ef7eccb2a9b713d34211cb
5
5
  SHA512:
6
- metadata.gz: fd2e3eb6d0f629cf9eaacb6c8c8f09c92bd9b77a9815a7025717913d2542a6f38451a6f1c16b3cfdecc5c09c22f2949ab6b9cb77b9f349cec88bd22cef7ee375
7
- data.tar.gz: 99177b3fe5a775615b8bf01cb88e23a3e6100409fee7a1a0af486ad918adf6de4c0c52d8e9b7c660f08110825ecd1609a713f9a7dc739cdb4a6ae67a13753af3
6
+ metadata.gz: ca46b44d6ee87b156d066e1d9e3736fb74b9c0b1ed2df4634a62bbc879fc23aaa9fb42b4dd6857eda5a47a4968fe8c157b384044da1cda65fd20a45b4071bbc2
7
+ data.tar.gz: 1e52c60928f864586e7361ec0a63419d6763f3f8b6339395157750ffd78a2cd672179aa9028d83db26be79351e68625243c052c6001b1f07f3acac6dc4fbb728
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
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
+
9
+ ## 1.5.0
10
+
11
+ ### Fixed
12
+
13
+ * Allow Camille::Controller::ParamsTypeError to be rescued by `rescue_from` in controllers.
14
+
3
15
  ## 1.4.0
4
16
 
5
17
  ### Added
data/CLAUDE.md ADDED
@@ -0,0 +1,3 @@
1
+ # Testing
2
+
3
+ Run the test suite with `bundle exec rake` (not `bundle exec rspec` directly).
data/Gemfile.lock CHANGED
@@ -1,72 +1,71 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- camille (1.3.0)
4
+ camille (1.6.0)
5
5
  rails (>= 6.1, < 8.1)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- actioncable (7.2.2.1)
11
- actionpack (= 7.2.2.1)
12
- activesupport (= 7.2.2.1)
10
+ actioncable (8.0.4)
11
+ actionpack (= 8.0.4)
12
+ activesupport (= 8.0.4)
13
13
  nio4r (~> 2.0)
14
14
  websocket-driver (>= 0.6.1)
15
15
  zeitwerk (~> 2.6)
16
- actionmailbox (7.2.2.1)
17
- actionpack (= 7.2.2.1)
18
- activejob (= 7.2.2.1)
19
- activerecord (= 7.2.2.1)
20
- activestorage (= 7.2.2.1)
21
- activesupport (= 7.2.2.1)
16
+ actionmailbox (8.0.4)
17
+ actionpack (= 8.0.4)
18
+ activejob (= 8.0.4)
19
+ activerecord (= 8.0.4)
20
+ activestorage (= 8.0.4)
21
+ activesupport (= 8.0.4)
22
22
  mail (>= 2.8.0)
23
- actionmailer (7.2.2.1)
24
- actionpack (= 7.2.2.1)
25
- actionview (= 7.2.2.1)
26
- activejob (= 7.2.2.1)
27
- activesupport (= 7.2.2.1)
23
+ actionmailer (8.0.4)
24
+ actionpack (= 8.0.4)
25
+ actionview (= 8.0.4)
26
+ activejob (= 8.0.4)
27
+ activesupport (= 8.0.4)
28
28
  mail (>= 2.8.0)
29
29
  rails-dom-testing (~> 2.2)
30
- actionpack (7.2.2.1)
31
- actionview (= 7.2.2.1)
32
- activesupport (= 7.2.2.1)
30
+ actionpack (8.0.4)
31
+ actionview (= 8.0.4)
32
+ activesupport (= 8.0.4)
33
33
  nokogiri (>= 1.8.5)
34
- racc
35
- rack (>= 2.2.4, < 3.2)
34
+ rack (>= 2.2.4)
36
35
  rack-session (>= 1.0.1)
37
36
  rack-test (>= 0.6.3)
38
37
  rails-dom-testing (~> 2.2)
39
38
  rails-html-sanitizer (~> 1.6)
40
39
  useragent (~> 0.16)
41
- actiontext (7.2.2.1)
42
- actionpack (= 7.2.2.1)
43
- activerecord (= 7.2.2.1)
44
- activestorage (= 7.2.2.1)
45
- activesupport (= 7.2.2.1)
40
+ actiontext (8.0.4)
41
+ actionpack (= 8.0.4)
42
+ activerecord (= 8.0.4)
43
+ activestorage (= 8.0.4)
44
+ activesupport (= 8.0.4)
46
45
  globalid (>= 0.6.0)
47
46
  nokogiri (>= 1.8.5)
48
- actionview (7.2.2.1)
49
- activesupport (= 7.2.2.1)
47
+ actionview (8.0.4)
48
+ activesupport (= 8.0.4)
50
49
  builder (~> 3.1)
51
50
  erubi (~> 1.11)
52
51
  rails-dom-testing (~> 2.2)
53
52
  rails-html-sanitizer (~> 1.6)
54
- activejob (7.2.2.1)
55
- activesupport (= 7.2.2.1)
53
+ activejob (8.0.4)
54
+ activesupport (= 8.0.4)
56
55
  globalid (>= 0.3.6)
57
- activemodel (7.2.2.1)
58
- activesupport (= 7.2.2.1)
59
- activerecord (7.2.2.1)
60
- activemodel (= 7.2.2.1)
61
- activesupport (= 7.2.2.1)
56
+ activemodel (8.0.4)
57
+ activesupport (= 8.0.4)
58
+ activerecord (8.0.4)
59
+ activemodel (= 8.0.4)
60
+ activesupport (= 8.0.4)
62
61
  timeout (>= 0.4.0)
63
- activestorage (7.2.2.1)
64
- actionpack (= 7.2.2.1)
65
- activejob (= 7.2.2.1)
66
- activerecord (= 7.2.2.1)
67
- activesupport (= 7.2.2.1)
62
+ activestorage (8.0.4)
63
+ actionpack (= 8.0.4)
64
+ activejob (= 8.0.4)
65
+ activerecord (= 8.0.4)
66
+ activesupport (= 8.0.4)
68
67
  marcel (~> 1.0)
69
- activesupport (7.2.2.1)
68
+ activesupport (8.0.4)
70
69
  base64
71
70
  benchmark (>= 0.3)
72
71
  bigdecimal
@@ -78,39 +77,43 @@ GEM
78
77
  minitest (>= 5.1)
79
78
  securerandom (>= 0.3)
80
79
  tzinfo (~> 2.0, >= 2.0.5)
81
- base64 (0.2.0)
82
- benchmark (0.4.0)
83
- bigdecimal (3.1.8)
80
+ uri (>= 0.13.1)
81
+ base64 (0.3.0)
82
+ benchmark (0.5.0)
83
+ bigdecimal (4.0.1)
84
84
  builder (3.3.0)
85
- concurrent-ruby (1.3.4)
86
- connection_pool (2.4.1)
85
+ concurrent-ruby (1.3.6)
86
+ connection_pool (3.0.2)
87
87
  crass (1.0.6)
88
- date (3.4.1)
88
+ date (3.5.1)
89
89
  diff-lcs (1.5.1)
90
- drb (2.2.1)
91
- erubi (1.13.0)
92
- globalid (1.2.1)
90
+ drb (2.2.3)
91
+ erb (6.0.1)
92
+ erubi (1.13.1)
93
+ globalid (1.3.0)
93
94
  activesupport (>= 6.1)
94
- i18n (1.14.6)
95
+ i18n (1.14.8)
95
96
  concurrent-ruby (~> 1.0)
96
- io-console (0.8.0)
97
- irb (1.14.2)
97
+ io-console (0.8.2)
98
+ irb (1.16.0)
99
+ pp (>= 0.6.0)
98
100
  rdoc (>= 4.0.0)
99
101
  reline (>= 0.4.2)
100
- logger (1.6.3)
101
- loofah (2.23.1)
102
+ logger (1.7.0)
103
+ loofah (2.25.0)
102
104
  crass (~> 1.0.2)
103
105
  nokogiri (>= 1.12.0)
104
- mail (2.8.1)
106
+ mail (2.9.0)
107
+ logger
105
108
  mini_mime (>= 0.1.1)
106
109
  net-imap
107
110
  net-pop
108
111
  net-smtp
109
- marcel (1.0.4)
112
+ marcel (1.1.0)
110
113
  mini_mime (1.1.5)
111
- mini_portile2 (2.8.9)
112
- minitest (5.25.4)
113
- net-imap (0.5.6)
114
+ minitest (6.0.1)
115
+ prism (~> 1.5)
116
+ net-imap (0.6.2)
114
117
  date
115
118
  net-protocol
116
119
  net-pop (0.1.2)
@@ -119,56 +122,61 @@ GEM
119
122
  timeout
120
123
  net-smtp (0.5.1)
121
124
  net-protocol
122
- nio4r (2.7.4)
123
- nokogiri (1.17.2)
124
- mini_portile2 (~> 2.8.2)
125
+ nio4r (2.7.5)
126
+ nokogiri (1.19.0-x86_64-linux-gnu)
125
127
  racc (~> 1.4)
126
- nokogiri (1.17.2-x86_64-linux)
127
- racc (~> 1.4)
128
- psych (5.2.1)
128
+ pp (0.6.3)
129
+ prettyprint
130
+ prettyprint (0.2.0)
131
+ prism (1.9.0)
132
+ psych (5.3.1)
129
133
  date
130
134
  stringio
131
135
  racc (1.8.1)
132
- rack (3.1.8)
133
- rack-session (2.0.0)
136
+ rack (3.2.4)
137
+ rack-session (2.1.1)
138
+ base64 (>= 0.1.0)
134
139
  rack (>= 3.0.0)
135
- rack-test (2.1.0)
140
+ rack-test (2.2.0)
136
141
  rack (>= 1.3)
137
- rackup (2.2.1)
142
+ rackup (2.3.1)
138
143
  rack (>= 3)
139
- rails (7.2.2.1)
140
- actioncable (= 7.2.2.1)
141
- actionmailbox (= 7.2.2.1)
142
- actionmailer (= 7.2.2.1)
143
- actionpack (= 7.2.2.1)
144
- actiontext (= 7.2.2.1)
145
- actionview (= 7.2.2.1)
146
- activejob (= 7.2.2.1)
147
- activemodel (= 7.2.2.1)
148
- activerecord (= 7.2.2.1)
149
- activestorage (= 7.2.2.1)
150
- activesupport (= 7.2.2.1)
144
+ rails (8.0.4)
145
+ actioncable (= 8.0.4)
146
+ actionmailbox (= 8.0.4)
147
+ actionmailer (= 8.0.4)
148
+ actionpack (= 8.0.4)
149
+ actiontext (= 8.0.4)
150
+ actionview (= 8.0.4)
151
+ activejob (= 8.0.4)
152
+ activemodel (= 8.0.4)
153
+ activerecord (= 8.0.4)
154
+ activestorage (= 8.0.4)
155
+ activesupport (= 8.0.4)
151
156
  bundler (>= 1.15.0)
152
- railties (= 7.2.2.1)
153
- rails-dom-testing (2.2.0)
157
+ railties (= 8.0.4)
158
+ rails-dom-testing (2.3.0)
154
159
  activesupport (>= 5.0.0)
155
160
  minitest
156
161
  nokogiri (>= 1.6)
157
162
  rails-html-sanitizer (1.6.2)
158
163
  loofah (~> 2.21)
159
164
  nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
160
- railties (7.2.2.1)
161
- actionpack (= 7.2.2.1)
162
- activesupport (= 7.2.2.1)
165
+ railties (8.0.4)
166
+ actionpack (= 8.0.4)
167
+ activesupport (= 8.0.4)
163
168
  irb (~> 1.13)
164
169
  rackup (>= 1.0.0)
165
170
  rake (>= 12.2)
166
171
  thor (~> 1.0, >= 1.2.2)
172
+ tsort (>= 0.2)
167
173
  zeitwerk (~> 2.6)
168
- rake (13.2.1)
169
- rdoc (6.9.0)
174
+ rake (13.3.1)
175
+ rdoc (7.1.0)
176
+ erb
170
177
  psych (>= 4.0.0)
171
- reline (0.5.12)
178
+ tsort
179
+ reline (0.6.3)
172
180
  io-console (~> 0.5)
173
181
  rspec (3.13.0)
174
182
  rspec-core (~> 3.13.0)
@@ -191,18 +199,20 @@ GEM
191
199
  rspec-mocks (~> 3.13)
192
200
  rspec-support (~> 3.13)
193
201
  rspec-support (3.13.2)
194
- securerandom (0.4.0)
195
- stringio (3.1.2)
196
- thor (1.3.2)
197
- timeout (0.4.3)
202
+ securerandom (0.4.1)
203
+ stringio (3.2.0)
204
+ thor (1.5.0)
205
+ timeout (0.6.0)
206
+ tsort (0.2.0)
198
207
  tzinfo (2.0.6)
199
208
  concurrent-ruby (~> 1.0)
209
+ uri (1.1.1)
200
210
  useragent (0.16.11)
201
- websocket-driver (0.7.7)
211
+ websocket-driver (0.8.0)
202
212
  base64
203
213
  websocket-extensions (>= 0.1.0)
204
214
  websocket-extensions (0.1.5)
205
- zeitwerk (2.7.1)
215
+ zeitwerk (2.7.4)
206
216
 
207
217
  PLATFORMS
208
218
  x86_64-linux
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/).
@@ -71,6 +71,8 @@ module Camille
71
71
  raise_missing_render_error
72
72
  end
73
73
  result
74
+ rescue ParamsTypeError => e
75
+ rescue_with_handler(e) || raise
74
76
  rescue ActionController::MissingExactTemplate
75
77
  raise_missing_render_error
76
78
  end
@@ -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)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Camille
4
- VERSION = "1.4.0"
4
+ VERSION = "1.6.0"
5
5
  end
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.0
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
@@ -122,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
122
124
  - !ruby/object:Gem::Version
123
125
  version: '0'
124
126
  requirements: []
125
- rubygems_version: 3.6.9
127
+ rubygems_version: 4.0.3
126
128
  specification_version: 4
127
129
  summary: Typed API schema for Rails with TypeScript codegen
128
130
  test_files: []