coaster 1.0.5 → 1.2.1
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/lib/coaster.rb +11 -1
- data/lib/coaster/core_ext/object_translation.rb +7 -12
- data/lib/coaster/core_ext/standard_error.rb +59 -25
- data/lib/coaster/core_ext/standard_error/raven.rb +13 -0
- data/lib/coaster/version.rb +1 -1
- data/test/locales/en.yml +3 -0
- data/test/test_helper.rb +9 -0
- data/test/test_object_translation.rb +2 -0
- data/test/test_standard_error.rb +104 -24
- metadata +38 -38
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c85271d1d65e61c492464d2e3bc610bad2fa784ba3da758e246c599ba655262c
|
4
|
+
data.tar.gz: b2715ff440d638cdd164338a1c55b4c689cdad95e54a65b66c29d8ad5e7d7d75
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f74c50dce4b7d64a44ec89a67814d2ce2ee1b9c8b89b75aae0fe4dbe05182ac444ac7903f1a5585d227cdb890f566727506722c9878ed12bcd1a583aea42080f
|
7
|
+
data.tar.gz: 19fd1dad72c06d49b5f3a380519a5f1ec7677c201d0485e6eceea866739513989decadafd396733dcffb66392b9ef8dd609feb2a510d307c9ab6e60e36a6faa8
|
data/lib/coaster.rb
CHANGED
@@ -5,7 +5,7 @@ require 'active_support/core_ext/string'
|
|
5
5
|
require 'active_support/core_ext/hash/slice'
|
6
6
|
|
7
7
|
module Coaster
|
8
|
-
|
8
|
+
mattr_writer :logger
|
9
9
|
mattr_writer :default_fingerprint
|
10
10
|
|
11
11
|
DEFAULT_FINGERPRINT = [:default, :class].freeze
|
@@ -18,6 +18,16 @@ module Coaster
|
|
18
18
|
def default_fingerprint
|
19
19
|
@@default_fingerprint ||= DEFAULT_FINGERPRINT
|
20
20
|
end
|
21
|
+
|
22
|
+
def logger
|
23
|
+
return @@logger if defined?(@@logger) && @@logger
|
24
|
+
return Rails.logger if defined?(Rails)
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def logger
|
30
|
+
self.class.logger
|
21
31
|
end
|
22
32
|
end
|
23
33
|
|
@@ -4,7 +4,7 @@ class Object
|
|
4
4
|
class << self
|
5
5
|
def _translate(*args)
|
6
6
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
7
|
-
options.merge
|
7
|
+
options = _translate_params.merge(options)
|
8
8
|
options = options.to_hash.symbolize_keys!
|
9
9
|
|
10
10
|
key = args.shift
|
@@ -45,7 +45,10 @@ class Object
|
|
45
45
|
|
46
46
|
if key_class.superclass == Object || key_class == Object
|
47
47
|
return options[:description] if options[:description].present?
|
48
|
-
Coaster.logger
|
48
|
+
if Coaster.logger
|
49
|
+
Coaster.logger.info(options[:original_missing])
|
50
|
+
Coaster.logger.debug(caller.join("\n"))
|
51
|
+
end
|
49
52
|
throw :exception, result if options[:original_throw]
|
50
53
|
missing = options[:original_missing] || result
|
51
54
|
msg = missing.message
|
@@ -61,6 +64,7 @@ class Object
|
|
61
64
|
result = result.dup if result.frozen?
|
62
65
|
result.instance_variable_set(:@translated, true)
|
63
66
|
result.instance_variable_set(:@tkey, options[:tkey])
|
67
|
+
result.instance_variable_set(:@missing, options[:original_missing])
|
64
68
|
result
|
65
69
|
end
|
66
70
|
end
|
@@ -78,16 +82,7 @@ class Object
|
|
78
82
|
def _translate(*args)
|
79
83
|
options = (args.last.is_a?(Hash) ? args.pop : {}).with_indifferent_access
|
80
84
|
key = args.shift || (respond_to?(:tkey) ? tkey : nil)
|
81
|
-
|
82
|
-
if respond_to?(:description) && description.present? && description != 'false' && description != self.class.name
|
83
|
-
if !key.is_a?(String) && key != :force
|
84
|
-
desc = description
|
85
|
-
return desc unless desc.instance_variable_get(:@raw)
|
86
|
-
end
|
87
|
-
options.merge!(description: description)
|
88
|
-
end
|
89
|
-
|
90
|
-
options.merge!(_translate_params)
|
85
|
+
options = _translate_params.merge(options)
|
91
86
|
self.class._translate(key, *args, options)
|
92
87
|
end
|
93
88
|
|
@@ -9,10 +9,24 @@ class StandardError
|
|
9
9
|
def http_status; 500 end
|
10
10
|
def report?; true end
|
11
11
|
def intentional?; false end
|
12
|
+
def title; _translate('.title') end
|
12
13
|
|
13
|
-
def
|
14
|
-
|
15
|
-
|
14
|
+
def before_logging(name, &block)
|
15
|
+
@before_logging_blocks ||= {}
|
16
|
+
@before_logging_blocks[name] = block
|
17
|
+
end
|
18
|
+
def before_logging_blocks
|
19
|
+
@before_logging_blocks ||= {}
|
20
|
+
superclass <= StandardError ? superclass.before_logging_blocks.merge(@before_logging_blocks) : @before_logging_blocks
|
21
|
+
end
|
22
|
+
|
23
|
+
def after_logging(name, &block)
|
24
|
+
@after_logging_blocks ||= {}
|
25
|
+
@after_logging_blocks[name] = block
|
26
|
+
end
|
27
|
+
def after_logging_blocks
|
28
|
+
@after_logging_blocks ||= {}
|
29
|
+
superclass <= StandardError ? superclass.after_logging_blocks.merge(@after_logging_blocks) : @after_logging_blocks
|
16
30
|
end
|
17
31
|
end
|
18
32
|
|
@@ -43,6 +57,7 @@ class StandardError
|
|
43
57
|
msg = hash.delete(:m)
|
44
58
|
msg = hash.delete(:msg) || msg
|
45
59
|
msg = hash.delete(:message) || msg
|
60
|
+
hash[:description] ||= hash.delete(:desc) if hash[:desc].present?
|
46
61
|
@fingerprint = hash.delete(:fingerprint) || hash.delete(:fingerprints)
|
47
62
|
@tags = hash.delete(:tags) || hash.delete(:tag)
|
48
63
|
@level = hash.delete(:level) || hash.delete(:severity) || @level
|
@@ -65,6 +80,8 @@ class StandardError
|
|
65
80
|
|
66
81
|
def safe_message; message || '' end
|
67
82
|
def status; self.class.status end
|
83
|
+
def before_logging_blocks; self.class.before_logging_blocks end
|
84
|
+
def after_logging_blocks; self.class.after_logging_blocks end
|
68
85
|
def root_cause; cause.respond_to?(:root_cause) ? cause.root_cause : self end
|
69
86
|
|
70
87
|
def attributes
|
@@ -82,23 +99,40 @@ class StandardError
|
|
82
99
|
def code; attributes[:code] || status end
|
83
100
|
def code=(value); attributes[:code] = value end
|
84
101
|
def title; attributes[:title] || self.class.title end
|
85
|
-
def
|
86
|
-
def
|
102
|
+
def it_might_happen?; attributes[:it] == :might_happen end
|
103
|
+
def it_should_not_happen?; attributes[:it] == :should_not_happen end
|
104
|
+
def report?
|
105
|
+
return attributes[:report] if attributes.key?(:report)
|
106
|
+
return false if it_might_happen?
|
107
|
+
self.class.report?
|
108
|
+
end
|
109
|
+
def intentional? # not logging in test
|
110
|
+
return attributes[:intentional] if attributes.key?(:intentional)
|
111
|
+
return true if it_should_not_happen?
|
112
|
+
self.class.intentional?
|
113
|
+
end
|
87
114
|
def object; attributes[:object] || attributes[:obj] end
|
88
115
|
alias_method :obj, :object
|
89
116
|
|
90
|
-
# description is user friendly
|
117
|
+
# description is user friendly message as a attribute, do not use error's message
|
91
118
|
# error message is not user friendly in many cases.
|
92
119
|
def description
|
93
|
-
|
94
|
-
return dsc if dsc
|
95
|
-
msg = safe_message.dup
|
96
|
-
msg.instance_variable_set(:@raw, true)
|
97
|
-
msg
|
120
|
+
attributes[:description] || attributes[:desc]
|
98
121
|
end
|
99
122
|
alias_method :desc, :description
|
100
123
|
|
101
|
-
|
124
|
+
def _translate(*args)
|
125
|
+
return description if description.present?
|
126
|
+
super
|
127
|
+
end
|
128
|
+
|
129
|
+
# user friendly message, for overid
|
130
|
+
def user_message
|
131
|
+
return description if description.present?
|
132
|
+
_translate
|
133
|
+
end
|
134
|
+
|
135
|
+
# another user friendly messages
|
102
136
|
def descriptions
|
103
137
|
return attributes[:descriptions] if attributes[:descriptions]
|
104
138
|
attributes[:descriptions] = {}
|
@@ -120,13 +154,6 @@ class StandardError
|
|
120
154
|
hash
|
121
155
|
end
|
122
156
|
|
123
|
-
def _translate_params
|
124
|
-
attributes.merge(
|
125
|
-
type: self.class.name, status: status,
|
126
|
-
http_status: http_status, message: message
|
127
|
-
)
|
128
|
-
end
|
129
|
-
|
130
157
|
def to_json
|
131
158
|
Oj.dump(to_hash.with_indifferent_access, mode: :compat)
|
132
159
|
end
|
@@ -172,13 +199,17 @@ class StandardError
|
|
172
199
|
end
|
173
200
|
|
174
201
|
def logging(options = {})
|
175
|
-
|
176
|
-
|
177
|
-
if
|
178
|
-
|
179
|
-
|
202
|
+
before_logging_blocks.values.each { |blk| instance_exec &blk }
|
203
|
+
|
204
|
+
if !report? || intentional?
|
205
|
+
if defined?(Rails)
|
206
|
+
return if Rails.env.test?
|
207
|
+
else
|
208
|
+
return
|
209
|
+
end
|
180
210
|
end
|
181
|
-
|
211
|
+
|
212
|
+
logger = options[:logger] || Coaster.logger
|
182
213
|
return unless logger
|
183
214
|
|
184
215
|
cl = options[:cleaner] || cleaner
|
@@ -196,5 +227,8 @@ class StandardError
|
|
196
227
|
else
|
197
228
|
logger.error(msg)
|
198
229
|
end
|
230
|
+
msg
|
231
|
+
ensure
|
232
|
+
after_logging_blocks.values.each { |blk| instance_exec &blk }
|
199
233
|
end
|
200
234
|
end
|
@@ -66,4 +66,17 @@ class StandardError
|
|
66
66
|
capture(options)
|
67
67
|
just_logging(options)
|
68
68
|
end
|
69
|
+
|
70
|
+
# https://github.com/getsentry/sentry-ruby/blob/fbbc7a51ed10684d0e8b7bd9d2a1b65a7351c9ef/lib/raven/event.rb#L162
|
71
|
+
# sentry use `to_s` as a message
|
72
|
+
alias to_origin_s to_s
|
73
|
+
def message
|
74
|
+
to_origin_s
|
75
|
+
end
|
76
|
+
|
77
|
+
def to_s
|
78
|
+
str = super # https://ruby-doc.org/core-2.5.1/Exception.html#method-i-to_s
|
79
|
+
str = "#{user_message} / #{str}" if user_message.present?
|
80
|
+
str
|
81
|
+
end
|
69
82
|
end
|
data/lib/coaster/version.rb
CHANGED
data/test/locales/en.yml
CHANGED
data/test/test_helper.rb
CHANGED
@@ -37,6 +37,7 @@ module Coaster
|
|
37
37
|
def test_translation_sub
|
38
38
|
assert_equal 'Coaster SampleObject Title (class.Coaster.SampleObject.title)', SampleObject._translate('.title')
|
39
39
|
assert_equal 'Coaster SampleObject Title (class.Coaster.SampleObject.title)', SampleObject._translate(:title)
|
40
|
+
assert_nil SampleObject._translate(:title).instance_variable_get(:@missing)
|
40
41
|
end
|
41
42
|
|
42
43
|
def test_translation_with_key
|
@@ -46,6 +47,7 @@ module Coaster
|
|
46
47
|
def test_translation_inheritance
|
47
48
|
assert_equal 'Coaster SampleObject Translated', Inherited._translate
|
48
49
|
assert_equal 'Coaster SampleObject Title (class.Coaster.Inherited.title)', Inherited._translate(:title)
|
50
|
+
assert Inherited._translate.instance_variable_get(:@missing)
|
49
51
|
end
|
50
52
|
|
51
53
|
def test_interpolation
|
data/test/test_standard_error.rb
CHANGED
@@ -20,6 +20,63 @@ module Coaster
|
|
20
20
|
I18n.enforce_available_locales = false
|
21
21
|
end
|
22
22
|
|
23
|
+
def test_standard_messages
|
24
|
+
e = StandardError.new('asdf')
|
25
|
+
assert_equal 'asdf', e.message
|
26
|
+
assert_nil e.description
|
27
|
+
assert_nil e.desc
|
28
|
+
assert_equal 'standard error translation', e._translate
|
29
|
+
assert_equal 'standard error translation', e.user_message
|
30
|
+
assert_equal 'standard error translation / asdf', e.to_s
|
31
|
+
assert_equal 'standard error title', e.title
|
32
|
+
e = StandardError.new(m: 'foo', desc: 'bar')
|
33
|
+
assert_equal 'foo', e.message
|
34
|
+
assert_equal 'bar', e.description
|
35
|
+
assert_equal 'bar', e.desc
|
36
|
+
assert_equal 'bar', e._translate
|
37
|
+
assert_equal 'bar', e.user_message
|
38
|
+
assert_equal 'standard error title', e.title
|
39
|
+
assert_equal 'bar / foo', e.to_s
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_no_translation_class
|
43
|
+
e = UntitledError.new('asdf')
|
44
|
+
assert_equal 'asdf', e.message
|
45
|
+
assert_nil e.description
|
46
|
+
assert_nil e.desc
|
47
|
+
assert_equal 'standard error translation', e._translate
|
48
|
+
assert_equal 'standard error translation', e.user_message
|
49
|
+
assert_equal 'standard error translation / asdf', e.to_s
|
50
|
+
assert_equal 'standard error title', e.title
|
51
|
+
e = UntitledError.new(m: 'foo', desc: 'bar')
|
52
|
+
assert_equal 'foo', e.message
|
53
|
+
assert_equal 'bar', e.description
|
54
|
+
assert_equal 'bar', e.desc
|
55
|
+
assert_equal 'bar', e._translate
|
56
|
+
assert_equal 'bar', e.user_message
|
57
|
+
assert_equal 'bar / foo', e.to_s
|
58
|
+
assert_equal 'standard error title', e.title
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_with_translation_class
|
62
|
+
e = SampleError.new('asdf')
|
63
|
+
assert_equal 'asdf', e.message
|
64
|
+
assert_nil e.description
|
65
|
+
assert_nil e.desc
|
66
|
+
assert_equal 'Test sample error', e._translate
|
67
|
+
assert_equal 'Test sample error', e.user_message
|
68
|
+
assert_equal 'Test sample error / asdf', e.to_s
|
69
|
+
assert_equal 'Test this title', e.title
|
70
|
+
e = SampleError.new(m: 'foo', desc: 'bar')
|
71
|
+
assert_equal 'foo', e.message
|
72
|
+
assert_equal 'bar', e.description
|
73
|
+
assert_equal 'bar', e.desc
|
74
|
+
assert_equal 'bar', e._translate
|
75
|
+
assert_equal 'bar', e.user_message
|
76
|
+
assert_equal 'bar / foo', e.to_s
|
77
|
+
assert_equal 'Test this title', e.title
|
78
|
+
end
|
79
|
+
|
23
80
|
def test_message
|
24
81
|
raise SampleError, {m: 'beer is proof'}
|
25
82
|
rescue => e
|
@@ -39,16 +96,16 @@ module Coaster
|
|
39
96
|
raise ExampleError, {wat: 'cha'}
|
40
97
|
end
|
41
98
|
rescue => e
|
42
|
-
assert_equal e.to_hash['wat']
|
43
|
-
assert_equal e.to_hash['type']
|
44
|
-
assert_equal e.to_hash['status']
|
45
|
-
assert_equal e.to_hash['http_status']
|
46
|
-
assert_equal e.to_hash['message']
|
47
|
-
assert_equal e.to_hash['cause']['frog']
|
48
|
-
assert_equal e.to_hash['cause']['type']
|
49
|
-
assert_equal e.to_hash['cause']['status']
|
50
|
-
assert_equal e.to_hash['cause']['http_status']
|
51
|
-
assert_equal e.to_hash['cause']['message']
|
99
|
+
assert_equal 'cha', e.to_hash['wat']
|
100
|
+
assert_equal 'Coaster::TestStandardError::ExampleError', e.to_hash['type']
|
101
|
+
assert_equal 20, e.to_hash['status']
|
102
|
+
assert_equal 500, e.to_hash['http_status']
|
103
|
+
assert_equal 'Test sample error', e.to_hash['message']
|
104
|
+
assert_equal 'rams', e.to_hash['cause']['frog']
|
105
|
+
assert_equal 'Coaster::TestStandardError::SampleError', e.to_hash['cause']['type']
|
106
|
+
assert_equal 10, e.to_hash['cause']['status']
|
107
|
+
assert_equal 500, e.to_hash['cause']['http_status']
|
108
|
+
assert_equal 'Test sample error', e.to_hash['cause']['message']
|
52
109
|
end
|
53
110
|
|
54
111
|
def test_cause_attributes
|
@@ -58,9 +115,9 @@ module Coaster
|
|
58
115
|
raise ExampleError, {wat: 'cha'}
|
59
116
|
end
|
60
117
|
rescue => e
|
61
|
-
assert_equal e.cause.attr['frog']
|
62
|
-
assert_equal e.attr['frog']
|
63
|
-
assert_equal e.attr['wat']
|
118
|
+
assert_equal 'rams', e.cause.attr['frog']
|
119
|
+
assert_equal 'rams', e.attr['frog']
|
120
|
+
assert_equal 'cha', e.attr['wat']
|
64
121
|
end
|
65
122
|
|
66
123
|
def test_to_detail
|
@@ -94,19 +151,19 @@ LOG
|
|
94
151
|
def test_translation
|
95
152
|
raise SampleError, {tkey: '.test'}
|
96
153
|
rescue => e
|
97
|
-
assert_equal
|
154
|
+
assert_equal 'Test this translation', e._translate
|
98
155
|
end
|
99
156
|
|
100
157
|
def test_title
|
101
158
|
raise SampleError, 'foobar'
|
102
159
|
rescue => e
|
103
|
-
assert_equal
|
160
|
+
assert_equal 'Test this title', e.title
|
104
161
|
end
|
105
162
|
|
106
163
|
def test_title_missing
|
107
164
|
raise UntitledError, 'untitled'
|
108
165
|
rescue => e
|
109
|
-
|
166
|
+
assert_equal 'standard error title', e.title
|
110
167
|
end
|
111
168
|
|
112
169
|
def root_cause_sample1
|
@@ -129,31 +186,54 @@ LOG
|
|
129
186
|
begin
|
130
187
|
root_cause_sample3
|
131
188
|
rescue => e
|
132
|
-
assert_equal e.root_cause.message
|
189
|
+
assert_equal 'a', e.root_cause.message
|
133
190
|
end
|
134
191
|
end
|
135
192
|
|
136
193
|
def test_raven_notes
|
137
194
|
raise SampleError, m: 'foofoo', something: 'other'
|
138
195
|
rescue => e
|
139
|
-
assert_equal e.notes(the_other: 'something')[:extra][:something]
|
140
|
-
assert_equal e.notes(the_other: 'something')[:extra][:the_other]
|
196
|
+
assert_equal 'other', e.notes(the_other: 'something')[:extra][:something]
|
197
|
+
assert_equal 'something', e.notes(the_other: 'something')[:extra][:the_other]
|
141
198
|
end
|
142
199
|
|
143
200
|
def test_to_hash
|
144
201
|
aa # raise NameError
|
145
202
|
rescue => e
|
146
|
-
assert_equal e.to_hash['type']
|
147
|
-
assert_equal e.to_hash['status']
|
148
|
-
assert_equal e.to_hash['http_status']
|
149
|
-
|
203
|
+
assert_equal 'NameError', e.to_hash['type']
|
204
|
+
assert_equal 999999, e.to_hash['status']
|
205
|
+
assert_equal 500, e.to_hash['http_status']
|
206
|
+
assert_match /undefined local variable or method `aa'/, e.to_hash['message']
|
150
207
|
end
|
151
208
|
|
152
209
|
def test_descriptions
|
153
210
|
raise SampleError
|
154
211
|
rescue => e
|
155
212
|
e.descriptions.merge!(a: 1)
|
156
|
-
assert_equal e.descriptions['a']
|
213
|
+
assert_equal 1, e.descriptions['a']
|
214
|
+
end
|
215
|
+
|
216
|
+
class SampleErrorSub < SampleError; end
|
217
|
+
class SampleErrorSubSub < SampleErrorSub
|
218
|
+
def it_might_happen?; true end
|
219
|
+
end
|
220
|
+
SampleError.after_logging(:blah) do
|
221
|
+
self.attributes[:abc] = 100
|
222
|
+
@blah = 101
|
223
|
+
end
|
224
|
+
def test_before_logging
|
225
|
+
e = SampleErrorSubSub.new(m: 'foo')
|
226
|
+
assert !e.after_logging_blocks[:blah].nil?
|
227
|
+
e.logging
|
228
|
+
assert_equal 100, e.attributes[:abc]
|
229
|
+
assert_equal 101, e.instance_variable_get(:@blah)
|
230
|
+
end
|
231
|
+
class SampleErrorMightHappen < SampleErrorSub
|
232
|
+
def it_might_happen?; true end
|
233
|
+
end
|
234
|
+
def test_might_happen
|
235
|
+
e = SampleErrorMightHappen.new('fbar')
|
236
|
+
assert !e.report?
|
157
237
|
end
|
158
238
|
end
|
159
239
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: coaster
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- buzz jung
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-10-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: i18n
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 6.0.3.1
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 6.0.3.1
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: attr_extras
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -70,114 +70,114 @@ dependencies:
|
|
70
70
|
name: bundler
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
75
|
+
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - "
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
82
|
+
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: pry
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - "
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '0
|
89
|
+
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - "
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '0
|
96
|
+
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: pry-stack_explorer
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- - "
|
101
|
+
- - ">="
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '0
|
103
|
+
version: '0'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- - "
|
108
|
+
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: '0
|
110
|
+
version: '0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: pry-byebug
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- - "
|
115
|
+
- - ">="
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: '
|
117
|
+
version: '0'
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- - "
|
122
|
+
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version: '
|
124
|
+
version: '0'
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: minitest
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
|
-
- - "
|
129
|
+
- - ">="
|
130
130
|
- !ruby/object:Gem::Version
|
131
|
-
version: '
|
131
|
+
version: '0'
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
|
-
- - "
|
136
|
+
- - ">="
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version: '
|
138
|
+
version: '0'
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
140
|
name: mocha
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
|
-
- - "
|
143
|
+
- - ">="
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version: '
|
145
|
+
version: '0'
|
146
146
|
type: :development
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
|
-
- - "
|
150
|
+
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version: '
|
152
|
+
version: '0'
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
154
|
name: shoulda
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
156
156
|
requirements:
|
157
|
-
- - "
|
157
|
+
- - ">="
|
158
158
|
- !ruby/object:Gem::Version
|
159
|
-
version: '
|
159
|
+
version: '0'
|
160
160
|
type: :development
|
161
161
|
prerelease: false
|
162
162
|
version_requirements: !ruby/object:Gem::Requirement
|
163
163
|
requirements:
|
164
|
-
- - "
|
164
|
+
- - ">="
|
165
165
|
- !ruby/object:Gem::Version
|
166
|
-
version: '
|
166
|
+
version: '0'
|
167
167
|
- !ruby/object:Gem::Dependency
|
168
168
|
name: shoulda-context
|
169
169
|
requirement: !ruby/object:Gem::Requirement
|
170
170
|
requirements:
|
171
|
-
- - "
|
171
|
+
- - ">="
|
172
172
|
- !ruby/object:Gem::Version
|
173
|
-
version: '
|
173
|
+
version: '0'
|
174
174
|
type: :development
|
175
175
|
prerelease: false
|
176
176
|
version_requirements: !ruby/object:Gem::Requirement
|
177
177
|
requirements:
|
178
|
-
- - "
|
178
|
+
- - ">="
|
179
179
|
- !ruby/object:Gem::Version
|
180
|
-
version: '
|
180
|
+
version: '0'
|
181
181
|
description: Ruby Core Extensions
|
182
182
|
email: buzz@frograms.com
|
183
183
|
executables: []
|
@@ -221,12 +221,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
221
221
|
- !ruby/object:Gem::Version
|
222
222
|
version: '0'
|
223
223
|
requirements: []
|
224
|
-
rubygems_version: 3.
|
224
|
+
rubygems_version: 3.1.2
|
225
225
|
signing_key:
|
226
226
|
specification_version: 4
|
227
227
|
summary: A little convenient feature for standard library
|
228
228
|
test_files:
|
229
|
+
- test/test_object_translation.rb
|
229
230
|
- test/test_helper.rb
|
230
231
|
- test/test_standard_error.rb
|
231
232
|
- test/locales/en.yml
|
232
|
-
- test/test_object_translation.rb
|