active_model-better_errors 1.6.3 → 1.6.5

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.
Files changed (71) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +37 -0
  3. data/.rspec +4 -1
  4. data/.ruby-gemset +1 -0
  5. data/.travis.yml +5 -1
  6. data/Gemfile +9 -13
  7. data/Gemfile.devtools +66 -0
  8. data/Guardfile +32 -0
  9. data/LICENSE.txt +2 -0
  10. data/README.md +12 -10
  11. data/Rakefile +20 -49
  12. data/active_model-better_errors.gemspec +27 -107
  13. data/config/devtools.yml +4 -0
  14. data/config/flay.yml +3 -0
  15. data/config/flog.yml +2 -0
  16. data/config/mutant.yml +3 -0
  17. data/config/reek.yml +103 -0
  18. data/config/rubocop.yml +62 -0
  19. data/config/yardstick.yml +2 -0
  20. data/lib/active_model/better_errors.rb +64 -4
  21. data/lib/active_model/better_errors/array_reporter.rb +14 -0
  22. data/lib/active_model/{error_collecting → better_errors}/emulation.rb +15 -8
  23. data/lib/active_model/{error_collecting → better_errors}/error_collection.rb +14 -6
  24. data/lib/active_model/{error_collecting → better_errors}/error_message.rb +16 -5
  25. data/lib/active_model/{error_collecting → better_errors}/error_message_set.rb +7 -2
  26. data/lib/active_model/{error_collecting → better_errors}/errors.rb +10 -3
  27. data/lib/active_model/better_errors/formatter.rb +26 -0
  28. data/lib/active_model/better_errors/hash_reporter.rb +14 -0
  29. data/lib/active_model/{error_collecting → better_errors}/human_array_reporter.rb +6 -1
  30. data/lib/active_model/{error_collecting → better_errors}/human_hash_reporter.rb +8 -3
  31. data/lib/active_model/better_errors/human_message_formatter.rb +66 -0
  32. data/lib/active_model/{error_collecting → better_errors}/human_message_reporter.rb +19 -12
  33. data/lib/active_model/{error_collecting → better_errors}/machine_array_reporter.rb +10 -2
  34. data/lib/active_model/{error_collecting → better_errors}/machine_hash_reporter.rb +10 -3
  35. data/lib/active_model/{error_collecting → better_errors}/message_reporter.rb +10 -5
  36. data/lib/active_model/{error_collecting → better_errors}/reporter.rb +7 -2
  37. data/lib/active_model/better_errors/version.rb +10 -0
  38. data/spec/spec_helper.rb +19 -10
  39. data/spec/support/i18n_deprecation_silence.rb +4 -0
  40. data/spec/support/models.rb +11 -4
  41. data/spec/support/string_ext.rb +14 -0
  42. data/spec/{lib/active_model/error_collecting → unit/lib/active_model/better_errors}/emulation_spec.rb +8 -6
  43. data/spec/{lib/active_model/error_collecting → unit/lib/active_model/better_errors}/error_collection_spec.rb +66 -62
  44. data/spec/{lib/active_model/error_collecting → unit/lib/active_model/better_errors}/error_message_set_spec.rb +27 -25
  45. data/spec/unit/lib/active_model/better_errors/error_message_spec.rb +315 -0
  46. data/spec/unit/lib/active_model/better_errors/errors_spec.rb +98 -0
  47. data/spec/unit/lib/active_model/better_errors/human_array_reporter_spec.rb +39 -0
  48. data/spec/unit/lib/active_model/better_errors/human_hash_reporter_spec.rb +37 -0
  49. data/spec/{lib/active_model/error_collecting → unit/lib/active_model/better_errors}/human_message_formatter_spec.rb +13 -7
  50. data/spec/unit/lib/active_model/better_errors/human_message_reporter_spec.rb +65 -0
  51. data/spec/unit/lib/active_model/better_errors/machine_array_reporter_spec.rb +45 -0
  52. data/spec/unit/lib/active_model/better_errors/machine_hash_reporter_spec.rb +45 -0
  53. data/spec/unit/lib/active_model/better_errors_spec.rb +37 -0
  54. metadata +98 -143
  55. data/.document +0 -5
  56. data/VERSION +0 -1
  57. data/lib/active_model/error_collecting.rb +0 -49
  58. data/lib/active_model/error_collecting/array_reporter.rb +0 -9
  59. data/lib/active_model/error_collecting/core_ext.rb +0 -6
  60. data/lib/active_model/error_collecting/hash_reporter.rb +0 -9
  61. data/lib/active_model/error_collecting/human_message_formatter.rb +0 -58
  62. data/spec/lib/active_model/better_errors_spec.rb +0 -7
  63. data/spec/lib/active_model/error_collecting/error_message_spec.rb +0 -293
  64. data/spec/lib/active_model/error_collecting/errors_spec.rb +0 -95
  65. data/spec/lib/active_model/error_collecting/human_array_reporter_spec.rb +0 -33
  66. data/spec/lib/active_model/error_collecting/human_hash_reporter_spec.rb +0 -32
  67. data/spec/lib/active_model/error_collecting/human_message_reporter_spec.rb +0 -61
  68. data/spec/lib/active_model/error_collecting/machine_array_reporter_spec.rb +0 -40
  69. data/spec/lib/active_model/error_collecting/machine_hash_reporter_spec.rb +0 -40
  70. data/spec/lib/active_model/error_collecting_spec.rb +0 -22
  71. data/test/integration.rb +0 -10
