ohm-contrib 0.1.2 → 1.0.rc0

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 (52) hide show
  1. data/lib/ohm/{contrib/callbacks.rb → callbacks.rb} +20 -65
  2. data/lib/ohm/contrib.rb +9 -17
  3. data/lib/ohm/datatypes.rb +38 -0
  4. data/lib/ohm/{contrib/locking.rb → locking.rb} +1 -2
  5. data/lib/ohm/plugin.rb +54 -0
  6. data/lib/ohm/{contrib/scope.rb → scope.rb} +7 -6
  7. data/lib/ohm/{contrib/slug.rb → slug.rb} +11 -6
  8. data/lib/ohm/{contrib/soft_delete.rb → softdelete.rb} +23 -19
  9. data/lib/ohm/timestamping.rb +41 -0
  10. data/ohm-contrib.gemspec +30 -0
  11. data/rakefile +6 -0
  12. data/test/{instance_callbacks_test.rb → instance_callbacks.rb} +2 -6
  13. data/test/{macro_callbacks_test.rb → macro_callbacks.rb} +1 -9
  14. data/test/plugin.rb +212 -0
  15. data/test/{scope_test.rb → scope.rb} +2 -3
  16. data/test/slug.rb +24 -0
  17. data/test/{soft_delete_test.rb → soft_delete.rb} +13 -3
  18. data/test/{timestamping_test.rb → timestamping.rb} +5 -6
  19. metadata +33 -70
  20. data/Rakefile +0 -8
  21. data/lib/ohm/contrib/active_model_extension.rb +0 -87
  22. data/lib/ohm/contrib/boundaries.rb +0 -41
  23. data/lib/ohm/contrib/date_validations.rb +0 -23
  24. data/lib/ohm/contrib/extra_validations.rb +0 -48
  25. data/lib/ohm/contrib/fulltext_searching.rb +0 -80
  26. data/lib/ohm/contrib/length_validations.rb +0 -32
  27. data/lib/ohm/contrib/number_validations.rb +0 -14
  28. data/lib/ohm/contrib/timestamping.rb +0 -38
  29. data/lib/ohm/contrib/typecast.rb +0 -350
  30. data/lib/ohm/contrib/web_validations.rb +0 -52
  31. data/test/activemodel_test.rb +0 -27
  32. data/test/boundaries_test.rb +0 -45
  33. data/test/callbacks_lint.rb +0 -141
  34. data/test/date_validations_test.rb +0 -29
  35. data/test/fixtures/ascii8bit.txt +0 -1
  36. data/test/fulltext_searching_test.rb +0 -63
  37. data/test/length_validations_test.rb +0 -31
  38. data/test/membership_validation_test.rb +0 -31
  39. data/test/number_validations_test.rb +0 -37
  40. data/test/slug_test.rb +0 -30
  41. data/test/typecast_array_test.rb +0 -146
  42. data/test/typecast_boolean_test.rb +0 -43
  43. data/test/typecast_date_test.rb +0 -82
  44. data/test/typecast_decimal_test.rb +0 -82
  45. data/test/typecast_existing_attribute_test.rb +0 -22
  46. data/test/typecast_float_test.rb +0 -57
  47. data/test/typecast_hash_test.rb +0 -120
  48. data/test/typecast_integer_test.rb +0 -71
  49. data/test/typecast_string_test.rb +0 -43
  50. data/test/typecast_time_test.rb +0 -72
  51. data/test/typecast_timezone_test.rb +0 -37
  52. data/test/web_validations_test.rb +0 -79
