kinetic_cafe_error 1.1 → 1.2

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.
data/test/test_helper.rb CHANGED
@@ -2,8 +2,9 @@
2
2
 
3
3
  gem 'minitest'
4
4
  require 'minitest/autorun'
5
- require 'minitest/stub_const'
5
+ require 'minitest/focus'
6
6
  require 'minitest/moar'
7
+ require 'minitest/stub_const'
7
8
  require 'rack/test'
8
9
  require 'kinetic_cafe_error'
9
10
 
@@ -66,16 +66,35 @@ describe KineticCafe::Error do
66
66
  end
67
67
 
68
68
  it 'encodes the :query parameter specially for I18n parameters' do
69
- exception = KineticCafe::Error.new(query: { a: 1, b: %w(x y z )})
69
+ query = {
70
+ a: 1,
71
+ b: %w(x y z),
72
+ c: [ d: 1, e: 2 ],
73
+ f: []
74
+ }
75
+
76
+ exception = KineticCafe::Error.new(query: query)
70
77
  Object.stub_remove_const(:I18n) do
71
78
  assert_equal(
72
79
  [
73
80
  'kcerrors.error',
74
- { query: "a: 1; b[]: x, b[]: y, b[]: z" }
81
+ { query: "a: 1; b[]: x, b[]: y, b[]: z; c[][d]: 1; c[][e]: 2; f[]: []" }
75
82
  ],
76
83
  exception.i18n_message
77
84
  )
78
85
  end
79
86
  end
87
+
88
+ it 'is not #header? by default' do
89
+ refute exception.header?
90
+ end
91
+
92
+ it 'is not #internal? by default' do
93
+ refute exception.internal?
94
+ end
95
+
96
+ it 'has no I18n parameters by default' do
97
+ assert_empty KineticCafe::Error.i18n_params
98
+ end
80
99
  end
81
100
  end
@@ -197,8 +197,15 @@ describe KineticCafe::ErrorDSL do
197
197
  end
198
198
  end
199
199
 
200
- it 'defines #header_only? if requested' do
201
- child = base.define_error key: :foo, header_only: true
200
+ it 'defines #header? if requested' do
201
+ child = base.define_error key: :foo, header: true
202
+ assert child.new.header?
203
+ assert child.new.header_only?
204
+ end
205
+
206
+ it 'still recognizes #header_only? requests' do
207
+ child = base.define_error key: :bar, header_only: true
208
+ assert child.new.header?
202
209
  assert child.new.header_only?
203
210
  end
204
211
 
@@ -213,6 +220,80 @@ describe KineticCafe::ErrorDSL do
213
220
  assert base.const_defined?(:BarMissing)
214
221
  assert base::BarMissing < base
215
222
  end
223
+
224
+ it 'has no I18n parameters by default' do
225
+ child = base.define_error key: :foo
226
+ assert_equal [], child.i18n_params
227
+ end
228
+ end
229
+ end
230
+
231
+ describe 'when Rack::Utils is defined' do
232
+ it 'defines .not_found by default' do
233
+ base = Class.new(StandardError) do
234
+ extend KineticCafe::ErrorDSL
235
+ end
236
+ assert base.respond_to?(:not_found)
237
+
238
+ child = base.not_found class: :child
239
+ assert_equal :not_found, child.new.send(:default_status)
240
+ end
241
+
242
+ it 'defines NotFound by default' do
243
+ base = Class.new(StandardError) do
244
+ extend KineticCafe::ErrorDSL
245
+ end
246
+ assert base.const_defined?(:NotFound)
247
+ end
248
+
249
+ it 'respects the method __rack_status if defined' do
250
+ base = Class.new(StandardError) do
251
+ def self.__rack_status
252
+ { methods: true, errors: false }
253
+ end
254
+
255
+ extend KineticCafe::ErrorDSL
256
+ end
257
+
258
+ assert base.respond_to?(:not_found)
259
+ refute base.const_defined?(:NotFound)
260
+ end
261
+ end
262
+
263
+ describe 'when Rack::Utils is not defined' do
264
+ it 'does not define .not_found' do
265
+ Rack.stub_remove_const(:Utils) do
266
+ base = Class.new(StandardError) do
267
+ extend KineticCafe::ErrorDSL
268
+ end
269
+
270
+ refute base.respond_to?(:not_found)
271
+ end
272
+ end
273
+
274
+ it 'does not define NotFound' do
275
+ Rack.stub_remove_const(:Utils) do
276
+ base = Class.new(StandardError) do
277
+ extend KineticCafe::ErrorDSL
278
+ end
279
+
280
+ refute base.const_defined?(:NotFound)
281
+ end
282
+ end
283
+
284
+ it 'ignores __rack_status if defined' do
285
+ Rack.stub_remove_const(:Utils) do
286
+ base = Class.new(StandardError) do
287
+ def self.__rack_status
288
+ { methods: true, errors: false }
289
+ end
290
+
291
+ extend KineticCafe::ErrorDSL
292
+ end
293
+
294
+ refute base.respond_to?(:not_found)
295
+ refute base.const_defined?(:NotFound)
296
+ end
216
297
  end
