coaster 0.5.7 → 1.0.4

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: 5d412837bcd6f0a5a4373bc2aa8722a76256bddf964bc9ed16cee5259578e799
4
- data.tar.gz: f68f15518cecb6971a01203ffb1f2e6bf974ae87d594bfb3f9bfd1fbb49735d1
3
+ metadata.gz: 1efdff11e3158914f521590fb64642e9c1834987317b896db24896c31e772bcf
4
+ data.tar.gz: 3fcdb6480424ddcc27cc50c0568e6b8d9967bf494f8118d174d82e9072c03974
5
5
  SHA512:
6
- metadata.gz: '08b3cdfaf858436cba05f579637d3bf1209b0612365ef064eaf4b1a03a72c8dfe88eff23913787e3c1a358e4772685fc94f440e910801314a01c8fc01729adb1'
7
- data.tar.gz: 6a16cc58fd47a3d295da129c168fd4d2dd23e5ff8741894e40b7bd27a36904a950fdf9799d7be37c47f3742175333fe7562caa994c78cddced66132d664fd1ed
6
+ metadata.gz: 270b1faeeae2fe9fcccd3e0f2c4d9d8234c7d0288ee949ea29b7faac70e711e5394b2cb06b14da11a6e71fe770c46416e9e8e10fadca2303470171986e6a3911
7
+ data.tar.gz: c895e44a856beae32d2b46f09547d5c69aba008a46581ee096f9b069e6909251574f6dccf62f899fa3e51771e48acc1ad601f0a46e07a87cb5c8e59b706ea1f4
@@ -3,8 +3,9 @@ require 'i18n'
3
3
  class Object
4
4
  class << self
5
5
  def _translate(*args)
6
- options = args.last.is_a?(Hash) ? args.pop.dup : {}
6
+ options = args.last.is_a?(Hash) ? args.pop : {}
7
7
  options.merge!(_translate_params)
8
+ options = options.to_hash.symbolize_keys!
8
9
 
9
10
  key = args.shift
10
11
  subkey = nil
@@ -33,22 +34,22 @@ class Object
33
34
  end
34
35
  options[:tkey] ||= key
35
36
  options.merge!(throw: true)
36
- options.symbolize_keys!
37
37
  result = catch(:exception) do
38
38
  I18n.t(key, *args, options)
39
39
  end
40
40
 
41
41
  if result.is_a?(I18n::MissingTranslation)
42
- Coaster.logger && Coaster.logger.warn(result)
43
42
  unless options.key?(:original_missing)
44
43
  options.merge!(original_missing: result)
45
44
  end
46
45
 
47
46
  if key_class.superclass == Object || key_class == Object
48
47
  return options[:description] if options[:description].present?
48
+ Coaster.logger && Coaster.logger.warn(result)
49
49
  throw :exception, result if options[:original_throw]
50
50
  missing = options[:original_missing] || result
51
51
  msg = missing.message
52
+ msg = msg.dup
52
53
  msg.instance_variable_set(:@missing, missing)
53
54
  msg.instance_variable_set(:@tkey, options[:tkey])
54
55
  msg
@@ -57,6 +58,7 @@ class Object
57
58
  _translate(subkey, *args, options)
58
59
  end
59
60
  else
61
+ result = result.dup if result.frozen?
60
62
  result.instance_variable_set(:@translated, true)
61
63
  result.instance_variable_set(:@tkey, options[:tkey])
62
64
  result
@@ -74,7 +76,7 @@ class Object
74
76
  # Foo::Bar.new._translate(:force) #=> ignore 'message' even if message exists
75
77
  #
76
78
  def _translate(*args)
77
- options = args.last.is_a?(Hash) ? args.pop.dup : {}
79
+ options = (args.last.is_a?(Hash) ? args.pop : {}).with_indifferent_access
78
80
  key = args.shift || (respond_to?(:tkey) ? tkey : nil)
79
81
 
