i18n_alchemy 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,9 @@
1
+ ## v0.2.0 - 2013-11-28
2
+
3
+ * Rails 4 integration
4
+ * Drop support to Ruby 1.8.7 and Rails 3.0 / 3.1
5
+ * Remove support to passing old mass assignment options to assign methods (:without_protection and friends)
6
+
1
7
  ## v0.1.0 - 2013-2-27
2
8
 
3
9
  * Fix json serialization to delegate to the target object instead of the proxy
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  ## I18nAlchemy
2
2
 
3
- [![Build Status](https://secure.travis-ci.org/carlosantoniodasilva/i18n_alchemy.png)](http://travis-ci.org/carlosantoniodasilva/i18n_alchemy)
3
+ [![Gem Version](https://badge.fury.io/rb/i18n_alchemy.png)](http://badge.fury.io/rb/i18n_alchemy)
4
+ [![Build Status](https://api.travis-ci.org/carlosantoniodasilva/i18n_alchemy.png?branch=master)](http://travis-ci.org/carlosantoniodasilva/i18n_alchemy)
5
+ [![Code Climate](https://codeclimate.com/github/carlosantoniodasilva/i18n_alchemy.png)](https://codeclimate.com/github/carlosantoniodasilva/i18n_alchemy)
4
6
 
5
7
  I18n date/number parsing/localization
6
8
 
@@ -14,8 +14,8 @@ module I18n
14
14
  module Alchemy
15
15
  extend ActiveSupport::Concern
16
16
 
17
- def localized(attributes=nil, *args)
18
- I18n::Alchemy::Proxy.new(self, attributes, *args)
17
+ def localized(attributes = nil)
18
+ I18n::Alchemy::Proxy.new(self, attributes)
19
19
  end
20
20
 
21
21
  included do
@@ -25,8 +25,7 @@ module I18n
25
25
  end
26
26
 
27
27
  module ClassMethods
28
- def localize(*methods)
29
- options = methods.extract_options!
28
+ def localize(*methods, options)
30
29
  parser = options[:using]
31
30
  methods = methods.each_with_object({}) do |method_name, hash|
32
31
  hash[method_name] = parser
@@ -5,22 +5,16 @@ module I18n
5
5
  @target.attributes = parse_attributes(attributes)
6
6
  end
7
7
 
8
- # This method is added to the proxy even thought it does not exist in
9
- # Rails 3.0 (only >= 3.1).
10
- def assign_attributes(attributes, *args)
11
- if @target.respond_to?(:assign_attributes)
12
- @target.assign_attributes(parse_attributes(attributes), *args)
13
- else
14
- self.attributes = attributes
15
- end
8
+ def assign_attributes(attributes)
9
+ @target.assign_attributes(parse_attributes(attributes))
16
10
  end
17
11
 
18
- def update_attributes(attributes, *args)
19
- @target.update_attributes(parse_attributes(attributes), *args)
12
+ def update_attributes(attributes)
13
+ @target.update_attributes(parse_attributes(attributes))
20
14
  end
21
15
 
22
- def update_attributes!(attributes, *args)
23
- @target.update_attributes!(parse_attributes(attributes), *args)
16
+ def update_attributes!(attributes)
17
+ @target.update_attributes!(parse_attributes(attributes))
24
18
  end
25
19
 
26
20
  def update_attribute(attribute, value)
@@ -1,13 +1,17 @@
1
1
  module I18n
2
2
  module Alchemy
3
- # Depend on AS::BasicObject which has a "blank slate" - no methods.
4
- class Proxy < ActiveSupport::BasicObject
3
+ # Depend on AS::Basic/ProxyObject which has a "blank slate" - no methods.
4
+ base_proxy = defined?(ActiveSupport::ProxyObject) ?
5
+ ActiveSupport::ProxyObject : ActiveSupport::BasicObject
6
+
7
+ class Proxy < base_proxy
5
8
  include AttributesParsing
6
9
 
7
10
  # TODO: cannot assume _id is always a foreign key.
8
11
  # Find a better way to find that and skip these columns.
9
- def initialize(target, attributes=nil, *args)
12
+ def initialize(target, attributes = nil)
10
13
  @target = target
14
+ @target_class = target.class
11
15
 
12
16
  @localized_attributes = {}
13
17
  @localized_associations = []
@@ -18,7 +22,7 @@ module I18n
18
22
  build_associations
19
23
  end
20
24
 
21
- assign_attributes(attributes, *args) if attributes
25
+ assign_attributes(attributes) if attributes
22
26
  end
23
27
 
24
28
  # Override to_param to always return the +proxy.to_param+. This allow us
@@ -59,12 +63,11 @@ module I18n
59
63
  private
60
64
 
61
65
  def active_record_compatible?
62
- target_class = @target.class
63
- target_class.respond_to?(:columns) && target_class.respond_to?(:nested_attributes_options)
66
+ @target_class.respond_to?(:columns) && @target_class.respond_to?(:nested_attributes_options)
64
67
  end
65
68
 
66
69
  def build_attributes
67
- @target.class.columns.each do |column|
70
+ @target_class.columns.each do |column|
68
71
  column_name = column.name
69
72
  next if column.primary || column_name.ends_with?("_id") || @localized_attributes.key?(column_name)
70
73
 
@@ -74,7 +77,7 @@ module I18n
74
77
  end
75
78
 
76
79
  def build_methods
77
- @target.class.localized_methods.each_pair do |method, parser_type|
80
+ @target_class.localized_methods.each_pair do |method, parser_type|
78
81
  method = method.to_s
79
82
  parser = detect_parser(parser_type)
80
83
  build_attribute(method, parser)
@@ -82,7 +85,7 @@ module I18n
82
85
  end
83
86
 
84
87
  def build_associations
85
- @target.class.nested_attributes_options.each_key do |association_name|
88
+ @target_class.nested_attributes_options.each_key do |association_name|
86
89
  create_localized_association(association_name)
87
90
  end
88
91
  end
@@ -95,7 +98,7 @@ module I18n
95
98
 
96
99
  def create_localized_association(association_name)
97
100
  @localized_associations <<
98
- AssociationParser.new(@target.class, association_name)
101
+ AssociationParser.new(@target_class, association_name)
99
102
  end
100
103
 
101
104
  def create_localized_attribute(column_name, parser)
@@ -1,5 +1,5 @@
1
1
  module I18n
2
2
  module Alchemy
3
- VERSION = "0.1.0"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
@@ -20,27 +20,38 @@ class ActionViewTest < I18n::Alchemy::TestCase
20
20
  end
21
21
 
22
22
  def test_text_field_with_string_attribute
23
- assert_equal '<input id="product_name" name="product[name]" size="30" type="text" value="Potato" />',
23
+ assert_equal text_input(:name, 'Potato'),
24
24
  @template.text_field(:product, :name, :object => @localized)
25
25
  end
26
26
 
27
27
  def test_text_field_with_integer_attribute
28
- assert_equal '<input id="product_quantity" name="product[quantity]" size="30" type="text" value="10" />',
28
+ assert_equal text_input(:quantity, '10'),
29
29
  @template.text_field(:product, :quantity, :object => @localized)
30
30
  end
31
31
 
32
32
  def test_text_field_with_decimal_attribute
33
- assert_equal '<input id="product_price" name="product[price]" size="30" type="text" value="1,99" />',
33
+ assert_equal text_input(:price, '1,99'),
34
34
  @template.text_field(:product, :price, :object => @localized)
35
35
  end
36
36
 
37
37
  def test_text_field_with_date_attribute
38
- assert_equal '<input id="product_released_at" name="product[released_at]" size="30" type="text" value="28/02/2011" />',
38
+ assert_equal text_input(:released_at, '28/02/2011'),
39
39
  @template.text_field(:product, :released_at, :object => @localized)
40
40
  end
41
41
 
42
42
  def test_text_field_with_time_attribute
43
- assert_equal '<input id="product_last_sale_at" name="product[last_sale_at]" size="30" type="text" value="28/02/2011 13:25:30" />',
43
+ assert_equal text_input(:last_sale_at, '28/02/2011 13:25:30'),
44
44
  @template.text_field(:product, :last_sale_at, :object => @localized)
45
45
  end
46
+
47
+ private
48
+
49
+ def text_input(attribute_name, value)
50
+ size = rails4? ? ' ' : ' size="30" '
51
+ %Q[<input id="product_#{attribute_name}" name="product[#{attribute_name}]"#{size}type="text" value="#{value}" />]
52
+ end
53
+
54
+ def rails4?
55
+ ActionPack::VERSION::STRING.start_with? "4"
56
+ end
46
57
  end
@@ -15,7 +15,6 @@ ActiveRecord::Schema.define do
15
15
  t.datetime :updated_at
16
16
  t.timestamp :last_sale_at
17
17
  t.references :supplier
18
- t.string :my_precious
19
18
  end
20
19
 
21
20
  create_table :suppliers do |t|
@@ -13,16 +13,6 @@ class ProxyAttributesParsingTest < I18n::Alchemy::ProxyTestCase
13
13
  assert_equal "28/02/2011", @localized.released_at
14
14
  end
15
15
 
16
- def test_initializes_proxy_with_attributes_and_skips_mass_assignment_security_protection_when_without_protection_is_used
17
- @localized = @product.localized(attributes_hash, :without_protection => true)
18
- if support_assign_attributes_without_protection?
19
- assert_equal 'My Precious!', @localized.my_precious
20
- else
21
- assert_nil @localized.my_precious
22
- end
23
- assert_equal 1, @localized.quantity
24
- end
25
-
26
16
  def test_assign_attributes
27
17
  @localized.assign_attributes(:price => '1,99')
28
18
  assert_equal "1,99", @localized.price
@@ -34,24 +24,8 @@ class ProxyAttributesParsingTest < I18n::Alchemy::ProxyTestCase
34
24
  end
35
25
  end
36
26
 
37
- def test_new_with_attr_protected_attributes
38
- @localized.assign_attributes(attributes_hash)
39
- assert_nil @localized.my_precious
40
- assert_equal 1, @localized.quantity
41
- end
42
-
43
- def test_assign_attributes_skips_mass_assignment_security_protection_when_without_protection_is_used
44
- @localized.assign_attributes(attributes_hash, :without_protection => true)
45
- if support_assign_attributes_without_protection?
46
- assert_equal 'My Precious!', @localized.my_precious
47
- else
48
- assert_nil @localized.my_precious
49
- end
50
- assert_equal 1, @localized.quantity
51
- end
52
-
53
27
  def test_assign_attributes_does_not_change_given_attributes_hash
54
- assert_attributes_hash_is_not_changed(attributes = attributes_hash) do
28
+ assert_attributes_hash_is_unchanged do |attributes|
55
29
  @localized.assign_attributes(attributes)
56
30
  end
57
31
  end
@@ -62,7 +36,7 @@ class ProxyAttributesParsingTest < I18n::Alchemy::ProxyTestCase
62
36
  end
63
37
 
64
38
  def test_attributes_assignment_does_not_change_given_attributes_hash
65
- assert_attributes_hash_is_not_changed(attributes = attributes_hash) do
39
+ assert_attributes_hash_is_unchanged do |attributes|
66
40
  @localized.attributes = attributes
67
41
  end
68
42
  end
@@ -74,7 +48,7 @@ class ProxyAttributesParsingTest < I18n::Alchemy::ProxyTestCase
74
48
  end
75
49
 
76
50
  def test_update_attributes_does_not_change_given_attributes_hash
77
- assert_attributes_hash_is_not_changed(attributes = attributes_hash) do
51
+ assert_attributes_hash_is_unchanged do |attributes|
78
52
  @localized.update_attributes(attributes)
79
53
  end
80
54
  end
@@ -86,7 +60,7 @@ class ProxyAttributesParsingTest < I18n::Alchemy::ProxyTestCase
86
60
  end
87
61
 
88
62
  def test_update_attributes_bang_does_not_change_given_attributes_hash
89
- assert_attributes_hash_is_not_changed(attributes = attributes_hash) do
63
+ assert_attributes_hash_is_unchanged do |attributes|
90
64
  @localized.update_attributes!(attributes)
91
65
  end
92
66
  end
@@ -130,13 +104,9 @@ class ProxyAttributesParsingTest < I18n::Alchemy::ProxyTestCase
130
104
 
131
105
  private
132
106
 
133
- def attributes_hash
134
- { :my_precious => 'My Precious!', :quantity => 1 }
135
- end
136
-
137
- def assert_attributes_hash_is_not_changed(attributes)
138
- yield
139
- assert_equal 1, attributes[:quantity]
140
- assert_equal 'My Precious!', attributes[:my_precious]
107
+ def assert_attributes_hash_is_unchanged
108
+ attributes = { :quantity => 1 }
109
+ yield attributes
110
+ assert_equal({ :quantity => 1 }, attributes)
141
111
  end
142
112
  end
@@ -124,32 +124,32 @@ class ProxyTest < I18n::Alchemy::ProxyTestCase
124
124
  # DateTime
125
125
  def test_parses_datetime_attribute_input
126
126
  @localized.updated_at = "28/02/2011 13:25:30"
127
- assert_equal Time.mktime(2011, 2, 28, 13, 25, 30), @product.updated_at
127
+ assert_equal Time.utc(2011,"feb",28,13,25,30), @product.updated_at
128
128
  end
129
129
 
130
130
  def test_localizes_datetime_attribute_output
131
- @product.updated_at = Time.mktime(2011, 2, 28, 13, 25, 30)
131
+ @product.updated_at = Time.utc(2011,"feb",28,13,25,30)
132
132
  assert_equal "28/02/2011 13:25:30", @localized.updated_at
133
133
  end
134
134
 
135
135
  def test_localizes_datetime_attribute_before_type_cast_output
136
- @product.updated_at = Time.mktime(2011, 2, 28, 13, 25, 30)
136
+ @product.updated_at = Time.utc(2011,"feb",28,13,25,30)
137
137
  assert_equal "28/02/2011 13:25:30", @localized.updated_at_before_type_cast
138
138
  end
139
139
 
140
140
  # Timestamp
141
141
  def test_parses_timestamp_attribute_input
142
142
  @localized.last_sale_at = "28/02/2011 13:25:30"
143
- assert_equal Time.mktime(2011, 2, 28, 13, 25, 30), @product.last_sale_at
143
+ assert_equal Time.utc(2011,"feb",28,13,25,30), @product.last_sale_at
144
144
  end
145
145
 
146
146
  def test_localizes_timestamp_attribute_output
147
- @product.last_sale_at = Time.mktime(2011, 2, 28, 13, 25, 30)
147
+ @product.last_sale_at = Time.utc(2011,"feb",28,13,25,30)
148
148
  assert_equal "28/02/2011 13:25:30", @localized.last_sale_at
149
149
  end
150
150
 
151
151
  def test_localizes_timestamp_attribute_before_type_cast_output
152
- @product.last_sale_at = Time.mktime(2011, 2, 28, 13, 25, 30)
152
+ @product.last_sale_at = Time.utc(2011,"feb",28,13,25,30)
153
153
  assert_equal "28/02/2011 13:25:30", @localized.last_sale_at_before_type_cast
154
154
  end
155
155
 
@@ -7,24 +7,12 @@ module BaseTimeParserTest
7
7
 
8
8
  # TODO: why so many time differences on the output?
9
9
  def test_parses_valid_string_times_with_default_i18n_locale
10
- output_timestamp = if RUBY_VERSION < "1.9"
11
- "Sat Dec 31 12:15:45 UTC 2011"
12
- else
13
- "2011-12-31 12:15:45 UTC"
14
- end
15
-
16
- assert_equal output_timestamp, @parser.parse("12/31/2011 12:15:45")
10
+ assert_equal "2011-12-31 12:15:45 UTC", @parser.parse("12/31/2011 12:15:45")
17
11
  end
18
12
 
19
13
  def test_parsers_string_times_on_current_i18n_locale
20
14
  I18n.with_locale :pt do
21
- output_timestamp = if RUBY_VERSION < "1.9"
22
- "Sat Dec 31 12:15:45 UTC 2011"
23
- else
24
- "2011-12-31 12:15:45 UTC"
25
- end
26
-
27
- assert_equal output_timestamp, @parser.parse("31/12/2011 12:15:45")
15
+ assert_equal "2011-12-31 12:15:45 UTC", @parser.parse("31/12/2011 12:15:45")
28
16
  end
29
17
  end
30
18
 
@@ -5,8 +5,6 @@ class Product < ActiveRecord::Base
5
5
  localize :estimated_last_comission_payment_at, :using => :timestamp
6
6
  localize :released_month, :using => MyCustomDateParser
7
7
 
8
- attr_protected :my_precious
9
-
10
8
  belongs_to :supplier
11
9
 
12
10
  def initialize(*)
@@ -21,11 +21,6 @@ Dir["test/models/*.rb"].each { |file| require File.expand_path(file) }
21
21
 
22
22
  module I18n::Alchemy
23
23
  class TestCase < MiniTest::Unit::TestCase
24
- # AR 3.0 does not have assign_attributes and without_protection option, so we
25
- # are going to skip such tests in this version.
26
- def support_assign_attributes_without_protection?
27
- @support_assign_attributes ||= ActiveRecord::VERSION::STRING >= "3.1.0"
28
- end
29
24
  end
30
25
 
31
26
  class ProxyTestCase < TestCase
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: i18n_alchemy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,24 +9,30 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-28 00:00:00.000000000 Z
12
+ date: 2013-11-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
- - - ~>
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 3.2.0
22
+ - - <
20
23
  - !ruby/object:Gem::Version
21
- version: '3.0'
24
+ version: '4.1'
22
25
  type: :runtime
23
26
  prerelease: false
24
27
  version_requirements: !ruby/object:Gem::Requirement
25
28
  none: false
26
29
  requirements:
27
- - - ~>
30
+ - - ! '>='
28
31
  - !ruby/object:Gem::Version
29
- version: '3.0'
32
+ version: 3.2.0
33
+ - - <
34
+ - !ruby/object:Gem::Version
35
+ version: '4.1'
30
36
  - !ruby/object:Gem::Dependency
31
37
  name: i18n
32
38
  requirement: !ruby/object:Gem::Requirement
@@ -34,7 +40,7 @@ dependencies:
34
40
  requirements:
35
41
  - - ~>
36
42
  - !ruby/object:Gem::Version
37
- version: '0.5'
43
+ version: '0.6'
38
44
  type: :runtime
39
45
  prerelease: false
40
46
  version_requirements: !ruby/object:Gem::Requirement
@@ -42,39 +48,51 @@ dependencies:
42
48
  requirements:
43
49
  - - ~>
44
50
  - !ruby/object:Gem::Version
45
- version: '0.5'
51
+ version: '0.6'
46
52
  - !ruby/object:Gem::Dependency
47
53
  name: actionpack
48
54
  requirement: !ruby/object:Gem::Requirement
49
55
  none: false
50
56
  requirements:
51
- - - ~>
57
+ - - ! '>='
58
+ - !ruby/object:Gem::Version
59
+ version: 3.2.0
60
+ - - <
52
61
  - !ruby/object:Gem::Version
53
- version: '3.0'
62
+ version: '4.1'
54
63
  type: :development
55
64
  prerelease: false
56
65
  version_requirements: !ruby/object:Gem::Requirement
57
66
  none: false
58
67
  requirements:
59
- - - ~>
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: 3.2.0
71
+ - - <
60
72
  - !ruby/object:Gem::Version
61
- version: '3.0'
73
+ version: '4.1'
62
74
  - !ruby/object:Gem::Dependency
63
75
  name: activerecord
64
76
  requirement: !ruby/object:Gem::Requirement
65
77
  none: false
66
78
  requirements:
67
- - - ~>
79
+ - - ! '>='
68
80
  - !ruby/object:Gem::Version
69
- version: '3.0'
81
+ version: 3.2.0
82
+ - - <
83
+ - !ruby/object:Gem::Version
84
+ version: '4.1'
70
85
  type: :development
71
86
  prerelease: false
72
87
  version_requirements: !ruby/object:Gem::Requirement
73
88
  none: false
74
89
  requirements:
75
- - - ~>
90
+ - - ! '>='
91
+ - !ruby/object:Gem::Version
92
+ version: 3.2.0
93
+ - - <
76
94
  - !ruby/object:Gem::Version
77
- version: '3.0'
95
+ version: '4.1'
78
96
  - !ruby/object:Gem::Dependency
79
97
  name: minitest
80
98
  requirement: !ruby/object:Gem::Requirement
@@ -98,7 +116,7 @@ dependencies:
98
116
  requirements:
99
117
  - - ~>
100
118
  - !ruby/object:Gem::Version
101
- version: 10.0.2
119
+ version: '10.1'
102
120
  type: :development
103
121
  prerelease: false
104
122
  version_requirements: !ruby/object:Gem::Requirement
@@ -106,7 +124,7 @@ dependencies:
106
124
  requirements:
107
125
  - - ~>
108
126
  - !ruby/object:Gem::Version
109
- version: 10.0.2
127
+ version: '10.1'
110
128
  description: I18n date/number parsing/localization
111
129
  email:
112
130
  - carlosantoniodasilva@gmail.com
@@ -156,18 +174,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
156
174
  - - ! '>='
157
175
  - !ruby/object:Gem::Version
158
176
  version: '0'
159
- segments:
160
- - 0
161
- hash: 2006072931743591474
162
177
  required_rubygems_version: !ruby/object:Gem::Requirement
163
178
  none: false
164
179
  requirements:
165
180
  - - ! '>='
166
181
  - !ruby/object:Gem::Version
167
182
  version: '0'
168
- segments:
169
- - 0
170
- hash: 2006072931743591474
171
183
  requirements: []
172
184
  rubyforge_project: i18n_alchemy
173
185
  rubygems_version: 1.8.23