enumerations 1.3.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/Readme.md +98 -15
- data/enumerations.gemspec +6 -3
- data/lib/enumerations.rb +67 -35
- data/lib/enumerations/base.rb +16 -109
- data/lib/enumerations/finder_methods.rb +38 -0
- data/lib/enumerations/reflection.rb +8 -4
- data/lib/enumerations/value.rb +80 -0
- data/lib/enumerations/version.rb +2 -2
- data/test/base_test.rb +33 -36
- data/test/database_helper.rb +15 -0
- data/test/enumerations_test.rb +47 -0
- data/test/reflection_test.rb +32 -5
- data/test/test_helper.rb +24 -7
- data/test/value_test.rb +63 -0
- data/test/version_test.rb +1 -1
- metadata +55 -7
- data/.travis.yml +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a75cec2684b73e9e83a7b60ddd48b95ac01fd991
|
4
|
+
data.tar.gz: 822d8484b921612c31deadd8491994ad1e22a66d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3df5039cf8d021b312058982c26edee6d8e24c56bd05a4f9cba6db2f55adef3f311d3181a544e774cd3607750d0c813e4935fcbf3079608eec3a7a142a546d4d
|
7
|
+
data.tar.gz: 04c31625eecf7f4276bf11d673aa66d2290ca086d49d728502cde004166a32c7a2ff051367356299feeee8399afc0b486551b00694b51fe47b69d1e72aaf05d1
|
data/Readme.md
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
Enumerations
|
2
2
|
============
|
3
3
|
|
4
|
-
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/enumerations.svg)](https://badge.fury.io/rb/enumerations)
|
5
|
+
[![Code Climate](https://codeclimate.com/github/infinum/enumerations/badges/gpa.svg)](https://codeclimate.com/github/infinum/enumerations)
|
6
|
+
[![Build Status](https://semaphoreci.com/api/v1/infinum/enumerations/branches/master/shields_badge.svg)](https://semaphoreci.com/infinum/enumerations)
|
7
|
+
[![Test Coverage](https://codeclimate.com/github/infinum/enumerations/badges/coverage.svg)](https://codeclimate.com/github/infinum/enumerations/coverage)
|
5
8
|
|
6
|
-
|
9
|
+
Rails plugin for enumerations in ActiveRecord models.
|
7
10
|
|
8
11
|
Installation
|
9
12
|
============
|
@@ -17,10 +20,12 @@ gem 'enumerations'
|
|
17
20
|
Usage
|
18
21
|
=====
|
19
22
|
|
23
|
+
## Defining enumerations
|
24
|
+
|
20
25
|
Create a model for your enumerations:
|
21
26
|
|
22
27
|
```ruby
|
23
|
-
class Status <
|
28
|
+
class Status < Enumerations::Base
|
24
29
|
values draft: { id: 1, name: 'Draft' },
|
25
30
|
review_pending: { id: 2, name: 'Review pending' },
|
26
31
|
published: { id: 3, name: 'Published' }
|
@@ -30,7 +35,7 @@ end
|
|
30
35
|
Or you can use `value` method for defining your enumerations:
|
31
36
|
|
32
37
|
```ruby
|
33
|
-
class Status <
|
38
|
+
class Status < Enumerations::Base
|
34
39
|
value :draft, id: 1, name: 'Draft'
|
35
40
|
value :review_pending, id: 2, name: 'Review pending'
|
36
41
|
value :published, id: 3, name: 'Published'
|
@@ -46,16 +51,21 @@ class Post < ActiveRecord::Base
|
|
46
51
|
end
|
47
52
|
```
|
48
53
|
|
49
|
-
You can pass attributes to specify which
|
54
|
+
You can pass attributes to specify which enumeration and which column to use:
|
50
55
|
|
51
56
|
```ruby
|
52
57
|
class Post < ActiveRecord::Base
|
53
58
|
enumeration :status,
|
54
|
-
foreign_key: :post_status_id,
|
55
|
-
class_name: Post::Status
|
59
|
+
foreign_key: :post_status_id, # specifies which column to use
|
60
|
+
class_name: Post::Status # specifies the class of the enumerator
|
56
61
|
validates :post_status_id, presence: true
|
57
62
|
end
|
58
63
|
```
|
64
|
+
Attribute `foreign_key` you can pass as a `String` or a `Symbol`. Attribute `class_name` can be set as a `String`, a `Symbol` or a `String`.
|
65
|
+
|
66
|
+
|
67
|
+
|
68
|
+
## Setting enumeration value to objects
|
59
69
|
|
60
70
|
Set enumerations, find enumerations by `symbol`:
|
61
71
|
|
@@ -71,20 +81,56 @@ Or you can set enumerations on this way:
|
|
71
81
|
@post.status = Status.draft
|
72
82
|
```
|
73
83
|
|
84
|
+
Also, you can set enumeration value like this:
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
@post.status_draft!
|
88
|
+
```
|
89
|
+
|
90
|
+
> When you include enumerations into your model, you'll get methods for setting each enumeration value. Each method name is consists from enumeration name and enumeration value name with **!** at the end. Examples:
|
91
|
+
|
92
|
+
```ruby
|
93
|
+
class Post < ActiveRecord::Base
|
94
|
+
enumeration :status
|
95
|
+
end
|
96
|
+
|
97
|
+
@post.status_draft!
|
98
|
+
```
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
class User < ActiveRecord::Base
|
102
|
+
enumeration :role
|
103
|
+
end
|
104
|
+
|
105
|
+
@user.role_admin!
|
106
|
+
```
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
class User < ActiveRecord::Base
|
110
|
+
enumeration :type, class_name: Role
|
111
|
+
end
|
112
|
+
|
113
|
+
@user.type_editor!
|
114
|
+
```
|
115
|
+
|
116
|
+
|
117
|
+
|
118
|
+
## Finder methods
|
119
|
+
|
74
120
|
Find enumerations by `id`:
|
75
121
|
|
76
122
|
```ruby
|
77
|
-
@post.status = Status.find(2)
|
123
|
+
@post.status = Status.find(2) # => Review pending
|
78
124
|
@post.save
|
79
125
|
```
|
80
126
|
|
81
127
|
Compare enumerations:
|
82
128
|
|
83
129
|
```ruby
|
84
|
-
@post.status == :published
|
85
|
-
@post.status == 3
|
86
|
-
@post.status == Status.find(:published)
|
87
|
-
@post.status.published?
|
130
|
+
@post.status == :published # => true
|
131
|
+
@post.status == 3 # => true
|
132
|
+
@post.status == Status.find(:published) # => true
|
133
|
+
@post.status.published? # => true
|
88
134
|
```
|
89
135
|
|
90
136
|
Get all enumerations:
|
@@ -93,6 +139,43 @@ Get all enumerations:
|
|
93
139
|
Status.all
|
94
140
|
```
|
95
141
|
|
142
|
+
|
143
|
+
|
144
|
+
## Scopes on model
|
145
|
+
|
146
|
+
With enumerations, you'll get scope for each enumeration value in the
|
147
|
+
following format:
|
148
|
+
|
149
|
+
```ruby
|
150
|
+
with_#{enumeration_name}_#{enumeration_value_name}
|
151
|
+
```
|
152
|
+
|
153
|
+
Examples:
|
154
|
+
|
155
|
+
```ruby
|
156
|
+
class Post < ActiveRecord::Base
|
157
|
+
enumeration :status
|
158
|
+
end
|
159
|
+
|
160
|
+
Post.with_status_draft # => <#ActiveRecord::Relation []>
|
161
|
+
Post.with_status_review_pending # => <#ActiveRecord::Relation []>
|
162
|
+
```
|
163
|
+
|
164
|
+
```ruby
|
165
|
+
class Post < ActiveRecord::Base
|
166
|
+
enumeration :my_status, class_name: Status
|
167
|
+
end
|
168
|
+
|
169
|
+
Post.with_my_status_draft # => <#ActiveRecord::Relation []>
|
170
|
+
Post.with_my_status_review_pending # => <#ActiveRecord::Relation []>
|
171
|
+
```
|
172
|
+
|
173
|
+
Each scope returns all records with specified enumeration value.
|
174
|
+
|
175
|
+
|
176
|
+
|
177
|
+
## Forms usage
|
178
|
+
|
96
179
|
Use in forms:
|
97
180
|
|
98
181
|
```ruby
|
@@ -108,7 +191,7 @@ Advance Usage
|
|
108
191
|
Except `id` and `name` you can specify other attributes to your enumerations:
|
109
192
|
|
110
193
|
```ruby
|
111
|
-
class Status <
|
194
|
+
class Status < Enumerations::Base
|
112
195
|
value :draft, id: 1, name: 'Draft'
|
113
196
|
value :review_pending, id: 2, name: 'Review pending', description: 'Some description...'
|
114
197
|
value :published, id: 3, name: 'Published'
|
@@ -118,8 +201,8 @@ end
|
|
118
201
|
Every enumeration has `id`, `name` and `description` methods. If you call method that is not in attribute list for enumeration, it will return `nil`.
|
119
202
|
|
120
203
|
```ruby
|
121
|
-
Status.review_pending.description
|
122
|
-
Status.draft.description
|
204
|
+
Status.review_pending.description # => 'Some description...'
|
205
|
+
Status.draft.description # => nil
|
123
206
|
```
|
124
207
|
|
125
208
|
Author
|
data/enumerations.gemspec
CHANGED
@@ -2,9 +2,9 @@ require File.expand_path('../lib/enumerations/version', __FILE__)
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = 'enumerations'
|
5
|
-
s.version =
|
6
|
-
s.date = '
|
7
|
-
s.summary =
|
5
|
+
s.version = Enumerations::VERSION
|
6
|
+
s.date = '2016-08-15'
|
7
|
+
s.summary = 'Enumerations for ActiveRecord!'
|
8
8
|
s.description = 'Extends ActiveRecord with enumeration capabilites.'
|
9
9
|
s.authors = ['Tomislav Car', 'Nikica Jokic', 'Nikola Santic']
|
10
10
|
s.email = ['tomislav@infinum.hr', 'nikica.jokic@infinum.hr', 'nikola.santic@infinum.hr']
|
@@ -13,6 +13,9 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.add_dependency 'activerecord'
|
14
14
|
s.add_dependency 'activesupport'
|
15
15
|
s.add_development_dependency 'pry-byebug'
|
16
|
+
s.add_development_dependency 'rake'
|
17
|
+
s.add_development_dependency 'codeclimate-test-reporter'
|
18
|
+
s.add_development_dependency 'sqlite3'
|
16
19
|
|
17
20
|
s.files = `git ls-files`.split("\n")
|
18
21
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
data/lib/enumerations.rb
CHANGED
@@ -7,8 +7,7 @@ require 'enumerations/version'
|
|
7
7
|
require 'enumerations/base'
|
8
8
|
require 'enumerations/reflection'
|
9
9
|
|
10
|
-
|
11
|
-
module Enumeration
|
10
|
+
module Enumerations
|
12
11
|
extend ActiveSupport::Concern
|
13
12
|
|
14
13
|
included do
|
@@ -27,17 +26,15 @@ module Enumeration
|
|
27
26
|
# end
|
28
27
|
#
|
29
28
|
# user.role_id = 1
|
30
|
-
# user.role => #<
|
29
|
+
# user.role => #<Enumerations::Value: @base=Role, @symbol=:admin...>
|
31
30
|
#
|
32
31
|
# user.role = Role.staff
|
33
32
|
# user.role_id => 2
|
34
33
|
#
|
35
|
-
# TODO: add documentation for foreign_key and class_name
|
36
34
|
def enumeration(name, options = {})
|
37
|
-
|
38
|
-
options[:class_name] ||= name.to_s.camelize
|
35
|
+
reflection = Reflection.new(name, options)
|
39
36
|
|
40
|
-
add_enumeration(
|
37
|
+
add_enumeration(reflection)
|
41
38
|
end
|
42
39
|
|
43
40
|
# Output all the enumerations that this model has defined
|
@@ -47,8 +44,9 @@ module Enumeration
|
|
47
44
|
# Example:
|
48
45
|
#
|
49
46
|
# User.reflect_on_all_enumerations => # [
|
50
|
-
# #<
|
51
|
-
# #<
|
47
|
+
# #<Enumerations::Reflection: @name=:role...>,
|
48
|
+
# #<Enumerations::Reflection: @name=:status...>
|
49
|
+
# ]
|
52
50
|
#
|
53
51
|
def reflect_on_all_enumerations
|
54
52
|
_enumerations
|
@@ -56,41 +54,75 @@ module Enumeration
|
|
56
54
|
|
57
55
|
private
|
58
56
|
|
59
|
-
def add_enumeration(
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
# user.role_id = 1
|
65
|
-
# user.role => #<Enumeration::Value:0x007fff45d7ec30 @base=Role, @symbol=:admin...>
|
66
|
-
#
|
67
|
-
define_method name do
|
68
|
-
enumerator_class = if options[:class_name].is_a?(Class)
|
69
|
-
options[:class_name]
|
70
|
-
else
|
71
|
-
options[:class_name].constantize
|
72
|
-
end
|
57
|
+
def add_enumeration(reflection)
|
58
|
+
define_getter_method(reflection)
|
59
|
+
define_setter_method(reflection)
|
60
|
+
define_bang_methods(reflection)
|
61
|
+
define_scopes(reflection)
|
73
62
|
|
74
|
-
|
63
|
+
self._enumerations += [reflection]
|
64
|
+
end
|
65
|
+
|
66
|
+
# Getter for belongs_to
|
67
|
+
#
|
68
|
+
# Example:
|
69
|
+
#
|
70
|
+
# user.role_id = 1
|
71
|
+
# user.role => #<Enumerations::Value: @base=Role, @symbol=:admin...>
|
72
|
+
#
|
73
|
+
def define_getter_method(reflection)
|
74
|
+
define_method(reflection.name) do
|
75
|
+
reflection.enumerator_class.find(send(reflection.foreign_key))
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Setter for belongs_to
|
80
|
+
#
|
81
|
+
# Example:
|
82
|
+
#
|
83
|
+
# user.role = Role.admin
|
84
|
+
# user.role_id => 1
|
85
|
+
#
|
86
|
+
def define_setter_method(reflection)
|
87
|
+
define_method("#{reflection.name}=") do |other|
|
88
|
+
send("#{reflection.foreign_key}=", other.id)
|
75
89
|
end
|
90
|
+
end
|
76
91
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
92
|
+
# Add bang methods for setting all enumeration values.
|
93
|
+
# All methods are prefixed with enumeration name.
|
94
|
+
#
|
95
|
+
# Example:
|
96
|
+
#
|
97
|
+
# user.role_admin!
|
98
|
+
# user.role => #<Enumerations::Value: @base=Role, @symbol=:admin...>
|
99
|
+
#
|
100
|
+
def define_bang_methods(reflection)
|
101
|
+
reflection.enumerator_class.all.each do |enumeration|
|
102
|
+
define_method("#{reflection.name}_#{enumeration.to_sym}!") do
|
103
|
+
send("#{reflection.name}=", enumeration)
|
104
|
+
end
|
86
105
|
end
|
106
|
+
end
|
87
107
|
|
88
|
-
|
108
|
+
# Scopes for enumerated ActiveRecord model.
|
109
|
+
# Format of scope name is with_#{enumeration_name}_#{enumeration_value_name}.
|
110
|
+
#
|
111
|
+
# Example:
|
112
|
+
#
|
113
|
+
# User.with_role_admin => <#ActiveRecord::Relation []>
|
114
|
+
# User.with_role_editor => <#ActiveRecord::Relation []>
|
115
|
+
#
|
116
|
+
def define_scopes(reflection)
|
117
|
+
reflection.enumerator_class.all.each do |enumeration|
|
118
|
+
scope "with_#{reflection.name}_#{enumeration.symbol}",
|
119
|
+
-> { where(reflection.foreign_key => enumeration.id) }
|
120
|
+
end
|
89
121
|
end
|
90
122
|
end
|
91
123
|
end
|
92
124
|
|
93
125
|
# Extend ActiveRecord with Enumeration capabilites
|
94
126
|
ActiveSupport.on_load(:active_record) do
|
95
|
-
include
|
127
|
+
include Enumerations
|
96
128
|
end
|
data/lib/enumerations/base.rb
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
require 'active_support/core_ext/class/attribute'
|
2
2
|
require 'active_support/core_ext/string/inflections'
|
3
|
+
require 'enumerations/value'
|
4
|
+
require 'enumerations/finder_methods'
|
3
5
|
|
4
|
-
module
|
6
|
+
module Enumerations
|
5
7
|
class Base
|
8
|
+
extend Enumerations::FinderMethods
|
9
|
+
include Enumerations::Value
|
10
|
+
|
6
11
|
class_attribute :_values, :_symbol_index
|
7
12
|
self._values = {}
|
8
13
|
self._symbol_index = {}
|
@@ -13,13 +18,11 @@ module Enumeration
|
|
13
18
|
#
|
14
19
|
# value :admin, id: 1, name: 'Admin', description: 'Some description...'
|
15
20
|
#
|
16
|
-
# Role.admin.id
|
17
|
-
# Role.find(:admin).name
|
18
|
-
# Role.find(1).description
|
21
|
+
# Role.admin.id => # 1
|
22
|
+
# Role.find(:admin).name => # "Admin"
|
23
|
+
# Role.find(1).description => # "Some description..."
|
19
24
|
#
|
20
25
|
def self.value(symbol, attributes)
|
21
|
-
# TODO: make this errors better if needed
|
22
|
-
# TODO: test this errors
|
23
26
|
raise 'Enumeration id is required' if attributes[:id].nil?
|
24
27
|
raise "Duplicate symbol #{symbol}" if find(symbol)
|
25
28
|
raise "Duplicate id #{attributes[:id]}" if find(attributes[:id])
|
@@ -31,8 +34,8 @@ module Enumeration
|
|
31
34
|
#
|
32
35
|
# Example:
|
33
36
|
#
|
34
|
-
# Role.admin => #<
|
35
|
-
# Role.staff => #<
|
37
|
+
# Role.admin => #<Enumerations::Value: @base=Role, @symbol=:admin...>
|
38
|
+
# Role.staff => #<Enumerations::Value: @base=Role, @symbol=:staff...>
|
36
39
|
#
|
37
40
|
singleton_class.send(:define_method, symbol) do
|
38
41
|
find(symbol)
|
@@ -71,117 +74,21 @@ module Enumeration
|
|
71
74
|
#
|
72
75
|
# Example:
|
73
76
|
#
|
74
|
-
# Role.all => # [#<
|
75
|
-
# #<
|
76
|
-
# #<
|
77
|
+
# Role.all => # [#<Enumerations::Value: @base=Role, @symbol=:admin...>,
|
78
|
+
# #<Enumerations::Value: @base=Role, @symbol=:manager...>,
|
79
|
+
# #<Enumerations::Value: @base=Role, @symbol=:staff...>]
|
77
80
|
#
|
78
81
|
def self.all
|
79
82
|
_values.values
|
80
83
|
end
|
81
84
|
|
82
|
-
|
83
|
-
#
|
84
|
-
# Example:
|
85
|
-
#
|
86
|
-
# Role.find(:admin) => #<Enumeration::Value:0x007f8ed7f46100 @base=Role, @symbol=:admin...>
|
87
|
-
# Role.find(2) => #<Enumeration::Value:0x007f8ed7f45de0 @base=Role, @symbol=:manager...>
|
88
|
-
# Role.find('2') => #<Enumeration::Value:0x007f8ed7f45de0 @base=Role, @symbol=:manager...>
|
89
|
-
# Role.find('staff') => #<Enumeration::Value:0x007f8ed7f45ae8 @base=Role, @symbol=:staff...>
|
90
|
-
#
|
91
|
-
def self.find(key)
|
92
|
-
case key
|
93
|
-
when Symbol then find_by_key(key)
|
94
|
-
when String then find_by_key(key.to_sym) || find_by_id(key.to_i)
|
95
|
-
when Integer then find_by_id(key)
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
# Finds an enumeration by defined attribute. Simmilar to AcriveRecord::FinderMethods#find_by
|
100
|
-
#
|
101
|
-
# Example:
|
102
|
-
#
|
103
|
-
# Role.find_by(name: 'Admin') => #<Enumeration::Value:0x007f8ed7f46100 @base=Role, @symbol=:admin...>
|
104
|
-
#
|
105
|
-
def self.find_by(**args)
|
106
|
-
_values.values.find { |value| args.map { |k, v| value.send(k) == v }.all? }
|
107
|
-
end
|
108
|
-
|
109
|
-
def self.find_by_key(key)
|
110
|
-
_values[key]
|
111
|
-
end
|
112
|
-
|
113
|
-
def self.find_by_id(id)
|
114
|
-
_values[_symbol_index.key(id)]
|
115
|
-
end
|
85
|
+
attr_reader :symbol
|
116
86
|
|
117
87
|
def initialize(symbol, attributes)
|
118
88
|
@symbol = symbol
|
119
89
|
@attributes = attributes
|
120
|
-
create_instance_methods
|
121
|
-
end
|
122
90
|
|
123
|
-
|
124
|
-
|
125
|
-
def to_i
|
126
|
-
id
|
127
|
-
end
|
128
|
-
|
129
|
-
def to_s
|
130
|
-
name
|
131
|
-
end
|
132
|
-
|
133
|
-
def to_sym
|
134
|
-
@symbol
|
135
|
-
end
|
136
|
-
|
137
|
-
def to_param
|
138
|
-
id
|
139
|
-
end
|
140
|
-
|
141
|
-
# Comparison by id, symbol or object
|
142
|
-
#
|
143
|
-
# Example:
|
144
|
-
#
|
145
|
-
# Role.admin == 1 => true
|
146
|
-
# Role.admin == :admin => true
|
147
|
-
# Role.admin == Role.admin => true
|
148
|
-
# Role.admin == 2 => false
|
149
|
-
# Role.admin == :staff => false
|
150
|
-
# Role.admin == Role.staff => false
|
151
|
-
#
|
152
|
-
# TODO: test if case..when is working with this
|
153
|
-
def ==(other)
|
154
|
-
case other
|
155
|
-
when Integer then other == id
|
156
|
-
when Symbol then other == @symbol
|
157
|
-
else super
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
private
|
162
|
-
|
163
|
-
# Getters for all attributes
|
164
|
-
#
|
165
|
-
# Example:
|
166
|
-
#
|
167
|
-
# Role.admin => #<Enumeration::Value:0x007fff45d7ec30 @base=Role, @symbol=:admin,
|
168
|
-
# @attributes={:id=>1, :name=>"Admin", :description=>"Some description..."}>
|
169
|
-
# user.role.id => # 1
|
170
|
-
# user.role.name => # "Admin"
|
171
|
-
# user.role.description => # "Some description..."
|
172
|
-
# user.role.admin? => # true
|
173
|
-
# user.role.staff? => # false
|
174
|
-
#
|
175
|
-
def create_instance_methods
|
176
|
-
@attributes.each do |key, _|
|
177
|
-
self.class.send :define_method, key do
|
178
|
-
@attributes[key]
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
self.class.send :define_method, "#{@symbol}?" do
|
183
|
-
__callee__[0..-2].to_sym == @symbol
|
184
|
-
end
|
91
|
+
create_instance_methods
|
185
92
|
end
|
186
93
|
end
|
187
94
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Enumerations
|
2
|
+
module FinderMethods
|
3
|
+
# Finds an enumeration by symbol, id or name
|
4
|
+
#
|
5
|
+
# Example:
|
6
|
+
#
|
7
|
+
# Role.find(:admin) => #<Enumerations::Value: @base=Role, @symbol=:admin...>
|
8
|
+
# Role.find(2) => #<Enumerations::Value: @base=Role, @symbol=:manager...>
|
9
|
+
# Role.find('2') => #<Enumerations::Value: @base=Role, @symbol=:manager...>
|
10
|
+
# Role.find('staff') => #<Enumerations::Value: @base=Role, @symbol=:staff...>
|
11
|
+
#
|
12
|
+
def find(key)
|
13
|
+
case key
|
14
|
+
when Symbol then find_by_key(key)
|
15
|
+
when String then find_by_key(key.to_sym) || find_by_id(key.to_i)
|
16
|
+
when Fixnum then find_by_id(key)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Finds an enumeration by defined attribute. Similar to ActiveRecord::FinderMethods#find_by
|
21
|
+
#
|
22
|
+
# Example:
|
23
|
+
#
|
24
|
+
# Role.find_by(name: 'Admin') => #<Enumerations::Value: @base=Role, @symbol=:admin...>
|
25
|
+
#
|
26
|
+
def find_by(**args)
|
27
|
+
_values.values.find { |value| args.map { |k, v| value.send(k) == v }.all? }
|
28
|
+
end
|
29
|
+
|
30
|
+
def find_by_key(key)
|
31
|
+
_values[key]
|
32
|
+
end
|
33
|
+
|
34
|
+
def find_by_id(id)
|
35
|
+
_values[_symbol_index.key(id)]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -1,18 +1,22 @@
|
|
1
|
-
module
|
1
|
+
module Enumerations
|
2
2
|
class Reflection
|
3
3
|
attr_reader :name
|
4
4
|
|
5
|
-
def initialize(name, options)
|
5
|
+
def initialize(name, options = {})
|
6
6
|
@name = name
|
7
7
|
@options = options
|
8
8
|
end
|
9
9
|
|
10
10
|
def class_name
|
11
|
-
@options[:class_name]
|
11
|
+
@class_name ||= (@options[:class_name] || name).to_s.camelize
|
12
12
|
end
|
13
13
|
|
14
14
|
def foreign_key
|
15
|
-
@options[:foreign_key]
|
15
|
+
@foreign_key ||= (@options[:foreign_key] || "#{name}_id").to_sym
|
16
|
+
end
|
17
|
+
|
18
|
+
def enumerator_class
|
19
|
+
@enumerator_class ||= class_name.constantize
|
16
20
|
end
|
17
21
|
end
|
18
22
|
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Enumerations
|
2
|
+
module Value
|
3
|
+
def to_i
|
4
|
+
id
|
5
|
+
end
|
6
|
+
|
7
|
+
def to_s
|
8
|
+
name
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_sym
|
12
|
+
symbol
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_param
|
16
|
+
id
|
17
|
+
end
|
18
|
+
|
19
|
+
# Comparison by id, symbol or object
|
20
|
+
#
|
21
|
+
# Example:
|
22
|
+
#
|
23
|
+
# Role.admin == 1 => true
|
24
|
+
# Role.admin == :admin => true
|
25
|
+
# Role.admin == Role.admin => true
|
26
|
+
# Role.admin == 2 => false
|
27
|
+
# Role.admin == :staff => false
|
28
|
+
# Role.admin == Role.staff => false
|
29
|
+
#
|
30
|
+
# TODO: test if case..when is working with this
|
31
|
+
def ==(other)
|
32
|
+
case other
|
33
|
+
when Fixnum then other == id
|
34
|
+
when Symbol then other == symbol
|
35
|
+
else super
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def create_instance_methods
|
42
|
+
define_attributes_getters
|
43
|
+
define_value_checking_method
|
44
|
+
end
|
45
|
+
|
46
|
+
# Getters for all attributes
|
47
|
+
#
|
48
|
+
# Example:
|
49
|
+
#
|
50
|
+
# Role.admin => #<Enumerations::Value:0x007fff45d7ec30 @base=Role, @symbol=:admin,
|
51
|
+
# @attributes={:id=>1, :name=>"Admin", :description=>"Some description..."}>
|
52
|
+
# user.role.id => # 1
|
53
|
+
# user.role.name => # "Admin"
|
54
|
+
# user.role.description => # "Some description..."
|
55
|
+
#
|
56
|
+
def define_attributes_getters
|
57
|
+
@attributes.each do |key, _|
|
58
|
+
next if respond_to?(key)
|
59
|
+
|
60
|
+
self.class.send :define_method, key do
|
61
|
+
@attributes[key]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Predicate methods for values
|
67
|
+
#
|
68
|
+
# Example:
|
69
|
+
#
|
70
|
+
# user.role = Role.admin
|
71
|
+
# user.role.admin? => # true
|
72
|
+
# user.role.staff? => # false
|
73
|
+
#
|
74
|
+
def define_value_checking_method
|
75
|
+
self.class.send :define_method, "#{symbol}?" do
|
76
|
+
__callee__[0..-2].to_sym == symbol
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/lib/enumerations/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
module
|
2
|
-
VERSION = '
|
1
|
+
module Enumerations
|
2
|
+
VERSION = '2.0.0'
|
3
3
|
end
|
data/test/base_test.rb
CHANGED
@@ -13,6 +13,18 @@ class BaseTest < Minitest::Test
|
|
13
13
|
refute_same :published, status.symbol
|
14
14
|
end
|
15
15
|
|
16
|
+
def test_lookup_by_string_id
|
17
|
+
status = Status.find('1')
|
18
|
+
|
19
|
+
assert_equal :draft, status.symbol
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_lookup_by_string_key
|
23
|
+
status = Status.find('draft')
|
24
|
+
|
25
|
+
assert_equal :draft, status.symbol
|
26
|
+
end
|
27
|
+
|
16
28
|
def test_find_by
|
17
29
|
status = Status.find_by(name: 'Draft')
|
18
30
|
|
@@ -32,6 +44,19 @@ class BaseTest < Minitest::Test
|
|
32
44
|
assert_equal statuses.first, Status.draft
|
33
45
|
end
|
34
46
|
|
47
|
+
def test_symbols
|
48
|
+
status_symbols = Status.symbols
|
49
|
+
|
50
|
+
assert_equal 5, status_symbols.size
|
51
|
+
assert_equal status_symbols.first, Status.draft.to_sym
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_required_id
|
55
|
+
assert_raises 'Enumeration id is required' do
|
56
|
+
Class.new.value draft: { name: 'Draft' }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
35
60
|
def test_duplicated_id
|
36
61
|
assert_raises 'Duplicate id 1' do
|
37
62
|
Class.new.values draft: { id: 1, name: 'Draft' },
|
@@ -57,45 +82,17 @@ class BaseTest < Minitest::Test
|
|
57
82
|
end
|
58
83
|
end
|
59
84
|
|
60
|
-
def
|
61
|
-
|
85
|
+
def test_enumerations_custom_instance_method
|
86
|
+
role = Role.find(:admin)
|
62
87
|
|
63
|
-
assert_equal
|
88
|
+
assert_equal 'user_Admin', role.my_custom_name
|
64
89
|
end
|
65
90
|
|
66
|
-
def
|
67
|
-
|
68
|
-
|
69
|
-
assert_equal true, status.deleted
|
70
|
-
end
|
91
|
+
def test_all_enumerations_has_custom_instance_methods
|
92
|
+
roles = Role.all
|
71
93
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
assert_equal nil, status.visible
|
76
|
-
end
|
77
|
-
|
78
|
-
def test_equal_by_id
|
79
|
-
status = Status.find(:draft)
|
80
|
-
|
81
|
-
assert_equal true, status == 1
|
82
|
-
end
|
83
|
-
|
84
|
-
def test_equal_by_symbol
|
85
|
-
status = Status.draft
|
86
|
-
|
87
|
-
assert_equal true, status == :draft
|
88
|
-
end
|
89
|
-
|
90
|
-
def test_equal_by_enumeration
|
91
|
-
status = Status.draft
|
92
|
-
|
93
|
-
assert_equal true, status == Status.draft
|
94
|
-
end
|
95
|
-
|
96
|
-
def test_not_equal_by_enumeration
|
97
|
-
status = Status.draft
|
98
|
-
|
99
|
-
assert_equal false, status == Status.published
|
94
|
+
assert_silent do
|
95
|
+
roles.map(&:my_custom_name)
|
96
|
+
end
|
100
97
|
end
|
101
98
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
|
4
|
+
|
5
|
+
ActiveRecord::Schema.define do
|
6
|
+
create_table :posts, force: true do |t|
|
7
|
+
t.integer :status_id
|
8
|
+
t.integer :some_other_status_id
|
9
|
+
end
|
10
|
+
|
11
|
+
create_table :users, force: true do |t|
|
12
|
+
t.integer :role_id
|
13
|
+
t.string :status_id
|
14
|
+
end
|
15
|
+
end
|
data/test/enumerations_test.rb
CHANGED
@@ -18,6 +18,20 @@ class EnumerationsTest < Minitest::Test
|
|
18
18
|
assert_equal 'Draft', p.status.to_s
|
19
19
|
end
|
20
20
|
|
21
|
+
def test_model_bang_assignment
|
22
|
+
p = Post.new
|
23
|
+
p.status_draft!
|
24
|
+
|
25
|
+
assert_equal 'Draft', p.status.to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_model_bang_assignment_with_custom_name
|
29
|
+
p = Post.new
|
30
|
+
p.different_status_draft!
|
31
|
+
|
32
|
+
assert_equal 'Draft', p.different_status.to_s
|
33
|
+
end
|
34
|
+
|
21
35
|
def test_model_via_id_assignment
|
22
36
|
p = Post.new
|
23
37
|
p.some_other_status_id = Status.published.id
|
@@ -38,4 +52,37 @@ class EnumerationsTest < Minitest::Test
|
|
38
52
|
|
39
53
|
assert_equal false, p.status.published?
|
40
54
|
end
|
55
|
+
|
56
|
+
def test_multiple_enumerations_on_model
|
57
|
+
enumerations = User.reflect_on_all_enumerations
|
58
|
+
|
59
|
+
assert_equal 2, enumerations.size
|
60
|
+
|
61
|
+
assert_equal :role, enumerations.first.name
|
62
|
+
assert_equal :role_id, enumerations.first.foreign_key
|
63
|
+
|
64
|
+
assert_equal :status, enumerations[1].name
|
65
|
+
assert_equal :status_id, enumerations[1].foreign_key
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_multiple_enumeration_assignments_on_model
|
69
|
+
u = User.new
|
70
|
+
u.role = Role.admin
|
71
|
+
u.status = Status.published
|
72
|
+
|
73
|
+
assert_equal 'Admin', u.role.to_s
|
74
|
+
assert_equal 'Published', u.status.to_s
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_enumerated_class_has_scopes
|
78
|
+
Role.all do |role|
|
79
|
+
assert_respond_to User, ['with_role', role.name].join('_').to_sym
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_enumerated_class_scope_hash_value
|
84
|
+
query_hash = User.with_role_admin.where_values_hash.symbolize_keys
|
85
|
+
|
86
|
+
assert_equal query_hash, role_id: 1
|
87
|
+
end
|
41
88
|
end
|
data/test/reflection_test.rb
CHANGED
@@ -1,11 +1,38 @@
|
|
1
1
|
require_relative 'test_helper'
|
2
2
|
|
3
3
|
class ReflectionTest < Minitest::Test
|
4
|
-
def
|
5
|
-
reflection =
|
4
|
+
def test_reflection_with_all_attributes
|
5
|
+
reflection = Enumerations::Reflection.new(:status, class_name: 'Status',
|
6
|
+
foreign_key: :status_id)
|
6
7
|
|
7
|
-
assert_equal :
|
8
|
-
assert_equal '
|
9
|
-
assert_equal :
|
8
|
+
assert_equal :status, reflection.name
|
9
|
+
assert_equal 'Status', reflection.class_name
|
10
|
+
assert_equal :status_id, reflection.foreign_key
|
11
|
+
assert_equal ::Status, reflection.enumerator_class
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_reflection_without_class_name_and_foreign_key
|
15
|
+
reflection = Enumerations::Reflection.new(:status)
|
16
|
+
|
17
|
+
assert_equal :status, reflection.name
|
18
|
+
assert_equal 'Status', reflection.class_name
|
19
|
+
assert_equal :status_id, reflection.foreign_key
|
20
|
+
assert_equal ::Status, reflection.enumerator_class
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_reflection_with_custom_name_and_without_foreign_key
|
24
|
+
reflection = Enumerations::Reflection.new(:my_status, class_name: 'Status')
|
25
|
+
|
26
|
+
assert_equal :my_status, reflection.name
|
27
|
+
assert_equal 'Status', reflection.class_name
|
28
|
+
assert_equal :my_status_id, reflection.foreign_key
|
29
|
+
assert_equal ::Status, reflection.enumerator_class
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_reflection_with_class_name_as_constant
|
33
|
+
reflection = Enumerations::Reflection.new(:status, class_name: Status)
|
34
|
+
|
35
|
+
assert_equal 'Status', reflection.class_name
|
36
|
+
assert_equal ::Status, reflection.enumerator_class
|
10
37
|
end
|
11
38
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
|
-
|
1
|
+
require 'codeclimate-test-reporter'
|
2
|
+
CodeClimate::TestReporter.start
|
3
|
+
|
2
4
|
require 'minitest/autorun'
|
3
5
|
require 'enumerations'
|
6
|
+
require 'active_record'
|
4
7
|
require 'pry'
|
5
8
|
|
6
|
-
|
7
|
-
class MockActiveRecordBase
|
8
|
-
include Enumeration
|
9
|
-
end
|
9
|
+
require_relative 'database_helper'
|
10
10
|
|
11
|
-
class Status <
|
11
|
+
class Status < Enumerations::Base
|
12
12
|
values draft: { id: 1, name: 'Draft' },
|
13
13
|
review_pending: { id: 2, name: 'Review pending' },
|
14
14
|
published: { id: 3, name: 'Published' }
|
@@ -17,9 +17,26 @@ class Status < Enumeration::Base
|
|
17
17
|
value :deleted, id: 5, deleted: true
|
18
18
|
end
|
19
19
|
|
20
|
-
class
|
20
|
+
class Role < Enumerations::Base
|
21
|
+
value :admin, id: 1, name: 'Admin', admin: true
|
22
|
+
value :editor, id: 2, name: 'Editor'
|
23
|
+
value :author, id: 3, name: 'Author'
|
24
|
+
|
25
|
+
def my_custom_name
|
26
|
+
['user', name].join('_')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Post < ActiveRecord::Base
|
21
31
|
attr_accessor :status_id, :some_other_status_id
|
22
32
|
|
23
33
|
enumeration :status
|
24
34
|
enumeration :different_status, foreign_key: :some_other_status_id, class_name: 'Status'
|
25
35
|
end
|
36
|
+
|
37
|
+
class User < ActiveRecord::Base
|
38
|
+
attr_accessor :role_id, :status_id
|
39
|
+
|
40
|
+
enumeration :role
|
41
|
+
enumeration :status
|
42
|
+
end
|
data/test/value_test.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
|
3
|
+
class ValueTest < Minitest::Test
|
4
|
+
def test_equal_by_id
|
5
|
+
status = Status.find(:draft)
|
6
|
+
|
7
|
+
assert_equal true, status == 1
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_equal_by_symbol
|
11
|
+
status = Status.draft
|
12
|
+
|
13
|
+
assert_equal true, status == :draft
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_equal_by_enumeration
|
17
|
+
status = Status.draft
|
18
|
+
|
19
|
+
assert_equal true, status == Status.draft
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_not_equal_by_enumeration
|
23
|
+
status = Status.draft
|
24
|
+
|
25
|
+
assert_equal false, status == Status.published
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_with_defined_custom_attributes_visible
|
29
|
+
status = Status.find(:none)
|
30
|
+
|
31
|
+
assert_equal true, status.visible
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_with_defined_custom_attributes_deleted
|
35
|
+
status = Status.find(:deleted)
|
36
|
+
|
37
|
+
assert_equal true, status.deleted
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_without_defined_custom_attributes
|
41
|
+
status = Status.find(:draft)
|
42
|
+
|
43
|
+
assert_equal nil, status.visible
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_enumeration_to_i
|
47
|
+
status = Status.find(:draft)
|
48
|
+
|
49
|
+
assert_equal status.to_i, 1
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_enumeration_to_sym
|
53
|
+
status = Status.find(:draft)
|
54
|
+
|
55
|
+
assert_equal status.to_sym, :draft
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_enumeration_to_param
|
59
|
+
status = Status.find(:draft)
|
60
|
+
|
61
|
+
assert_equal status.to_param, 1
|
62
|
+
end
|
63
|
+
end
|
data/test/version_test.rb
CHANGED
metadata
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: enumerations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tomislav Car
|
8
8
|
- Nikica Jokic
|
9
9
|
- Nikola Santic
|
10
|
-
autorequire:
|
10
|
+
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2016-08-15 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|
@@ -54,6 +54,48 @@ dependencies:
|
|
54
54
|
- - ">="
|
55
55
|
- !ruby/object:Gem::Version
|
56
56
|
version: '0'
|
57
|
+
- !ruby/object:Gem::Dependency
|
58
|
+
name: rake
|
59
|
+
requirement: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
type: :development
|
65
|
+
prerelease: false
|
66
|
+
version_requirements: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: codeclimate-test-reporter
|
73
|
+
requirement: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
type: :development
|
79
|
+
prerelease: false
|
80
|
+
version_requirements: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
- !ruby/object:Gem::Dependency
|
86
|
+
name: sqlite3
|
87
|
+
requirement: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
type: :development
|
93
|
+
prerelease: false
|
94
|
+
version_requirements: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
57
99
|
description: Extends ActiveRecord with enumeration capabilites.
|
58
100
|
email:
|
59
101
|
- tomislav@infinum.hr
|
@@ -64,24 +106,27 @@ extensions: []
|
|
64
106
|
extra_rdoc_files: []
|
65
107
|
files:
|
66
108
|
- ".gitignore"
|
67
|
-
- ".travis.yml"
|
68
109
|
- Gemfile
|
69
110
|
- Rakefile
|
70
111
|
- Readme.md
|
71
112
|
- enumerations.gemspec
|
72
113
|
- lib/enumerations.rb
|
73
114
|
- lib/enumerations/base.rb
|
115
|
+
- lib/enumerations/finder_methods.rb
|
74
116
|
- lib/enumerations/reflection.rb
|
117
|
+
- lib/enumerations/value.rb
|
75
118
|
- lib/enumerations/version.rb
|
76
119
|
- test/base_test.rb
|
120
|
+
- test/database_helper.rb
|
77
121
|
- test/enumerations_test.rb
|
78
122
|
- test/reflection_test.rb
|
79
123
|
- test/test_helper.rb
|
124
|
+
- test/value_test.rb
|
80
125
|
- test/version_test.rb
|
81
126
|
homepage: https://github.com/infinum/enumerations
|
82
127
|
licenses: []
|
83
128
|
metadata: {}
|
84
|
-
post_install_message:
|
129
|
+
post_install_message:
|
85
130
|
rdoc_options: []
|
86
131
|
require_paths:
|
87
132
|
- lib
|
@@ -96,13 +141,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
96
141
|
- !ruby/object:Gem::Version
|
97
142
|
version: '0'
|
98
143
|
requirements: []
|
99
|
-
|
100
|
-
|
144
|
+
rubyforge_project:
|
145
|
+
rubygems_version: 2.5.1
|
146
|
+
signing_key:
|
101
147
|
specification_version: 4
|
102
148
|
summary: Enumerations for ActiveRecord!
|
103
149
|
test_files:
|
104
150
|
- test/base_test.rb
|
151
|
+
- test/database_helper.rb
|
105
152
|
- test/enumerations_test.rb
|
106
153
|
- test/reflection_test.rb
|
107
154
|
- test/test_helper.rb
|
155
|
+
- test/value_test.rb
|
108
156
|
- test/version_test.rb
|