currency 0.2.1 → 0.3.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.
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