data/test/plugin.rb ADDED
@@ -0,0 +1,212 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative "helper"
4
+
5
+ class Comment < Ohm::Model
6
+ include Ohm::Timestamping
7
+ end
8
+
9
+ test "timestamps are added during creation" do
10
+ e = Comment.new
11
+ e.save
12
+
13
+ assert e.created_at
14
+ assert e.updated_at
15
+ end
16
+
17
+ class Server < Ohm::Model
18
+ include Ohm::Locking
19
+ end
20
+
21
+ test "mutex method is added at instance and class level" do
22
+ assert Server.new.respond_to?(:mutex)
23
+ end
24
+
25
+ class Article < Ohm::Model
26
+ include Ohm::Callbacks
27
+
28
+ attribute :title
29
+
30
+ list :comments, Comment
31
+ after :save, :append_comment
32
+
33
+ private
34
+ def before_save
35
+ self.title = title.gsub("<br>", " ")
36
+ end
37
+
38
+ def append_comment
39
+ comments.add(Comment.create)
40
+ end
41
+ end
42
+
43
+ test "class-level, instance level callbacks" do
44
+ a = Article.create(title: "Foo<br>Bar")
45
+
46
+ assert_equal "Foo Bar", a.title
47
+ assert_equal 1, a.comments.size
48
+ end
49
+
50
+ class Post < Ohm::Model
51
+ attribute :title
52
+
53
+ include Ohm::Slug
54
+
55
+ def to_s
56
+ title
57
+ end
58
+ end
59
+
60
+ test "slugging" do
61
+ post = Post.create(title: "Foo Bar Baz")
62
+ assert_equal "1-foo-bar-baz", post.to_param
63
+
64
+ post = Post.create(title: "Décor")
65
+ assert_equal "2-decor", post.to_param
66
+ end
67
+
68
+ class Order < Ohm::Model
69
+ include Ohm::Scope
70
+
71
+ attribute :state
72
+ index :state
73
+
74
+ attribute :deleted
75
+ index :deleted
76
+
77
+ scope do
78
+ def paid
79
+ find(state: "paid")
80
+ end
81
+
82
+ def deleted
83
+ find(deleted: 1)
84
+ end
85
+ end
86
+ end
87
+
88
+ test "scope" do
89
+ paid = Order.create(state: "paid", deleted: nil)
90
+
91
+ assert Order.all.paid.include?(paid)
92
+ assert_equal 0, Order.all.paid.deleted.size
93
+
94
+ paid.update(deleted: 1)
95
+ assert Order.all.paid.deleted.include?(paid)
96
+ end
97
+
98
+ class User < Ohm::Model
99
+ include Ohm::SoftDelete
100
+
101
+ attribute :email
102
+ index :email
103
+ end
104
+
105
+ test "soft delete" do
106
+ user = User.create(email: "a@a.com")
107
+ user.delete
108
+
109
+ assert User.all.empty?
110
+ assert User.deleted.include?(user)
111
+ assert User.find(email: "a@a.com").include?(user)
112
+
113
+ assert user.deleted?
114
+ assert User[user.id] == user
115
+
116
+ user.restore
117
+
118
+ assert User.all.include?(user)
119
+ assert User.deleted.empty?
120
+
121
+ assert ! user.deleted?
122
+ end
123
+
124
+ class Product < Ohm::Model
125
+ include Ohm::DataTypes
126
+
127
+ attribute :name
128
+ attribute :stock, Type::Integer
129
+ attribute :price, Type::Decimal
130
+ attribute :rating, Type::Float
131
+ attribute :bought_at, Type::Time
132
+ attribute :date_released, Type::Date
133
+ attribute :sizes, Type::Hash
134
+ attribute :stores, Type::Array
135
+ attribute :published, Type::Boolean
136
+ end
137
+
138
+ test "typecast" do
139
+ p = Product.new(stock: "1")
140
+
141
+ assert_equal 1, p.stock
142
+ p.save
143
+
144
+ p = Product[p.id]
145
+ assert_equal 1, p.stock
146
+
147
+ time = Time.now.utc
148
+ p = Product.new(bought_at: time)
149
+ assert p.bought_at.kind_of?(Time)
150
+
151
+ p.save
152
+
153
+ p = Product[p.id]
154
+ assert p.bought_at.kind_of?(Time)
155
+ assert_equal time, p.bought_at
156
+
157
+ p = Product.new(date_released: Date.today)
158
+ assert p.date_released.kind_of?(Date)
159
+
160
+ p = Product.new(date_released: "2011-11-22")
161
+ assert p.date_released.kind_of?(Date)
162
+
163
+ p.save
164
+
165
+ p = Product[p.id]
166
+ assert_equal Date.today, p.date_released
167
+
168
+ sizes = { "XS" => 1, "S" => 2, "L" => 3 }
169
+
170
+ p = Product.new(sizes: sizes)
171
+ assert p.sizes.kind_of?(Hash)
172
+
173
+ p.save
174
+
175
+ p = Product[p.id]
176
+ assert_equal sizes, p.sizes
177
+
178
+ stores = ["walmart", "marshalls", "jcpenny"]
179
+ p = Product.new(stores: stores)
180
+ assert p.stores.kind_of?(Array)
181
+
182
+ p.save
183
+
184
+ p = Product[p.id]
185
+ assert_equal stores, p.stores
186
+
187
+ p = Product.new(price: 0.001)
188
+
189
+ x = 0
190
+ 1000.times { x += p.price }
191
+ assert_equal 1, x
192
+
193
+ p.save
194
+
195
+ p = Product[p.id]
196
+ assert_equal 0.001, p.price
197
+
198
+ p = Product.new(rating: 4.5)
199
+ assert p.rating.kind_of?(Float)
200
+
201
+ p.save
202
+ p = Product[p.id]
203
+ assert_equal 4.5, p.rating
204
+
205
+ p = Product.new(published: 1)
206
+ assert_equal true, p.published
207
+
208
+ p.save
209
+
210
+ p = Product[p.id]
211
+ assert_equal true, p.published
212
+ end
@@ -1,6 +1,6 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require File.expand_path("./helper", File.dirname(__FILE__))
3
+ require_relative "helper"
4
4
 
