amount_field 1.4.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.
@@ -0,0 +1,387 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ class ValidationsTest < ActiveSupport::TestCase
4
+
5
+ # allows stuff like de_test_values.with_minus.to_us
6
+ class ::Hash
7
+ def with_plus
8
+ self.inject({}) { |h, (k, v)| h["+#{k}"] = v; h }
9
+ end
10
+
11
+ def with_minus
12
+ self.inject({}) { |h, (k, v)| h["-#{k}"] = (v*-1.0); h }
13
+ end
14
+
15
+ def to_us
16
+ self.inject({}) { |h, (k, v)| h[k.sub(',', ';').gsub('.', ',').sub(';', '.')] = v; h }
17
+ end
18
+ end
19
+
20
+ def de_test_values
21
+ {
22
+ '0' => 0.0,
23
+ ',0' => 0.0,
24
+ ',00' => 0.0,
25
+ '1' => 1.0,
26
+ '1,' => 1.0,
27
+ '1,0' => 1.0,
28
+ '1,00' => 1.0,
29
+ '12' => 12.0,
30
+ '12,' => 12.0,
31
+ '12,0' => 12.0,
32
+ '12,00' => 12.0,
33
+ '123' => 123.0,
34
+ '123,' => 123.0,
35
+ '123,0' => 123.0,
36
+ '123,00' => 123.0,
37
+ '1234' => 1234.0,
38
+ '1234,' => 1234.0,
39
+ '1234,0' => 1234.0,
40
+ '1234,00' => 1234.0,
41
+ '1234,56' => 1234.56,
42
+ '1.234,56' => 1234.56,
43
+ '12345,67' => 12345.67,
44
+ '12.345,67' => 12345.67,
45
+ '123456,78' => 123456.78,
46
+ '123.456,78' => 123456.78,
47
+ '1234567,89' => 1234567.89,
48
+ '1.234.567,89' => 1234567.89
49
+ }
50
+ end
51
+
52
+
53
+ test "orignal setter accept ruby value if set via new" do
54
+ product = TestProduct.new(:price => 12.34)
55
+ assert_in_delta 12.34, product.price, 0.001
56
+ end
57
+
58
+ test "orignal setter accept ruby value" do
59
+ product = TestProduct.new
60
+ product.price = 12.34
61
+ assert_in_delta 12.34, product.price, 0.001
62
+ end
63
+
64
+ test "price is valid for loaded record" do
65
+ product = TestProduct.create!(:price => 12.34)
66
+ assert_in_delta 12.34, product.price, 0.001
67
+ end
68
+
69
+ test "special setter does not accept a decimal value" do
70
+ # Special case: The value is assign via the special setter as a decimal not as a string.
71
+ # The validation fails because the value is not of the german format '1234,56' and therefore
72
+ # the price should be 0.0 (not assiged) but is 1234.56
73
+ product = TestProduct.new
74
+ product.amount_field_price = 1234.56
75
+ assert !product.valid?, "expect 1234.56 to be invalid (#{product.errors.full_messages.inspect})"
76
+ assert_in_delta 1234.56, product.price.to_f, 0.001
77
+ end
78
+
79
+ test "special setter accept german format value" do
80
+ with_locale('de') do
81
+ product = TestProduct.new
82
+ product.amount_field_price = '1.234,56'
83
+ assert product.valid?, "expect '1.234,56' to be valid (#{product.errors.full_messages.inspect})"
84
+ assert_in_delta 1234.56, product.price, 0.001
85
+ end
86
+ end
87
+
88
+ test "accept valid german formats" do
89
+ class TestProductValidGermanFormat < ActiveRecord::Base
90
+ set_table_name 'test_products'
91
+ validates_amount_format_of :price
92
+ end
93
+
94
+ with_locale('de') do
95
+ assert_valid_formats(de_test_values, TestProductValidGermanFormat)
96
+ assert_valid_formats(de_test_values.with_minus, TestProductValidGermanFormat) # -value
97
+ assert_valid_formats(de_test_values.with_plus, TestProductValidGermanFormat) # +value
98
+ end
99
+ end
100
+
101
+ test "accept valid us formats" do
102
+ with_configuration({ :separator => '.', :delimiter => ',', :precision => 2 }) do
103
+ class TestProductValidUsFormat < ActiveRecord::Base
104
+ set_table_name 'test_products'
105
+ validates_amount_format_of :price
106
+ end
107
+
108
+ with_locale('de') do
109
+ assert_valid_formats(de_test_values.to_us, TestProductValidUsFormat)
110
+ assert_valid_formats(de_test_values.to_us.with_minus, TestProductValidUsFormat) # -value
111
+ assert_valid_formats(de_test_values.to_us.with_plus, TestProductValidUsFormat) # +value
112
+ end
113
+ end
114
+ end
115
+
116
+ test "dont accept invalid formats" do
117
+ class TestProductInValidGermanFormat < ActiveRecord::Base
118
+ set_table_name 'test_products'
119
+ validates_amount_format_of :price
120
+ end
121
+
122
+ with_locale('de') do
123
+ assert_invalid_formats(['1234.567.890,12', '123.4567.890,12', '1,2.34', '1,2,3', '1.23,45',
124
+ '1.23.45,6', '2,1x', '2,x', 'x2', '++1,23', '+-1,23', '--1,23', '-+1,23', nil],
125
+ TestProductInValidGermanFormat)
126
+ end
127
+ end
128
+
129
+ test "accept only values of format with the defined configuration" do
130
+ class TestProductConfiguration < ActiveRecord::Base
131
+ set_table_name 'test_products'
132
+ validates_amount_format_of :price, :separator => '.', :delimiter => ','
133
+ validates_amount_format_of :stock_price, :separator => ',', :delimiter => '.'
134
+ end
135
+
136
+ product = TestProductConfiguration.new(:amount_field_price => '1,234,567.89',
137
+ :amount_field_stock_price => '1.234.567,89')
138
+ assert product.valid?
139
+ assert_in_delta 1234567.89, product.price, 0.001
140
+ assert_in_delta 1234567.89, product.stock_price, 0.001
141
+ end
142
+
143
+ test "accept only values of format with the defined precision" do
144
+ class TestProductPrecision < ActiveRecord::Base
145
+ set_table_name 'test_products'
146
+ validates_amount_format_of :price # default 2
147
+ validates_amount_format_of :stock_price, :precision => 1
148
+ end
149
+
150
+ product = TestProductPrecision.new(:amount_field_price => '1,234.56',
151
+ :amount_field_stock_price => '1,234.5')
152
+ assert product.valid?
153
+ assert_in_delta 1234.56, product.price, 0.001
154
+ assert_in_delta 1234.50, product.stock_price, 0.001
155
+ end
156
+
157
+ test "accept only integer if precision is 0 or nil" do
158
+ class TestProductInteger < ActiveRecord::Base
159
+ set_table_name 'test_products'
160
+ validates_amount_format_of :price, :precision => 0, :separator => nil
161
+ end
162
+
163
+ with_locale('de') do
164
+ assert_valid_formats({'0' => 0.0, '1' => 1.0, '12' => 12.0, '123' => 123.0, '1.234' => 1234.0}, TestProductInteger)
165
+ assert_invalid_formats(['1,', '1,0', '1,2', '1,23'], TestProductInteger)
166
+ end
167
+ end
168
+
169
+ test "accept only values with no delimiter" do
170
+ class TestProductNoDelimiter < ActiveRecord::Base
171
+ set_table_name 'test_products'
172
+ validates_amount_format_of :price, :separator => '.', :delimiter => nil
173
+ end
174
+
175
+ with_locale('de') do
176
+ assert_valid_formats({'.00' => 0.0, '1.00' => 1.0, '12.00' => 12.0, '123.00' => 123.0, '1234.00' => 1234.0, '12345.00' => 12345.0, '123456.00' => 123456.0}, TestProductNoDelimiter)
177
+ assert_invalid_formats(['1,234.56', '123,456.00'], TestProductNoDelimiter)
178
+ end
179
+ end
180
+
181
+ test "use english default message" do
182
+ class TestProductEnglishMessage < ActiveRecord::Base
183
+ set_table_name 'test_products'
184
+ validates_amount_format_of :price
185
+ end
186
+
187
+ with_locale('en') do
188
+ product = TestProductEnglishMessage.new(:amount_field_price => 'x')
189
+ assert !product.valid?
190
+ assert_equal "'x' is not a valid amount format (d,ddd.dd)", product.errors.on(:price)
191
+ end
192
+ end
193
+
194
+ test "use german default message" do
195
+ class TestProductGermanMessage < ActiveRecord::Base
196
+ set_table_name 'test_products'
197
+ validates_amount_format_of :price
198
+ end
199
+
200
+ with_locale('de') do
201
+ product = TestProductGermanMessage.new(:amount_field_price => 'x')
202
+ assert !product.valid?
203
+ assert_equal "'x' ist ein ungültiges Format (d.ddd,dd)", product.errors.on(:price)
204
+ end
205
+ end
206
+
207
+ test "validates_amount_format_of use given message" do
208
+ class TestProductGivenMessage < ActiveRecord::Base
209
+ set_table_name 'test_products'
210
+ validates_amount_format_of :price, :message => "special message {{value}}"
211
+ end
212
+
213
+ product = TestProductGivenMessage.new(:amount_field_price => 'x')
214
+ assert !product.valid?
215
+ assert_equal "special message x", product.errors.on(:price)
216
+ end
217
+
218
+ test "matches if precision is right" do
219
+ class TestProductValidPrecision < ActiveRecord::Base
220
+ set_table_name 'test_products'
221
+ validates_amount_format_of :price, :precision => 1
222
+ end
223
+
224
+ with_locale('de') do
225
+ [ ',0', '1,0', '1,0'].each do |value|
226
+ assert TestProductValidPrecision.new(:amount_field_price => value).valid?, "expected '#{value}' to be valid"
227
+ end
228
+ end
229
+ end
230
+
231
+ test "explicit definition overwrites default configuration" do
232
+ with_configuration(default = { :separator => '_', :delimiter => ';', :precision => 2 }) do
233
+ class TestProductOverwriteConfiguration < ActiveRecord::Base
234
+ set_table_name 'test_products'
235
+ validates_amount_format_of :price, :separator => '/', :delimiter => '@'
236
+ validates_amount_format_of :stock_price
237
+ end
238
+
239
+ [ '/00', '1/00', '12/00', '123/00', '1234/00', '1@234/00', '12@345/00', '123@456/00', '1@234@567/00'
240
+ ].each do |param|
241
+ param2 = param.gsub('/', '_').gsub('@', ';')
242
+ product = TestProductOverwriteConfiguration.new(:amount_field_price => param, :amount_field_stock_price => param2)
243
+ assert product.valid?, product.errors.full_messages.inspect
244
+ assert_in_delta Float(param.gsub('@', '').sub('/', '.')), product.price, 0.001
245
+ end
246
+ end
247
+ end
248
+
249
+ test "nil or blank value is not valid by default" do
250
+ class TestProductNilOrBlankNotValidByDefault < ActiveRecord::Base
251
+ set_table_name 'test_products'
252
+ validates_amount_format_of :price
253
+ validates_amount_format_of :stock_price
254
+ end
255
+
256
+ product = TestProductNilOrBlankNotValidByDefault.new(:amount_field_price => nil, :amount_field_stock_price => "")
257
+ assert !product.valid?
258
+ assert_match /format/, product.errors.on(:price)
259
+ assert_match /format/, product.errors.on(:stock_price)
260
+ end
261
+
262
+ test "nil or blank value is valid if option :allow_nil or :allow_blank is set to true" do
263
+ class TestProductNilOrBlankValidIfAllowed < ActiveRecord::Base
264
+ set_table_name 'test_products'
265
+ validates_amount_format_of :price, :allow_nil => true
266
+ validates_amount_format_of :stock_price, :allow_blank => true
267
+ end
268
+
269
+ product = TestProductNilOrBlankValidIfAllowed.new(:amount_field_price => nil, :amount_field_stock_price => "")
270
+ assert product.valid?, product.errors.full_messages.inspect
271
+ assert_in_delta 0.0, product.price, 0.001
272
+ end
273
+
274
+ test "valid format example returns string depending on given configuration" do
275
+ assert_equal "d.ddd,dd", TestProduct.send(:valid_format_example, { :precision => 2, :delimiter => '.', :separator => ',' })
276
+ assert_equal "d,ddd.dd", TestProduct.send(:valid_format_example, { :precision => 2, :delimiter => ',', :separator => '.' })
277
+ assert_equal "dddd,dd", TestProduct.send(:valid_format_example, { :precision => 2, :delimiter => nil, :separator => ',' })
278
+ assert_equal "dddd,d", TestProduct.send(:valid_format_example, { :precision => 1, :delimiter => nil, :separator => ',' })
279
+ assert_equal "dddd", TestProduct.send(:valid_format_example, { :precision => nil, :delimiter => nil, :separator => nil })
280
+ assert_equal "d.ddd", TestProduct.send(:valid_format_example, { :precision => nil, :delimiter => '.', :separator => nil })
281
+ end
282
+
283
+ test "default prefix is use for special setter name" do
284
+ class TestProductDefaultPrefix < ActiveRecord::Base
285
+ set_table_name 'test_products'
286
+ validates_amount_format_of :price
287
+ end
288
+
289
+ assert TestProductDefaultPrefix.new.respond_to?("#{AmountField::Configuration.prefix}_price=")
290
+ end
291
+
292
+ test "configured prefix is use for special setter name" do
293
+ AmountField::Configuration.prefix = 'my_prefix'
294
+ class TestProductConfigPrefix < ActiveRecord::Base
295
+ set_table_name 'test_products'
296
+ validates_amount_format_of :price
297
+ end
298
+
299
+ assert TestProductConfigPrefix.new.respond_to?('my_prefix_price=')
300
+ AmountField::Configuration.prefix = 'amount_field'
301
+ end
302
+
303
+ test "works with float attribute" do
304
+ class TestProductFloatAttribute < ActiveRecord::Base
305
+ set_table_name 'test_products'
306
+ validates_amount_format_of :float_price
307
+ end
308
+ with_locale('de') do
309
+ assert TestProductFloatAttribute.new(:amount_field_float_price => '1.234,00').valid?
310
+ assert TestProductFloatAttribute.new(:amount_field_float_price => '1234').valid?
311
+ end
312
+ end
313
+
314
+ test "allow separator and delimiter to be optional for german format" do
315
+ class TestProductOptionalSeparatorAndDelimiterForGerman < ActiveRecord::Base
316
+ set_table_name 'test_products'
317
+ validates_amount_format_of :float_price
318
+ end
319
+ with_locale('de') do
320
+ ['1.234,00', '1234,00', '1.234', '1234'].each do |v|
321
+ p = TestProductOptionalSeparatorAndDelimiterForGerman.new(:amount_field_float_price => v)
322
+ assert p.valid?, p.errors.full_messages.inspect
323
+ end
324
+ end
325
+ end
326
+
327
+ test "allow separator and delimiter to be optional for us format" do
328
+ class TestProductOptionalSeparatorAndDelimiterForUs < ActiveRecord::Base
329
+ set_table_name 'test_products'
330
+ validates_amount_format_of :float_price
331
+ end
332
+ with_locale('en') do
333
+ ['1,234.00', '1234.00', '1,234', '1234'].each do |v|
334
+ p = TestProductOptionalSeparatorAndDelimiterForUs.new(:amount_field_float_price => v)
335
+ assert p.valid?, p.errors.full_messages.inspect
336
+ end
337
+ end
338
+ end
339
+
340
+ test "an invalid value is still invalid after multiple validation" do
341
+ class TestProductValidValid < ActiveRecord::Base
342
+ set_table_name 'test_products'
343
+ validates_amount_format_of :price
344
+ end
345
+ p = TestProductValidValid.new(:amount_field_price => "x")
346
+ assert !p.valid?
347
+ assert !p.valid?
348
+ end
349
+
350
+ test "a value is not invalid after multiple validation" do
351
+ with_locale('de') do
352
+ class TestProductValidValid < ActiveRecord::Base
353
+ set_table_name 'test_products'
354
+ validates_amount_format_of :price
355
+ end
356
+ p = TestProductValidValid.new(:amount_field_price => "1.234,56")
357
+ assert p.valid?
358
+ assert p.valid?
359
+ end
360
+ end
361
+
362
+ test "calling create with an invalid value does not save the model" do
363
+ class TestProductViaCreate< ActiveRecord::Base
364
+ set_table_name 'test_products'
365
+ validates_amount_format_of :price
366
+ end
367
+ assert_no_difference 'TestProduct.count' do
368
+ p = TestProductViaCreate.create(:amount_field_price => "x")
369
+ assert p.new_record?
370
+ assert !p.valid?
371
+ end
372
+ end
373
+
374
+ test "something interesting" do
375
+ class TestProductWithOtherValidationMacros < ActiveRecord::Base
376
+ set_table_name 'test_products'
377
+ validates_amount_format_of :price
378
+ validates_numericality_of :price
379
+ end
380
+ p = TestProductWithOtherValidationMacros.new(:amount_field_price => "x")
381
+ assert !p.valid?
382
+ assert p.errors.full_messages.include?("Price 'x' is not a valid amount format (d,ddd.dd)")
383
+ assert p.errors.full_messages.include?("Price is not a number")
384
+ end
385
+
386
+ end
387
+
@@ -0,0 +1 @@
1
+ # Uninstall hook code here
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: amount_field
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.4.0
5
+ platform: ruby
6
+ authors:
7
+ - Thomas Baustert
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-06 00:00:00 +02:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Rails gem/plugin that accepts (amount) values in german or us format like 1.234,56 or 1,234.56
17
+ email: " business@thomasbaustert.de"
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.rdoc
24
+ - lib/amount_field.rb
25
+ - lib/amount_field/configuration.rb
26
+ - lib/amount_field/form_helper.rb
27
+ - lib/amount_field/form_tag_helper.rb
28
+ - lib/amount_field/validations.rb
29
+ files:
30
+ - History.txt
31
+ - MIT-LICENSE
32
+ - Manifest
33
+ - README.rdoc
34
+ - Rakefile
35
+ - init.rb
36
+ - install.rb
37
+ - lib/amount_field.rb
38
+ - lib/amount_field/configuration.rb
39
+ - lib/amount_field/form_helper.rb
40
+ - lib/amount_field/form_tag_helper.rb
41
+ - lib/amount_field/validations.rb
42
+ - locale/de.yml
43
+ - locale/en.yml
44
+ - test/form_helper_test.rb
45
+ - test/form_tag_helper_test.rb
46
+ - test/models/test_product.rb
47
+ - test/test_helper.rb
48
+ - test/validations_test.rb
49
+ - uninstall.rb
50
+ - amount_field.gemspec
51
+ has_rdoc: true
52
+ homepage: http://github.com/thomasbaustert/amount_field
53
+ licenses: []
54
+
55
+ post_install_message:
56
+ rdoc_options:
57
+ - --line-numbers
58
+ - --inline-source
59
+ - --title
60
+ - Amount_field
61
+ - --main
62
+ - README.rdoc
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: "0"
70
+ version:
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: "1.2"
76
+ version:
77
+ requirements: []
78
+
79
+ rubyforge_project: amount_field
80
+ rubygems_version: 1.3.5
81
+ signing_key:
82
+ specification_version: 3
83
+ summary: Rails gem/plugin that accepts (amount) values in german or us format like 1.234,56 or 1,234.56
84
+ test_files:
85
+ - test/form_helper_test.rb
86
+ - test/form_tag_helper_test.rb
87
+ - test/models/test_product.rb
88
+ - test/test_helper.rb
89
+ - test/validations_test.rb