currency 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest.txt CHANGED
@@ -20,6 +20,8 @@ Rakefile
20
20
  README
21
21
  Releases
22
22
  test/ar_test_base.rb
23
+ test/ar_simple_test.rb
24
+ test/ar_column_test.rb
23
25
  test/money_test.rb
24
26
  test/test_base.rb
25
27
  test/xe_test.rb
data/Rakefile CHANGED
@@ -12,7 +12,7 @@ require 'hoe'
12
12
  PKG_Name = 'Currency'
13
13
  PKG_NAME = PKG_Name.gsub(/[a-z][A-Z]/) {|x| "#{x[0,1]}_#{x[1,1]}"}.downcase
14
14
 
15
- hoe = Hoe.new("currency", '0.2.1') do |p|
15
+ hoe = Hoe.new("currency", '0.3.0') do |p|
16
16
  p.author = 'Kurt Stephens'
17
17
  p.description = %{Currency models currencies, monetary values, foreign exchanges.}
18
18
  p.email = "ruby-#{PKG_NAME}@umleta.com"
data/Releases CHANGED
@@ -1,5 +1,10 @@
1
1
  = Currency Release History
2
2
 
3
+ == Release 0.3.0: 2006/10/31
4
+
5
+ * ActiveRecord money :*_field options are now named :*_column.
6
+ * More ActiveRecord tests
7
+
3
8
  == Release 0.2.1: 2006/10/31
4
9
 
5
10
  * Fixed Manifest.txt
@@ -12,7 +12,7 @@ module Currency
12
12
 
13
13
  # == ActiveRecord Suppport
14
14
  #
15
- # This package also contains ActiveRecord support for money values:
15
+ # Support for Money attributes in ActiveRecord::Base subclasses:
16
16
  #
17
17
  # require 'currency'
18
18
  # require 'currency/active_record'
@@ -33,90 +33,109 @@ module Currency
33
33
  # :currency => :USD
34
34
  #
35
35
  # Defines the Currency to use for storing a normalized Money
36
- # value. This allows SQL summary operations,
36
+ # value.
37
+ #
38
+ # All Money values will be converted to this Currency before
39
+ # storing in the column. This allows SQL summary operations,
37
40
  # like SUM(), MAX(), AVG(), etc., to produce meaningful results,
38
41
  # regardless of the initial currency specified. If this
39
42
  # option is used, subsequent reads will be in the specified
40
43
  # normalization :currency. Defaults to :USD.
41
44
  #
42
- # :currency_field => undef
45
+ # :currency_column => undef
43
46
  #
44
- # Defines the name of the CHAR(3) column that is used to store and
47
+ # Defines the name of the CHAR(3) column used to store and
45
48
  # retrieve the Money's Currency code. If this option is used, each
46
49
  # record may use a different Currency to store the result, such
47
50
  # that SQL summary operations, like SUM(), MAX(), AVG(),
48
51
  # may return meaningless results.
49
52
  #
50
- # :currency_preferred_field => undef
53
+ # :currency_preferred_column => undef
51
54
  #
52
55
  # Defines the name of a CHAR(3) column used to store and
53
56
  # retrieve the Money's Currency code. This option can be used
54
- # with normalize Money values to retrieve the Money value
57
+ # with normalized Money values to retrieve the Money value
55
58
  # in its original Currency, while
56
- # allowing SQL summary operations on a normalized Money value
59
+ # allowing SQL summary operations on the normalized Money values
57
60
  # to still be valid.
58
61
  #
59
62
  def money(attr_name, *opts)
60
- opts = Hash.[](*opts)
63
+ opts = Hash[*opts]
61
64
 
62
65
  attr_name = attr_name.to_s
63
66
 
64
67
  currency = opts[:currency]
65
68
 