@@ -1,5 +1,10 @@
1
+ # encoding: utf-8
2
+
1
3
  module ActiveModel
2
- module ErrorCollecting
4
+ module BetterErrors
5
+ #
6
+ # Errors
7
+ #
3
8
  class Errors
4
9
  include Emulation
5
10
 
@@ -28,7 +33,9 @@ module ActiveModel
28
33
 
29
34
  def set_reporter(type, reporter)
30
35
  type = type.to_s
31
- klass = ::ActiveModel::ErrorCollecting.get_reporter_class(type, reporter)
36
+ klass = ::ActiveModel::BetterErrors
37
+ .get_reporter_class(type, reporter)
38
+
32
39
  @reporter_classes[type] = klass
33
40
  @reporters.delete type
34
41
  end
@@ -40,7 +47,7 @@ module ActiveModel
40
47
  end
41
48
 
42
49
  def reporter_classes
43
- ::ActiveModel::ErrorCollecting.reporters
50
+ ::ActiveModel::BetterErrors.reporters
44
51
  end
45
52
 
46
53
  def get_reporter_class(type)
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+
3
+ module ActiveModel
4
+ module BetterErrors
5
+ #
6
+ # Abstract Formatter class
7
+ class Formatter
8
+ extend Forwardable
9
+
10
+ def_delegators :@error_message, :attribute, :message, :options
11
+
12
+ attr_reader :base, :error_message
13
+
14
+ def initialize(base, error_message)
15
+ @base, @error_message = base, error_message
16
+ end
17
+
18
+ #
19
+ # @abstract
20
+ # Formats the error message into a comsumable string.
21
+ # see HumanMessageFormatter for more details.
22
+ def format_message
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+
3
+ module ActiveModel
4
+ module BetterErrors
5
+ #
6
+ # HashReporter
7
+ #
8
+ class HashReporter < Reporter
9
+ def to_hash
10
+ fail 'abstract method'
11
+ end
12
+ end
13
+ end
14
+ end
@@ -1,5 +1,10 @@
1
+ # encoding: utf-8
2
+
1
3
  module ActiveModel
2
- module ErrorCollecting
4
+ module BetterErrors
5
+ #
6
+ # HumanArrayReporter
7
+ #
3
8
  class HumanArrayReporter < ArrayReporter
4
9
  def to_a
5
10
  HumanMessageReporter.new(collection).full_messages
@@ -1,11 +1,16 @@
1
+ # encoding: utf-8
2
+
1
3
  module ActiveModel
