measured-rails 2.3.0 → 2.6.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 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