i18n_alchemy 0.1.0 → 0.2.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.
@@ -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