acvwilson-currency 0.6.4 → 0.7

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.
data/currency.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = %q{currency}
3
- s.version = "0.6.4"
3
+ s.version = "0.7"
4
4
 
5
5
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
6
6
  s.authors = ["Asa Wilson", "David Palm"]
@@ -145,27 +145,29 @@ module Currency::ActiveRecord
145
145
  column = opts[:column] || opts[:attr_name]
146
146
  opts[:column] = column
147
147
 
148
+ # TODO: rewrite with define_method (dvd, 15-03-2009)
148
149
  if column.to_s != attr_name.to_s
149
150
  alias_accessor = <<-"end_eval"
150
- alias :before_money_#{column}=, :#{column}=
151
-
152
- def #{column}=(__value)
153
- @{attr_name} = nil # uncache
154
- before_money#{column} = __value
155
- end
151
+ alias :before_money_#{column}=, :#{column}=
156
152
 
153
+ def #{column}=(__value)
154
+ @{attr_name} = nil # uncache
155
+ before_money#{column} = __value
156
+ end
157
157
  end_eval
158
- end
159
158
 
159
+ end
160
+ alias_accessor ||= ''
161
+
160
162
  currency = opts[:currency]
161
163
 
162
164
  currency_column = opts[:currency_column]
163
165
  if currency_column && ! currency_column.kind_of?(String)
164
- currency_column = currency_column.to_s
165
166
  currency_column = "#{column}_currency"
166
167
  end
168
+
167
169
  if currency_column
168
- read_currency = "read_attribute(:#{currency_column.to_s})"
170
+ read_currency = "read_attribute(:#{currency_column})"
169
171
  write_currency = "write_attribute(:#{currency_column}, #{attr_name}_money.nil? ? nil : #{attr_name}_money.currency.code.to_s)"
170
172
  end
171
173
  opts[:currency_column] = currency_column
@@ -187,6 +189,7 @@ end_eval
187
189
  read_time = "self.#{time}"
188
190
  end
189
191
  opts[:time] = time
192
+
190
193
  if opts[:time_update]
191
194
  write_time = "self.#{time} = #{attr_name}_money && #{attr_name}_money.time"
192
195
  end
@@ -201,63 +204,66 @@ end_eval
201
204
 
202
205
  validate_allow_nil = opts[:allow_nil] ? ', :allow_nil => true' : ''
203
206
  validate = "# Validation\n"
204
- validate << "\nvalidates_numericality_of :#{attr_name}#{validate_allow_nil}\n"
207
+ validate << "\nvalidates_numericality_of :#{attr_name} #{validate_allow_nil}\n"
205
208
  validate << "\nvalidates_format_of :#{currency_column}, :with => /^[A-Z][A-Z][A-Z]$/#{validate_allow_nil}\n" if currency_column