66
- currency_field = opts[:currency_field]
67
- if currency_field
68
- currency = "read_attribute(:#{currency_field})"
69
+ currency_column = opts[:currency_column]
70
+ if currency_column && ! currency_column.kind_of?(String)
71
+ currency_column = currency_column.to_s
72
+ currency_column = "#{attr_name}_currency"
73
+ end
74
+ if currency_column
75
+ read_currency = "read_attribute(:#{currency_column.to_s})"
76
+ write_currency = "write_attribute(:#{currency_column}, #{attr_name}_money.nil? ? nil : #{attr_name}_money.currency.code.to_s)"
69
77
  end
70
78
 
71
- currency_preferred_field = opts[:currency_preferred_field]
72
- if currency_preferred_field
73
- read_preferred_currency = "@#{attr_name} = @#{attr_name}.convert(read_attribute(:#{:currency_preferred_field}))"
74
- write_preferred_currency = "write_attribute(:#{currency_preferred_field}, @#{attr_name}_money.currency.code)"
79
+ currency_preferred_column = opts[:currency_preferred_column]
80
+ if currency_preferred_column
81
+ currency_preferred_column = currency_preferred_column.to_s
82
+ read_preferred_currency = "@#{attr_name} = @#{attr_name}.convert(read_attribute(:#{currency_preferred_column}))"
83
+ write_preferred_currency = "write_attribute(:#{currency_preferred_column}, @#{attr_name}_money.currency.code)"
75
84
  end
76
85
 
77
86
  currency ||= ':USD'
78
87
 
79
- validate = ''
80
- validate = "validates_numericality_of :#{attr_name}" unless opts[:allow_nil]
88
+ read_currency ||= currency
89
+
90
+ validate = "# Validation\n"
91
+ validate << "\nvalidates_numericality_of :#{attr_name}\n" unless opts[:allow_nil]
92
+ validate << "\nvalidates_format_of :#{currency_column}, :with => /^[A-Z][A-Z][A-Z]$/\n" if currency_column && ! opts[:allow_nil]
81
93
 
82
94
  module_eval (x = <<-"end_eval"), __FILE__, __LINE__
83
95
  #{validate}
96
+
84
97
  def #{attr_name}
85
98
  # $stderr.puts " \#{self.class.name}##{attr_name}"
86
99
  unless @#{attr_name}
87
100
  #{attr_name}_rep = read_attribute(:#{attr_name})
88
101
  unless #{attr_name}_rep.nil?
89
- @#{attr_name} = Money.new_rep(#{attr_name}_rep, #{currency})
102
+ @#{attr_name} = Currency::Money.new_rep(#{attr_name}_rep, #{read_currency} || #{currency})
90
103
  #{read_preferred_currency}
91
104
  end
92
105
  end
93
106
  @#{attr_name}
94
107
  end
108
+
95
109
  def #{attr_name}=(value)
96
110
  if value.nil?
97
111
  ;
98
112
  elsif value.kind_of?(Integer) || value.kind_of?(String) || value.kind_of?(Float)
99
- #{attr_name}_money = Money.new(value, #{currency})
113
+ #{attr_name}_money = Currency::Money.new(value, #{currency})
100
114
  #{write_preferred_currency}
101
115
  elsif value.kind_of?(Money)
116
+ #{attr_name}_money = value
102
117
  #{write_preferred_currency}
103
- #{attr_name}_money = value.convert(#{currency})
118
+ #{write_currency ? write_currency : "#{attr_name}_money = #{attr_name}_money.convert(#{currency})"}
104
119
  else
105
- throw "Bad money format \#{value.inspect}"
120
+ throw Currency::Exception::InvalidMoneyValue.new(value)
106
121
  end
122
+
107
123
  @#{attr_name} = #{attr_name}_money