5
5
  class Post < Ohm::Model
6
6
  set :comments, Comment
@@ -72,5 +72,4 @@ test "isolated from List" do
72
72
  assert_raise NoMethodError do
73
73
  video.comments.rejected
74
74
  end
75
- end
76
-
75
+ end
data/test/slug.rb ADDED
@@ -0,0 +1,24 @@
1
+ # encoding: UTF-8
2
+
3
+ require_relative "helper"
4
+
5
+ class Article < Ohm::Model
6
+ include Ohm::Slug
7
+ attribute :title
8
+
9
+ def to_s
10
+ title
11
+ end
12
+ end
13
+
14
+ test "to_param" do
15
+ article = Article.create(title: "A very Unique and Interesting String?'")
16
+
17
+ assert '1-a-very-unique-and-interesting-string' == article.to_param
18
+ end
19
+
20
+ test "finding" do
21
+ article = Article.create(title: "A very Unique and Interesting String?'")
22
+
23
+ assert 1 == Article["1-a-very-unique-and-interesting-string"].id
24
+ end
@@ -32,15 +32,15 @@ test "all excludes deleted records" do
32
32
  assert Person.all.empty?
33
33
  end
34
34
 
35
- test "find excludes deleted records" do
35
+ test "find does not exclude deleted records" do
36
36
  person = Person.create(:name => "matz")
37
37
 
38
38
  assert Person.find(:name => "matz").first == person
39
39
 
40
40
  person.delete
41
41
 
42
- assert Person.find(:name => "matz").empty?
43
- assert Person.all.find(:name => "matz").empty?
42
+ assert Person.find(:name => "matz").include?(person)
43
+ assert Person.all.find(:name => "matz").include?(person)
44
44
  end
45
45
 
46
46
  test "find with many criteria excludes deleted records" do
@@ -69,4 +69,14 @@ test "Model[n] can be used to retrieve deleted records" do
69
69
 
70
70
  assert Person[person.id].deleted?
71
71
  assert Person[person.id].name == "matz"
72
+ end
73
+
74
+ test "restoring" do
75
+ person = Person.create(:name => "matz")
76
+ person.delete
77
+
78
+ assert Person.all.empty?
79
+
80
+ person.restore
81
+ assert Person.all.include?(person)
72
82
  end