206
- # validate << "\nbefore_validation :debug_#{attr_name}_before_validate\n"
207
- #
208
- # validate << %Q{
209
- # def debug_#{attr_name}_before_validate
210
- # logger.debug "\tValidating #{attr_name}. Allow nils? #{validate_allow_nil}"
211
- # logger.debug "\t\t'#{attr_name}': '\#\{#{attr_name}.inspect\}' (class: '\#\{#{attr_name}.class\}')"
212
- # logger.debug "\t\tcurrency column, '#{currency_column}': '\#\{#{currency_column}.inspect\}' (class: '\#\{#{currency_column}.class\}'), matches '/^[A-Z][A-Z][A-Z]$/': \#\{'#{currency_column}'.match(/^[A-Z][A-Z][A-Z]$/).to_a.inspect\}"
213
- # end
214
- # }
215
-
216
- alias_accessor ||= ''
217
-
218
- module_eval (opts[:module_eval] = x = <<-"end_eval"), __FILE__, __LINE__
219
- #{validate}
220
-
221
- #{alias_accessor}
222
-
223
- def #{attr_name}
224
- # $stderr.puts " \#{self.class.name}##{attr_name}"
225
- unless @#{attr_name}
226
- #{attr_name}_rep = read_attribute(:#{column})
227
- unless #{attr_name}_rep.nil?
228
- @#{attr_name} = ::Currency::Money.new_rep(#{attr_name}_rep, #{read_currency} || #{currency}, #{read_time} || #{time})
229
- #{read_preferred_currency}
230
- end
231
- end
232
- @#{attr_name}
233
- end
234
-
235
- def #{attr_name}=(value)
236
- if value.nil? || value.to_s.strip == ''
237
- #{attr_name}_money = nil
238
- elsif value.kind_of?(Integer) || value.kind_of?(String) || value.kind_of?(Float)
239
- #{attr_name}_money = ::Currency::Money(value, #{currency})
240
- #{write_preferred_currency}
241
- elsif value.kind_of?(::Currency::Money)
242
- #{attr_name}_money = value
243
- #{write_preferred_currency}
244
- #{write_currency ? write_currency : "#{attr_name}_money = #{attr_name}_money.convert(#{currency})"}
245
- else
246
- raise ::Currency::Exception::InvalidMoneyValue, value
247
- end
248
-
249
- @#{attr_name} = #{attr_name}_money # TODO: Really needed? Isn't the write_attribute enough?
209
+
210
+ # =================================================================================================
211
+ # = Define the currency_column setter, so that the Money object changes when the currency changes =
212
+ # =================================================================================================
213
+ if currency_column
214
+ currency_column_setter = %Q{
215
+ def #{currency_column}=(currency_code)
216
+ @#{attr_name} = nil
217
+ write_attribute(:#{currency_column}, currency_code)
218
+ end
219
+ }
220
+ class_eval currency_column_setter, __FILE__, __LINE__
221
+ end
222
+
223
+ class_eval (opts[:module_eval] = x = <<-"end_eval"), __FILE__, __LINE__
224
+ #{validate}
225
+
226
+ #{alias_accessor}
227
+
228
+ # Getter
229
+ def #{attr_name}
230
+ unless @#{attr_name}
231
+ rep = read_attribute(:#{column})
232
+ unless rep.nil?
233
+ @#{attr_name} = ::Currency::Money.new_rep(rep, #{read_currency} || #{currency}, #{read_time} || #{time})
234
+ #{read_preferred_currency}
235
+ end
236
+ end
237
+ @#{attr_name}
238
+ end
239
+
240
+ # Setter
241
+ def #{attr_name}=(value)
242
+ if value.nil? || value.to_s.strip == ''
243
+ #{attr_name}_money = nil
244
+ elsif value.kind_of?(Integer) || value.kind_of?(String) || value.kind_of?(Float)
245
+ #{attr_name}_money = ::Currency::Money(value, #{read_currency})
246
+ #{write_preferred_currency}
247
+ elsif value.kind_of?(::Currency::Money)
248
+ #{attr_name}_money = value
249
+ #{write_preferred_currency}
250
+ #{write_currency ? write_currency : "#{attr_name}_money = #{attr_name}_money.convert(#{currency})"}
251
+ else
252
+ raise ::Currency::Exception::InvalidMoneyValue, value
253
+ end
254
+
255
+ @#{attr_name} = #{attr_name}_money # TODO: Really needed? Isn't the write_attribute enough? (answer: no, because the getter method does an "if @#{attr_name}" to check if it's set)
250
256
 
251
- write_attribute(:#{column}, #{attr_name}_money.nil? ? nil : #{money_rep})
252
- #{write_time}
257
+ write_attribute(:#{column}, #{attr_name}_money.nil? ? nil : #{attr_name}_money.rep)
258
+ #{write_time}
253
259
 
254
- value
255
- end
256
-
257
- def #{attr_name}_before_type_cast
258
- #{attr_name}.to_f if #{attr_name}
259
- end
260
+ value
261
+ end
260
262
 
263
+ def #{attr_name}_before_type_cast
264
+ #{attr_name}.to_f if #{attr_name}
265
+ end
266
+
261
267
  end_eval
262
268
  =begin
263
269
  Replaced the _before_type_cast because it's buggy and weird:
data/lib/currency.rb CHANGED
@@ -130,7 +130,7 @@ require 'currency/exception'
130
130
  require 'currency/money'
131
131
  require 'currency/currency'
132
132
  require 'currency/currency/factory'
133
- require 'currency/money'
133
+ require 'currency/money' # TODO: Why require this twice? (dvd, 15-03-2009)
134
134
  require 'currency/parser'
135
135
  require 'currency/formatter' # require this one before the parser and enjoy the weird bugs!
136
136
  require 'currency/exchange'
@@ -1,23 +1,80 @@
1
1
  # Copyright (C) 2006-2007 Kurt Stephens <ruby-currency(at)umleta.com>
2
2
  # Copyright (C) 2008 Asa Wilson <acvwilson(at)gmail.com>
3
+ # Copyright (C) 2009 David Palm <dvdplm(at)gmail.com>
3
4
  # See LICENSE.txt for details.
4
5
 
5
6
  require File.dirname(__FILE__) + '/ar_spec_helper'
6
7
 
7
- describe Currency::ActiveRecord do
8
- it "simple" do
9
- # TODO: move insert_records into a before block?
10
- insert_records
8
+ class Dog < ActiveRecord::Base
9
+ attr_money :price, :currency_column => true, :allow_nil => true
10
+ end
11
11
 
12
- usd = @currency_test.find(@usd.id)
13
- usd.should_not be_nil
14
- assert_equal_currency usd, @usd
12
+ describe "extending ActiveRecord" do
13
+ describe "attr_money" do
14
+ before do
15
+ Dog.connection.execute("INSERT INTO dogs VALUES(null, 'fido', 1500, 'USD')") # NOTE: by-passing AR here to achieve clean slate (dvd, 15-03-2009)
16
+ @dog = Dog.first
17
+ end
15
18
 
16
- cad = @currency_test.find(@cad.id)
17
- cad.should_not == nil
18
- assert_equal_money cad, @cad
19
+ describe "retrieving money values" do
20
+ it "sets up the Money object at first read" do
21
+ pending
22
+ end
23
+
24
+ it "returns the ivar on subsequent reads" do
25
+ pending
26
+ end
27
+
28
+ it "does not setup a Money object if the db column does not contain an integer to use for money rep" do
29
+ pending
30
+ end
31
+
32
+ it "casts the currency to the preferred one, if a preferred currency was set" do
33
+ pending
34
+ end
35
+ end
36
+
37
+ describe "currency column" do
38
+ before do
39
+ Dog.connection.execute("INSERT INTO dogs VALUES(null, 'fido', 1500, 'USD')") # NOTE: by-passing AR here to achieve clean slate (dvd, 15-03-2009)
40
+ @dog = Dog.first
41
+ end
19
42
 
20
- cad.amount.currency.code.should == :USD
21
- end
22
- end
43
+ it "changes the currency when the value on the currency column changes" do
44
+ @dog.price.currency.code.should == :USD
45
+ @dog.update_attributes(:price_currency => 'EUR')
46
+ @dog.price.currency.code.should == :EUR
47
+ end
48
+
49
+ it "does NOT convert to the new currency when the currency column changes" do
50
+ @dog.price.rep.should == 1500
51
+ @dog.update_attributes(:price_currency => :EUR)
52
+ @dog.price.rep.should == 1500
53
+ end
54
+ end
55
+
56
+ describe "saving" do
57
+ it "saves the price with the default currency when set to 10.money" do
58
+ @dog.price = 10.money
59
+ @dog.price.should == Currency::Money("10")
60
+ end
61
+
62
+ it "saves the price with the currency of the Money object" do
63
+ @dog.price = 10.money(:EUR)
64
+ @dog.price.should == Currency::Money("10", "EUR")
65
+ end
66
+
67
+ it "can change just the currency" do
68
+ @dog.price_currency = 'CAD'
69
+ @dog.save
70
+ @dog.price.should == Currency::Money("15", "CAD")
71
+ end
72
+
73
+ it "can save changes using update_attributes" do
74
+ @dog.update_attributes(:price => 5, :price_currency => 'CAD')
75
+ @dog.price.should == 5.money('CAD')
76
+ end
77
+ end
23
78
 
79
+ end
80
+ end
@@ -8,6 +8,42 @@ require 'active_record'
8
8
  require 'active_record/migration'
9
9
  require File.dirname(__FILE__) + '/../lib/currency/active_record'
10
10
 
11
+ config = YAML::load(IO.read(File.dirname(__FILE__) + '/db/database.yml'))
12
+ ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
13
+ # ActiveRecord::Base.establish_connection(config['mysql_debug'])
14
+ ActiveRecord::Base.establish_connection(config['sqlite3mem'])
15
+
16
+ ActiveRecord::Migration.verbose = false
17
+ load(File.dirname(__FILE__) + "/db/schema.rb")
18
+
19
+ # ============================================
20
+ # = Load some currency symbols (171 records) =
21
+ # ============================================
22
+ currency_codes = IO.read(File.dirname(__FILE__) + '/db/currency_codes.sql')
23
+ currency_codes.each_line do |sql_insert|
24
+ ActiveRecord::Base.connection.execute(sql_insert)
25
+ end
26
+
27
+ # ================================
28
+ # = Load some rates (84 records) =
29
+ # ================================
30
+ rates = IO.read(File.dirname(__FILE__) + '/db/currency_historical_rates.sql')
31
+ rates.each_line do |sql_insert|
32
+ ActiveRecord::Base.connection.execute(sql_insert)
33
+ end
34
+
35
+ AR_M = ActiveRecord::Migration
36
+ AR_B = ActiveRecord::Base
37
+
38
+
39
+
40
+ =begin
41
+ require File.dirname(__FILE__) + '/spec_helper'
42
+
43
+ require 'active_record'
44
+ require 'active_record/migration'
45
+ require File.dirname(__FILE__) + '/../lib/currency/active_record'
46
+
11
47
  AR_M = ActiveRecord::Migration
12
48
  AR_B = ActiveRecord::Base
13
49
 
@@ -124,4 +160,5 @@ def assert_equal_currency(a,b)
124
160
  b.amount.currency.should == a.amount.currency
125
161
  b.amount.currency.code.should == a.amount.currency.code
126
162
 
127
- end
163
+ end
164
+ =end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acvwilson-currency
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.4
4
+ version: "0.7"
5
5
  platform: ruby
6
6
  authors:
7
7
  - Asa Wilson
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2009-02-05 06:05:45.477389 -08:00
13
+ date: 2009-03-15 11:25:57.897576 -07:00
14
14
  default_executable:
15
15
  dependencies: []
16
16
 
@@ -1,56 +0,0 @@
1
- require File.dirname(__FILE__) + '/ar_spec_helper'
2
-
3
- ##################################################
4
- # Basic CurrenyTest AR::B class
5
- #
6
-
7
- # TODO: Move elsewhere, combine with other AR tests
8
-
9
- TABLE_NAME = 'currency_column_test'
10
-
11
- class CurrencyColumnTestMigration < AR_M
12
- def self.up
13
- create_table TABLE_NAME.intern do |t|
14
- t.column :name, :string
15
- t.column :amount, :integer # Money
16
- t.column :amount_currency, :string, :size => 3 # Money.currency.code
17
- end
18
- end
19
-
20
- def self.down
21
- drop_table TABLE_NAME.intern
22
- end
23
- end
24
-
25
- class CurrencyColumnTest < AR_B
26
- set_table_name TABLE_NAME
27
- attr_money :amount, :currency_column => true
28
- end
29
-
30
- ##################################################
31
-
32
- describe "ActiveRecord macros" do
33
- before(:all) do
34
- AR_B.establish_connection(database_spec)
35
- @currency_test_migration ||= CurrencyColumnTestMigration
36
- @currency_test ||= CurrencyColumnTest
37
- schema_down
38
- schema_up
39
- end
40
-
41
- after(:all) do
42
- schema_down
43
- end
44
-
45
- it "can store and retrieve money values from a DB and automagically transfomr them to Money" do
46
- insert_records
47
-
48
- usd = @currency_test.find(@usd.id)
49
- usd.should == @usd
50
- usd.object_id.should_not == @usd.object_id # not same object
51
-
52
- cad = @currency_test.find(@cad.id)
53
- cad.should == @cad
54
- cad.object_id.should_not == @cad.object_id # not same object
55
- end
56
- end