80
82
  if respond_to?(:description) && description.present? && description != 'false' && description != self.class.name
@@ -26,42 +26,43 @@ class StandardError
26
26
  @tags = {}
27
27
  @level = 'error'
28
28
  @attributes = HashWithIndifferentAccess.new
29
+ @attributes.merge!(cause.attributes || {}) if cause && cause.respond_to?(:attributes)
29
30
  @tkey = nil
30
31
 
31
32
  case message
32
- when Exception
33
- msg = message
34
- set_backtrace(message.backtrace)
35
- when StandardError
36
- @fingerprint = message.fingerprint
37
- @tags = message.tags
38
- @level = message.level
39
- @tkey = message.tkey
40
- @attributes = message.attributes
41
- msg = message
42
- set_backtrace(message.backtrace)
43
- when Hash then
44
- hash = message.with_indifferent_access rescue message
45
- msg = hash.delete(:m)
46
- msg = hash.delete(:msg) || msg
47
- msg = hash.delete(:message) || msg
48
- @fingerprint = hash.delete(:fingerprint) || hash.delete(:fingerprints)
49
- @tags = hash.delete(:tags) || hash.delete(:tag)
50
- @level = hash.delete(:level) || hash.delete(:severity) || @level
51
- @tkey = hash.delete(:tkey)
52
- msg = cause.message if msg.nil? && cause
53
- @attributes.merge!(hash)
54
- when String then
55
- msg = message
56
- when FalseClass, NilClass then
57
- msg = ''
58
- else
59
- msg = message
33
+ when Exception
34
+ msg = message
35
+ set_backtrace(message.backtrace)
36
+ when StandardError
37
+ @fingerprint = message.fingerprint
38
+ @tags = message.tags
39
+ @level = message.level
40
+ @tkey = message.tkey
41
+ @attributes = message.attributes
42
+ msg = message
43
+ set_backtrace(message.backtrace)
44
+ when Hash then
45
+ hash = message.with_indifferent_access rescue message
46
+ msg = hash.delete(:m)
47
+ msg = hash.delete(:msg) || msg
48
+ msg = hash.delete(:message) || msg
49
+ @fingerprint = hash.delete(:fingerprint) || hash.delete(:fingerprints)
50
+ @tags = hash.delete(:tags) || hash.delete(:tag)
51
+ @level = hash.delete(:level) || hash.delete(:severity) || @level
52
+ @tkey = hash.delete(:tkey)
53
+ msg = cause.message if msg.nil? && cause
54
+ @attributes.merge!(hash)
55
+ when String then
56
+ msg = message
57
+ when FalseClass, NilClass then
58
+ msg = ''
59
+ else
60
+ msg = message
60
61
  end
61
62
 
62
63
  @fingerprint = [] unless @fingerprint.is_a?(Array)
63
64
  @tags = {} unless @tags.is_a?(Hash)
64
- msg ||= self.class.title
65
+ msg ||= self.class._translate
65
66
  super(msg)
66
67
  end
67
68
 
@@ -95,6 +96,14 @@ class StandardError
95
96
  attributes[:http_status] = value
96
97
  end
97
98
 
99
+ def report?
100
+ attributes.key?(:report) ? attributes[:report] : true
101
+ end
102
+
103
+ def intentional?
104
+ attributes[:intentional]
105
+ end
106
+
98
107
  def code
99
108
  attributes[:code] || status
100
109
  end
@@ -114,6 +123,13 @@ class StandardError
114
123
  end
115
124
  alias_method :desc, :description
116
125
 
126
+ # more user friendly messages
127
+ def descriptions
128
+ return attributes[:descriptions] if attributes[:descriptions]
129
+ attributes[:descriptions] = {}
130
+ attributes[:descriptions]
131
+ end
132
+
117
133
  def object
118
134
  attributes[:object] || attributes[:obj]
119
135
  end
@@ -124,7 +140,7 @@ class StandardError
124
140
  end
125
141
 
126
142
  def to_hash