2
- module ErrorCollecting
4
+ module BetterErrors
5
+ #
6
+ # HumanHashReporter
7
+ #
3
8
  class HumanHashReporter < HashReporter
4
9
  def to_hash
5
- collection.to_hash.inject({}) do |hash, kv|
10
+ collection.to_hash.reduce({}) do |hash, kv|
6
11
  attribute, error_message_set = kv
7
12
  hash[attribute] = error_message_set.map do |error_message|
8
- HumanMessageFormatter.new(base, error_message).format_message
13
+ ::ActiveModel::BetterErrors.format_message(base, error_message)
9
14
  end
10
15
  hash
11
16
  end
@@ -0,0 +1,66 @@
1
+ # encoding: utf-8
2
+
3
+ module ActiveModel
4
+ module BetterErrors
5
+ #
6
+ # HumanMessageFormatter
7
+ #
8
+ class HumanMessageFormatter < Formatter
9
+ def format_message
10
+ return message if message && type.nil?
11
+
12
+ keys = i18n_keys
13
+ key = keys.shift
14
+
15
+ options = {
16
+ default: keys,
17
+ model: base.class.model_name.human,
18
+ attribute: base.class.human_attribute_name(attribute),
19
+ value: value
20
+ }.merge(self.options)
21
+
22
+ I18n.translate key, options
23
+ end
24
+
25
+ private
26
+
27
+ def type
28
+ error_message.type || :invalid
29
+ end
30
+
31
+ def value
32
+ return if attribute == :base
33
+ base.send :read_attribute_for_validation, attribute
34
+ end
35
+
36
+ def ancestor_keys
37
+ return [] unless base.class.respond_to?(:i18n_scope)
38
+ scope = base.class.i18n_scope
39
+
40
+ base.class.lookup_ancestors.map do |klass|
41
+ key_base = "#{scope}.errors.models.#{klass.model_name.i18n_key}"
42
+ [
43
+ :"#{key_base}.attributes.#{attribute}.#{type}",
44
+ :"#{key_base}.#{type}"
45
+ ]
46
+ end
47
+ end
48
+
49
+ def i18n_keys
50
+ keys = ancestor_keys
51
+ keys << message
52
+
53
+ if base.class.respond_to?(:i18n_scope)
54
+ keys << :"#{base.class.i18n_scope}.errors.messages.#{type}"
55
+ end
56
+
57
+ keys << :"errors.attributes.#{attribute}.#{type}"
58
+ keys << :"errors.messages.#{type}"
59
+
60
+ keys.compact!
61
+ keys.flatten!
62
+ keys
63
+ end
64
+ end
65
+ end
66
+ end
@@ -1,31 +1,38 @@
1
+ # encoding: utf-8
2
+
1
3
  module ActiveModel
2
- module ErrorCollecting
4
+ module BetterErrors
5
+ #
6
+ # HumanMessageReporter
7
+ #
3
8
  class HumanMessageReporter < MessageReporter
4
9
  def full_messages
5
10
  @collection.map do |attribute, error_message|
6
- formatter = HumanMessageFormatter.new(base, error_message)
7
- message = formatter.format_message
11
+ message = ::ActiveModel::BetterErrors.format_message(
12
+ base, error_message
13
+ )
8
14
  full_message attribute, message
9
15
  end
10
16
  end
11
17
 
12
18
  def full_message(attribute, message)
13
19
  return message if attribute == :base
14
- attr_name = attribute.to_s.gsub('.', '_').humanize
15
- attr_name = base.class.human_attribute_name(attribute, :default => attr_name)
16
- I18n.t(:"errors.format", {
17
- :default => "%{attribute} %{message}",
18
- :attribute => attr_name,
19
- :message => message
20
- })
20
+ str = attribute.to_s.gsub('.', '_').humanize
21
+ str = base.class.human_attribute_name(attribute, default: str)
22
+
23
+ I18n.t(
24
+ 'errors.format',
25
+ default: '%{attribute} %{message}',
26
+ attribute: str,
27
+ message: message
28
+ )
21
29
  end
22
30
 
23
31
  # This method is not used internally.
