measured-rails 2.3.0 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: e25d74338a45ea007da8a2083a82bff7e15ad14c
4
- data.tar.gz: 0f76e9afd77a70843d717e7885647ecf29224b85
2
+ SHA256:
3
+ metadata.gz: bd5658fda3d706ca2a15122793008dea4a312e8fe6dccbeb72743dbabc165d1d
4
+ data.tar.gz: 96eb251668aca9622ec35cafba76730edfa1243749b8cdced184aa6e49c2c754
5
5
  SHA512:
6
- metadata.gz: '087156ee6df2abcc75863b4cb341e3c3b815b266f7dfd5bfbfe471efdde4b805d95451b5c31bd80ce55104a962552ccbbc52e557f8bf0903afbf7188e59f9b80'
7
- data.tar.gz: c875cdba0ba0a95aabdfa4bce6736fb3d38d3602580501153b373f45fde9ff621307e620457ad61cdf5de333e540ab5fd7115917f5308c54e96314e5ee353085
6
+ metadata.gz: 130a3980eb4b1eaa5de174316ac1073f144bb1bf9676a906f68f3cc44bb3752a825b81a5a5cc20768c01ad86cad5ee0cb7ca24e32a28327bd0f6853b564fb4bb
7
+ data.tar.gz: edcb3fd7eb2fdd691c49cd31f44047d0cf1d63c3ebe5e27fbad3bd96aee8a2ed965c48ac29da846d11c0ca3f2ac592698e26b6ca9faeff2ea9f5dfe55475a5c8
@@ -0,0 +1,32 @@
1
+ name: CI
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ build:
7
+ runs-on: ubuntu-latest
8
+ env:
9
+ BUNDLE_GEMFILE: ${{ matrix.gemfile }}
10
+ strategy:
11
+ matrix:
12
+ ruby:
13
+ - 2.5
14
+ - 2.6
15
+ - 2.7
16
+ gemfile:
17
+ - Gemfile
18
+ - gemfiles/rails-5.2.gemfile
19
+ - gemfiles/rails-6.0.gemfile
20
+ - gemfiles/rails-6.1.gemfile
21
+ - gemfiles/rails-master.gemfile
22
+ name: Ruby ${{ matrix.ruby }} ${{ matrix.gemfile }}
23
+ steps:
24
+ - uses: actions/checkout@v1
25
+ - name: Set up Ruby ${{ matrix.ruby }}
26
+ uses: ruby/setup-ruby@v1
27
+ with:
28
+ ruby-version: ${{ matrix.ruby }}
29
+ bundler-cache: true
30
+ - name: Run tests
31
+ run: |
32
+ bundle exec rake
@@ -0,0 +1,23 @@
1
+ 2.6.0
2
+ -----
3
+
4
+ * Only support Rails 5.2 and above.
5
+
6
+
7
+ 2.5.2
8
+ -----
9
+
10
+ * Fix some deprecations in tests and CI.
11
+
12
+ 2.5.1
13
+ -----
14
+
15
+ * Bump `measured` to 2.5.1
16
+
17
+ 2.5.0
18
+ -----
19
+
20
+ * Add `CHANGELOG.md`.
21
+ * Fix some deprecations and warnings.
22
+ * Support Rails 6 and Ruby 2.6.
23
+ * Load `Measured::Volume` by default and add helper method.
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/dev.yml CHANGED
@@ -2,7 +2,7 @@ name: measured-rails
2
2
 
3
3
  up:
4
4
  - ruby:
5
- version: 2.3.1
5
+ version: 2.6.3
6
6
  - bundler
7
7
 
8
8
  commands:
@@ -2,4 +2,4 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec path: '..'
4
4
 
5
- gem 'rails', '~> 5.0'
5
+ gem 'rails', '~> 5.2'
@@ -2,5 +2,4 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec path: '..'
4
4
 
5
- gem 'rails', '~> 4.2'
6
- gem 'rack', '< 2.0'
5
+ gem 'rails', '~> 6.0'
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec path: '..'
4
+
5
+ gem 'rails', '~> 6.1'
@@ -1,4 +1,6 @@
1
+ # frozen_string_literal: true
1
2
  require "measured/rails/base"
2
3
 
3
4
  require "measured/rails/units/length"
4
5
  require "measured/rails/units/weight"
6
+ require "measured/rails/units/volume"
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Measured::Rails::ActiveRecord
2
3
  extend ActiveSupport::Concern