@@ -15,8 +15,8 @@ test "on create" do
15
15
  person = Person.create
16
16
  person = Person[person.id]
17
17
 
18
- assert NOW.to_s == person.created_at
19
- assert NOW.to_s == person.updated_at
18
+ assert NOW == person.created_at
19
+ assert NOW == person.updated_at
20
20
  end
21
21
 
22
22
  test "on update" do
@@ -26,7 +26,6 @@ test "on update" do
26
26
  person.save
27
27
  person = Person[person.id]
28
28
 
29
- assert NOW.to_s == person.created_at
30
- assert Time.utc(2010, 5, 13).to_s == person.updated_at
31
- end
32
-
29
+ assert NOW == person.created_at
30
+ assert Time.utc(2010, 5, 13) == person.updated_at
31
+ end
metadata CHANGED
@@ -1,19 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ohm-contrib
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
5
- prerelease:
4
+ version: 1.0.rc0
5
+ prerelease: 4
6
6
  platform: ruby
7
7
  authors:
8
8
  - Cyril David
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-21 00:00:00.000000000Z
12
+ date: 2011-11-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ohm
16
- requirement: &2164476460 !ruby/object:Gem::Requirement
16
+ requirement: &2164457940 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2164476460
24
+ version_requirements: *2164457940
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: cutest
27
- requirement: &2164475860 !ruby/object:Gem::Requirement
27
+ requirement: &2164457380 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *2164475860
35
+ version_requirements: *2164457380
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: redis
38
- requirement: &2164474640 !ruby/object:Gem::Requirement
38
+ requirement: &2164472240 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,21 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *2164474640
47
- - !ruby/object:Gem::Dependency
48
- name: lunar
49
- requirement: &2164474060 !ruby/object:Gem::Requirement
50
- none: false
51
- requirements:
52
- - - ! '>='
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- type: :development
56
- prerelease: false
57
- version_requirements: *2164474060
46
+ version_requirements: *2164472240
58
47
  - !ruby/object:Gem::Dependency
59
48
  name: override
60
- requirement: &2164473440 !ruby/object:Gem::Requirement
49
+ requirement: &2164471540 !ruby/object:Gem::Requirement
61
50
  none: false
62
51
  requirements:
63
52
  - - ! '>='
@@ -65,7 +54,7 @@ dependencies:
65
54
  version: '0'
66
55
  type: :development
67
56
  prerelease: false
68
- version_requirements: *2164473440
57
+ version_requirements: *2164471540
69
58
  description: Includes a couple of core functions such as callbacks, timestamping,
70
59
  typecasting and lots of generic validation routines.
71
60
  email: cyx.ucron@gmail.com
@@ -73,53 +62,27 @@ executables: []
73
62
  extensions: []
74
63
  extra_rdoc_files: []
75
64
  files:
76
- - lib/ohm/contrib/active_model_extension.rb
77
- - lib/ohm/contrib/boundaries.rb
78
- - lib/ohm/contrib/callbacks.rb
79
- - lib/ohm/contrib/date_validations.rb
80
- - lib/ohm/contrib/extra_validations.rb
81
- - lib/ohm/contrib/fulltext_searching.rb
82
- - lib/ohm/contrib/length_validations.rb
83
- - lib/ohm/contrib/locking.rb
84
- - lib/ohm/contrib/number_validations.rb
85
- - lib/ohm/contrib/scope.rb
86
- - lib/ohm/contrib/slug.rb
87
- - lib/ohm/contrib/soft_delete.rb
88
- - lib/ohm/contrib/timestamping.rb
89
- - lib/ohm/contrib/typecast.rb
90
- - lib/ohm/contrib/web_validations.rb
91
- - lib/ohm/contrib.rb
92
- - README.markdown
93
65
  - LICENSE