24
32
  # This is for API Compatibility with ActiveModel::Errors only
25
33
  def generate_message(attribute, type = :invalid, options = {})
26
34
  error_message = ErrorMessage.build(base, attribute, type, options)
27
- formatter = HumanMessageFormatter.new(base, error_message)
28
- formatter.format_message
35
+ ::ActiveModel::BetterErrors.format_message(base, error_message)
29
36
  end
30
37
  end
31
38
  end
@@ -1,5 +1,10 @@
1
+ # encoding: utf-8
2
+
1
3
  module ActiveModel
2
- module ErrorCollecting
4
+ module BetterErrors
5
+ #
6
+ # MachineArrayReporter
7
+ #
3
8
  class MachineArrayReporter < ArrayReporter
4
9
  def to_a
5
10
  collection.to_a.map do |error_message|
@@ -11,7 +16,10 @@ module ActiveModel
11
16
  result = {}
12
17
  result[:attribute] = error_message.attribute.to_s
13
18
  result[:type] = error_message.type || :invalid
14
- result[:options] = error_message.options unless error_message.options.blank?
19
+
20
+ options = error_message.options
21
+ result[:options] = options unless options.blank?
22
+
15
23
  result
16
24
  end
17
25
  end
@@ -1,8 +1,13 @@
1
+ # encoding: utf-8
2
+
1
3
  module ActiveModel
2
- module ErrorCollecting
4
+ module BetterErrors
5
+ #
6
+ # MachineHashReporter
7
+ #
3
8
  class MachineHashReporter < HashReporter
4
9
  def to_hash
5
- collection.to_hash.inject({}) do |hash, kv|
10
+ collection.to_hash.reduce({}) do |hash, kv|
6
11
  attribute, error_message_set = kv
7
12
  hash[attribute] = error_message_set.map do |error_message|
8
13
  format_error_message(error_message)
@@ -14,7 +19,9 @@ module ActiveModel
14
19
  def format_error_message(error_message)
15
20
  result = {}
16
21
  result[:type] = error_message.type || :invalid
17
- result[:options] = error_message.options unless error_message.options.blank?
22
+
23
+ options = error_message.options
24
+ result[:options] = options unless options.blank?
18
25
  result
19
26
  end
20
27
  end
@@ -1,17 +1,22 @@
1
+ # encoding: utf-8
2
+
1
3
  module ActiveModel
2
- module ErrorCollecting
4
+ module BetterErrors
5
+ #
6
+ # MessageReporter
7
+ #
3
8
  class MessageReporter < Reporter
4
9
  def full_messages
5
- raise "abstract method"
10
+ fail 'abstract method'
6
11
  end
7
12
 
8
13
  def full_message(attribute, message)
9
- raise "abstract method"
14
+ fail 'abstract method'
10
15
  end
11
16
 
12
17
  def generate_message(attribute, type = :invalid, options = {})
13
- raise "abstract method"
18
+ fail 'abstract method'
14
19
  end
15
20
  end
16
21
  end
17
- end
22
+ end
@@ -1,5 +1,10 @@
1
+ # encoding: utf-8
2
+
1
3
  module ActiveModel
2
- module ErrorCollecting
4
+ module BetterErrors
5
+ #
6
+ # Reporter
7
+ #
3
8
  class Reporter
4
9
  attr_reader :collection
5
10
  def initialize(collection)
@@ -11,4 +16,4 @@ module ActiveModel
11
16
  end
12
17
  end
13
18
  end
14
- end
19
+ end
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+
3
+ module ActiveModel
4
+ #
5
+ # BetterErrors
6
+ #
7
+ module BetterErrors
8
+ VERSION = '1.6.5'
9
+ end
10
+ end
@@ -1,15 +1,24 @@
1
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
- $LOAD_PATH.unshift(File.dirname(__FILE__))
3
- require 'rspec'
4
- require 'pry'
1
+ # encoding: utf-8
5
2
 
6
- require 'active_model'
7
- require 'active_model/better_errors'
3
+ # SimpleCov MUST be started before require 'rom-relation'
4
+ #
5
+ if ENV['COVERAGE'] == 'true'
6
+ require 'simplecov'
7
+ require 'coveralls'
8
8
 