3
4
 
@@ -5,7 +6,6 @@ module Measured::Rails::ActiveRecord
5
6
  def measured(measured_class, *fields)
6
7
  options = fields.extract_options!
7
8
  options = {}.merge(options)
8
- defined_unit_accessors = []
9
9
 
10
10
  measured_class = measured_class.constantize if measured_class.is_a?(String)
11
11
  unless measured_class.is_a?(Class) && measured_class.ancestors.include?(Measured::Measurable)
@@ -34,7 +34,7 @@ module Measured::Rails::ActiveRecord
34
34
 
35
35
  return nil unless value && unit
36
36
 
37
- instance = instance_variable_get("@measured_#{ field }")
37
+ instance = instance_variable_get("@measured_#{ field }") if instance_variable_defined?("@measured_#{ field }")
38
38
  new_instance = begin
39
39
  measured_class.new(value, unit)
40
40
  rescue Measured::UnitError
@@ -72,11 +72,8 @@ module Measured::Rails::ActiveRecord
72
72
  end
73
73
  end
74
74
 
75
- next if defined_unit_accessors.include?(unit_field_name)
76
-
77
75
  # Writer to override unit assignment
78
- define_method("#{ unit_field_name }=") do |incoming|
79
- defined_unit_accessors << unit_field_name
76
+ redefine_method("#{ unit_field_name }=") do |incoming|
80
77
  unit_name = measured_class.unit_system.unit_for(incoming).try!(:name)
81
78
  write_attribute(unit_field_name, unit_name || incoming)
82
79
  end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
1
2
  require "measured/rails/version"
2
3
  require "measured"
3
4
 
4
- require "active_support"
5
+ require "active_support/all"
6
+ require "active_record"
5
7
  require "active_model"
6
8
  require "active_model/validations"
7
9
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Measured::Rails
2
3
  class Railtie < ::Rails::Railtie
3
4
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Measured::Rails::ActiveRecord::Length
2
3
  extend ActiveSupport::Concern