94
- - Rakefile
95
- - test/activemodel_test.rb
96
- - test/boundaries_test.rb
97
- - test/callbacks_lint.rb
98
- - test/date_validations_test.rb
99
- - test/fixtures/ascii8bit.txt
100
- - test/fulltext_searching_test.rb
66
+ - README.markdown
67
+ - rakefile
68
+ - lib/ohm/callbacks.rb
69
+ - lib/ohm/contrib.rb
70
+ - lib/ohm/datatypes.rb
71
+ - lib/ohm/locking.rb
72
+ - lib/ohm/plugin.rb
73
+ - lib/ohm/scope.rb
74
+ - lib/ohm/slug.rb
75
+ - lib/ohm/softdelete.rb
76
+ - lib/ohm/timestamping.rb
77
+ - ohm-contrib.gemspec
101
78
  - test/helper.rb
102
- - test/instance_callbacks_test.rb
103
- - test/length_validations_test.rb
104
- - test/macro_callbacks_test.rb
105
- - test/membership_validation_test.rb
106
- - test/number_validations_test.rb
107
- - test/scope_test.rb
108
- - test/slug_test.rb
109
- - test/soft_delete_test.rb
110
- - test/timestamping_test.rb
111
- - test/typecast_array_test.rb
112
- - test/typecast_boolean_test.rb
113
- - test/typecast_date_test.rb
114
- - test/typecast_decimal_test.rb
115
- - test/typecast_existing_attribute_test.rb
116
- - test/typecast_float_test.rb
117
- - test/typecast_hash_test.rb
118
- - test/typecast_integer_test.rb
119
- - test/typecast_string_test.rb
120
- - test/typecast_time_test.rb
121
- - test/typecast_timezone_test.rb
122
- - test/web_validations_test.rb
79
+ - test/instance_callbacks.rb
80
+ - test/macro_callbacks.rb
81
+ - test/plugin.rb
82
+ - test/scope.rb
83
+ - test/slug.rb
84
+ - test/soft_delete.rb
85
+ - test/timestamping.rb
123
86
  homepage: http://github.com/cyx/ohm-contrib
124
87
  licenses: []
125
88
  post_install_message:
@@ -135,12 +98,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
135
98
  required_rubygems_version: !ruby/object:Gem::Requirement
136
99
  none: false
137
100
  requirements:
138
- - - ! '>='
101
+ - - ! '>'
139
102
  - !ruby/object:Gem::Version
140
- version: '0'
103
+ version: 1.3.1
141
104
  requirements: []
142
105
  rubyforge_project: ohm-contrib
143
- rubygems_version: 1.8.11
106
+ rubygems_version: 1.8.10
144
107
  signing_key:
145
108
  specification_version: 2
146
109
  summary: A collection of decoupled drop-in modules for Ohm.