127
- hash = @attributes.merge(
143
+ hash = attributes.merge(
128
144
  type: self.class.name, status: status,
129
145
  http_status: http_status, message: message
130
146
  )
@@ -190,16 +206,23 @@ class StandardError
190
206
  end
191
207
 
192
208
  def logging(options = {})
193
- logger = options[:logger] || Coaster.logger
194
- logger = Rails.logger if logger.nil? && defined?(Rails)
195
- return nil unless logger
209
+ return unless report?
210
+ logger = nil
211
+ if defined?(Rails)
212
+ return if Rails.env.test? && intentional?
213
+ logger = Rails.logger
214
+ end
215
+ logger = options[:logger] || Coaster.logger || logger
216
+ return unless logger
196
217
 
197
218
  cl = options[:cleaner] || cleaner
198
219
  msg = to_detail
199
220
 
200
221
  if cl && backtrace
222
+ bt = cl.clean(backtrace)
223
+ bt = bt[0..2] if intentional?
201
224
  msg += "\tBACKTRACE:\n\t"
202
- msg += cl.clean(backtrace).join("\n\t")
225
+ msg += bt.join("\n\t")
203
226
  end
204
227
 
205
228
  if level && logger.respond_to?(level)
@@ -38,7 +38,7 @@ class StandardError
38
38
 
39
39
  def capture(options = {})
40
40
  return if options.key?(:report) && !options[:report]
41
- return if attributes.key?(:report) && !attributes[:report]
41
+ return unless report?
42
42
  nt = notes(options)
43
43
  Raven.capture_exception(self, level: nt[:level]) do |event|
44
44
  event.user.merge!(nt[:user] || {})
@@ -1,3 +1,3 @@
1
1
  module Coaster
2
- VERSION = '0.5.7'
2
+ VERSION = '1.0.4'
3
3
  end
@@ -5,8 +5,12 @@ en:
5
5
  SampleObject:
6
6
  self: 'Coaster SampleObject Translated'
7
7
  title: 'Coaster SampleObject Title (%{tkey})'
8
+ interpolation: 'Coaster SampleObject interpolation test %{test_this}'
8
9
  TestStandardError:
10
+ ExampleError:
11
+ self: 'Test example error'
9
12
  SampleError:
13
+ self: 'Test sample error'
10
14
  test: 'Test this translation'
11
15
  title: 'Test this title'
12
16
  sample:
@@ -48,6 +48,10 @@ module Coaster
48
48
  assert_equal 'Coaster SampleObject Title (class.Coaster.Inherited.title)', Inherited._translate(:title)
49
49
  end
50
50
 
51
+ def test_interpolation
52
+ assert_equal 'Coaster SampleObject interpolation test this interpolated', SampleObject._translate('.interpolation', {test_this: 'this interpolated'}.with_indifferent_access)
53
+ end
54
+
51
55
  def teardown
52
56
  I18n.locale = nil
53
57
  I18n.default_locale = nil
@@ -39,20 +39,16 @@ module Coaster
39
39
  raise ExampleError, {wat: 'cha'}
40
40
  end
41
41
  rescue => e
42
- assert_equal({
43
- "wat"=>"cha",
44
- "type"=>"Coaster::TestStandardError::ExampleError",
45
- "status"=>20,
46
- "http_status"=>500,
47
- "message"=>"Test this title",
48
- "cause"=>{
49
- "frog"=>"rams",
50
- "type"=>"Coaster::TestStandardError::SampleError",
51
- "status"=>10,
52
- "http_status"=>500,
53
- "message"=>"Test this title"
54
- }
55
- }, e.to_hash)
42
+ assert_equal e.to_hash['wat'], 'cha'
43
+ assert_equal e.to_hash['type'], 'Coaster::TestStandardError::ExampleError'
44
+ assert_equal e.to_hash['status'], 20
45
+ assert_equal e.to_hash['http_status'], 500
46
+ assert_equal e.to_hash['message'], 'Test sample error'
47
+ assert_equal e.to_hash['cause']['frog'], 'rams'
48
+ assert_equal e.to_hash['cause']['type'], 'Coaster::TestStandardError::SampleError'
49
+ assert_equal e.to_hash['cause']['status'], 10
50
+ assert_equal e.to_hash['cause']['http_status'], 500
51
+ assert_equal e.to_hash['cause']['message'], 'Test sample error'
56
52
  end
57
53
 
58
54
  def test_cause_attributes
@@ -62,7 +58,9 @@ module Coaster
62
58
  raise ExampleError, {wat: 'cha'}
63
59
  end
64
60
  rescue => e
65
- assert_equal({frog: 'rams', wat: 'cha'}.with_indifferent_access, e.attr)
61
+ assert_equal e.cause.attr['frog'], 'rams'
62
+ assert_equal e.attr['frog'], 'rams'
63
+ assert_equal e.attr['wat'], 'cha'
66
64
  end
67
65
 
68
66
  def test_to_detail
@@ -74,15 +72,15 @@ module Coaster
74
72
  rescue => e
75
73
  detail = <<-LOG
76
74
  [Coaster::TestStandardError::ExampleError] status:20
77
- MESSAGE: Test this title
75
+ MESSAGE: Test sample error
78
76
  @fingerprint: []
79
77
  @tags: {}
80
78
  @level: \"error\"
81
- @attributes: {\"wat\"=>\"cha\"}
79
+ @attributes: {\"frog\"=>\"rams\", \"wat\"=>\"cha\"}
82
80
  @tkey: nil
83
81
  @raven: {}
84
82
  CAUSE: [Coaster::TestStandardError::SampleError] status:10
85
- MESSAGE: Test this title
83
+ MESSAGE: Test sample error
86
84
  @fingerprint: []
87
85
  @tags: {}
88
86
  @level: \"error\"
@@ -108,7 +106,7 @@ LOG
108
106
  def test_title_missing
109
107
  raise UntitledError, 'untitled'
110
108
  rescue => e
111
- assert_equal e.title, nil
109
+ assert_nil e.title
112
110
  end
113
111
 
114
112
  def root_cause_sample1
@@ -138,7 +136,24 @@ LOG
138
136
  def test_raven_notes
139
137
  raise SampleError, m: 'foofoo', something: 'other'
140
138
  rescue => e
141
- assert_equal e.notes(the_other: 'something'), {extra: {something: 'other', the_other: 'something'}, fingerprint: [], tags: {}, level: 'error'}.with_indifferent_access
139
+ assert_equal e.notes(the_other: 'something')[:extra][:something], 'other'
140
+ assert_equal e.notes(the_other: 'something')[:extra][:the_other], 'something'
141
+ end
142
+
143
+ def test_to_hash
144
+ aa # raise NameError
145
+ rescue => e
146
+ assert_equal e.to_hash['type'], 'NameError'
147
+ assert_equal e.to_hash['status'], 999999
148
+ assert_equal e.to_hash['http_status'], 500
149
+ assert e.to_hash['message'] =~ /undefined local variable or method `aa'/
150
+ end
151
+
152
+ def test_descriptions
153
+ raise SampleError
154
+ rescue => e
155
+ e.descriptions.merge!(a: 1)
156
+ assert_equal e.descriptions['a'], 1
142
157
  end
143
158
  end
144
159
  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: 0.5.7
4
+ version: 1.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - buzz jung
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-17 00:00:00.000000000 Z
11
+ date: 2020-07-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: i18n
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '1.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: '1.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -226,7 +226,7 @@ signing_key:
226
226
  specification_version: 4
227
227
  summary: A little convenient feature for standard library
228
228
  test_files:
229
- - test/locales/en.yml
230
- - test/test_standard_error.rb
231
229
  - test/test_helper.rb
230
+ - test/test_standard_error.rb
231
+ - test/locales/en.yml
232
232
  - test/test_object_translation.rb