enumerize 0.8.0 → 2.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rspec +2 -0
- data/.travis.yml +27 -12
- data/CHANGELOG.md +141 -0
- data/Gemfile +5 -21
- data/Gemfile.global +20 -0
- data/Gemfile.mongo_mapper +7 -0
- data/Gemfile.rails42 +7 -0
- data/Gemfile.rails51 +7 -0
- data/README.md +185 -9
- data/Rakefile +2 -4
- data/enumerize.gemspec +1 -0
- data/lib/enumerize/activerecord.rb +68 -27
- data/lib/enumerize/attribute.rb +42 -10
- data/lib/enumerize/base.rb +28 -17
- data/lib/enumerize/hooks/formtastic.rb +3 -8
- data/lib/enumerize/hooks/sequel_dataset.rb +15 -0
- data/lib/enumerize/hooks/simple_form.rb +5 -11
- data/lib/enumerize/hooks/uniqueness.rb +3 -8
- data/lib/enumerize/integrations/rspec/matcher.rb +107 -26
- data/lib/enumerize/mongoid.rb +13 -0
- data/lib/enumerize/predicatable.rb +7 -16
- data/lib/enumerize/predicates.rb +3 -1
- data/lib/enumerize/scope/activerecord.rb +37 -0
- data/lib/enumerize/scope/mongoid.rb +35 -0
- data/lib/enumerize/scope/sequel.rb +40 -0
- data/lib/enumerize/sequel.rb +57 -0
- data/lib/enumerize/set.rb +18 -8
- data/lib/enumerize/value.rb +10 -9
- data/lib/enumerize/version.rb +3 -1
- data/lib/enumerize.rb +23 -1
- data/spec/enumerize/integrations/rspec/matcher_spec.rb +258 -0
- data/spec/spec_helper.rb +28 -0
- data/test/activerecord_test.rb +238 -10
- data/test/attribute_test.rb +22 -0
- data/test/base_test.rb +7 -7
- data/test/formtastic_test.rb +3 -12
- data/test/mongo_mapper_test.rb +7 -1
- data/test/mongoid_test.rb +63 -7
- data/test/multiple_test.rb +21 -0
- data/test/predicates_test.rb +6 -0
- data/test/sequel_test.rb +291 -0
- data/test/set_test.rb +14 -0
- data/test/simple_form_test.rb +0 -1
- data/test/support/mock_controller.rb +4 -0
- data/test/support/view_test_helper.rb +4 -0
- data/test/test_helper.rb +23 -2
- data/test/value_test.rb +51 -21
- metadata +40 -9
- data/Gemfile.rails4 +0 -23
- data/lib/enumerize/form_helper.rb +0 -23
- data/test/rspec_matcher_test.rb +0 -76
- data/test/rspec_spec.rb +0 -13
@@ -4,48 +4,34 @@ module Enumerize
|
|
4
4
|
super
|
5
5
|
|
6
6
|
_enumerize_module.dependent_eval do
|
7
|
-
if
|
8
|
-
if options[:scope]
|
9
|
-
_define_scope_methods!(name, options)
|
10
|
-
end
|
11
|
-
|
7
|
+
if self < ::ActiveRecord::Base
|
12
8
|
include InstanceMethods
|
13
9
|
|
10
|
+
const_get(:ActiveRecord_Relation).include(RelationMethods)
|
11
|
+
const_get(:ActiveRecord_AssociationRelation).include(RelationMethods)
|
12
|
+
const_get(:ActiveRecord_Associations_CollectionProxy).include(RelationMethods)
|
13
|
+
|
14
14
|
# Since Rails use `allocate` method on models and initializes them with `init_with` method.
|
15
15
|
# This way `initialize` method is not being called, but `after_initialize` callback always gets triggered.
|
16
16
|
after_initialize :_set_default_value_for_enumerized_attributes
|
17
17
|
|
18
18
|
# https://github.com/brainspec/enumerize/issues/111
|
19
19
|
require 'enumerize/hooks/uniqueness'
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
private
|
25
|
-
|
26
|
-
def _define_scope_methods!(name, options)
|
27
|
-
scope_name = options[:scope] == true ? "with_#{name}" : options[:scope]
|
28
|
-
|
29
|
-
define_singleton_method scope_name do |*values|
|
30
|
-
values = values.map { |value| enumerized_attributes[name].find_value(value).value }
|
31
|
-
values = values.first if values.size == 1
|
32
20
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
values = values.map { |value| enumerized_attributes[name].find_value(value).value }
|
39
|
-
where(arel_table[name].not_in(values))
|
21
|
+
unless options[:multiple]
|
22
|
+
decorate_attribute_type(name, :enumerize) do |subtype|
|
23
|
+
Type.new(enumerized_attributes[name], subtype)
|
24
|
+
end
|
25
|
+
end
|
40
26
|
end
|
41
27
|
end
|
42
28
|
end
|
43
29
|
|
44
30
|
module InstanceMethods
|
45
31
|
# https://github.com/brainspec/enumerize/issues/74
|
46
|
-
def write_attribute(attr_name, value)
|
32
|
+
def write_attribute(attr_name, value, *options)
|
47
33
|
if self.class.enumerized_attributes[attr_name]
|
48
|
-
_enumerized_values_for_validation[attr_name] = value
|
34
|
+
_enumerized_values_for_validation[attr_name.to_s] = value
|
49
35
|
end
|
50
36
|
|
51
37
|
super
|
@@ -55,13 +41,68 @@ module Enumerize
|
|
55
41
|
def becomes(klass)
|
56
42
|
became = super
|
57
43
|
klass.enumerized_attributes.each do |attr|
|
58
|
-
|
44
|
+
# Rescue when column associated to the enum does not exist.
|
45
|
+
begin
|
59
46
|
became.send("#{attr.name}=", send(attr.name))
|
47
|
+
rescue ActiveModel::MissingAttributeError
|
60
48
|
end
|
61
49
|
end
|
62
50
|
|
63
51
|
became
|
64
52
|
end
|
65
53
|
end
|
54
|
+
|
55
|
+
module RelationMethods
|
56
|
+
def update_all(updates)
|
57
|
+
if updates.is_a?(Hash)
|
58
|
+
enumerized_attributes.each do |attr|
|
59
|
+
next if updates[attr.name].blank? || attr.kind_of?(Enumerize::Multiple)
|
60
|
+
enumerize_value = attr.find_value(updates[attr.name])
|
61
|
+
updates[attr.name] = enumerize_value && enumerize_value.value
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
super(updates)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class Type < ActiveRecord::Type::Value
|
70
|
+
delegate :type, to: :@subtype
|
71
|
+
|
72
|
+
def initialize(attr, subtype)
|
73
|
+
@attr = attr
|
74
|
+
@subtype = subtype
|
75
|
+
end
|
76
|
+
|
77
|
+
def serialize(value)
|
78
|
+
v = @attr.find_value(value)
|
79
|
+
v && v.value
|
80
|
+
end
|
81
|
+
|
82
|
+
alias type_cast_for_database serialize
|
83
|
+
|
84
|
+
def deserialize(value)
|
85
|
+
@attr.find_value(value)
|
86
|
+
end
|
87
|
+
|
88
|
+
alias type_cast_from_database deserialize
|
89
|
+
|
90
|
+
def as_json(options = nil)
|
91
|
+
{attr: @attr.name, subtype: @subtype}.as_json(options)
|
92
|
+
end
|
93
|
+
|
94
|
+
def encode_with(coder)
|
95
|
+
coder[:class_name] = @attr.klass.name
|
96
|
+
coder[:attr_name] = @attr.name
|
97
|
+
coder[:subtype] = @subtype
|
98
|
+
end
|
99
|
+
|
100
|
+
def init_with(coder)
|
101
|
+
initialize(
|
102
|
+
coder[:class_name].constantize.enumerized_attributes[coder[:attr_name]],
|
103
|
+
coder[:subtype]
|
104
|
+
)
|
105
|
+
end
|
106
|
+
end
|
66
107
|
end
|
67
108
|
end
|
data/lib/enumerize/attribute.rb
CHANGED
@@ -1,15 +1,19 @@
|
|
1
1
|
module Enumerize
|
2
2
|
class Attribute
|
3
|
-
attr_reader :name, :values, :default_value, :i18n_scope
|
3
|
+
attr_reader :klass, :name, :values, :default_value, :i18n_scope
|
4
4
|
|
5
5
|
def initialize(klass, name, options={})
|
6
6
|
raise ArgumentError, ':in option is required' unless options[:in]
|
7
|
+
raise ArgumentError, ':scope option does not work with option :multiple' if options[:multiple] && options[:scope]
|
7
8
|
|
8
9
|
extend Multiple if options[:multiple]
|
9
10
|
|
10
11
|
@klass = klass
|
11
12
|
@name = name.to_sym
|
12
|
-
|
13
|
+
|
14
|
+
value_class = options.fetch(:value_class, Value)
|
15
|
+
@values = Array(options[:in]).map { |v| value_class.new(self, *v) }
|
16
|
+
|
13
17
|
@value_hash = Hash[@values.map { |v| [v.value.to_s, v] }]
|
14
18
|
@value_hash.merge! Hash[@values.map { |v| [v.to_s, v] }]
|
15
19
|
|
@@ -36,6 +40,10 @@ module Enumerize
|
|
36
40
|
@value_hash[value.to_s] unless value.nil?
|
37
41
|
end
|
38
42
|
|
43
|
+
def find_values(*values)
|
44
|
+
values.map { |value| find_value(value) }.compact
|
45
|
+
end
|
46
|
+
|
39
47
|
def i18n_scopes
|
40
48
|
@i18n_scopes ||= if i18n_scope
|
41
49
|
scopes = Array(i18n_scope)
|
@@ -67,6 +75,10 @@ module Enumerize
|
|
67
75
|
values.map { |v| [v.text, v.to_s] }
|
68
76
|
end
|
69
77
|
|
78
|
+
def respond_to_missing?(method, include_private=false)
|
79
|
+
@value_hash.include?(method.to_s) || super
|
80
|
+
end
|
81
|
+
|
70
82
|
def define_methods!(mod)
|
71
83
|
mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
72
84
|
def #{name}
|
@@ -84,8 +96,6 @@ module Enumerize
|
|
84
96
|
end
|
85
97
|
|
86
98
|
def #{name}=(new_value)
|
87
|
-
_enumerized_values_for_validation[:#{name}] = new_value.nil? ? nil : new_value.to_s
|
88
|
-
|
89
99
|
allowed_value_or_nil = self.class.enumerized_attributes[:#{name}].find_value(new_value)
|
90
100
|
allowed_value_or_nil = allowed_value_or_nil.value unless allowed_value_or_nil.nil?
|
91
101
|
|
@@ -96,6 +106,10 @@ module Enumerize
|
|
96
106
|
else
|
97
107
|
@#{name} = allowed_value_or_nil
|
98
108
|
end
|
109
|
+
|
110
|
+
_enumerized_values_for_validation['#{name}'] = new_value.nil? ? nil : new_value.to_s
|
111
|
+
|
112
|
+
allowed_value_or_nil
|
99
113
|
end
|
100
114
|
|
101
115
|
def #{name}_text
|
@@ -107,9 +121,27 @@ module Enumerize
|
|
107
121
|
end
|
108
122
|
RUBY
|
109
123
|
end
|
124
|
+
|
125
|
+
private
|
126
|
+
|
127
|
+
def method_missing(method)
|
128
|
+
if @value_hash.include?(method.to_s)
|
129
|
+
find_value(method)
|
130
|
+
else
|
131
|
+
super
|
132
|
+
end
|
133
|
+
end
|
110
134
|
end
|
111
135
|
|
112
136
|
module Multiple
|
137
|
+
def find_default_value(value)
|
138
|
+
if value.respond_to?(:call)
|
139
|
+
value
|
140
|
+
else
|
141
|
+
find_values(*value)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
113
145
|
def define_methods!(mod)
|
114
146
|
mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
115
147
|
def #{name}
|
@@ -131,19 +163,19 @@ module Enumerize
|
|
131
163
|
end
|
132
164
|
|
133
165
|
def #{name}=(values)
|
134
|
-
_enumerized_values_for_validation[:#{name}] = values.respond_to?(:map) ? values.map(&:to_s) : values
|
135
|
-
|
136
166
|
@_#{name}_enumerized_set = Enumerize::Set.new(self, self.class.enumerized_attributes[:#{name}], values)
|
137
|
-
|
167
|
+
raw_values = #{name}.values.map(&:value)
|
138
168
|
|
139
169
|
if defined?(super)
|
140
|
-
super
|
170
|
+
super raw_values
|
141
171
|
elsif respond_to?(:write_attribute, true)
|
142
|
-
write_attribute '#{name}',
|
172
|
+
write_attribute '#{name}', raw_values
|
143
173
|
else
|
144
|
-
@#{name} =
|
174
|
+
@#{name} = raw_values
|
145
175
|
end
|
146
176
|
|
177
|
+
_enumerized_values_for_validation['#{name}'] = values.respond_to?(:map) ? values.reject(&:blank?).map(&:to_s) : values
|
178
|
+
|
147
179
|
#{name}
|
148
180
|
end
|
149
181
|
RUBY
|
data/lib/enumerize/base.rb
CHANGED
@@ -2,6 +2,7 @@ module Enumerize
|
|
2
2
|
module Base
|
3
3
|
def self.included(base)
|
4
4
|
base.extend ClassMethods
|
5
|
+
base.singleton_class.prepend ClassMethods::Hook
|
5
6
|
|
6
7
|
if base.respond_to?(:validate)
|
7
8
|
base.validate :_validate_enumerized_attributes
|
@@ -28,9 +29,11 @@ module Enumerize
|
|
28
29
|
@enumerized_attributes ||= AttributeMap.new
|
29
30
|
end
|
30
31
|
|
31
|
-
|
32
|
-
|
33
|
-
|
32
|
+
module Hook
|
33
|
+
def inherited(subclass)
|
34
|
+
enumerized_attributes.add_dependant subclass.enumerized_attributes
|
35
|
+
super subclass
|
36
|
+
end
|
34
37
|
end
|
35
38
|
|
36
39
|
private
|
@@ -50,10 +53,14 @@ module Enumerize
|
|
50
53
|
end
|
51
54
|
|
52
55
|
def read_attribute_for_validation(key)
|
56
|
+
key = key.to_s
|
57
|
+
|
53
58
|
if _enumerized_values_for_validation.has_key?(key)
|
54
59
|
_enumerized_values_for_validation[key]
|
55
|
-
|
60
|
+
elsif defined?(super)
|
56
61
|
super
|
62
|
+
else
|
63
|
+
send(key)
|
57
64
|
end
|
58
65
|
end
|
59
66
|
|
@@ -78,22 +85,26 @@ module Enumerize
|
|
78
85
|
|
79
86
|
def _set_default_value_for_enumerized_attributes
|
80
87
|
self.class.enumerized_attributes.each do |attr|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
+
next if attr.default_value.nil?
|
89
|
+
begin
|
90
|
+
if respond_to?(attr.name)
|
91
|
+
attr_value = public_send(attr.name)
|
92
|
+
else
|
93
|
+
next
|
94
|
+
end
|
88
95
|
|
89
|
-
|
90
|
-
value = attr.default_value
|
96
|
+
value_for_validation = _enumerized_values_for_validation[attr.name.to_s]
|
91
97
|
|
92
|
-
if
|
93
|
-
value =
|
94
|
-
|
98
|
+
if (!attr_value || attr_value.empty?) && (!value_for_validation || value_for_validation.empty?)
|
99
|
+
value = attr.default_value
|
100
|
+
|
101
|
+
if value.respond_to?(:call)
|
102
|
+
value = value.arity == 0 ? value.call : value.call(self)
|
103
|
+
end
|
95
104
|
|
96
|
-
|
105
|
+
public_send("#{attr.name}=", value)
|
106
|
+
end
|
107
|
+
rescue ActiveModel::MissingAttributeError
|
97
108
|
end
|
98
109
|
end
|
99
110
|
end
|
@@ -3,13 +3,8 @@ require 'active_support/concern'
|
|
3
3
|
module Enumerize
|
4
4
|
module Hooks
|
5
5
|
module FormtasticFormBuilderExtension
|
6
|
-
extend ActiveSupport::Concern
|
7
6
|
|
8
|
-
|
9
|
-
alias_method_chain :input, :enumerize
|
10
|
-
end
|
11
|
-
|
12
|
-
def input_with_enumerize(method, options={})
|
7
|
+
def input(method, options={})
|
13
8
|
klass = object.class
|
14
9
|
|
15
10
|
if klass.respond_to?(:enumerized_attributes) && (attr = klass.enumerized_attributes[method])
|
@@ -20,10 +15,10 @@ module Enumerize
|
|
20
15
|
end
|
21
16
|
end
|
22
17
|
|
23
|
-
|
18
|
+
super(method, options)
|
24
19
|
end
|
25
20
|
end
|
26
21
|
end
|
27
22
|
end
|
28
23
|
|
29
|
-
::Formtastic::FormBuilder.send :
|
24
|
+
::Formtastic::FormBuilder.send :prepend, Enumerize::Hooks::FormtasticFormBuilderExtension
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Enumerize
|
2
|
+
module Hooks
|
3
|
+
module SequelDataset
|
4
|
+
def literal_append(sql, v)
|
5
|
+
if v.is_a?(Enumerize::Value)
|
6
|
+
super(sql, v.value)
|
7
|
+
else
|
8
|
+
super(sql, v)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
::Sequel::Dataset.send :prepend, Enumerize::Hooks::SequelDataset
|
@@ -3,21 +3,15 @@ require 'active_support/concern'
|
|
3
3
|
module Enumerize
|
4
4
|
module Hooks
|
5
5
|
module SimpleFormBuilderExtension
|
6
|
-
extend ActiveSupport::Concern
|
7
6
|
|
8
|
-
|
9
|
-
alias_method_chain :input, :enumerize
|
10
|
-
alias_method_chain :input_field, :enumerize
|
11
|
-
end
|
12
|
-
|
13
|
-
def input_with_enumerize(attribute_name, options={}, &block)
|
7
|
+
def input(attribute_name, options={}, &block)
|
14
8
|
add_input_options_for_enumerized_attribute(attribute_name, options)
|
15
|
-
|
9
|
+
super(attribute_name, options, &block)
|
16
10
|
end
|
17
11
|
|
18
|
-
def
|
12
|
+
def input_field(attribute_name, options={})
|
19
13
|
add_input_options_for_enumerized_attribute(attribute_name, options)
|
20
|
-
|
14
|
+
super(attribute_name, options)
|
21
15
|
end
|
22
16
|
|
23
17
|
private
|
@@ -37,4 +31,4 @@ module Enumerize
|
|
37
31
|
end
|
38
32
|
end
|
39
33
|
|
40
|
-
::SimpleForm::FormBuilder.send :
|
34
|
+
::SimpleForm::FormBuilder.send :prepend, Enumerize::Hooks::SimpleFormBuilderExtension
|
@@ -3,21 +3,16 @@ require 'active_support/concern'
|
|
3
3
|
module Enumerize
|
4
4
|
module Hooks
|
5
5
|
module UniquenessValidator
|
6
|
-
extend ActiveSupport::Concern
|
7
6
|
|
8
|
-
|
9
|
-
alias_method_chain :validate_each, :enumerize
|
10
|
-
end
|
11
|
-
|
12
|
-
def validate_each_with_enumerize(record, name, value)
|
7
|
+
def validate_each(record, name, value)
|
13
8
|
if record.class.respond_to?(:enumerized_attributes) && (attr = record.class.enumerized_attributes[name])
|
14
9
|
value = attr.find_value(value).try(:value)
|
15
10
|
end
|
16
11
|
|
17
|
-
|
12
|
+
super(record, name, value)
|
18
13
|
end
|
19
14
|
end
|
20
15
|
end
|
21
16
|
end
|
22
17
|
|
23
|
-
::ActiveRecord::Validations::UniquenessValidator.send :
|
18
|
+
::ActiveRecord::Validations::UniquenessValidator.send :prepend, Enumerize::Hooks::UniquenessValidator
|
@@ -2,37 +2,57 @@ module Enumerize
|
|
2
2
|
module Integrations
|
3
3
|
module RSpec
|
4
4
|
class Matcher
|
5
|
-
attr_accessor :attr, :values, :subject, :default
|
6
5
|
|
7
|
-
def initialize(
|
8
|
-
self.
|
6
|
+
def initialize(expected_attr)
|
7
|
+
self.expected_attr = expected_attr
|
9
8
|
end
|
10
9
|
|
11
|
-
def in(*
|
12
|
-
self.
|
10
|
+
def in(*expected_values)
|
11
|
+
self.expected_values = expected_values.flatten
|
13
12
|
self
|
14
13
|
end
|
15
14
|
|
16
|
-
def with_default(
|
17
|
-
self.
|
15
|
+
def with_default(expected_default)
|
16
|
+
self.expected_default = expected_default.to_s
|
18
17
|
self
|
19
18
|
end
|
20
19
|
|
21
|
-
def
|
22
|
-
|
23
|
-
|
20
|
+
def with_i18n_scope(expected_i18n_scope)
|
21
|
+
self.expected_i18n_scope = expected_i18n_scope
|
22
|
+
self
|
23
|
+
end
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
def with_predicates(expected_predicates)
|
26
|
+
self.expected_predicates = expected_predicates
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
def with_multiple(expected_multiple)
|
31
|
+
self.expected_multiple = expected_multiple
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def with_scope(expected_scope)
|
36
|
+
self.expected_scope = expected_scope
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
def failure_message
|
41
|
+
"Expected #{expectation}"
|
42
|
+
end
|
29
43
|
|
30
|
-
|
44
|
+
def failure_message_when_negated
|
45
|
+
"Did not expect #{expectation}"
|
31
46
|
end
|
32
47
|
|
33
48
|
def description
|
34
|
-
description = "enumerize :#{
|
35
|
-
description += "
|
49
|
+
description = "define enumerize :#{expected_attr}"
|
50
|
+
description += " in: #{quote_values(expected_values)}" if expected_values
|
51
|
+
description += " with #{expected_default.inspect} as default value" if expected_default
|
52
|
+
description += " i18n_scope: #{expected_i18n_scope.inspect}" if expected_i18n_scope
|
53
|
+
description += " predicates: #{expected_predicates.inspect}" if expected_predicates
|
54
|
+
description += " multiple: #{expected_multiple.inspect}" if expected_multiple
|
55
|
+
description += " scope: #{expected_scope.inspect}" if expected_scope
|
36
56
|
|
37
57
|
description
|
38
58
|
end
|
@@ -41,36 +61,97 @@ module Enumerize
|
|
41
61
|
self.subject = subject
|
42
62
|
matches = true
|
43
63
|
|
44
|
-
matches &=
|
45
|
-
matches &=
|
64
|
+
matches &= matches_attribute?
|
65
|
+
matches &= matches_values? if expected_values
|
66
|
+
matches &= matches_default_value? if expected_default
|
67
|
+
matches &= matches_i18n_scope? if expected_i18n_scope
|
68
|
+
matches &= matches_predicates? if expected_predicates
|
69
|
+
matches &= matches_multiple? if expected_multiple
|
70
|
+
matches &= matches_scope? if expected_scope
|
46
71
|
|
47
72
|
matches
|
48
73
|
end
|
49
74
|
|
50
75
|
private
|
76
|
+
attr_accessor :expected_attr, :expected_values, :subject, :expected_default,
|
77
|
+
:expected_i18n_scope, :expected_predicates, :expected_multiple,
|
78
|
+
:expected_scope
|
51
79
|
|
52
|
-
def
|
53
|
-
|
80
|
+
def expectation
|
81
|
+
"#{subject.class.name} to #{description}"
|
82
|
+
end
|
83
|
+
|
84
|
+
def matches_attribute?
|
85
|
+
attributes.present?
|
86
|
+
end
|
87
|
+
|
88
|
+
def matches_values?
|
89
|
+
matches_array_values? || matches_hash_values?
|
90
|
+
end
|
91
|
+
|
92
|
+
def matches_array_values?
|
93
|
+
sorted_values == enumerized_values
|
94
|
+
end
|
95
|
+
|
96
|
+
def matches_hash_values?
|
97
|
+
return unless expected_values.first.is_a?(Hash)
|
98
|
+
expected_values.first.all? { |k, v| enumerized_value_hash[k.to_s] == v; }
|
54
99
|
end
|
55
100
|
|
56
101
|
def matches_default_value?
|
57
|
-
|
102
|
+
expected_default == enumerized_default
|
103
|
+
end
|
104
|
+
|
105
|
+
def matches_i18n_scope?
|
106
|
+
attributes.i18n_scope == expected_i18n_scope
|
107
|
+
end
|
108
|
+
|
109
|
+
def matches_predicates?
|
110
|
+
if expected_predicates.is_a?(TrueClass)
|
111
|
+
subject.respond_to?("#{sorted_values.first}?")
|
112
|
+
else
|
113
|
+
subject.respond_to?("#{expected_attr}_#{attributes.values.first}?")
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def matches_multiple?
|
118
|
+
subject.public_send(expected_attr).is_a?(Enumerize::Set)
|
119
|
+
end
|
120
|
+
|
121
|
+
def matches_scope?
|
122
|
+
if expected_scope.is_a?(TrueClass)
|
123
|
+
subject_class.respond_to?("with_#{expected_attr}")
|
124
|
+
else
|
125
|
+
subject_class.respond_to?(expected_scope[:scope])
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def sorted_values
|
130
|
+
@sorted_values ||=expected_values.map(&:to_s).sort
|
58
131
|
end
|
59
132
|
|
60
133
|
def enumerized_values
|
61
|
-
@enumerized_values ||= attributes
|
134
|
+
@enumerized_values ||= attributes.values.sort
|
62
135
|
end
|
63
136
|
|
64
137
|
def enumerized_default
|
65
|
-
@enumerized_default ||= attributes
|
138
|
+
@enumerized_default ||= attributes.default_value
|
139
|
+
end
|
140
|
+
|
141
|
+
def enumerized_value_hash
|
142
|
+
@enumerized_value_hash ||= attributes.instance_variable_get('@value_hash')
|
66
143
|
end
|
67
144
|
|
68
145
|
def attributes
|
69
|
-
|
146
|
+
subject_class.enumerized_attributes.attributes[expected_attr.to_s]
|
147
|
+
end
|
148
|
+
|
149
|
+
def subject_class
|
150
|
+
@subject_class ||= subject.class
|
70
151
|
end
|
71
152
|
|
72
153
|
def quote_values(values)
|
73
|
-
|
154
|
+
sorted_values.map(&:inspect).join(', ')
|
74
155
|
end
|
75
156
|
end
|
76
157
|
end
|
@@ -1,29 +1,20 @@
|
|
1
1
|
module Enumerize
|
2
2
|
module Predicatable
|
3
|
-
def method_missing(method, *args, &block)
|
4
|
-
if boolean_method?(method)
|
5
|
-
define_query_methods
|
6
|
-
send(method, *args, &block)
|
7
|
-
else
|
8
|
-
super
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
3
|
def respond_to_missing?(method, include_private=false)
|
13
|
-
|
4
|
+
predicate_method?(method) || super
|
14
5
|
end
|
15
6
|
|
16
7
|
private
|
17
8
|
|
18
|
-
def
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
9
|
+
def method_missing(method, *args, &block)
|
10
|
+
if predicate_method?(method)
|
11
|
+
predicate_call(method[0..-2], *args, &block)
|
12
|
+
else
|
13
|
+
super
|
23
14
|
end
|
24
15
|
end
|
25
16
|
|
26
|
-
def
|
17
|
+
def predicate_method?(method)
|
27
18
|
method[-1] == '?' && @attr.values.include?(method[0..-2])
|
28
19
|
end
|
29
20
|
end
|
data/lib/enumerize/predicates.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'active_support/core_ext/module/delegation'
|
2
|
+
|
1
3
|
module Enumerize
|
2
4
|
# Predicate methods.
|
3
5
|
#
|
@@ -61,7 +63,7 @@ module Enumerize
|
|
61
63
|
end
|
62
64
|
|
63
65
|
def names
|
64
|
-
values.map { |v| "#{v}?" }
|
66
|
+
values.map { |v| "#{v.tr('-', '_')}?" }
|
65
67
|
end
|
66
68
|
|
67
69
|
def build(klass)
|