data/Rakefile DELETED
@@ -1,8 +0,0 @@
1
- require 'cutest'
2
-
3
- task :test do
4
- $:.unshift('./lib', './test')
5
-
6
- Cutest.run(Dir['./test/*_test.rb'])
7
- end
8
-
@@ -1,87 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require "active_model"
4
-
5
- # Extension for ActiveModel compatibility
6
- #
7
- # @example
8
- #
9
- # class Post < Ohm::Model
10
- # include Ohm::ActiveModelExtension
11
- # end
12
- module Ohm
13
- module ActiveModelExtension
14
- def self.included(model)
15
- model.extend ActiveModel::Naming
16
- end
17
-
18
- def to_model
19
- ActiveModelInterface.new(self)
20
- end
21
- end
22
-
23
- class ActiveModelInterface
24
- extend ActiveModel::Naming
25
-
26
- def initialize(model)
27
- @model = model
28
- end
29
-
30
- def to_model
31
- self
32
- end
33
-
34
- def valid?
35
- @model.valid?
36
- end
37
-
38
- def new_record?
39
- @model.new?
40
- end
41
-
42
- def destroyed?
43
- false
44
- end
45
-
46
- def to_key
47
- [@model.id] if persisted?
48
- end
49
-
50
- def persisted?
51
- ! new_record?
52
- end
53
-
54
- def to_param
55
- if persisted?
56
- @model.respond_to?(:to_param) ?
57
- @model.to_param :
58
- @model.id
59
- end
60
- end
61
-
62
- def errors
63
- Errors.new(@model.class.to_reference, @model.errors)
64
- end
65
-
66
- class Errors
67
- def initialize(scope, errors)
68
- @scope = scope
69
- @errors = Hash.new { |hash, key| hash[key] = [] }
70
-
71
- errors.each do |key, value|
72
- @errors[key] << value
73
- end
74
- end
75
-
76
- def [](key)
77
- @errors[key]
78
- end
79
-
80
- def full_messages
81
- @errors.map do |key, value|
82
- I18n::t("ohm.%s.%s.%s" % [@scope, key, value])
83
- end
84
- end
85
- end
86
- end
87
- end
@@ -1,41 +0,0 @@
1
- module Ohm
2
- # Dirt cheap ::first and ::last support.
3
- #
4
- # @example
5
- #
6
- # class Post < Ohm::Model
7
- # include Ohm::Boundaries
8
- # end
9
- #
10
- # post1 = Post.create
11
- # post2 = Post.create
12
- # post1 == Post.first
13
- # # => true
14
- #
15
- # post2 == Post.last
16
- # # => true
17
- module Boundaries
18
- def self.included(base)
19
- base.extend ClassMethods
20
- end
21
-
22
- module ClassMethods
23
- def first(opts = {})
24
- if opts.any?
25
- find(opts).first
26
- else
27
- all.first(opts)
28
- end
29
- end
30
-
31
- def last(opts = {})
32
- if opts.any?
33
- find(opts).first(:order => "DESC")
34
- else
35
- all.first(:order => "DESC")
36
- end
37
- end
38
- end
39
- end
40
- end
41
-
@@ -1,23 +0,0 @@
1
- require 'date'
2
-
3
- module Ohm
4
- module DateValidations
5
- DATE_REGEX = /\A([0-9]{4})-([01]?[0-9])-([0123]?[0-9])\z/
6
-
7
- def assert_date(att, error = [att, :not_date])
8
- if assert_format att, DATE_REGEX, error
9
- m = send(att).to_s.match(DATE_REGEX)
10
- assert is_date_parseable?(m[1], m[2], m[3]), error
11
- end
12
- end
13
-
14
- private
15
- def is_date_parseable?(year, month, day)
16
- Date.new(year.to_i, month.to_i, day.to_i)
17
- rescue ArgumentError
18
- return false
19
- else
20
- return true
21
- end
22
- end
23
- end
@@ -1,48 +0,0 @@
1
- module Ohm
2
- # Includes Ohm::NumberValidations and Ohm::WebValidations.
3
- #
4
- # @example
5
- #
6
- # class Post < Ohm::Model
7
- # include Ohm::ExtraValidations
8
- #
9
- # attribute :price
10
- # attribute :state
11
- # attribute :slug
12
- # attribute :author_email
13
- # attribute :url
14
- # attribute :ipaddr
15
- # attribute :birthday
16
- #
17
- # def validate
18
- # super
19
- #
20
- # assert_decimal :price
21
- # assert_member :state, ['published', 'unpublished']
22
- # assert_ipaddr :ipaddr
23
- # assert_url :url
24
- # assert_email :author_email
25
- # assert_date :birthday
26
- # assert_min_length :slug, 10
27
- # assert_max_length :slug, 25
28
- # end
29
- # end
30
- #
31
- # post = Post.new
32
- # post.valid?
33
- # post.errors
34
- # # [[:price, :not_decimal], [:state, :not_member], [:ipaddr, :not_ipaddr],
35
- # # [:url, :not_url], [:author_email, :not_email],[:slug, :too_short]]
36
- module ExtraValidations
37
- include NumberValidations
38
- include WebValidations
39
- include DateValidations
40
- include LengthValidations
41
-
42
- protected
43
- def assert_member(att, set, error = [att, :not_member])
44
- assert set.include?(send(att)), error
45
- end
46
- end
47
- end
48
-