217
298
  end
218
299
  end
@@ -0,0 +1,147 @@
1
+ require 'test_helper'
2
+ require 'rack/test'
3
+
4
+ describe KineticCafe::Error, '.hierarchy' do
5
+ describe '(class: :My)' do
6
+ def my(&block)
7
+ KineticCafe::Error.hierarchy(class: :My, &block)
8
+ end
9
+
10
+ it 'creates a new object' do
11
+ my
12
+ assert Object.const_defined?(:My)
13
+ end
14
+
15
+ it 'descends from KineticCafe::Error' do
16
+ my
17
+ assert My < KineticCafe::Error
18
+ end
19
+
20
+ it 'has been extended with KineticCafe::ErrorDSL' do
21
+ my
22
+ assert My.singleton_class < KineticCafe::ErrorDSL
23
+ end
24
+
25
+ it 'yields self if a block with an argument is given' do
26
+ my do |err|
27
+ assert_same My, err
28
+ end
29
+ end
30
+
31
+ it 'runs instance_exec against self if a no-argument block is given' do
32
+ assert my { My == self }
33
+ end
34
+
35
+ it 'cannot be extended a second time' do
36
+ my
37
+ ex = assert_raises do
38
+ KineticCafe::Error.hierarchy(class: :My)
39
+ end
40
+ assert_match(/is already a root hierarchy/, ex.message)
41
+ end
42
+
43
+ after do
44
+ Object.send(:remove_const, :My) if Object.const_defined?(:My)
45
+ end
46
+ end
47
+
48
+ describe '(class: :My, namespace: Foo)' do
49
+ before do
50
+ Foo = Module.new
51
+ KineticCafe::Error.hierarchy(class: :My, namespace: Foo)
52
+ end
53
+
54
+ it 'creates a new object' do
55
+ assert Foo.const_defined?(:My)
56
+ end
57
+
58
+ it 'descends from KineticCafe::Error' do
59
+ assert Foo::My < KineticCafe::Error
60
+ end
61
+
62
+ it 'has been extended with KineticCafe::ErrorDSL' do
63
+ assert Foo::My.singleton_class < KineticCafe::ErrorDSL
64
+ end
65
+
66
+ it 'cannot be extended a second time' do
67
+ ex = assert_raises do
68
+ KineticCafe::Error.hierarchy(class: :My, namespace: Foo)
69
+ end
70
+ assert_match(/is already a root hierarchy/, ex.message)
71
+ end
72
+
73
+ after do
74
+ Foo.send(:remove_const, :My) if Foo.const_defined?(:My)
75
+ Object.send(:remove_const, :Foo) if Object.const_defined?(:Foo)
76
+ end
77
+ end
78
+
79
+ describe '(class: My)' do
80
+ describe 'when My is a StandardError' do
81
+ before do
82
+ My = Class.new(StandardError)
83
+ KineticCafe::Error.hierarchy(class: My)
84
+ end
85
+
86
+ it 'has been extended with KineticCafe::ErrorDSL' do
87
+ assert My.singleton_class < KineticCafe::ErrorDSL
88
+ end
89
+
90
+ it 'has KineticCafe::ErrorModule included' do
91
+ assert My < KineticCafe::ErrorModule
92
+ end
93
+
94
+ it 'cannot be extended a second time' do
95
+ ex = assert_raises do
96
+ KineticCafe::Error.hierarchy(class: :My)
97
+ end
98
+ assert_match(/is already a root hierarchy/, ex.message)
99
+ end
100
+
101
+ after do
102
+ Object.send(:remove_const, :My) if Object.const_defined?(:My)
103
+ end
104
+ end
105
+
106
+ it 'fails if My is not an Exception' do
107
+ ex = assert_raises do
108
+ KineticCafe::Error.hierarchy(class: Class.new)
109
+ end
110
+ assert_match(/cannot root.*StandardError/, ex.message)
111
+ end
112
+
113
+ it 'fails if My is not a StandardError' do
114
+ assert_raises do
115
+ KineticCafe::Error.hierarchy(class: Class.new(Exception))
116
+ end
117
+ end
118
+ end
119
+
120
+ describe '(class: :My, rack_status: option)' do
121
+ def my(option, &block)
122
+ KineticCafe::Error.hierarchy(class: :My, rack_status: option, &block)
123
+ end
124
+
125
+ it 'disables method and object creation when rack_status: false' do
126
+ my(false)
127
+ refute My.const_defined?(:NotFound)
128
+ refute My.respond_to?(:not_found)
129
+ end
130
+
131
+ it 'disables method creation when rack_status: { methods: false }' do
132
+ my(methods: false)
133
+ assert My.const_defined?(:NotFound)
134
+ refute My.respond_to?(:not_found)
135
+ end
136
+
137
+ it 'disables object creation when rack_status: { errors: false }' do
138
+ my(errors: false)
139
+ refute My.const_defined?(:NotFound)
140
+ assert My.respond_to?(:not_found)
141
+ end
142
+
143
+ after do
144
+ Object.send(:remove_const, :My) if Object.const_defined?(:My)
145
+ end
146
+ end
147
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kinetic_cafe_error
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.1'
4
+ version: '1.2'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Austin Ziegler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-05 00:00:00.000000000 Z
11
+ date: 2015-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -238,7 +238,12 @@ description: |-
238
238
  kinetic_cafe_error provides an API-smart error base class and a DSL for
