measured-rails 2.4.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.travis.yml +15 -12
- data/README.md +3 -0
- data/bin/console +0 -0
- data/bin/setup +0 -0
- data/dev.yml +1 -1
- data/gemfiles/{rails-4.2.gemfile → rails-5.1.gemfile} +1 -2
- data/gemfiles/rails-6.0.gemfile +5 -0
- data/lib/measured-rails.rb +1 -0
- data/lib/measured/rails/active_record.rb +2 -6
- data/lib/measured/rails/base.rb +2 -1
- data/lib/measured/rails/units/volume.rb +13 -0
- data/lib/measured/rails/version.rb +1 -1
- data/measured-rails.gemspec +4 -3
- data/test/active_record_test.rb +434 -0
- data/test/support/models/thing.rb +14 -0
- data/test/support/models/thing_with_custom_unit_accessor.rb +18 -0
- data/test/support/models/validated_thing.rb +46 -0
- data/test/support/schema.rb +83 -0
- data/test/test_helper.rb +29 -0
- data/test/validation_test.rb +237 -0
- metadata +41 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6077a6cf4bf52eb20d9601faeb82f7d86ed17cdef9f8ba1790911976d947d9e2
|
4
|
+
data.tar.gz: 39beec03cf41ae5ecfb31f3f5fc9c6910bd06741403871db080dcef7065347c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0dd1f19a73555bfdbc885ab5b0a0ac41dc5692bfa68cd573c28add607c12f94c397ed75f3e02245026db799d65b3ecdc538cf5033a49df3562375a6931a0563f
|
7
|
+
data.tar.gz: 7c15e21fe5726761ebb6364285c2872f11818158f815601b7a772576c9f99ef11a6b9f7e9bb91d229a375f9fd0eba74b6a7cb03b5abbc3e5c8003e1b283eb391
|
data/.travis.yml
CHANGED
@@ -2,24 +2,27 @@ language: ruby
|
|
2
2
|
sudo: false
|
3
3
|
cache: bundler
|
4
4
|
rvm:
|
5
|
-
- 2.
|
6
|
-
- 2.
|
7
|
-
- 2.
|
8
|
-
- 2.
|
5
|
+
- 2.3.8
|
6
|
+
- 2.4.5
|
7
|
+
- 2.5.5
|
8
|
+
- 2.6.3
|
9
9
|
gemfile:
|
10
10
|
- Gemfile
|
11
|
-
- gemfiles/rails-4.2.gemfile
|
12
11
|
- gemfiles/rails-5.0.gemfile
|
12
|
+
- gemfiles/rails-5.1.gemfile
|
13
|
+
- gemfiles/rails-6.0.gemfile
|
13
14
|
- gemfiles/rails-master.gemfile
|
15
|
+
before_script:
|
16
|
+
- gem update --system
|
14
17
|
matrix:
|
15
18
|
exclude:
|
16
|
-
- gemfile: Gemfile
|
17
|
-
rvm: 2.1.8
|
18
19
|
- gemfile: gemfiles/rails-master.gemfile
|
19
|
-
rvm: 2.
|
20
|
-
- gemfile: gemfiles/rails-
|
21
|
-
rvm: 2.
|
22
|
-
- gemfile: gemfiles/rails-
|
23
|
-
rvm: 2.
|
20
|
+
rvm: 2.3.8
|
21
|
+
- gemfile: gemfiles/rails-master.gemfile
|
22
|
+
rvm: 2.4.5
|
23
|
+
- gemfile: gemfiles/rails-6.0.gemfile
|
24
|
+
rvm: 2.3.8
|
25
|
+
- gemfile: gemfiles/rails-6.0.gemfile
|
26
|
+
rvm: 2.4.5
|
24
27
|
allow_failures:
|
25
28
|
- gemfile: gemfiles/rails-master.gemfile
|
data/README.md
CHANGED
@@ -40,6 +40,7 @@ A column can be declared as a measurement with its measurement subclass:
|
|
40
40
|
class Thing < ActiveRecord::Base
|
41
41
|
measured Measured::Weight, :minimum_weight
|
42
42
|
measured Measured::Length, :total_length
|
43
|
+
measured Measured::Volume, :total_volume
|
43
44
|
end
|
44
45
|
```
|
45
46
|
|
@@ -49,6 +50,7 @@ You can optionally customize the model's unit column by specifying it in the `un
|
|
49
50
|
class ThingWithCustomUnitAccessor < ActiveRecord::Base
|
50
51
|
measured_length :length, :width, :height, unit_field_name: :size_unit
|
51
52
|
measured_weight :total_weight, :extra_weight, unit_field_name: :weight_unit
|
53
|
+
measured_volume :total_volume, :extra_volume, unit_field_name: :volume_unit
|
52
54
|
end
|
53
55
|
```
|
54
56
|
|
@@ -58,6 +60,7 @@ There are some simpler methods for predefined types:
|
|
58
60
|
class Thing < ActiveRecord::Base
|
59
61
|
measured_weight :minimum_weight
|
60
62
|
measured_length :total_length
|
63
|
+
measured_volume :total_volume
|
61
64
|
end
|
62
65
|
```
|
63
66
|
|
data/bin/console
CHANGED
File without changes
|
data/bin/setup
CHANGED
File without changes
|
data/dev.yml
CHANGED
data/lib/measured-rails.rb
CHANGED
@@ -5,7 +5,6 @@ module Measured::Rails::ActiveRecord
|
|
5
5
|
def measured(measured_class, *fields)
|
6
6
|
options = fields.extract_options!
|
7
7
|
options = {}.merge(options)
|
8
|
-
defined_unit_accessors = []
|
9
8
|
|
10
9
|
measured_class = measured_class.constantize if measured_class.is_a?(String)
|
11
10
|
unless measured_class.is_a?(Class) && measured_class.ancestors.include?(Measured::Measurable)
|
@@ -34,7 +33,7 @@ module Measured::Rails::ActiveRecord
|
|
34
33
|
|
35
34
|
return nil unless value && unit
|
36
35
|
|
37
|
-
instance = instance_variable_get("@measured_#{ field }")
|
36
|
+
instance = instance_variable_get("@measured_#{ field }") if instance_variable_defined?("@measured_#{ field }")
|
38
37
|
new_instance = begin
|
39
38
|
measured_class.new(value, unit)
|
40
39
|
rescue Measured::UnitError
|
@@ -72,11 +71,8 @@ module Measured::Rails::ActiveRecord
|
|
72
71
|
end
|
73
72
|
end
|
74
73
|
|
75
|
-
next if defined_unit_accessors.include?(unit_field_name)
|
76
|
-
|
77
74
|
# Writer to override unit assignment
|
78
|
-
|
79
|
-
defined_unit_accessors << unit_field_name
|
75
|
+
redefine_method("#{ unit_field_name }=") do |incoming|
|
80
76
|
unit_name = measured_class.unit_system.unit_for(incoming).try!(:name)
|
81
77
|
write_attribute(unit_field_name, unit_name || incoming)
|
82
78
|
end
|
data/lib/measured/rails/base.rb
CHANGED
@@ -0,0 +1,13 @@
|
|
1
|
+
module Measured::Rails::ActiveRecord::Volume
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
module ClassMethods
|
5
|
+
def measured_volume(*fields)
|
6
|
+
measured(Measured::Volume, *fields)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
ActiveSupport.on_load(:active_record) do
|
12
|
+
::ActiveRecord::Base.send :include, Measured::Rails::ActiveRecord::Volume
|
13
|
+
end
|
data/measured-rails.gemspec
CHANGED
@@ -13,15 +13,16 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.homepage = "https://github.com/Shopify/measured-rails"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
|
-
spec.files = `git ls-files -z`.split("\x0")
|
17
|
-
spec.
|
18
|
-
spec.
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.add_runtime_dependency "measured", Measured::Rails::VERSION
|
22
22
|
|
23
23
|
spec.add_runtime_dependency "railties", ">= 4.2"
|
24
24
|
spec.add_runtime_dependency "activemodel", ">= 4.2"
|
25
|
+
spec.add_runtime_dependency "activerecord", ">= 4.2"
|
25
26
|
|
26
27
|
spec.add_development_dependency "rake", "> 10.0"
|
27
28
|
spec.add_development_dependency "minitest", "> 5.5.1"
|
@@ -0,0 +1,434 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class Measured::Rails::ActiveRecordTest < ActiveSupport::TestCase
|
4
|
+
setup do
|
5
|
+
reset_db
|
6
|
+
end
|
7
|
+
|
8
|
+
test ".measured raises if called with something that isn't a Measured::Measurable" do
|
9
|
+
assert_raises Measured::Rails::Error do
|
10
|
+
Thing.measured(Object, :field)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
test ".measured raises if called with something that isn't a class" do
|
15
|
+
assert_raises Measured::Rails::Error do
|
16
|
+
Thing.measured(:not_correct, :field)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
test ".measured raises if you attempt to define a field twice" do
|
21
|
+
assert_raises Measured::Rails::Error do
|
22
|
+
Thing.measured Measured::Length, :height
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
test ".measured defines a reader for the field" do
|
27
|
+
assert_equal length, thing.length
|
28
|
+
end
|
29
|
+
|
30
|
+
test ".measured defines a writer for the field that returns" do
|
31
|
+
assert_equal new_length, thing.length=(new_length)
|
32
|
+
end
|
33
|
+
|
34
|
+
test ".measured_fields returns the configuration for all measured fields on the class" do
|
35
|
+
expected = {
|
36
|
+
length: { class: Measured::Length },
|
37
|
+
width: { class: Measured::Length },
|
38
|
+
height: { class: Measured::Length },
|
39
|
+
volume: { class: Measured::Volume },
|
40
|
+
total_weight: { class: Measured::Weight },
|
41
|
+
extra_weight: { class: Measured::Weight },
|
42
|
+
length_with_max_on_assignment: { max_on_assignment: 500, class: Measured::Length }
|
43
|
+
}
|
44
|
+
|
45
|
+
assert_equal expected, Thing.measured_fields
|
46
|
+
end
|
47
|
+
|
48
|
+
test "reader returns the exact same object if the values are equivalent" do
|
49
|
+
thing.length = new_length
|
50
|
+
assert_equal new_length.object_id, thing.length.object_id
|
51
|
+
end
|
52
|
+
|
53
|
+
test "reader creates an instance from the _value and _unit columns" do
|
54
|
+
thing = Thing.new
|
55
|
+
thing.width_value = 23
|
56
|
+
thing.width_unit = "ft"
|
57
|
+
assert_equal Measured::Length.new(23, :ft), thing.width
|
58
|
+
end
|
59
|
+
|
60
|
+
test "reader creates creating an instance from columns caches the same object" do
|
61
|
+
thing = Thing.new
|
62
|
+
thing.width_value = 23
|
63
|
+
thing.width_unit = "ft"
|
64
|
+
assert_equal thing.width.object_id, thing.width.object_id
|
65
|
+
end
|
66
|
+
|
67
|
+
test "reader deals with only the _value column set" do
|
68
|
+
thing = Thing.new
|
69
|
+
thing.width_value = 23
|
70
|
+
assert_nil thing.width
|
71
|
+
end
|
72
|
+
|
73
|
+
test "reader deals with only the _unit column set" do
|
74
|
+
thing = Thing.new
|
75
|
+
thing.width_unit = "cm"
|
76
|
+
assert_nil thing.width
|
77
|
+
end
|
78
|
+
|
79
|
+
test "reader deals with nil-ing out the _value column" do
|
80
|
+
thing.width_value = nil
|
81
|
+
assert_nil thing.width
|
82
|
+
end
|
83
|
+
|
84
|
+
test "reader deals with nil-ing out the _unit column" do
|
85
|
+
thing.width_unit = nil
|
86
|
+
assert_nil thing.width
|
87
|
+
end
|
88
|
+
|
89
|
+
test "writer sets the value to nil if it is an incompatible object" do
|
90
|
+
thing.length = Object.new
|
91
|
+
assert_nil thing.length
|
92
|
+
end
|
93
|
+
|
94
|
+
test "writer assigning nil blanks out the unit and value columns" do
|
95
|
+
thing.width = nil
|
96
|
+
assert_nil thing.width
|
97
|
+
assert_nil thing.width_unit
|
98
|
+
assert_nil thing.width_value
|
99
|
+
end
|
100
|
+
|
101
|
+
test "assigning an invalid _unit sets the column but the measurable object is nil" do
|
102
|
+
thing.width_unit = "invalid"
|
103
|
+
assert_nil thing.width
|
104
|
+
assert_equal "invalid", thing.width_unit
|
105
|
+
end
|
106
|
+
|
107
|
+
test "assigning an invalid _unit sets the column but the measurable object is nil and there is validation on the column" do
|
108
|
+
validated_thing.length_unit = "invalid"
|
109
|
+
validated_thing.valid?
|
110
|
+
assert_nil validated_thing.length
|
111
|
+
assert_equal "invalid", validated_thing.length_unit
|
112
|
+
end
|
113
|
+
|
114
|
+
test "assigning a valid _unit sets it" do
|
115
|
+
thing.width_unit = :mm
|
116
|
+
assert_equal thing.width, Measured::Length.new(6, "mm")
|
117
|
+
assert_equal "mm", thing.width_unit
|
118
|
+
end
|
119
|
+
|
120
|
+
test "assigning a non-base unit to _unit converts it to its base unit" do
|
121
|
+
thing.width_unit = "millimetre"
|
122
|
+
assert_equal thing.width, Measured::Length.new(6, "mm")
|
123
|
+
assert_equal "mm", thing.width_unit
|
124
|
+
end
|
125
|
+
|
126
|
+
test "building a new object from attributes builds a measured object" do
|
127
|
+
thing = Thing.new(length_value: "30", length_unit: "m")
|
128
|
+
assert_equal Measured::Length.new(30, :m), thing.length
|
129
|
+
end
|
130
|
+
|
131
|
+
test "building a new object with a measured object assigns the properties" do
|
132
|
+
thing = Thing.new(length: new_length)
|
133
|
+
assert_equal new_length, thing.length
|
134
|
+
assert_equal 20, thing.length_value
|
135
|
+
assert_equal "in", thing.length_unit
|
136
|
+
end
|
137
|
+
|
138
|
+
test "assigning attributes updates the measured object" do
|
139
|
+
thing.attributes = {length_value: "30", length_unit: "m"}
|
140
|
+
assert_equal Measured::Length.new(30, :m), thing.length
|
141
|
+
end
|
142
|
+
|
143
|
+
test "assigning partial attributes updates the measured object" do
|
144
|
+
thing.attributes = {length_value: "30"}
|
145
|
+
assert_equal Measured::Length.new(30, :cm), thing.length
|
146
|
+
end
|
147
|
+
|
148
|
+
test "assigning the _unit leaves the _value unchanged" do
|
149
|
+
thing.total_weight_unit = :lb
|
150
|
+
assert_equal thing.total_weight, Measured::Weight.new(200, "lb")
|
151
|
+
end
|
152
|
+
|
153
|
+
test "assigning the _value leaves the _unit unchanged" do
|
154
|
+
thing.total_weight_value = "10"
|
155
|
+
assert_equal thing.total_weight, Measured::Weight.new(10, :g)
|
156
|
+
end
|
157
|
+
|
158
|
+
test "assigning the _unit to an invalid unit does not raise" do
|
159
|
+
thing.total_weight_value = 123
|
160
|
+
thing.total_weight_unit = :invalid
|
161
|
+
assert_nil thing.total_weight
|
162
|
+
end
|
163
|
+
|
164
|
+
test "save persists the attributes and retrieves an object" do
|
165
|
+
thing = Thing.new length: Measured::Length.new(3, :m)
|
166
|
+
assert thing.save
|
167
|
+
assert_equal 3, thing.length_value
|
168
|
+
assert_equal "m", thing.length_unit
|
169
|
+
thing.reload
|
170
|
+
assert_equal 3, thing.length_value
|
171
|
+
assert_equal "m", thing.length_unit
|
172
|
+
end
|
173
|
+
|
174
|
+
test "save pulls attributes from assigned object" do
|
175
|
+
thing = Thing.new total_weight_value: "100", total_weight_unit: :lb
|
176
|
+
assert thing.save
|
177
|
+
thing.reload
|
178
|
+
assert_equal 100, thing.total_weight_value
|
179
|
+
assert_equal "lb", thing.total_weight_unit
|
180
|
+
assert_equal Measured::Weight.new(100, :lb), thing.total_weight
|
181
|
+
end
|
182
|
+
|
183
|
+
test "save succeeds if you assign an invalid unit and there is no validation" do
|
184
|
+
thing = Thing.new total_weight_value: "100", total_weight_unit: :invalid
|
185
|
+
assert thing.save
|
186
|
+
thing.reload
|
187
|
+
assert_nil thing.total_weight
|
188
|
+
assert_equal 100, thing.total_weight_value
|
189
|
+
end
|
190
|
+
|
191
|
+
test "save fails if you assign an invalid unit and there is validation" do
|
192
|
+
thing = validated_thing
|
193
|
+
thing.length_unit = "invalid"
|
194
|
+
refute thing.save
|
195
|
+
assert_nil thing.length
|
196
|
+
end
|
197
|
+
|
198
|
+
test "update_attribute sets only the _value column" do
|
199
|
+
thing = Thing.create!
|
200
|
+
thing.update_attribute(:width_value, 11)
|
201
|
+
assert_nil thing.width
|
202
|
+
end
|
203
|
+
|
204
|
+
test "update_attribute sets only the _unit column" do
|
205
|
+
thing = Thing.create!
|
206
|
+
thing.update_attribute(:width_unit, "cm")
|
207
|
+
assert_nil thing.width
|
208
|
+
end
|
209
|
+
|
210
|
+
test "update_attribute modifies the _value column" do
|
211
|
+
assert thing.update_attribute(:width_value, 99)
|
212
|
+
assert_equal Measured::Length.new(99, :in), thing.width
|
213
|
+
end
|
214
|
+
|
215
|
+
test "update_attribute modifies only the _unit column" do
|
216
|
+
assert thing.update_attribute(:width_unit, :cm)
|
217
|
+
assert_equal Measured::Length.new(6, :cm), thing.width
|
218
|
+
end
|
219
|
+
|
220
|
+
test "update_attribute sets one then the other" do
|
221
|
+
thing = Thing.create!
|
222
|
+
assert thing.update_attribute(:width_value, 11.1)
|
223
|
+
assert_nil thing.width
|
224
|
+
assert thing.update_attribute(:width_unit, "cm")
|
225
|
+
assert_equal Measured::Length.new(11.1, :cm), thing.width
|
226
|
+
end
|
227
|
+
|
228
|
+
test "update_attributes sets only the _value column" do
|
229
|
+
thing = Thing.create!
|
230
|
+
assert thing.update_attributes(width_value: "314")
|
231
|
+
assert_equal 314, thing.width_value
|
232
|
+
thing.reload
|
233
|
+
assert_equal 314, thing.width_value
|
234
|
+
assert_nil thing.width
|
235
|
+
end
|
236
|
+
|
237
|
+
test "update_attributes sets only the _unit column" do
|
238
|
+
thing = Thing.create!
|
239
|
+
assert thing.update_attributes(width_unit: :cm)
|
240
|
+
assert_equal "cm", thing.width_unit
|
241
|
+
thing.reload
|
242
|
+
assert_equal "cm", thing.width_unit
|
243
|
+
assert_nil thing.width
|
244
|
+
end
|
245
|
+
|
246
|
+
test "update_attributes sets only the _unit column and converts it" do
|
247
|
+
thing = Thing.create!
|
248
|
+
assert thing.update_attributes(width_unit: "inch")
|
249
|
+
assert_equal "in", thing.width_unit
|
250
|
+
thing.reload
|
251
|
+
assert_equal "in", thing.width_unit
|
252
|
+
end
|
253
|
+
|
254
|
+
test "update_attributes sets the _unit column to something invalid" do
|
255
|
+
thing = Thing.create!
|
256
|
+
assert thing.update_attributes(width_unit: :invalid)
|
257
|
+
assert_equal "invalid", thing.width_unit
|
258
|
+
thing.reload
|
259
|
+
assert_equal "invalid", thing.width_unit
|
260
|
+
assert_nil thing.width
|
261
|
+
end
|
262
|
+
|
263
|
+
test "update_attributes does not set the _unit column to something invalid if there is validation" do
|
264
|
+
thing = validated_thing
|
265
|
+
thing.save!
|
266
|
+
refute thing.update_attributes(length_unit: :invalid)
|
267
|
+
end
|
268
|
+
|
269
|
+
test "update_attributes sets one column then the other" do
|
270
|
+
thing = Thing.create!
|
271
|
+
assert thing.update_attributes(width_unit: "inch")
|
272
|
+
assert_nil thing.width
|
273
|
+
assert thing.update_attributes(width_value: "314")
|
274
|
+
assert_equal Measured::Length.new(314, :in), thing.width
|
275
|
+
end
|
276
|
+
|
277
|
+
test "update_attributes sets both columns" do
|
278
|
+
thing = Thing.create!
|
279
|
+
assert thing.update_attributes(width_unit: :cm, width_value: 2)
|
280
|
+
assert_equal Measured::Length.new(2, :cm), thing.width
|
281
|
+
thing.reload
|
282
|
+
assert_equal Measured::Length.new(2, :cm), thing.width
|
283
|
+
end
|
284
|
+
|
285
|
+
test "update_attributes modifies the _value column" do
|
286
|
+
assert thing.update_attributes(height_value: 2)
|
287
|
+
assert_equal Measured::Length.new(2, :m), thing.height
|
288
|
+
thing.reload
|
289
|
+
assert_equal Measured::Length.new(2, :m), thing.height
|
290
|
+
end
|
291
|
+
|
292
|
+
test "update_attributes modifies only the _unit column" do
|
293
|
+
assert thing.update_attributes(height_unit: "foot")
|
294
|
+
assert_equal Measured::Length.new(1, :ft), thing.height
|
295
|
+
thing.reload
|
296
|
+
assert_equal Measured::Length.new(1, :ft), thing.height
|
297
|
+
end
|
298
|
+
|
299
|
+
test "update_attributes modifies the _unit column to be something invalid" do
|
300
|
+
assert thing.update_attributes(height_unit: :invalid)
|
301
|
+
assert_nil thing.height
|
302
|
+
assert_equal "invalid", thing.height_unit
|
303
|
+
thing.reload
|
304
|
+
assert_nil thing.height
|
305
|
+
assert_equal "invalid", thing.height_unit
|
306
|
+
end
|
307
|
+
|
308
|
+
test "update_attributes modifies both columns" do
|
309
|
+
assert thing.update_attributes(height_unit: "mm", height_value: 1.23)
|
310
|
+
assert_equal Measured::Length.new(1.23, :mm), thing.height
|
311
|
+
thing.reload
|
312
|
+
assert_equal Measured::Length.new(1.23, :mm), thing.height
|
313
|
+
end
|
314
|
+
|
315
|
+
test "assigning the _value with a BigDecimal rounds to the column's rounding scale" do
|
316
|
+
thing.height = Measured::Length.new(BigDecimal('23.4567891'), :mm)
|
317
|
+
assert_equal thing.height_value, BigDecimal('23.46')
|
318
|
+
end
|
319
|
+
|
320
|
+
test "assigning the _value with a float uses all the rounding scale permissible" do
|
321
|
+
thing.height = Measured::Length.new(4.45678912, :mm)
|
322
|
+
assert_equal thing.height_value, BigDecimal('4.46')
|
323
|
+
end
|
324
|
+
|
325
|
+
test "assigning a number with more significant digits than permitted by the column precision does not raise exception when it can be rounded to have lesser significant digits per column's scale" do
|
326
|
+
assert_nothing_raised do
|
327
|
+
thing.height = Measured::Length.new(4.45678912123123123, :mm)
|
328
|
+
assert_equal thing.height_value, BigDecimal('4.46')
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
test "assigning a number with more significant digits than permitted by the column precision raises exception" do
|
333
|
+
assert_raises Measured::Rails::Error, "The value 44567891212312312.3 being set for column: 'height' has too many significant digits. Please ensure it has no more than 10 significant digits." do
|
334
|
+
thing.height = Measured::Length.new(44567891212312312.3, :mm)
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
test "assigning a large number but with a small amount of significant digits than permitted by the column precision raises exception" do
|
339
|
+
assert_raises Measured::Rails::Error, "The value 2000000000000000.0 being set for column: 'height' has too many significant digits. Please ensure it has no more than 10 significant digits." do
|
340
|
+
thing.height = Measured::Length.new(2_000_000_000_000_000, :mm)
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
test "assigning a large number that's just smaller, equal to, and over the size of the column precision raises exception" do
|
345
|
+
assert_nothing_raised do
|
346
|
+
thing.height = Measured::Length.new(99999999.99, :mm)
|
347
|
+
end
|
348
|
+
|
349
|
+
assert_raises Measured::Rails::Error, "The value 100000000.0 being set for column: 'height' has too many significant digits. Please ensure it has no more than 10 significant digits." do
|
350
|
+
thing.height = Measured::Length.new(100000000, :mm)
|
351
|
+
end
|
352
|
+
|
353
|
+
assert_raises Measured::Rails::Error, "The value 100000000.01 being set for column: 'height' has too many significant digits. Please ensure it has no more than 10 significant digits." do
|
354
|
+
thing.height = Measured::Length.new(100000000.01, :mm)
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
test "assigning a large number to a field that specifies max_on_assignment" do
|
359
|
+
thing = Thing.create!(length_with_max_on_assignment: Measured::Length.new(10000000000000000, :mm))
|
360
|
+
assert_equal Measured::Length.new(500, :mm), thing.length_with_max_on_assignment
|
361
|
+
end
|
362
|
+
|
363
|
+
test "assigning a small number to a field that specifies max_on_assignment" do
|
364
|
+
thing = Thing.create!(length_with_max_on_assignment: Measured::Length.new(1, :mm))
|
365
|
+
assert_equal Measured::Length.new(1, :mm), thing.length_with_max_on_assignment
|
366
|
+
end
|
367
|
+
|
368
|
+
test "using a similar unit accessor for multiple size fields" do
|
369
|
+
assert_equal Measured::Length.new(1, :m), custom_unit_thing.length
|
370
|
+
assert_equal Measured::Length.new(2, :m), custom_unit_thing.width
|
371
|
+
assert_equal Measured::Length.new(3, :m), custom_unit_thing.height
|
372
|
+
assert_equal Measured::Volume.new(9, :l), custom_unit_thing.volume
|
373
|
+
assert_equal Measured::Weight.new(10, :g), custom_unit_thing.total_weight
|
374
|
+
assert_equal Measured::Weight.new(12, :g), custom_unit_thing.extra_weight
|
375
|
+
end
|
376
|
+
|
377
|
+
test "changing unit value when shared affects all fields" do
|
378
|
+
custom_unit_thing.length = Measured::Length.new(15, :in)
|
379
|
+
custom_unit_thing.total_weight = Measured::Weight.new(42, :kg)
|
380
|
+
|
381
|
+
assert_equal custom_unit_thing.length, Measured::Length.new(15, :in)
|
382
|
+
assert_equal custom_unit_thing.width, Measured::Length.new(2, :in)
|
383
|
+
assert_equal custom_unit_thing.height, Measured::Length.new(3, :in)
|
384
|
+
assert_equal custom_unit_thing.total_weight, Measured::Weight.new(42, :kg)
|
385
|
+
assert_equal custom_unit_thing.extra_weight, Measured::Weight.new(12, :kg)
|
386
|
+
end
|
387
|
+
|
388
|
+
private
|
389
|
+
|
390
|
+
def length
|
391
|
+
@length ||= Measured::Length.new(10, :cm)
|
392
|
+
end
|
393
|
+
|
394
|
+
def new_length
|
395
|
+
@new_length ||= Measured::Length.new(20, :in)
|
396
|
+
end
|
397
|
+
|
398
|
+
def thing
|
399
|
+
@thing ||= Thing.create!(
|
400
|
+
length: length,
|
401
|
+
width: Measured::Length.new(6, :in),
|
402
|
+
volume: Measured::Volume.new(6, :l),
|
403
|
+
height: Measured::Length.new(1, :m),
|
404
|
+
total_weight: Measured::Weight.new(200, :g),
|
405
|
+
extra_weight: Measured::Weight.new(16, :oz)
|
406
|
+
)
|
407
|
+
end
|
408
|
+
|
409
|
+
def validated_thing
|
410
|
+
@thing ||= ValidatedThing.new(
|
411
|
+
length: Measured::Length.new(1, :m),
|
412
|
+
length_true: Measured::Length.new(2, :cm),
|
413
|
+
length_message: Measured::Length.new(3, :mm),
|
414
|
+
length_message_from_block: Measured::Length.new(7, :mm),
|
415
|
+
length_units: Measured::Length.new(4, :m),
|
416
|
+
length_units_singular: Measured::Length.new(5, :ft),
|
417
|
+
length_presence: Measured::Length.new(6, :m),
|
418
|
+
length_numericality_inclusive: Measured::Length.new(15, :in),
|
419
|
+
length_numericality_exclusive: Measured::Length.new(4, :m),
|
420
|
+
length_numericality_equality: Measured::Length.new(100, :cm),
|
421
|
+
)
|
422
|
+
end
|
423
|
+
|
424
|
+
def custom_unit_thing
|
425
|
+
@custom_unit_thing ||= ThingWithCustomUnitAccessor.new(
|
426
|
+
length: Measured::Length.new(1, :m),
|
427
|
+
width: Measured::Length.new(2, :m),
|
428
|
+
height: Measured::Length.new(3, :m),
|
429
|
+
volume: Measured::Volume.new(9, :l),
|
430
|
+
total_weight: Measured::Weight.new(10, :g),
|
431
|
+
extra_weight: Measured::Weight.new(12, :g),
|
432
|
+
)
|
433
|
+
end
|
434
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class Thing < ActiveRecord::Base
|
2
|
+
|
3
|
+
measured_length :length, :width
|
4
|
+
|
5
|
+
measured Measured::Length, :height
|
6
|
+
measured Measured::Volume, :volume
|
7
|
+
|
8
|
+
measured_weight :total_weight
|
9
|
+
|
10
|
+
measured "Measured::Weight", :extra_weight
|
11
|
+
|
12
|
+
measured_length :length_with_max_on_assignment, {max_on_assignment: 500}
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class ThingWithCustomUnitAccessor < ActiveRecord::Base
|
2
|
+
|
3
|
+
measured_length :length, :width, unit_field_name: :size_unit
|
4
|
+
validates :length, measured: true
|
5
|
+
validates :width, measured: true
|
6
|
+
|
7
|
+
measured_volume :volume
|
8
|
+
validates :volume, measured: true
|
9
|
+
|
10
|
+
measured Measured::Length, :height, unit_field_name: :size_unit
|
11
|
+
validates :height, measured: true
|
12
|
+
|
13
|
+
measured_weight :total_weight, unit_field_name: :weight_unit
|
14
|
+
validates :total_weight, measured: true
|
15
|
+
|
16
|
+
measured "Measured::Weight", :extra_weight, unit_field_name: :weight_unit
|
17
|
+
validates :extra_weight, measured: true
|
18
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
class ValidatedThing < ActiveRecord::Base
|
2
|
+
|
3
|
+
measured_length :length
|
4
|
+
validates :length, measured: true
|
5
|
+
|
6
|
+
measured_length :length_true
|
7
|
+
validates :length_true, measured: true
|
8
|
+
|
9
|
+
measured_length :length_message
|
10
|
+
validates :length_message, measured: {message: "has a custom failure message"}
|
11
|
+
|
12
|
+
measured_length :length_message_from_block
|
13
|
+
validates :length_message_from_block, measured: { message: Proc.new { |record| "#{record.length_message_from_block_unit} is not a valid unit" } }
|
14
|
+
|
15
|
+
measured_length :length_units
|
16
|
+
validates :length_units, measured: {units: [:meter, "cm"]}
|
17
|
+
|
18
|
+
measured_length :length_units_singular
|
19
|
+
validates :length_units_singular, measured: {units: :ft, message: "custom message too"}
|
20
|
+
|
21
|
+
measured_length :length_presence
|
22
|
+
validates :length_presence, measured: true, presence: true
|
23
|
+
|
24
|
+
measured_length :length_numericality_inclusive
|
25
|
+
validates :length_numericality_inclusive, measured: {greater_than_or_equal_to: :low_bound, less_than_or_equal_to: :high_bound }
|
26
|
+
|
27
|
+
measured_length :length_numericality_exclusive
|
28
|
+
validates :length_numericality_exclusive, measured: {greater_than: Measured::Length.new(3, :m), less_than: Measured::Length.new(500, :cm), message: "is super not ok"}
|
29
|
+
|
30
|
+
measured_length :length_numericality_equality
|
31
|
+
validates :length_numericality_equality, measured: {equal_to: Proc.new { Measured::Length.new(100, :cm) }, message: "must be exactly 100cm"}
|
32
|
+
|
33
|
+
measured_length :length_invalid_comparison
|
34
|
+
validates :length_invalid_comparison, measured: {equal_to: "not_a_measured_subclass"}
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def low_bound
|
39
|
+
Measured::Length.new(10, :in)
|
40
|
+
end
|
41
|
+
|
42
|
+
def high_bound
|
43
|
+
Measured::Length.new(20, :in)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# This file is auto-generated from the current state of the database. Instead
|
2
|
+
# of editing this file, please use the migrations feature of Active Record to
|
3
|
+
# incrementally modify your database, and then regenerate this schema definition.
|
4
|
+
#
|
5
|
+
# Note that this schema.rb definition is the authoritative source for your
|
6
|
+
# database schema. If you need to create the application database on another
|
7
|
+
# system, you should be using db:schema:load, not running all the migrations
|
8
|
+
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
9
|
+
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
10
|
+
#
|
11
|
+
# It's strongly recommended that you check this file into your version control system.
|
12
|
+
|
13
|
+
ActiveRecord::Schema.define(version: 20161118203701) do
|
14
|
+
|
15
|
+
create_table "thing_with_custom_unit_accessors", force: :cascade do |t|
|
16
|
+
t.decimal "length_value", precision: 10, scale: 2
|
17
|
+
t.decimal "width_value", precision: 10, scale: 2
|
18
|
+
t.decimal "height_value", precision: 10, scale: 2
|
19
|
+
t.decimal "volume_value", precision: 10, scale: 2
|
20
|
+
t.string "volume_unit", limit: 12
|
21
|
+
t.string "size_unit", limit: 12
|
22
|
+
t.decimal "total_weight_value", precision: 10, scale: 2, default: "10.0"
|
23
|
+
t.decimal "extra_weight_value", precision: 10, scale: 2
|
24
|
+
t.string "weight_unit", limit: 12
|
25
|
+
t.datetime "created_at", null: false
|
26
|
+
t.datetime "updated_at", null: false
|
27
|
+
end
|
28
|
+
|
29
|
+
create_table "things", force: :cascade do |t|
|
30
|
+
t.decimal "length_value", precision: 10, scale: 2
|
31
|
+
t.string "length_unit", limit: 12
|
32
|
+
t.decimal "width_value", precision: 10, scale: 2
|
33
|
+
t.string "width_unit", limit: 12
|
34
|
+
t.decimal "height_value", precision: 10, scale: 2
|
35
|
+
t.string "height_unit", limit: 12
|
36
|
+
t.decimal "volume_value", precision: 10, scale: 2
|
37
|
+
t.string "volume_unit", limit: 12
|
38
|
+
t.decimal "total_weight_value", precision: 10, scale: 2, default: "10.0"
|
39
|
+
t.string "total_weight_unit", limit: 12, default: "g"
|
40
|
+
t.decimal "extra_weight_value", precision: 10, scale: 2
|
41
|
+
t.string "extra_weight_unit", limit: 12
|
42
|
+
t.decimal "length_with_max_on_assignment_value", precision: 10, scale: 2
|
43
|
+
t.string "length_with_max_on_assignment_unit", limit: 12
|
44
|
+
t.datetime "created_at", null: false
|
45
|
+
t.datetime "updated_at", null: false
|
46
|
+
end
|
47
|
+
|
48
|
+
create_table "validated_things", force: :cascade do |t|
|
49
|
+
t.decimal "length_value", precision: 10, scale: 2
|
50
|
+
t.string "length_unit", limit: 12
|
51
|
+
t.decimal "length_true_value", precision: 10, scale: 2
|
52
|
+
t.string "length_true_unit", limit: 12
|
53
|
+
t.decimal "length_message_value", precision: 10, scale: 2
|
54
|
+
t.string "length_message_unit", limit: 12
|
55
|
+
t.decimal "length_message_from_block_value", precision: 10, scale: 2
|
56
|
+
t.string "length_message_from_block_unit", limit: 12
|
57
|
+
t.decimal "length_units_value", precision: 10, scale: 2
|
58
|
+
t.string "length_units_unit", limit: 12
|
59
|
+
t.decimal "length_units_singular_value", precision: 10, scale: 2
|
60
|
+
t.string "length_units_singular_unit", limit: 12
|
61
|
+
t.decimal "length_presence_value", precision: 10, scale: 2
|
62
|
+
t.string "length_presence_unit", limit: 12
|
63
|
+
t.decimal "length_invalid_value", precision: 10, scale: 2
|
64
|
+
t.string "length_invalid_unit", limit: 12
|
65
|
+
t.datetime "created_at", null: false
|
66
|
+
t.datetime "updated_at", null: false
|
67
|
+
t.decimal "length_numericality_inclusive_value", precision: 10, scale: 2
|
68
|
+
t.string "length_numericality_inclusive_unit", limit: 12
|
69
|
+
t.decimal "length_numericality_exclusive_value", precision: 10, scale: 2
|
70
|
+
t.string "length_numericality_exclusive_unit", limit: 12
|
71
|
+
t.decimal "length_numericality_equality_value", precision: 10, scale: 2
|
72
|
+
t.string "length_numericality_equality_unit", limit: 12
|
73
|
+
t.decimal "length_invalid_comparison_value", precision: 10, scale: 2
|
74
|
+
t.string "length_invalid_comparison_unit", limit: 12
|
75
|
+
t.decimal "length_non_zero_scalar_value", precision: 10, scale: 2
|
76
|
+
t.string "length_non_zero_scalar_unit", limit: 12
|
77
|
+
t.decimal "length_zero_scalar_value", precision: 10, scale: 2
|
78
|
+
t.string "length_zero_scalar_unit", limit: 12
|
79
|
+
t.decimal "length_numericality_less_than_than_scalar_value", precision: 10, scale: 2
|
80
|
+
t.string "length_numericality_less_than_than_scalar_unit", limit: 12
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require "pry" unless ENV["CI"]
|
2
|
+
require "measured"
|
3
|
+
require "measured-rails"
|
4
|
+
require "minitest/autorun"
|
5
|
+
require "minitest/reporters"
|
6
|
+
require "mocha/setup"
|
7
|
+
|
8
|
+
ActiveSupport.test_order = :random
|
9
|
+
|
10
|
+
# Prevent two reporters from printing
|
11
|
+
# https://github.com/kern/minitest-reporters/issues/230
|
12
|
+
# https://github.com/rails/rails/issues/30491
|
13
|
+
Minitest.load_plugins
|
14
|
+
Minitest.extensions.delete('rails')
|
15
|
+
Minitest.extensions.unshift('rails')
|
16
|
+
|
17
|
+
Minitest::Reporters.use! [Minitest::Reporters::ProgressReporter.new(color: true)]
|
18
|
+
|
19
|
+
class ActiveSupport::TestCase
|
20
|
+
def reset_db
|
21
|
+
ActiveRecord::Base.subclasses.each do |model|
|
22
|
+
model.delete_all
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
Dir.glob(File.expand_path("../support/models/*.rb", __FILE__)).each { |r| require r }
|
28
|
+
ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
|
29
|
+
require_relative "support/schema.rb"
|
@@ -0,0 +1,237 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class Measured::Rails::ValidationTest < ActiveSupport::TestCase
|
4
|
+
setup do
|
5
|
+
reset_db
|
6
|
+
end
|
7
|
+
|
8
|
+
test "validation mock is valid" do
|
9
|
+
assert thing.valid?
|
10
|
+
end
|
11
|
+
|
12
|
+
test "validation measurable: validation leaves a model valid and deals with blank unit" do
|
13
|
+
assert ValidatedThing.new(length_presence: Measured::Length.new(4, :in)).valid?
|
14
|
+
end
|
15
|
+
|
16
|
+
test "validation fails when unit is nil" do
|
17
|
+
thing.length_unit = ''
|
18
|
+
refute thing.valid?
|
19
|
+
assert_equal({ length: "is not a valid unit" }, thing.errors.to_h)
|
20
|
+
end
|
21
|
+
|
22
|
+
test "validation fails on model with custom unit with nil value" do
|
23
|
+
custom_unit_thing.size_unit = ''
|
24
|
+
refute custom_unit_thing.valid?
|
25
|
+
assert_equal(
|
26
|
+
{
|
27
|
+
length: "is not a valid unit",
|
28
|
+
width: "is not a valid unit",
|
29
|
+
height: "is not a valid unit",
|
30
|
+
},
|
31
|
+
custom_unit_thing.errors.to_h
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
test "validation true works by default" do
|
36
|
+
thing.length_unit = "junk"
|
37
|
+
refute thing.valid?
|
38
|
+
assert_equal ["Length is not a valid unit"], thing.errors.full_messages
|
39
|
+
end
|
40
|
+
|
41
|
+
test "validation can override the message with a static string" do
|
42
|
+
thing.length_message_unit = "junk"
|
43
|
+
refute thing.valid?
|
44
|
+
assert_equal ["Length message has a custom failure message"], thing.errors.full_messages
|
45
|
+
end
|
46
|
+
|
47
|
+
test "validation can override the message with a block" do
|
48
|
+
thing.length_message_from_block_unit = "junk"
|
49
|
+
refute thing.valid?
|
50
|
+
assert_equal ["Length message from block junk is not a valid unit"], thing.errors.full_messages
|
51
|
+
end
|
52
|
+
|
53
|
+
test "validation may be any valid unit" do
|
54
|
+
length_units.each do |unit|
|
55
|
+
thing.length_unit = unit
|
56
|
+
assert thing.valid?
|
57
|
+
thing.length_unit = unit.to_s
|
58
|
+
assert thing.valid?
|
59
|
+
thing.length = Measured::Length.new(123, unit)
|
60
|
+
assert thing.valid?
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
test "validation accepts a list of units in any format as an option and only allows them to be valid" do
|
65
|
+
thing.length_units_unit = :m
|
66
|
+
assert thing.valid?
|
67
|
+
thing.length_units_unit = :cm
|
68
|
+
assert thing.valid?
|
69
|
+
thing.length_units_unit = "cm"
|
70
|
+
assert thing.valid?
|
71
|
+
thing.length_units_unit = "meter"
|
72
|
+
assert thing.valid?
|
73
|
+
thing.length_units = Measured::Length.new(3, :cm)
|
74
|
+
assert thing.valid?
|
75
|
+
thing.length_units_unit = :mm
|
76
|
+
refute thing.valid?
|
77
|
+
thing.length_units = Measured::Length.new(3, :ft)
|
78
|
+
refute thing.valid?
|
79
|
+
end
|
80
|
+
|
81
|
+
test "validation lets the unit be singular" do
|
82
|
+
thing.length_units_singular_unit = :ft
|
83
|
+
assert thing.valid?
|
84
|
+
thing.length_units_singular_unit = "feet"
|
85
|
+
assert thing.valid?
|
86
|
+
thing.length_units_singular_unit = :mm
|
87
|
+
refute thing.valid?
|
88
|
+
thing.length_units_singular_unit = "meter"
|
89
|
+
refute thing.valid?
|
90
|
+
end
|
91
|
+
|
92
|
+
test "validation for unit reasons uses the default message" do
|
93
|
+
thing.length_units_unit = :mm
|
94
|
+
refute thing.valid?
|
95
|
+
assert_equal ["Length units is not a valid unit"], thing.errors.full_messages
|
96
|
+
end
|
97
|
+
|
98
|
+
test "validation for unit reasons also uses the custom message" do
|
99
|
+
thing.length_units_singular_unit = :mm
|
100
|
+
refute thing.valid?
|
101
|
+
assert_equal ["Length units singular custom message too"], thing.errors.full_messages
|
102
|
+
end
|
103
|
+
|
104
|
+
test "validation for unit reasons adds one message if unit is not supported by default and is not custom supported" do
|
105
|
+
thing.length_units_singular_unit = :t
|
106
|
+
refute thing.valid?
|
107
|
+
|
108
|
+
assert_equal ["Length units singular custom message too"], thing.errors.full_messages
|
109
|
+
end
|
110
|
+
|
111
|
+
test "validation presence works on measured columns" do
|
112
|
+
thing.length_presence = nil
|
113
|
+
refute thing.valid?
|
114
|
+
assert_equal ["Length presence can't be blank"], thing.errors.full_messages
|
115
|
+
thing.length_presence_unit = "m"
|
116
|
+
refute thing.valid?
|
117
|
+
thing.length_presence_value = "3"
|
118
|
+
assert thing.valid?
|
119
|
+
end
|
120
|
+
|
121
|
+
test "validation fails if only only the value is set" do
|
122
|
+
thing.length_unit = nil
|
123
|
+
refute thing.valid?
|
124
|
+
end
|
125
|
+
|
126
|
+
test "validation checks that numericality comparisons are against a Measurable subclass" do
|
127
|
+
thing.length_invalid_comparison = Measured::Length.new(30, :in)
|
128
|
+
assert_raises ArgumentError, ":not_a_measured_subclass must be a Measurable object" do
|
129
|
+
thing.valid?
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
test "validation for numericality uses a default invalid message" do
|
134
|
+
thing.length_numericality_inclusive = Measured::Length.new(30, :in)
|
135
|
+
refute thing.valid?
|
136
|
+
assert_equal ["Length numericality inclusive 30 in must be <= 20 in"], thing.errors.full_messages
|
137
|
+
|
138
|
+
thing.length_numericality_inclusive = Measured::Length.new(1, :mm)
|
139
|
+
refute thing.valid?
|
140
|
+
assert_equal ["Length numericality inclusive 1 mm must be >= 10 in"], thing.errors.full_messages
|
141
|
+
end
|
142
|
+
|
143
|
+
test "validation for numericality uses the override message" do
|
144
|
+
thing.length_numericality_exclusive = Measured::Length.new(2, :m)
|
145
|
+
refute thing.valid?
|
146
|
+
assert_equal ["Length numericality exclusive is super not ok"], thing.errors.full_messages
|
147
|
+
|
148
|
+
thing.length_numericality_exclusive = Measured::Length.new(6000, :mm)
|
149
|
+
refute thing.valid?
|
150
|
+
assert_equal ["Length numericality exclusive is super not ok"], thing.errors.full_messages
|
151
|
+
end
|
152
|
+
|
153
|
+
test "validation for numericality checks :greater_than and :less_than and can use symbols as method names to look up values" do
|
154
|
+
thing.length_numericality_exclusive = Measured::Length.new(4, :m)
|
155
|
+
assert thing.valid?
|
156
|
+
|
157
|
+
thing.length_numericality_exclusive = Measured::Length.new(1, :m)
|
158
|
+
refute thing.valid?
|
159
|
+
end
|
160
|
+
|
161
|
+
test "validation for numericality checks :greater_than_or_equal_to and :less_than_or_equal_to" do
|
162
|
+
thing.length_numericality_inclusive = Measured::Length.new(10, :in)
|
163
|
+
assert thing.valid?
|
164
|
+
|
165
|
+
thing.length_numericality_exclusive = Measured::Length.new(3, :m)
|
166
|
+
refute thing.valid?
|
167
|
+
end
|
168
|
+
|
169
|
+
test "validation for numericality checks :equal_to and can use procs to look up values" do
|
170
|
+
thing.length_numericality_equality = Measured::Length.new(100, :cm)
|
171
|
+
assert thing.valid?
|
172
|
+
|
173
|
+
thing.length_numericality_equality = Measured::Length.new(1, :m)
|
174
|
+
assert thing.valid?
|
175
|
+
|
176
|
+
thing.length_numericality_equality = Measured::Length.new("99.9", :cm)
|
177
|
+
refute thing.valid?
|
178
|
+
|
179
|
+
thing.length_numericality_equality = Measured::Length.new(101, :cm)
|
180
|
+
refute thing.valid?
|
181
|
+
end
|
182
|
+
|
183
|
+
test "validation for numericality handles a nil unit but a valid value" do
|
184
|
+
thing.length_numericality_exclusive_unit = nil
|
185
|
+
thing.length_numericality_exclusive_value = 1
|
186
|
+
refute thing.valid?
|
187
|
+
end
|
188
|
+
|
189
|
+
test "allow a nil value but a valid unit" do
|
190
|
+
thing.length_numericality_exclusive_unit = :cm
|
191
|
+
thing.length_numericality_exclusive_value = nil
|
192
|
+
assert thing.valid?
|
193
|
+
end
|
194
|
+
|
195
|
+
test "validations work as expected given a measured field with custom validators" do
|
196
|
+
assert custom_unit_thing.valid?
|
197
|
+
|
198
|
+
assert custom_unit_thing.size_unit = 'invalid'
|
199
|
+
|
200
|
+
refute custom_unit_thing.valid?
|
201
|
+
|
202
|
+
assert_equal(custom_unit_thing.errors[:length], ["is not a valid unit"])
|
203
|
+
assert_equal(custom_unit_thing.errors[:height], ["is not a valid unit"])
|
204
|
+
assert_equal(custom_unit_thing.errors[:width], ["is not a valid unit"])
|
205
|
+
end
|
206
|
+
|
207
|
+
private
|
208
|
+
|
209
|
+
def thing
|
210
|
+
@thing ||= ValidatedThing.new(
|
211
|
+
length: Measured::Length.new(1, :m),
|
212
|
+
length_true: Measured::Length.new(2, :cm),
|
213
|
+
length_message: Measured::Length.new(3, :mm),
|
214
|
+
length_message_from_block: Measured::Length.new(7, :mm),
|
215
|
+
length_units: Measured::Length.new(4, :m),
|
216
|
+
length_units_singular: Measured::Length.new(5, :ft),
|
217
|
+
length_presence: Measured::Length.new(6, :m),
|
218
|
+
length_numericality_inclusive: Measured::Length.new(15, :in),
|
219
|
+
length_numericality_exclusive: Measured::Length.new(4, :m),
|
220
|
+
length_numericality_equality: Measured::Length.new(100, :cm),
|
221
|
+
)
|
222
|
+
end
|
223
|
+
|
224
|
+
def custom_unit_thing
|
225
|
+
@custom_unit_thing ||= ThingWithCustomUnitAccessor.new(
|
226
|
+
length: Measured::Length.new(1, :m),
|
227
|
+
width: Measured::Length.new(2, :m),
|
228
|
+
height: Measured::Length.new(3, :m),
|
229
|
+
total_weight: Measured::Weight.new(10, :g),
|
230
|
+
extra_weight: Measured::Weight.new(12, :g),
|
231
|
+
)
|
232
|
+
end
|
233
|
+
|
234
|
+
def length_units
|
235
|
+
@length_units ||= [:m, :meter, :cm, :mm, :millimeter, :in, :ft, :feet, :yd]
|
236
|
+
end
|
237
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: measured-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin McPhillips
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-05-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: measured
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 2.
|
19
|
+
version: 2.5.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 2.
|
26
|
+
version: 2.5.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: railties
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '4.2'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activerecord
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '4.2'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '4.2'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: rake
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -140,7 +154,9 @@ description: Rails adapter for assigning and managing measurements with their un
|
|
140
154
|
provided by the measured gem.
|
141
155
|
email:
|
142
156
|
- gems@shopify.com
|
143
|
-
executables:
|
157
|
+
executables:
|
158
|
+
- console
|
159
|
+
- setup
|
144
160
|
extensions: []
|
145
161
|
extra_rdoc_files: []
|
146
162
|
files:
|
@@ -153,19 +169,28 @@ files:
|
|
153
169
|
- bin/console
|
154
170
|
- bin/setup
|
155
171
|
- dev.yml
|
156
|
-
- gemfiles/rails-4.2.gemfile
|
157
172
|
- gemfiles/rails-5.0.gemfile
|
173
|
+
- gemfiles/rails-5.1.gemfile
|
174
|
+
- gemfiles/rails-6.0.gemfile
|
158
175
|
- gemfiles/rails-master.gemfile
|
159
176
|
- lib/measured-rails.rb
|
160
177
|
- lib/measured/rails/active_record.rb
|
161
178
|
- lib/measured/rails/base.rb
|
162
179
|
- lib/measured/rails/railtie.rb
|
163
180
|
- lib/measured/rails/units/length.rb
|
181
|
+
- lib/measured/rails/units/volume.rb
|
164
182
|
- lib/measured/rails/units/weight.rb
|
165
183
|
- lib/measured/rails/validations.rb
|
166
184
|
- lib/measured/rails/version.rb
|
167
185
|
- measured-rails.gemspec
|
168
186
|
- shipit.rubygems.yml
|
187
|
+
- test/active_record_test.rb
|
188
|
+
- test/support/models/thing.rb
|
189
|
+
- test/support/models/thing_with_custom_unit_accessor.rb
|
190
|
+
- test/support/models/validated_thing.rb
|
191
|
+
- test/support/schema.rb
|
192
|
+
- test/test_helper.rb
|
193
|
+
- test/validation_test.rb
|
169
194
|
homepage: https://github.com/Shopify/measured-rails
|
170
195
|
licenses:
|
171
196
|
- MIT
|
@@ -186,8 +211,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
186
211
|
version: '0'
|
187
212
|
requirements: []
|
188
213
|
rubyforge_project:
|
189
|
-
rubygems_version: 2.6
|
214
|
+
rubygems_version: 2.7.6
|
190
215
|
signing_key:
|
191
216
|
specification_version: 4
|
192
217
|
summary: Rails adaptor for measured
|
193
|
-
test_files:
|
218
|
+
test_files:
|
219
|
+
- test/active_record_test.rb
|
220
|
+
- test/support/models/thing.rb
|
221
|
+
- test/support/models/thing_with_custom_unit_accessor.rb
|
222
|
+
- test/support/models/validated_thing.rb
|
223
|
+
- test/support/schema.rb
|
224
|
+
- test/test_helper.rb
|
225
|
+
- test/validation_test.rb
|