delocalize 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,16 +1,20 @@
1
- delocalize
2
- ==========
1
+ # delocalize
3
2
 
4
3
  [![Build Status](https://secure.travis-ci.org/clemens/delocalize.png)](http://travis-ci.org/clemens/delocalize)
5
4
 
6
5
  delocalize provides localized date/time and number parsing functionality for Rails.
7
6
 
8
- Installation
9
- ------------
7
+ ## 1.0 Beta
8
+
9
+ Check out the [1-0-beta branch](https://github.com/clemens/delocalize/tree/1-0-beta) for an unfinished/unreleased improved version of delocalize. The goal is to get rid of all the nasty hacks and have a library that doesn't break with every new release of Rails.
10
+
11
+ Also check out the [ongoing discussion the wiki](https://github.com/clemens/delocalize/wiki/delocalize-1.0) and feel free to put in your opinion there.
12
+
13
+ ## Installation
10
14
 
11
15
  You can use delocalize as a gem (preferred). Using delocalize as a Rails plugin has been discontinued and is no supported. If you want/need to use delocalize as a gem (I really don't see a reason why you'd want to), consider using the `0-2-stable` branch.
12
16
 
13
- ### Rails 3
17
+ ### Rails 3 and Rails 4
14
18
 
15
19
  To use delocalize, put the following gem requirement in your `Gemfile`:
16
20
 
@@ -20,7 +24,7 @@ gem "delocalize"
20
24
 
21
25
  ### Rails 2
22
26
 
23
- Note: Support for Rails 2 has been discontinued. This version is only considered stable for Rails 3. If you need Rails 2 support, please use the `0.2.x` versions or the `0-2-stable` branch respectively.
27
+ Note: Support for Rails 2 has been discontinued. This version is only considered stable for Rails >= 3. If you need Rails 2 support, please use the `0.2.x` versions or the `0-2-stable` branch respectively.
24
28
 
25
29
  To use delocalize, put the following gem requirement in your `environment.rb`:
26
30
 
@@ -30,8 +34,7 @@ config.gem "delocalize", :source => 'http://gemcutter.org'
30
34
 
31
35
  In Rails 2.3, alternatively, you can use it with Bundler. See http://gembundler.com/rails23.html for instructions.
32
36
 
33
- What does it do? And how do I use it?
34
- --------------------------------------
37
+ ## What does it do? And how do I use it?
35
38
 
36
39
  Delocalize, just as the name suggest, does pretty much the opposite of localize.
37
40
 
@@ -96,8 +99,8 @@ delocalize then overrides `to_input_field_tag` in ActionView's `InstanceTag` so
96
99
 
97
100
  In this example, a user can enter the release date and the price just like he's used to in his language, for example:
98
101
 
99
- > Name: "Couch"
100
- > Released on: "12. Oktober 2009"
102
+ > Name: "Couch"
103
+ > Released on: "12. Oktober 2009"
101
104
  > Price: "2.999,90"
102
105
 
103
106
  When saved, ActiveRecord automatically converts these to a regular Ruby date and number.
@@ -107,11 +110,11 @@ Edit forms then also show localized dates/numbers. By default, dates and times a
107
110
  You can also customize the output using some options:
108
111
 
109
112
  The price should always show two decimal digits and we don't need the delimiter:
110
-
113
+
111
114
  ```erb
112
115
  <%= f.text_field :price, :precision => 2, :delimiter => '' %>
113
116
  ```
114
-
117
+
115
118
  The `released_on` date should be shown in the `:full` format:
116
119
 
117
120
  ```erb
@@ -124,7 +127,7 @@ You can also customize the output using some options:
124
127
  <%= f.text_field :released_on, :format => "%B %Y" %>
125
128
  ```
126
129
 
127
- ### Ruby 1.9 + Psych YAML Parser
130
+ ## Ruby 1.9 + Psych YAML Parser
128
131
 
129
132
  You will need to adjust the localization formatting when using the new YAML parser Psych. Below is an example error message you may receive in your logs as well as an example of acceptable formatting and helpful links for reference:
130
133
 
@@ -208,7 +211,7 @@ en:
208
211
  - :year
209
212
  time:
210
213
  input:
211
- formats:
214
+ formats:
212
215
  - :default
213
216
  - :long
214
217
  - :short
@@ -222,26 +225,17 @@ en:
222
225
  pm: "pm"
223
226
  ```
224
227
 
225
- ### Compatibility
228
+ ## Compatibility
226
229
 
227
230
  * Tested with Rails 2.3.5 in Ruby 1.8.7, Ruby 1.9.1 and Ruby 1.9.2 (head)
228
- * Tested with Rails 3 Beta 3 in Ruby 1.9.2 (head)
229
-
230
- ### Contributors
231
+ * Tested with Rails 3 in Ruby 1.9.3, Ruby 2.0 and Ruby 2.1 (head)
232
+ * Tested with Rails 4 in Ruby 1.9.3, Ruby 2.0 and Ruby 2.1 (head)
231
233
 
232
- People who have contributed to delocalize (in no particular order):
234
+ ## Contributors
233
235
 
234
- * [Fernando Luizao](http://github.com/fernandoluizao)
235
- * [Stephan Zalewski](http://github.com/stepahn)
236
- * [Lailson Bandeira](http://github.com/lailsonbm)
237
- * [Carlos Antonio da Silva](http://github.com/carlosantoniodasilva)
238
- * [Michele Franzin](http://github.com/michelefranzin)
239
- * [Raphaela Wrede](https://github.com/rwrede)
240
- * [Jan De Poorter](https://github.com/DefV)
241
- * [Blake Lucchesi](https://github.com/BlakeLucchesi)
242
- * [Ralph von der Heyden](https://github.com/ralph)
236
+ Thanks to [all the people who contributed](https://github.com/clemens/delocalize/graphs/contributors) and submitted issues.
243
237
 
244
- ### TODO
238
+ ## TODO
245
239
 
246
240
  * Improve test coverage
247
241
  * Separate Ruby/Rails stuff to make it usable outside Rails
@@ -249,6 +243,6 @@ People who have contributed to delocalize (in no particular order):
249
243
  * Implement AM/PM support
250
244
  * Cleanup, cleanup, cleanup ...
251
245
 
252
- Copyright (c) 2009-2011 Clemens Kofler <clemens@railway.at>
246
+ Copyright (c) 2009-2014 Clemens Kofler <clemens@railway.at>
253
247
  <http://www.railway.at/>
254
248
  Released under the MIT license
@@ -16,15 +16,21 @@ module I18n
16
16
  def with_delocalization_disabled(&block)
17
17
  old_value = I18n.enable_delocalization
18
18
  I18n.enable_delocalization = false
19
- yield
20
- I18n.enable_delocalization = old_value
19
+ begin
20
+ yield
21
+ ensure
22
+ I18n.enable_delocalization = old_value
23
+ end
21
24
  end
22
25
 
23
26
  def with_delocalization_enabled(&block)
24
27
  old_value = I18n.enable_delocalization
25
28
  I18n.enable_delocalization = true
26
- yield
27
- I18n.enable_delocalization = old_value
29
+ begin
30
+ yield
31
+ ensure
32
+ I18n.enable_delocalization = old_value
33
+ end
28
34
  end
29
35
  end
30
- end
36
+ end
@@ -1,54 +1,5 @@
1
- require 'action_view'
2
-
3
- # TODO: also override other methods like to_check_box_tag since they might contain numeric values?
4
- # ActionView needs some patching too
5
-
6
- ActionView::Helpers::InstanceTag.class_eval do
7
- include ActionView::Helpers::NumberHelper
8
-
9
- alias original_to_input_field_tag to_input_field_tag
10
- def to_input_field_tag(field_type, options = {})
11
- options.symbolize_keys!
12
- # numbers and dates/times should be localized unless value is already defined
13
- if object && (options[:value].blank? || !options[:value].is_a?(String)) && object.respond_to?(:column_for_attribute) && column = object.column_for_attribute(method_name)
14
- value = options[:value] || object.send(method_name)
15
-
16
- if column.number?
17
- number_options = I18n.t(:'number.format')
18
- separator = options.delete(:separator) || number_options[:separator]
19
- delimiter = options.delete(:delimiter) || number_options[:delimiter]
20
- precision = options.delete(:precision) || number_options[:precision]
21
- opts = { :separator => separator, :delimiter => delimiter, :precision => precision }
22
- # integers don't need a precision
23
- opts.merge!(:precision => 0) if column.type == :integer
24
-
25
- hidden_for_integer = field_type == 'hidden' && column.type == :integer
26
-
27
- # the number will be formatted only if it has no numericality errors
28
- if object.respond_to?(:errors) && !Array(object.errors[method_name]).try(:include?, 'is not a number')
29
- # we don't format integer hidden fields because this breaks nested_attributes
30
- options[:value] = number_with_precision(value, opts) unless hidden_for_integer
31
- end
32
- elsif column.date? || column.time?
33
- options[:value] = value ? I18n.l(value, :format => options.delete(:format)) : nil
34
- end
35
- end
36
-
37
- original_to_input_field_tag(field_type, options)
38
- end
1
+ if Gem::Version.new(ActionPack::VERSION::STRING) >= Gem::Version.new('4.0.0.beta')
2
+ require 'delocalize/rails_ext/action_view_rails4'
3
+ else
4
+ require 'delocalize/rails_ext/action_view_rails3'
39
5
  end
40
-
41
- # TODO: does it make sense to also override FormTagHelper methods?
42
- # ActionView::Helpers::FormTagHelper.class_eval do
43
- # include ActionView::Helpers::NumberHelper
44
- #
45
- # alias original_text_field_tag text_field_tag
46
- # def text_field_tag(name, value = nil, options = {})
47
- # value = options.delete(:value) if options.key?(:value)
48
- # if value.is_a?(Numeric)
49
- # value = number_with_delimiter(value)
50
- # end
51
- # original_text_field_tag(name, value, options)
52
- # end
53
- # end
54
-
@@ -0,0 +1,53 @@
1
+ require 'action_view'
2
+
3
+ # TODO: also override other methods like to_check_box_tag since they might contain numeric values?
4
+ # ActionView needs some patching too
5
+
6
+ ActionView::Helpers::InstanceTag.class_eval do
7
+ include ActionView::Helpers::NumberHelper
8
+
9
+ alias original_to_input_field_tag to_input_field_tag
10
+ def to_input_field_tag(field_type, options = {})
11
+ options.symbolize_keys!
12
+ # numbers and dates/times should be localized unless value is already defined
13
+ if object && (options[:value].blank? || !options[:value].is_a?(String)) && object.respond_to?(:column_for_attribute) && column = object.column_for_attribute(method_name)
14
+ value = options[:value] || object.send(method_name)
15
+
16
+ if column.number?
17
+ number_options = I18n.t(:'number.format')
18
+ separator = options.delete(:separator) || number_options[:separator]
19
+ delimiter = options.delete(:delimiter) || number_options[:delimiter]
20
+ precision = options.delete(:precision) || number_options[:precision]
21
+ opts = { :separator => separator, :delimiter => delimiter, :precision => precision }
22
+ # integers don't need a precision
23
+ opts.merge!(:precision => 0) if column.type == :integer
24
+
25
+ hidden_for_integer = field_type == 'hidden' && column.type == :integer
26
+
27
+ # the number will be formatted only if it has no numericality errors
28
+ if object.respond_to?(:errors) && !Array(object.errors[method_name]).try(:include?, 'is not a number')
29
+ # we don't format integer hidden fields because this breaks nested_attributes
30
+ options[:value] = number_with_precision(value, opts) unless hidden_for_integer
31
+ end
32
+ elsif column.date? || column.time?
33
+ options[:value] = value ? I18n.l(value, :format => options.delete(:format)) : nil
34
+ end
35
+ end
36
+
37
+ original_to_input_field_tag(field_type, options)
38
+ end
39
+ end
40
+
41
+ # TODO: does it make sense to also override FormTagHelper methods?
42
+ # ActionView::Helpers::FormTagHelper.class_eval do
43
+ # include ActionView::Helpers::NumberHelper
44
+ #
45
+ # alias original_text_field_tag text_field_tag
46
+ # def text_field_tag(name, value = nil, options = {})
47
+ # value = options.delete(:value) if options.key?(:value)
48
+ # if value.is_a?(Numeric)
49
+ # value = number_with_delimiter(value)
50
+ # end
51
+ # original_text_field_tag(name, value, options)
52
+ # end
53
+ # end
@@ -0,0 +1,38 @@
1
+ require 'action_view'
2
+
3
+ # TODO: also override other methods like to_check_box_tag since they might contain numeric values?
4
+ # ActionView needs some patching too
5
+
6
+ ActionView::Helpers::Tags::TextField.class_eval do
7
+ include ActionView::Helpers::NumberHelper
8
+
9
+ def render_with_localization
10
+ if object && (@options[:value].blank? || !@options[:value].is_a?(String)) && object.respond_to?(:column_for_attribute) && column = object.column_for_attribute(@method_name)
11
+ value = @options[:value] || object.send(@method_name)
12
+
13
+ if column.number?
14
+ number_options = I18n.t(:'number.format')
15
+ separator = @options.delete(:separator) || number_options[:separator]
16
+ delimiter = @options.delete(:delimiter) || number_options[:delimiter]
17
+ precision = @options.delete(:precision) || number_options[:precision]
18
+ opts = { :separator => separator, :delimiter => delimiter, :precision => precision }
19
+ # integers don't need a precision
20
+ opts.merge!(:precision => 0) if column.type == :integer
21
+
22
+ hidden_for_integer = field_type == 'hidden' && column.type == :integer
23
+
24
+ # the number will be formatted only if it has no numericality errors
25
+ if object.respond_to?(:errors) && !Array(object.errors[@method_name]).try(:include?, 'is not a number')
26
+ # we don't format integer hidden fields because this breaks nested_attributes
27
+ @options[:value] = number_with_precision(value, opts) unless hidden_for_integer
28
+ end
29
+ elsif column.date? || column.time?
30
+ @options[:value] = value ? I18n.l(value, :format => @options.delete(:format)) : nil
31
+ end
32
+ end
33
+
34
+ render_without_localization
35
+ end
36
+
37
+ alias_method_chain :render, :localization
38
+ end
@@ -1,80 +1,5 @@
1
- require 'active_record'
2
-
3
- require 'active_record/connection_adapters/abstract/schema_definitions'
4
- begin
5
- require 'active_record/connection_adapters/column'
6
- rescue LoadError
7
- # Not Rails 3.1, it seems
8
- end
9
-
10
- # let's hack into ActiveRecord a bit - everything at the lowest possible level, of course, so we minimalize side effects
11
- ActiveRecord::ConnectionAdapters::Column.class_eval do
12
- def date?
13
- klass == Date
14
- end
15
-
16
- def time?
17
- klass == Time
18
- end
19
- end
20
-
21
- ActiveRecord::Base.class_eval do
22
- def write_attribute_with_localization(attr_name, original_value)
23
- new_value = original_value
24
- if column = column_for_attribute(attr_name.to_s)
25
- if column.date?
26
- new_value = Date.parse_localized(original_value) rescue original_value
27
- elsif column.time?
28
- new_value = Time.parse_localized(original_value) rescue original_value
29
- end
30
- end
31
- write_attribute_without_localization(attr_name, new_value)
32
- end
33
- alias_method_chain :write_attribute, :localization
34
-
35
- def convert_number_column_value_with_localization(value)
36
- value = convert_number_column_value_without_localization(value)
37
- value = Numeric.parse_localized(value) if I18n.delocalization_enabled?
38
- value
39
- end
40
- alias_method_chain :convert_number_column_value, :localization
41
-
42
-
43
- define_method( (Gem::Version.new(ActiveRecord::VERSION::STRING) < Gem::Version.new('3.2.9')) ? :field_changed? : :_field_changed? ) do |attr, old, value|
44
- if column = column_for_attribute(attr)
45
- if column.number? && column.null && (old.nil? || old == 0) && value.blank?
46
- # For nullable numeric columns, NULL gets stored in database for blank (i.e. '') values.
47
- # Hence we don't record it as a change if the value changes from nil to ''.
48
- # If an old value of 0 is set to '' we want this to get changed to nil as otherwise it'll
49
- # be typecast back to 0 (''.to_i => 0)
50
- value = nil
51
- elsif column.number?
52
- value = column.type_cast(convert_number_column_value_with_localization(value))
53
- else
54
- value = column.type_cast(value)
55
- end
56
- end
57
- old != value
58
- end
59
- end
60
-
61
- ActiveRecord::Base.instance_eval do
62
- def define_method_attribute=(attr_name)
63
- if create_time_zone_conversion_attribute?(attr_name, columns_hash[attr_name])
64
- method_body, line = <<-EOV, __LINE__ + 1
65
- def #{attr_name}=(original_time)
66
- time = original_time
67
- unless time.acts_like?(:time)
68
- time = time.is_a?(String) ? (I18n.delocalization_enabled? ? Time.zone.parse_localized(time) : Time.zone.parse(time)) : time.to_time rescue time
69
- end
70
- time = time.in_time_zone rescue nil if time
71
- write_attribute(:#{attr_name}, original_time)
72
- @attributes_cache["#{attr_name}"] = time
73
- end
74
- EOV
75
- generated_attribute_methods.module_eval(method_body, __FILE__, line)
76
- else
77
- super
78
- end
79
- end
1
+ if Gem::Version.new(ActionPack::VERSION::STRING) >= Gem::Version.new('4.0.0.beta')
2
+ require 'delocalize/rails_ext/active_record_rails4'
3
+ else
4
+ require 'delocalize/rails_ext/active_record_rails3'
80
5
  end
@@ -0,0 +1,80 @@
1
+ require 'active_record'
2
+
3
+ require 'active_record/connection_adapters/abstract/schema_definitions'
4
+ begin
5
+ require 'active_record/connection_adapters/column'
6
+ rescue LoadError
7
+ # Not Rails 3.1, it seems
8
+ end
9
+
10
+ # let's hack into ActiveRecord a bit - everything at the lowest possible level, of course, so we minimalize side effects
11
+ ActiveRecord::ConnectionAdapters::Column.class_eval do
12
+ def date?
13
+ klass == Date
14
+ end
15
+
16
+ def time?
17
+ klass == Time
18
+ end
19
+ end
20
+
21
+ ActiveRecord::Base.class_eval do
22
+ def write_attribute_with_localization(attr_name, original_value)
23
+ new_value = original_value
24
+ if column = column_for_attribute(attr_name.to_s)
25
+ if column.date?
26
+ new_value = Date.parse_localized(original_value) rescue original_value
27
+ elsif column.time?
28
+ new_value = Time.parse_localized(original_value) rescue original_value
29
+ end
30
+ end
31
+ write_attribute_without_localization(attr_name, new_value)
32
+ end
33
+ alias_method_chain :write_attribute, :localization
34
+
35
+ def convert_number_column_value_with_localization(value)
36
+ value = convert_number_column_value_without_localization(value)
37
+ value = Numeric.parse_localized(value) if I18n.delocalization_enabled?
38
+ value
39
+ end
40
+ alias_method_chain :convert_number_column_value, :localization
41
+
42
+
43
+ define_method( (Gem::Version.new(ActiveRecord::VERSION::STRING) < Gem::Version.new('3.2.9')) ? :field_changed? : :_field_changed? ) do |attr, old, value|
44
+ if column = column_for_attribute(attr)
45
+ if column.number? && column.null && (old.nil? || old == 0) && value.blank?
46
+ # For nullable numeric columns, NULL gets stored in database for blank (i.e. '') values.
47
+ # Hence we don't record it as a change if the value changes from nil to ''.
48
+ # If an old value of 0 is set to '' we want this to get changed to nil as otherwise it'll
49
+ # be typecast back to 0 (''.to_i => 0)
50
+ value = nil
51
+ elsif column.number?
52
+ value = column.type_cast(convert_number_column_value_with_localization(value))
53
+ else
54
+ value = column.type_cast(value)
55
+ end
56
+ end
57
+ old != value
58
+ end
59
+ end
60
+
61
+ ActiveRecord::Base.instance_eval do
62
+ def define_method_attribute=(attr_name)
63
+ if create_time_zone_conversion_attribute?(attr_name, columns_hash[attr_name])
64
+ method_body, line = <<-EOV, __LINE__ + 1
65
+ def #{attr_name}=(original_time)
66
+ time = original_time
67
+ unless time.acts_like?(:time)
68
+ time = time.is_a?(String) ? (I18n.delocalization_enabled? ? Time.zone.parse_localized(time) : Time.zone.parse(time)) : time.to_time rescue time
69
+ end
70
+ time = time.in_time_zone rescue nil if time
71
+ write_attribute(:#{attr_name}, original_time)
72
+ @attributes_cache["#{attr_name}"] = time
73
+ end
74
+ EOV
75
+ generated_attribute_methods.module_eval(method_body, __FILE__, line)
76
+ else
77
+ super
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,72 @@
1
+ require 'active_record'
2
+
3
+ # let's hack into ActiveRecord a bit - everything at the lowest possible level, of course, so we minimalize side effects
4
+ ActiveRecord::ConnectionAdapters::Column.class_eval do
5
+ def date?
6
+ klass == Date
7
+ end
8
+
9
+ def time?
10
+ klass == Time
11
+ end
12
+ end
13
+
14
+ module ActiveRecord::AttributeMethods::Write
15
+ def type_cast_attribute_for_write(column, value)
16
+ return value unless column
17
+
18
+ value = Numeric.parse_localized(value) if column.number? && I18n.delocalization_enabled?
19
+ column.type_cast_for_write value
20
+ end
21
+ end
22
+
23
+ ActiveRecord::Base.class_eval do
24
+ def write_attribute_with_localization(attr_name, original_value)
25
+ new_value = original_value
26
+ if column = column_for_attribute(attr_name.to_s)
27
+ if column.date?
28
+ new_value = Date.parse_localized(original_value) rescue original_value
29
+ elsif column.time?
30
+ new_value = Time.parse_localized(original_value) rescue original_value
31
+ end
32
+ end
33
+ write_attribute_without_localization(attr_name, new_value)
34
+ end
35
+ alias_method_chain :write_attribute, :localization
36
+
37
+ define_method :_field_changed? do |attr, old, value|
38
+ if column = column_for_attribute(attr)
39
+ if column.number? && column.null && (old.nil? || old == 0) && value.blank?
40
+ # For nullable numeric columns, NULL gets stored in database for blank (i.e. '') values.
41
+ # Hence we don't record it as a change if the value changes from nil to ''.
42
+ # If an old value of 0 is set to '' we want this to get changed to nil as otherwise it'll
43
+ # be typecast back to 0 (''.to_i => 0)
44
+ value = nil
45
+ elsif column.number?
46
+ value = column.type_cast(Numeric.parse_localized(value))
47
+ else
48
+ value = column.type_cast(value)
49
+ end
50
+ end
51
+ old != value
52
+ end
53
+
54
+ def define_method_attribute=(attr_name)
55
+ if create_time_zone_conversion_attribute?(attr_name, columns_hash[attr_name])
56
+ method_body, line = <<-EOV, __LINE__ + 1
57
+ def #{attr_name}=(original_time)
58
+ time = original_time
59
+ unless time.acts_like?(:time)
60
+ time = time.is_a?(String) ? (I18n.delocalization_enabled? ? Time.zone.parse_localized(time) : Time.zone.parse(time)) : time.to_time rescue time
61
+ end
62
+ time = time.in_time_zone rescue nil if time
63
+ write_attribute(:#{attr_name}, original_time)
64
+ @attributes_cache["#{attr_name}"] = time
65
+ end
66
+ EOV
67
+ generated_attribute_methods.module_eval(method_body, __FILE__, line)
68
+ else
69
+ super
70
+ end
71
+ end
72
+ end
@@ -1,10 +1,8 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require 'test_helper'
4
- require 'active_record/test_case'
5
- require 'action_view/test_case'
6
4
 
7
- class DelocalizeActiveRecordTest < ActiveRecord::TestCase
5
+ class DelocalizeActiveRecordTest < ActiveSupport::TestCase
8
6
  def setup
9
7
  Time.zone = 'Berlin' # make sure everything works as expected with TimeWithZone
10
8
  Timecop.freeze(Time.zone.local(2009, 3, 1, 12, 0))
@@ -65,7 +63,7 @@ class DelocalizeActiveRecordTest < ActiveRecord::TestCase
65
63
  end
66
64
 
67
65
  test "delocalizes with fallback locale" do
68
- I18n::Backend::Simple.include(I18n::Backend::Fallbacks)
66
+ I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks)
69
67
  I18n.fallbacks[:xx] = [:xx, :tt]
70
68
 
71
69
  I18n.with_locale :xx do
@@ -147,6 +145,14 @@ class DelocalizeActiveRecordTest < ActiveRecord::TestCase
147
145
  end
148
146
  end
149
147
 
148
+ test "properly resets when an error is raised in a with_delocalization_disabled block" do
149
+ I18n.enable_delocalization = true
150
+ I18n.with_delocalization_disabled do
151
+ raise 'error'
152
+ end rescue nil
153
+ assert_equal true, I18n.enable_delocalization
154
+ end
155
+
150
156
  test "uses localized parsing if called with with_delocalization_enabled" do
151
157
  I18n.with_delocalization_enabled do
152
158
  @product.price = '1.299,99'
@@ -157,6 +163,14 @@ class DelocalizeActiveRecordTest < ActiveRecord::TestCase
157
163
  end
158
164
  end
159
165
 
166
+ test "properly resets when an error is raised in a with_delocalization_enabled block" do
167
+ I18n.enable_delocalization = false
168
+ I18n.with_delocalization_enabled do
169
+ raise 'error'
170
+ end rescue nil
171
+ assert_equal false, I18n.enable_delocalization
172
+ end
173
+
160
174
  test "dirty attributes must detect changes in decimal columns" do
161
175
  @product.price = 10
162
176
  @product.save
@@ -202,7 +216,7 @@ class DelocalizeActiveRecordTest < ActiveRecord::TestCase
202
216
  end
203
217
  end
204
218
 
205
- class DelocalizeActionViewTest < ActionView::TestCase
219
+ class DelocalizeActionViewTest < ActiveSupport::TestCase
206
220
  include ActionView::Helpers::FormHelper
207
221
 
208
222
  def setup
@@ -212,62 +226,52 @@ class DelocalizeActionViewTest < ActionView::TestCase
212
226
 
213
227
  test "shows text field using formatted number" do
214
228
  @product.price = 1299.9
215
- assert_dom_equal '<input id="product_price" name="product[price]" size="30" type="text" value="1.299,90" />',
216
- text_field(:product, :price)
229
+ assert_match /value="1\.299,90"/, text_field(:product, :price)
217
230
  end
218
231
 
219
232
  test "shows text field using formatted number with options" do
220
233
  @product.price = 1299.995
221
- assert_dom_equal '<input id="product_price" name="product[price]" size="30" type="text" value="1,299.995" />',
222
- text_field(:product, :price, :precision => 3, :delimiter => ',', :separator => '.')
234
+ assert_match /value="1,299\.995"/, text_field(:product, :price, :precision => 3, :delimiter => ',', :separator => '.')
223
235
  end
224
236
 
225
237
  test "shows text field using formatted number without precision if column is an integer" do
226
238
  @product.times_sold = 20
227
- assert_dom_equal '<input id="product_times_sold" name="product[times_sold]" size="30" type="text" value="20" />',
228
- text_field(:product, :times_sold)
239
+ assert_match /value="20"/, text_field(:product, :times_sold)
229
240
 
230
241
  @product.times_sold = 2000
231
- assert_dom_equal '<input id="product_times_sold" name="product[times_sold]" size="30" type="text" value="2.000" />',
232
- text_field(:product, :times_sold)
242
+ assert_match /value="2\.000"/, text_field(:product, :times_sold)
233
243
  end
234
244
 
235
245
  test "shows text field using formatted date" do
236
246
  @product.released_on = Date.civil(2009, 10, 19)
237
- assert_dom_equal '<input id="product_released_on" name="product[released_on]" size="30" type="text" value="19.10.2009" />',
238
- text_field(:product, :released_on)
247
+ assert_match /value="19\.10\.2009"/, text_field(:product, :released_on)
239
248
  end
240
249
 
241
250
  test "shows text field using formatted date and time" do
242
251
  @product.published_at = Time.zone.local(2009, 3, 1, 12, 0, 0)
243
252
  # careful - leading whitespace with %e
244
- assert_dom_equal '<input id="product_published_at" name="product[published_at]" size="30" type="text" value="Sonntag, 1. März 2009, 12:00 Uhr" />',
245
- text_field(:product, :published_at)
253
+ assert_match /value="Sonntag, 1\. März 2009, 12:00 Uhr"/, text_field(:product, :published_at)
246
254
  end
247
255
 
248
256
  test "shows text field using formatted date with format" do
249
257
  @product.released_on = Date.civil(2009, 10, 19)
250
- assert_dom_equal '<input id="product_released_on" name="product[released_on]" size="30" type="text" value="19. Oktober 2009" />',
251
- text_field(:product, :released_on, :format => :long)
258
+ assert_match /value="19\. Oktober 2009"/, text_field(:product, :released_on, :format => :long)
252
259
  end
253
260
 
254
261
  test "shows text field using formatted date and time with format" do
255
262
  @product.published_at = Time.zone.local(2009, 3, 1, 12, 0, 0)
256
263
  # careful - leading whitespace with %e
257
- assert_dom_equal '<input id="product_published_at" name="product[published_at]" size="30" type="text" value=" 1. März, 12:00 Uhr" />',
258
- text_field(:product, :published_at, :format => :short)
264
+ assert_match /value=" 1\. März, 12:00 Uhr"/, text_field(:product, :published_at, :format => :short)
259
265
  end
260
266
 
261
267
  test "shows text field using formatted time with format" do
262
268
  @product.cant_think_of_a_sensible_time_field = Time.zone.local(2009, 3, 1, 9, 0, 0)
263
- assert_dom_equal '<input id="product_cant_think_of_a_sensible_time_field" name="product[cant_think_of_a_sensible_time_field]" size="30" type="text" value="09:00 Uhr" />',
264
- text_field(:product, :cant_think_of_a_sensible_time_field, :format => :time)
269
+ assert_match /value="09:00 Uhr"/, text_field(:product, :cant_think_of_a_sensible_time_field, :format => :time)
265
270
  end
266
271
 
267
272
  test "integer hidden fields shouldn't be formatted" do
268
273
  @product.times_sold = 1000
269
- assert_dom_equal '<input id="product_times_sold" name="product[times_sold]" type="hidden" value="1000" />',
270
- hidden_field(:product, :times_sold)
274
+ assert_match /value="1000"/, hidden_field(:product, :times_sold)
271
275
  end
272
276
 
273
277
  test "doesn't raise an exception when object is nil" do
@@ -287,28 +291,24 @@ class DelocalizeActionViewTest < ActionView::TestCase
287
291
 
288
292
  test "delocalizes a given non-string :value" do
289
293
  @product.price = 1299.9
290
- assert_dom_equal '<input id="product_price" name="product[price]" size="30" type="text" value="1.499,90" />',
291
- text_field(:product, :price, :value => 1499.90)
294
+ assert_match /value="1\.499,90"/, text_field(:product, :price, :value => 1499.90)
292
295
  end
293
296
 
294
297
  test "doesn't override given string :value" do
295
298
  @product.price = 1299.9
296
- assert_dom_equal '<input id="product_price" name="product[price]" size="30" type="text" value="1.499,90" />',
297
- text_field(:product, :price, :value => "1.499,90")
299
+ assert_match /value="1\.499,90"/, text_field(:product, :price, :value => "1.499,90")
298
300
  end
299
301
 
300
302
  test "doesn't convert the value if field has numericality errors" do
301
303
  @product = ProductWithValidation.new(:price => 'this is not a number')
302
304
  @product.valid?
303
- assert_dom_equal %(<div class="field_with_errors"><input id="product_price" name="product[price]" size="30" type="text" value="this is not a number" /></div>),
304
- text_field(:product, :price)
305
+ assert_match /value="this is not a number"/, text_field(:product, :price)
305
306
  end
306
307
 
307
308
  test "should convert the value if field have non-numericality errors, but have other errors, e.g. business rules" do
308
309
  @product = ProductWithBusinessValidation.new(:price => '1.337,66')
309
310
  @product.valid?
310
- assert_dom_equal %(<div class="field_with_errors"><input id="product_price" name="product[price]" size="30" type="text" value="1.337,66" /></div>),
311
- text_field(:product, :price)
311
+ assert_match /value="1\.337,66"/, text_field(:product, :price)
312
312
  end
313
313
 
314
314
  test "doesn't raise an exception when object isn't an ActiveReccord" do
@@ -324,8 +324,7 @@ class DelocalizeActionViewTest < ActionView::TestCase
324
324
  end
325
325
 
326
326
  test "formats field with default value correctly" do
327
- assert_dom_equal '<input id="product_some_value_with_default" name="product[some_value_with_default]" size="30" type="text" value="0,00" />',
328
- text_field(:product, :some_value_with_default)
327
+ assert_match /value="0,00"/, text_field(:product, :some_value_with_default)
329
328
  end
330
329
  end
331
330
 
@@ -6,8 +6,7 @@ require 'bundler'
6
6
  Bundler.require(:default, :development)
7
7
 
8
8
  require 'rails/all'
9
-
10
- require 'test/unit'
9
+ require 'rails/test_help'
11
10
 
12
11
  require 'delocalize/rails_ext/action_view'
13
12
  require 'delocalize/rails_ext/active_record'
@@ -66,6 +65,7 @@ tt[:date][:formats][:default] = '%d|%m|%Y'
66
65
  I18n.backend.store_translations :de, de
67
66
  I18n.backend.store_translations :tt, tt
68
67
 
68
+ I18n.enforce_available_locales = false
69
69
  I18n.locale = :de
70
70
 
71
71
  class NonArProduct
@@ -83,11 +83,7 @@ class ProductWithValidation < Product
83
83
  end
84
84
 
85
85
  class ProductWithBusinessValidation < Product
86
- validate do |record|
87
- if record.price > 10
88
- record.errors.add(:price, :invalid)
89
- end
90
- end
86
+ validates_numericality_of :price, :less_than => 10
91
87
  end
92
88
 
93
89
  config = YAML.load_file(File.dirname(__FILE__) + '/database.yml')
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: delocalize
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-09-10 00:00:00.000000000 Z
12
+ date: 2014-08-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -19,9 +19,6 @@ dependencies:
19
19
  - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
21
  version: '3.0'
22
- - - <
23
- - !ruby/object:Gem::Version
24
- version: '4'
25
22
  type: :runtime
26
23
  prerelease: false
27
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -30,9 +27,6 @@ dependencies:
30
27
  - - ! '>='
31
28
  - !ruby/object:Gem::Version
32
29
  version: '3.0'
33
- - - <
34
- - !ruby/object:Gem::Version
35
- version: '4'
36
30
  - !ruby/object:Gem::Dependency
37
31
  name: timecop
38
32
  requirement: !ruby/object:Gem::Requirement
@@ -60,7 +54,11 @@ files:
60
54
  - lib/delocalize/localized_date_time_parser.rb
61
55
  - lib/delocalize/localized_numeric_parser.rb
62
56
  - lib/delocalize/rails_ext/action_view.rb
57
+ - lib/delocalize/rails_ext/action_view_rails3.rb
58
+ - lib/delocalize/rails_ext/action_view_rails4.rb
63
59
  - lib/delocalize/rails_ext/active_record.rb
60
+ - lib/delocalize/rails_ext/active_record_rails3.rb
61
+ - lib/delocalize/rails_ext/active_record_rails4.rb
64
62
  - lib/delocalize/rails_ext/time_zone.rb
65
63
  - lib/delocalize/railtie.rb
66
64
  - lib/delocalize/ruby_ext/date.rb
@@ -75,7 +73,8 @@ files:
75
73
  - test/delocalize_test.rb
76
74
  - test/test_helper.rb
77
75
  homepage: http://github.com/clemens/delocalize
78
- licenses: []
76
+ licenses:
77
+ - MIT
79
78
  post_install_message:
80
79
  rdoc_options:
81
80
  - --charset=UTF-8