239
239
  defining errors. Under Rails, it also provides a controller concern
240
240
  (KineticCafe::ErrorHandler) that has a useful implementation of +rescue_from+
241
- for KineticCafe::Error types.
241
+ to handle KineticCafe::Error types.
242
+
243
+ Exceptions in a hierarchy can be handled in a uniform manner, including getting
244
+ an I18n translation message with parameters, standard status values, and
245
+ meaningful JSON representations that can be used to establish a standard error
246
+ representations across both clients and servers.
242
247
  email:
243
248
  - aziegler@kineticcafe.com
244
249
  executables: []
@@ -278,11 +283,14 @@ files:
278
283
  - lib/kinetic_cafe/error/minitest.rb
279
284
  - lib/kinetic_cafe/error_dsl.rb
280
285
  - lib/kinetic_cafe/error_engine.rb
286
+ - lib/kinetic_cafe/error_module.rb
281
287
  - lib/kinetic_cafe/error_rspec.rb
288
+ - lib/kinetic_cafe/error_tasks.rake
282
289
  - lib/kinetic_cafe_error.rb
283
290
  - test/test_helper.rb
284
291
  - test/test_kinetic_cafe_error.rb
285
292
  - test/test_kinetic_cafe_error_dsl.rb
293
+ - test/test_kinetic_cafe_error_hierarchy.rb
286
294
  homepage: https://github.com/KineticCafe/kinetic_cafe_error/
287
295
  licenses:
288
296
  - MIT