3
4
 
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+ module Measured::Rails::ActiveRecord::Volume
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def measured_volume(*fields)
7
+ measured(Measured::Volume, *fields)
8
+ end
9
+ end
10
+ end
11
+
12
+ ActiveSupport.on_load(:active_record) do
13
+ ::ActiveRecord::Base.send :include, Measured::Rails::ActiveRecord::Volume
14
+ end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Measured::Rails::ActiveRecord::Weight
2
3
  extend ActiveSupport::Concern
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class MeasuredValidator < ActiveModel::EachValidator
2
3
  CHECKS = {
3
4
  greater_than: :>,
@@ -1,5 +1,6 @@
1
+ # frozen_string_literal: true
1
2
  module Measured
2
3
  module Rails
3
- VERSION = "2.3.0"
4
+ VERSION = "2.6.0"
4
5
  end
5
6
  end
@@ -7,26 +7,35 @@ Gem::Specification.new do |spec|
7
7
  spec.name = "measured-rails"
8
8
  spec.version = Measured::Rails::VERSION
9
9
  spec.authors = ["Kevin McPhillips"]
10
- spec.email = ["github@kevinmcphillips.ca"]
10
+ spec.email = ["gems@shopify.com"]
11
11
  spec.summary = %q{Rails adaptor for measured}
12
12
  spec.description = %q{Rails adapter for assigning and managing measurements with their units provided by the measured gem.}
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").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
- spec.bindir = "exe"
18
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
16
+ # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
17
+ # delete this section to allow pushing this gem to any host.
18
+ if spec.respond_to?(:metadata)
19
+ spec.metadata['allowed_push_host'] = "https://rubygems.org"
20
+ else
21
+ raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
22
+ end
23
+
24
+ spec.files = `git ls-files -z`.split("\x0")
25
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
26
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
27
  spec.require_paths = ["lib"]
20
28
 
21
29
  spec.add_runtime_dependency "measured", Measured::Rails::VERSION
22
30
 
23
- spec.add_runtime_dependency "railties", ">= 4.2"
24
- spec.add_runtime_dependency "activemodel", ">= 4.2"
31
+ spec.add_runtime_dependency "railties", ">= 5.2"
32
+ spec.add_runtime_dependency "activemodel", ">= 5.2"
33
+ spec.add_runtime_dependency "activerecord", ">= 5.2"
25
34
 
26
35
  spec.add_development_dependency "rake", "> 10.0"
27
36
  spec.add_development_dependency "minitest", "> 5.5.1"
28
37
  spec.add_development_dependency "minitest-reporters"
29
- spec.add_development_dependency "mocha", "> 1.1.0"
38
+ spec.add_development_dependency "mocha", ">= 1.4.0"
30
39
  spec.add_development_dependency "pry"
31
40
  spec.add_development_dependency "sqlite3"
32
41
  end
@@ -0,0 +1,413 @@
1
+ # frozen_string_literal: true
2
+ require "test_helper"
3
+
4
+ class Measured::Rails::ActiveRecordTest < ActiveSupport::TestCase
5
+ setup do
6
+ reset_db
7
+ end
8
+
9
+ test ".measured raises if called with something that isn't a Measured::Measurable" do
10
+ assert_raises Measured::Rails::Error do
11
+ Thing.measured(Object, :field)
12
+ end
13
+ end
14
+
15
+ test ".measured raises if called with something that isn't a class" do
16
+ assert_raises Measured::Rails::Error do
17
+ Thing.measured(:not_correct, :field)
18
+ end
19
+ end
20
+
21
+ test ".measured raises if you attempt to define a field twice" do
22
+ assert_raises Measured::Rails::Error do
23
+ Thing.measured Measured::Length, :height
24
+ end
25
+ end
26
+
27
+ test ".measured defines a reader for the field" do
28
+ assert_equal length, thing.length
29
+ end
30
+
31
+ test ".measured defines a writer for the field that returns" do
32
+ assert_equal new_length, thing.length=(new_length)
33
+ end
34
+
35
+ test ".measured_fields returns the configuration for all measured fields on the class" do
36
+ expected = {
37
+ length: { class: Measured::Length },
38
+ width: { class: Measured::Length },
39
+ height: { class: Measured::Length },
40
+ volume: { class: Measured::Volume },
41
+ total_weight: { class: Measured::Weight },
42
+ extra_weight: { class: Measured::Weight },
43
+ length_with_max_on_assignment: { max_on_assignment: 500, class: Measured::Length }
44
+ }
45
+
46
+ assert_equal expected, Thing.measured_fields
47
+ end
48
+
49
+ test "reader returns the exact same object if the values are equivalent" do
50
+ thing.length = new_length
51
+ assert_equal new_length.object_id, thing.length.object_id
52
+ end
53
+
54
+ test "reader creates an instance from the _value and _unit columns" do
55
+ thing = Thing.new
56
+ thing.width_value = 23
57
+ thing.width_unit = "ft"
58
+ assert_equal Measured::Length.new(23, :ft), thing.width
59
+ end
60
+
61
+ test "reader creates creating an instance from columns caches the same object" do
62
+ thing = Thing.new
63
+ thing.width_value = 23
64
+ thing.width_unit = "ft"
65
+ assert_equal thing.width.object_id, thing.width.object_id
66
+ end
67
+
68
+ test "reader deals with only the _value column set" do
69
+ thing = Thing.new
70
+ thing.width_value = 23
71
+ assert_nil thing.width
72
+ end
73
+
74
+ test "reader deals with only the _unit column set" do
75
+ thing = Thing.new
76
+ thing.width_unit = "cm"
77
+ assert_nil thing.width
78
+ end
79
+
80
+ test "reader deals with nil-ing out the _value column" do
81
+ thing.width_value = nil
82
+ assert_nil thing.width
83
+ end
84
+
85
+ test "reader deals with nil-ing out the _unit column" do
86
+ thing.width_unit = nil
87
+ assert_nil thing.width
88
+ end
89
+
90
+ test "writer sets the value to nil if it is an incompatible object" do
91
+ thing.length = Object.new
92
+ assert_nil thing.length
93
+ end
94
+
95
+ test "writer assigning nil blanks out the unit and value columns" do
96
+ thing.width = nil
97
+ assert_nil thing.width
98
+ assert_nil thing.width_unit
99
+ assert_nil thing.width_value
100
+ end
101
+
102
+ test "assigning an invalid _unit sets the column but the measurable object is nil" do
103
+ thing.width_unit = "invalid"
104
+ assert_nil thing.width
105
+ assert_equal "invalid", thing.width_unit
106
+ end
107
+
108
+ test "assigning an invalid _unit sets the column but the measurable object is nil and there is validation on the column" do
109
+ validated_thing.length_unit = "invalid"
110
+ validated_thing.valid?
111
+ assert_nil validated_thing.length
112
+ assert_equal "invalid", validated_thing.length_unit
113
+ end
114
+
115
+ test "assigning a valid _unit sets it" do
116
+ thing.width_unit = :mm
117
+ assert_equal thing.width, Measured::Length.new(6, "mm")
118
+ assert_equal "mm", thing.width_unit
119
+ end
120
+
121
+ test "assigning a non-base unit to _unit converts it to its base unit" do
122
+ thing.width_unit = "millimetre"
123
+ assert_equal thing.width, Measured::Length.new(6, "mm")
124
+ assert_equal "mm", thing.width_unit
125
+ end
126
+
127
+ test "building a new object from attributes builds a measured object" do
128
+ thing = Thing.new(length_value: "30", length_unit: "m")
129
+ assert_equal Measured::Length.new(30, :m), thing.length
130
+ end
131
+
132
+ test "building a new object with a measured object assigns the properties" do
133
+ thing = Thing.new(length: new_length)
134
+ assert_equal new_length, thing.length
135
+ assert_equal 20, thing.length_value
136
+ assert_equal "in", thing.length_unit
137
+ end
138
+
139
+ test "assigning attributes updates the measured object" do
140
+ thing.attributes = {length_value: "30", length_unit: "m"}
141
+ assert_equal Measured::Length.new(30, :m), thing.length
142
+ end
143
+
144
+ test "assigning partial attributes updates the measured object" do
145
+ thing.attributes = {length_value: "30"}
146
+ assert_equal Measured::Length.new(30, :cm), thing.length
147
+ end
148
+
149
+ test "assigning the _unit leaves the _value unchanged" do
150
+ thing.total_weight_unit = :lb
151
+ assert_equal thing.total_weight, Measured::Weight.new(200, "lb")
152
+ end
153
+
154
+ test "assigning the _value leaves the _unit unchanged" do
155
+ thing.total_weight_value = "10"
156
+ assert_equal thing.total_weight, Measured::Weight.new(10, :g)
157
+ end
158
+
159
+ test "assigning the _unit to an invalid unit does not raise" do
160
+ thing.total_weight_value = 123
161
+ thing.total_weight_unit = :invalid
162
+ assert_nil thing.total_weight
163
+ end
164
+
165
+ test "save persists the attributes and retrieves an object" do
166
+ thing = Thing.new length: Measured::Length.new(3, :m)
167
+ assert thing.save
168
+ assert_equal 3, thing.length_value
169
+ assert_equal "m", thing.length_unit
170
+ thing.reload
171
+ assert_equal 3, thing.length_value
172
+ assert_equal "m", thing.length_unit
173
+ end
174
+
175
+ test "save pulls attributes from assigned object" do
176
+ thing = Thing.new total_weight_value: "100", total_weight_unit: :lb
177
+ assert thing.save
178
+ thing.reload
179
+ assert_equal 100, thing.total_weight_value
180
+ assert_equal "lb", thing.total_weight_unit
181
+ assert_equal Measured::Weight.new(100, :lb), thing.total_weight
182
+ end
183
+
184
+ test "save succeeds if you assign an invalid unit and there is no validation" do
185
+ thing = Thing.new total_weight_value: "100", total_weight_unit: :invalid
186
+ assert thing.save
187
+ thing.reload
188
+ assert_nil thing.total_weight
189
+ assert_equal 100, thing.total_weight_value
190
+ end
191
+
192
+ test "save fails if you assign an invalid unit and there is validation" do
193
+ thing = validated_thing
194
+ thing.length_unit = "invalid"
195
+ refute thing.save
196
+ assert_nil thing.length
197
+ end
198
+
199
+ test "update sets one then the other" do
200
+ thing = Thing.create!
201
+ assert thing.update(width_value: 11.1)
202
+ assert_nil thing.width
203
+ assert thing.update(width_unit: "cm")
204
+ assert_equal Measured::Length.new(11.1, :cm), thing.width
205
+ end
206
+
207
+ test "update sets only the _value column" do
208
+ thing = Thing.create!
209
+ assert thing.update(width_value: "314")
210
+ assert_equal 314, thing.width_value
211
+ thing.reload
212
+ assert_equal 314, thing.width_value
213
+ assert_nil thing.width
214
+ end
215
+
216
+ test "update sets only the _unit column" do
217
+ thing = Thing.create!
218
+ assert thing.update(width_unit: :cm)
219
+ assert_equal "cm", thing.width_unit
220
+ thing.reload
221
+ assert_equal "cm", thing.width_unit
222
+ assert_nil thing.width
223
+ end
224
+
225
+ test "update sets only the _unit column and converts it" do
226
+ thing = Thing.create!
227
+ assert thing.update(width_unit: "inch")
228
+ assert_equal "in", thing.width_unit
229
+ thing.reload
230
+ assert_equal "in", thing.width_unit
231
+ end
232
+
233
+ test "update sets the _unit column to something invalid" do
234
+ thing = Thing.create!
235
+ assert thing.update(width_unit: :invalid)
236
+ assert_equal "invalid", thing.width_unit
237
+ thing.reload
238
+ assert_equal "invalid", thing.width_unit
239
+ assert_nil thing.width
240
+ end
241
+
242
+ test "update does not set the _unit column to something invalid if there is validation" do
243
+ thing = validated_thing
244
+ thing.save!
245
+ refute thing.update(length_unit: :invalid)
246
+ end
247
+
248
+ test "update sets one column then the other" do
249
+ thing = Thing.create!
250
+ assert thing.update(width_unit: "inch")
251
+ assert_nil thing.width
252
+ assert thing.update(width_value: "314")
253
+ assert_equal Measured::Length.new(314, :in), thing.width
254
+ end
255
+
256
+ test "update sets both columns" do
257
+ thing = Thing.create!
258
+ assert thing.update(width_unit: :cm, width_value: 2)
259
+ assert_equal Measured::Length.new(2, :cm), thing.width
260
+ thing.reload
261
+ assert_equal Measured::Length.new(2, :cm), thing.width
262
+ end
263
+
264
+ test "update modifies the _value column" do
265
+ assert thing.update(height_value: 2)
266
+ assert_equal Measured::Length.new(2, :m), thing.height
267
+ thing.reload
268
+ assert_equal Measured::Length.new(2, :m), thing.height
269
+ end
270
+
271
+ test "update modifies only the _unit column" do
272
+ assert thing.update(height_unit: "foot")
273
+ assert_equal Measured::Length.new(1, :ft), thing.height
274
+ thing.reload
275
+ assert_equal Measured::Length.new(1, :ft), thing.height
276
+ end
277
+
278
+ test "update modifies the _unit column to be something invalid" do
279
+ assert thing.update(height_unit: :invalid)
280
+ assert_nil thing.height
281
+ assert_equal "invalid", thing.height_unit
282
+ thing.reload
283
+ assert_nil thing.height
284
+ assert_equal "invalid", thing.height_unit
285
+ end
286
+
287
+ test "update modifies both columns" do
288
+ assert thing.update(height_unit: "mm", height_value: 1.23)
289
+ assert_equal Measured::Length.new(1.23, :mm), thing.height
290
+ thing.reload
291
+ assert_equal Measured::Length.new(1.23, :mm), thing.height
292
+ end
293
+
294
+ test "assigning the _value with a BigDecimal rounds to the column's rounding scale" do
295
+ thing.height = Measured::Length.new(BigDecimal('23.4567891'), :mm)
296
+ assert_equal thing.height_value, BigDecimal('23.46')
297
+ end
298
+
299
+ test "assigning the _value with a float uses all the rounding scale permissible" do
300
+ thing.height = Measured::Length.new(4.45678912, :mm)
301
+ assert_equal thing.height_value, BigDecimal('4.46')
302
+ end
303
+
304
+ 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
305
+ assert_nothing_raised do
306
+ thing.height = Measured::Length.new(4.45678912123123123, :mm)
307
+ assert_equal thing.height_value, BigDecimal('4.46')
308
+ end
309
+ end
310
+
311
+ test "assigning a number with more significant digits than permitted by the column precision raises exception" do
312
+ 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
313
+ thing.height = Measured::Length.new(44567891212312312.3, :mm)
314
+ end
315
+ end
316
+
317
+ test "assigning a large number but with a small amount of significant digits than permitted by the column precision raises exception" do
318
+ 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
319
+ thing.height = Measured::Length.new(2_000_000_000_000_000, :mm)
320
+ end
321
+ end
322
+
323
+ test "assigning a large number that's just smaller, equal to, and over the size of the column precision raises exception" do
324
+ assert_nothing_raised do
325
+ thing.height = Measured::Length.new(99999999.99, :mm)
326
+ end
327
+
328
+ 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
329
+ thing.height = Measured::Length.new(100000000, :mm)
330
+ end
331
+
332
+ 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
333
+ thing.height = Measured::Length.new(100000000.01, :mm)
334
+ end
335
+ end
336
+
337
+ test "assigning a large number to a field that specifies max_on_assignment" do
338
+ thing = Thing.create!(length_with_max_on_assignment: Measured::Length.new(10000000000000000, :mm))
339
+ assert_equal Measured::Length.new(500, :mm), thing.length_with_max_on_assignment
340
+ end
341
+
342
+ test "assigning a small number to a field that specifies max_on_assignment" do
343
+ thing = Thing.create!(length_with_max_on_assignment: Measured::Length.new(1, :mm))
344
+ assert_equal Measured::Length.new(1, :mm), thing.length_with_max_on_assignment
345
+ end
346
+
347
+ test "using a similar unit accessor for multiple size fields" do
348
+ assert_equal Measured::Length.new(1, :m), custom_unit_thing.length
349
+ assert_equal Measured::Length.new(2, :m), custom_unit_thing.width
350
+ assert_equal Measured::Length.new(3, :m), custom_unit_thing.height
351
+ assert_equal Measured::Volume.new(9, :l), custom_unit_thing.volume
352
+ assert_equal Measured::Weight.new(10, :g), custom_unit_thing.total_weight
353
+ assert_equal Measured::Weight.new(12, :g), custom_unit_thing.extra_weight
354
+ end
355
+
356
+ test "changing unit value when shared affects all fields" do
357
+ custom_unit_thing.length = Measured::Length.new(15, :in)
358
+ custom_unit_thing.total_weight = Measured::Weight.new(42, :kg)
359
+
360
+ assert_equal custom_unit_thing.length, Measured::Length.new(15, :in)
361
+ assert_equal custom_unit_thing.width, Measured::Length.new(2, :in)
362
+ assert_equal custom_unit_thing.height, Measured::Length.new(3, :in)
363
+ assert_equal custom_unit_thing.total_weight, Measured::Weight.new(42, :kg)
364
+ assert_equal custom_unit_thing.extra_weight, Measured::Weight.new(12, :kg)
365
+ end
366
+
367
+ private
368
+
369
+ def length
370
+ @length ||= Measured::Length.new(10, :cm)
371
+ end
372
+
373
+ def new_length
374
+ @new_length ||= Measured::Length.new(20, :in)
375
+ end
376
+
377
+ def thing
378
+ @thing ||= Thing.create!(
379
+ length: length,
380
+ width: Measured::Length.new(6, :in),
381
+ volume: Measured::Volume.new(6, :l),
382
+ height: Measured::Length.new(1, :m),
383
+ total_weight: Measured::Weight.new(200, :g),
384
+ extra_weight: Measured::Weight.new(16, :oz)
385
+ )
386
+ end
387
+
388
+ def validated_thing
389
+ @thing ||= ValidatedThing.new(
390
+ length: Measured::Length.new(1, :m),
391
+ length_true: Measured::Length.new(2, :cm),
392
+ length_message: Measured::Length.new(3, :mm),
393
+ length_message_from_block: Measured::Length.new(7, :mm),
394
+ length_units: Measured::Length.new(4, :m),
395
+ length_units_singular: Measured::Length.new(5, :ft),
396
+ length_presence: Measured::Length.new(6, :m),
397
+ length_numericality_inclusive: Measured::Length.new(15, :in),
398
+ length_numericality_exclusive: Measured::Length.new(4, :m),
399
+ length_numericality_equality: Measured::Length.new(100, :cm),
400
+ )
401
+ end
402
+
403
+ def custom_unit_thing
404
+ @custom_unit_thing ||= ThingWithCustomUnitAccessor.new(
405
+ length: Measured::Length.new(1, :m),
406
+ width: Measured::Length.new(2, :m),
407
+ height: Measured::Length.new(3, :m),
408
+ volume: Measured::Volume.new(9, :l),
409
+ total_weight: Measured::Weight.new(10, :g),
410
+ extra_weight: Measured::Weight.new(12, :g),
411
+ )
412
+ end
413
+ end