9
- # Requires supporting files with custom matchers and macros, etc,
10
- # in ./support/ and its subdirectories.
11
- Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
10
+ SimpleCov::Formatter::HTMLFormatter,
11
+ Coveralls::SimpleCov::Formatter
12
+ ]
12
13
 
13
- RSpec.configure do |config|
14
+ SimpleCov.start do
15
+ command_name 'spec:unit'
14
16
 
17
+ add_filter 'config'
18
+ add_filter 'lib/rom/support'
19
+ add_filter 'spec'
20
+ end
15
21
  end
22
+
23
+ require 'active_model/better_errors'
24
+ require 'devtools/spec_helper'
@@ -0,0 +1,4 @@
1
+ # encoding: utf-8
2
+
3
+ # silence deprecation warnings
4
+ I18n.enforce_available_locales = false
@@ -1,12 +1,15 @@
1
+ # encoding: utf-8
2
+
3
+ # :nodoc:
1
4
  class BasicModel
2
5
  extend ActiveModel::Naming
3
6
  extend ActiveModel::Translation
4
7
  include ActiveModel::Validations
5
8
  include ActiveModel::Conversion
6
9
 
7
- def initialize(params={})
10
+ def initialize(params = {})
8
11
  params.each do |attr, value|
9
- self.public_send("#{attr}=", value)
12
+ public_send("#{attr}=", value)
10
13
  end
11
14
  end
12
15
 
@@ -15,14 +18,18 @@ class BasicModel
15
18
  end
16
19
  end
17
20
 
21
+ # :nodoc:
18
22
  class User < BasicModel
19
23
  attr_accessor :first_name, :last_name, :email
20
24
 
21
- validates :first_name, :last_name, presence: { message: "plz...?" }
25
+ validates :first_name, :last_name, presence: { message: 'plz...?' }
22
26
  end
23
27
 
28
+ # :nodoc:
24
29
  class Ruler < BasicModel
25
30
  attr_accessor :length
26
31
 
27
- validates_numericality_of :length, less_than_or_equal_to: 12, greater_than_or_equal_to: 4
32
+ validates_numericality_of :length,
33
+ less_than_or_equal_to: 12,
34
+ greater_than_or_equal_to: 4
28
35
  end
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+
3
+ #
4
+ # String
5
+ #
6
+ class String
7
+ def ==(other)
8
+ if other.is_a? ActiveModel::BetterErrors::ErrorMessage
9
+ return super other.to_s
10
+ else
11
+ super
12
+ end
13
+ end
14
+ end
@@ -1,7 +1,9 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'spec_helper'
2
4
 
3
- shared_examples_for "a delegated method" do
4
- let(:target_instance) { mock() }
5
+ shared_examples_for 'a delegated method' do
6
+ let(:target_instance) { double }
5
7
  before do
6
8
  target_instance.should_receive method
7
9
  instance.stub(target).and_return(target_instance)
@@ -10,9 +12,9 @@ shared_examples_for "a delegated method" do
10
12
  specify { instance.send method }
11
13
  end
12
14
 
13
- describe ActiveModel::ErrorCollecting::Emulation do
15
+ describe ActiveModel::BetterErrors::Emulation do
14
16
  subject(:instance) { klass.new }
15
- let(:klass) { Class.new { include ActiveModel::ErrorCollecting::Emulation } }
17
+ let(:klass) { Class.new { include ActiveModel::BetterErrors::Emulation } }
16
18
 
17
19
  delegation_map = {
18
20
  error_collection: [
@@ -38,8 +40,8 @@ describe ActiveModel::ErrorCollecting::Emulation do
38
40
  describe "delegating ##{method} to ##{target}" do
39
41
  let(:target) { target }
40
42
  let(:method) { method }
41
- it_should_behave_like "a delegated method"
43
+ it_should_behave_like 'a delegated method'
42
44
  end
43
45
  end
44
46
  end
45
- end
47
+ end