108
- #{currency_field ? 'write_attribute(:#{currency_field}, #{attr_name}_money.nil? ? nil : #{attr_name}_money.currency.name)' : ''}
124
+
109
125
  write_attribute(:#{attr_name}, #{attr_name}_money.nil? ? nil : #{attr_name}_money.rep)
126
+
110
127
  value
111
128
  end
129
+
112
130
  def #{attr_name}_before_type_cast
113
- # FIX ME, User cannot specify Currency
131
+ # FIXME: User cannot specify Currency
114
132
  x = #{attr_name}
115
133
  x &&= x.format(:no_symbol, :no_currency, :no_thousands)
116
134
  x
117
135
  end
136
+
118
137
  end_eval
119
- # $stderr.puts " CODE = #{x}"
138
+ $stderr.puts " CODE = #{x}"
120
139
  end
121
140
  end
122
141
  end
@@ -2,5 +2,5 @@
2
2
  # This file is auto-generated by build scripts.
3
3
  # See: rake update_version
4
4
  module Currency
5
- CurrencyVersion = '0.2.1'
5
+ CurrencyVersion = '0.3.0'
6
6
  end
@@ -12,6 +12,10 @@ module Currency
12
12
  # Error during string parsing.
13
13
  class InvalidMoneyString < Base
14
14
  end
15
+
16
+ # Error during coercion of external Money values.
17
+ class InvalidMoneyValue < Base
18
+ end
15
19
 
16
20
  # Error in Currency code formeat.
17
21
  class InvalidCurrencyCode < Base
@@ -0,0 +1,66 @@
1
+ require 'test/ar_test_base'
2
+ require 'currency'
3
+
4
+ require 'rubygems'
5
+ require 'active_record'
6
+ require 'active_record/migration'
7
+ require 'currency/active_record'
8
+
9
+ module Currency
10
+
11
+ class ArFieldTest < ArTestBase
12
+
13
+ ##################################################
14
+ # Basic CurrenyTest AR::B class
15
+ #
16
+
17
+ TABLE_NAME = 'currency_column_test'
18
+
19
+ class CurrencyColumnTestMigration < AR_M
20
+ def self.up
21
+ create_table TABLE_NAME.intern do |t|
22
+ t.column :name, :string
23
+ t.column :amount, :integer # Money
24
+ t.column :amount_currency, :string, :size => 3 # Money.currency.code
25
+ end
26
+ end
27
+
28
+ def self.down
29
+ drop_table TABLE_NAME.intern
30
+ end
31
+ end
32
+
33
+ class CurrencyColumnTest < AR_B
34
+ set_table_name TABLE_NAME
35
+ money :amount, :currency_column => true
36
+ end
37
+
38
+ ##################################################
39
+
40
+ def setup
41
+ @currency_test_migration ||= CurrencyColumnTestMigration
42
+ @currency_test ||= CurrencyColumnTest
43
+ super
44
+ end
45
+
46
+ def teardown
47
+ super
48
+ end
49
+
50
+ ##################################################
51
+
52
+
53
+ def test_field
54
+ insert_records
55
+
56
+ assert_not_nil usd = @currency_test.find(@usd.id)
57
+ assert_equal_currency usd, @usd
58
+
59
+ assert_not_nil cad = @currency_test.find(@cad.id)
60
+ assert_equal_currency cad, @cad
61
+ end
62
+
63
+ end
64
+
65
+ end # module
66
+
@@ -0,0 +1,28 @@
1
+ require 'test/ar_test_base'
2
+ require 'currency'
3
+
4
+ require 'rubygems'
5
+ require 'active_record'
6
+ require 'active_record/migration'
7
+ require 'currency/active_record'
8
+
9
+ module Currency
10
+
11
+ class ArSimpleTest < ArTestBase
12
+
13
+ def test_simple
14
+ insert_records
15
+
16
+ assert_not_nil usd = @currency_test.find(@usd.id)
17
+ assert_equal_currency usd, @usd
18
+
19
+ assert_not_nil cad = @currency_test.find(@cad.id)
20
+ assert_equal_money cad, @cad
21
+
22
+ assert_equal cad.amount.currency.code, :USD
23
+ end
24
+
25
+ end
26
+
27
+ end # module
28
+
data/test/ar_test_base.rb CHANGED
@@ -21,12 +21,6 @@ class ArTestBase < TestBase
21
21
 
22
22
  class CurrencyTestMigration < AR_M
23
23
  def self.up
24
- begin
25
- down
26
- rescue Object => e
27
- announce("Warning: #{e}")
28
- end
29
-
30
24
  create_table TABLE_NAME.intern do |t|
31
25
  t.column :name, :string
32
26
  t.column :amount, :integer # Money
@@ -53,12 +47,14 @@ class ArTestBase < TestBase
53
47
  @currency_test_migration ||= CurrencyTestMigration
54
48
  @currency_test ||= CurrencyTest
55
49
 
50
+ # schema_down
51
+
56
52
  schema_up
57
53
  end
58
54
 
59
55
  def teardown
60
56
  super
61
- schema_down
57
+ # schema_down
62
58
  end
63
59
 
64
60
  def database_spec
@@ -73,12 +69,19 @@ class ArTestBase < TestBase
73
69
  end
74
70
 
75
71
  def schema_up
76
- @currency_test_migration.migrate(:up)
77
-
72
+ begin
73
+ @currency_test_migration.migrate(:up)
74
+ rescue Object =>e
75
+ $stderr.puts "Warning: #{e}"
76
+ end
78
77
  end
79
78
 
80
79
  def schema_down
81
- #@currency_test_migration.migrate(:down)
80
+ begin
81
+ @currency_test_migration.migrate(:down)
82
+ rescue Object => e
83
+ $stderr.puts "Warning: #{e}"
84
+ end
82
85
  end
83
86
 
84
87
  ##################################################
@@ -86,6 +89,8 @@ class ArTestBase < TestBase
86
89
  #
87
90
 
88
91
  def insert_records
92
+ delete_records
93
+
89
94
  @currency_test.reset_column_information
90
95
 
91
96
  @usd = @currency_test.new(:name => '#1: USD', :amount => Money.new("12.34", :USD))
@@ -96,12 +101,12 @@ class ArTestBase < TestBase
96
101
  end
97
102
 
98
103
  def delete_records
99
- # Simp
104
+ @currency_test.destroy_all
100
105
  end
101
106
 
102
107
  ##################################################
103
108
 
104
- def assert_currency_test(a,b)
109
+ def assert_equal_money(a,b)
105
110
  assert_not_nil a
106
111
  assert_not_nil b
107
112
  # Make sure a and b are not the same object.
@@ -116,22 +121,22 @@ class ArTestBase < TestBase
116
121
  assert_equal a.amount.convert(b.amount.currency).rep, b.amount.rep
117
122
  end
118
123
 
119
- def test_simple
120
- insert_records
121
-
122
- assert_not_nil usd = @currency_test.find(@usd.id)
123
- assert_currency_test usd, @usd
124
+ def assert_equal_currency(a,b)
124
125
 
125
- assert_equal usd.amount.rep, @usd.amount.rep
126
- assert_equal usd.amount.currency, @usd.amount.currency
127
- assert_equal usd.amount.currency.code, @usd.amount.currency.code
126
+ assert_equal_money a, b
128
127
 
129
- assert_not_nil cad = @currency_test.find(@cad.id)
130
- assert_currency_test cad, @cad
128
+ assert_equal a.amount.rep, b.amount.rep
129
+ assert_equal a.amount.currency, b.amount.currency
130
+ assert_equal a.amount.currency.code, b.amount.currency.code
131
131
 
132
- assert_equal cad.amount.currency.code, :USD
132
+ end
133
133
 
134
- delete_records
134
+ ##################################################
135
+ #
136
+ #
137
+
138
+ def test_dummy
139
+ insert_records
135
140
  end
136
141
 
137
142
  end
metadata CHANGED
@@ -3,7 +3,7 @@ rubygems_version: 0.9.0
3
3
  specification_version: 1
4
4
  name: currency
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.2.1
6
+ version: 0.3.0
7
7
  date: 2006-10-31 00:00:00 -05:00
8
8
  summary: Currency models currencies, monetary values, foreign exchanges.
9
9
  require_paths:
@@ -52,6 +52,8 @@ files:
52
52
  - README
53
53
  - Releases
54
54
  - test/ar_test_base.rb
55
+ - test/ar_simple_test.rb
56
+ - test/ar_column_test.rb
55
57
  - test/money_test.rb
56
58
  - test/test_base.rb
57
59
  - test/xe_test.rb