easy_rails_money 0.0.8 → 0.0.9.pre

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/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  [![Build Status](https://travis-ci.org/deepak/easy_rails_money.png?branch=master)](https://travis-ci.org/deepak/easy_rails_money)
2
2
  [![Dependency Status](https://gemnasium.com/deepak/easy_rails_money.png)](https://gemnasium.com/deepak/easy_rails_money)
3
3
  [![Code Climate](https://codeclimate.com/github/deepak/easy_rails_money.png)](https://codeclimate.com/github/deepak/easy_rails_money)
4
+ [![Gem Version](https://badge.fury.io/rb/easy_rails_money.png)](http://badge.fury.io/rb/easy_rails_money)
4
5
 
5
6
  # EasyRailsMoney
6
7
 
@@ -377,3 +378,8 @@ loan_usd.currency # equals Money::Currency.new(:usd)
377
378
  do we want a Money::Currency object back?
378
379
  not decided
379
380
  see currency_persistence_spec.rb
381
+ 14. make sure re-opening and redefining money dsl methods work
382
+ eg. moving from individual currencies to single currency
383
+ 15. document. methods defined inside activerecord's scope
384
+ move to a helper, no that its namespace is not polluted
385
+ 16. two specs tagged with fixme in validates_money_spec failing
@@ -2,6 +2,7 @@ require "easy_rails_money/active_record/money_dsl"
2
2
  require "easy_rails_money/active_record/migration/schema_statements"
3
3
  require "easy_rails_money/active_record/migration/table"
4
4
  require "easy_rails_money/active_record/migration/table_definition"
5
+ require "easy_rails_money/money_validator"
5
6
 
6
7
  ActiveRecord::Base.send :include, EasyRailsMoney::ActiveRecord::MoneyDsl
7
8
 
@@ -9,4 +10,24 @@ ActiveRecord::Migration.send :include, EasyRailsMoney::ActiveRecord::Migration::
9
10
 
10
11
  ActiveRecord::ConnectionAdapters::TableDefinition.send :include, EasyRailsMoney::ActiveRecord::Migration::TableDefinition
11
12
  ActiveRecord::ConnectionAdapters::Table.send :include, EasyRailsMoney::ActiveRecord::Migration::Table
13
+
14
+ class ActiveRecord::Base
15
+ def self.validates_money *args
16
+ options = args.extract_options!
17
+ validates_with EasyRailsMoney::MoneyValidator, options.merge(:attributes => args)
12
18
 
19
+ # validates lower-level columns
20
+ args.each do |column_name|
21
+ validates "#{column_name}_money", :numericality => { only_integer: true, greater_than_or_equal_to: 0 }, :allow_nil => options[:allow_nil]
22
+ end
23
+
24
+ allowed_currency = options[:allowed_currency] || Money::Currency.table.keys
25
+ if single_currency?
26
+ validates :currency, :inclusion => { in: allowed_currency }, :allow_nil => options[:allow_nil]
27
+ else
28
+ args.each do |column_name|
29
+ validates "#{column_name}_currency", :presence => true, :inclusion => { in: allowed_currency }, :allow_nil => options[:allow_nil]
30
+ end
31
+ end
32
+ end
33
+ end
@@ -5,6 +5,12 @@ module EasyRailsMoney
5
5
  module ActiveRecord
6
6
  module MoneyDsl
7
7
  extend ActiveSupport::Concern
8
+
9
+ included do
10
+ def money_attributes
11
+ attributes.keys.select {|x| x =~ /^(.+)_money/ }.map {|x| x.split('_')[0..-2].join }
12
+ end
13
+ end
8
14
 
9
15
  module ClassMethods
10
16
  attr_accessor :single_currency
@@ -69,6 +75,15 @@ module EasyRailsMoney
69
75
  # currency is stored in a seperate common column
70
76
  return Money.new(value, self.currency)
71
77
  end # define_method setter
78
+
79
+ define_method "currency=" do |value|
80
+ if value.nil?
81
+ money_attributes.map do |name|
82
+ send "#{name}=", nil
83
+ end
84
+ end
85
+ super value
86
+ end
72
87
  else
73
88
  # TODO: test if Memoization will make any difference
74
89
  define_method column_name do |*args|
@@ -0,0 +1,25 @@
1
+ require 'active_support/core_ext/array/extract_options'
2
+
3
+ module EasyRailsMoney
4
+ # TODO: there are a lot of validations here. customizing the messages
5
+ # for all of them seems cumbersome. if needed write your own. or even patch
6
+ # also while calling the individual validators in validates_money
7
+ # only allow_nil is passed around (as it was needed). test for other
8
+ # like if and unless as well
9
+ class MoneyValidator < ActiveModel::EachValidator
10
+ def validate_each(record, attribute, value)
11
+ if options[:allow_nil]
12
+ return if value.nil?
13
+ else
14
+ if value.nil?
15
+ record.errors[attribute] << "cannot be nil"
16
+ return
17
+ end
18
+ end
19
+
20
+ if value.fractional < 0
21
+ record.errors[attribute] << "cannot be negative"
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,3 +1,3 @@
1
1
  module EasyRailsMoney
2
- VERSION = "0.0.8"
2
+ VERSION = "0.0.9.pre"
3
3
  end
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+ require 'active_record_spec_helper'
3
+
4
+ describe "Validation" do
5
+ context "single currency" do
6
+ def loan_model
7
+ Object.send(:remove_const, "LoanWithCurrency") if defined? LoanWithCurrency
8
+ migrate CreateTableDefinition::CreateLoanWithCurrency
9
+ load 'loan_with_currency_model_spec_helper.rb'
10
+ LoanWithCurrency
11
+ end
12
+
13
+ # subject can be delayed bound ie. after some changes
14
+ def add_expectations subject, allow_nil
15
+ expect(subject.class.validators.length).to eq 5
16
+ expect(subject.class.validators.select {|x| x.is_a? EasyRailsMoney::MoneyValidator }.length).to eq 1
17
+ expect(subject.class.validators.map {|x| x.options[:allow_nil] }.uniq).to eq [allow_nil]
18
+
19
+ EasyRailsMoney::MoneyValidator.any_instance.should_receive(:validate_each).with(subject, :principal, subject.principal)
20
+ EasyRailsMoney::MoneyValidator.any_instance.should_receive(:validate_each).with(subject, :repaid, subject.repaid)
21
+ EasyRailsMoney::MoneyValidator.any_instance.should_receive(:validate_each).with(subject, :npa, subject.npa)
22
+ end
23
+
24
+ context "do not allow nil" do
25
+ let(:subject) do
26
+ model = loan_model
27
+ model.instance_eval {
28
+ validates_money :principal, :repaid, :npa, :allow_nil => false, :allowed_currency => %w[inr usd sgd]
29
+ }
30
+
31
+ loan = model.new
32
+ loan.name = "loan having some values"
33
+ loan.principal = 100 * 100
34
+ loan.repaid = 50 * 100
35
+ loan.npa = 10 * 100
36
+ loan
37
+ end
38
+
39
+ it "is valid when it is a Money object" do
40
+ add_expectations subject, false
41
+ expect(subject).to be_valid
42
+ end
43
+
44
+ it "is in-valid if values are nil and allow_nil is false" do
45
+ subject.principal = nil
46
+ add_expectations subject, false
47
+ expect(subject).not_to be_valid
48
+ expect(subject.errors.messages).to eq :principal_money=>["is not a number"]
49
+ end
50
+
51
+ it "is in-valid if currency is nil and allow_nil is false" do
52
+ old = subject.principal
53
+ expect { subject.currency = nil }.to change { subject.principal }.from(old).to(nil)
54
+ expect(subject.attributes["currency"]).to be_nil
55
+ add_expectations subject, false
56
+ expect(subject).not_to be_valid
57
+ puts subject.errors.messages
58
+ expect(subject.errors.messages).to eq(:principal_money=>["is not a number"], :repaid_money=>["is not a number"], :npa_money=>["is not a number"], :currency=>["is not included in the list"])
59
+ end
60
+ end # context "do not allow nil"
61
+
62
+ context "allow nil", :fixme do
63
+ let(:subject) do
64
+ model = loan_model
65
+ model.instance_eval {
66
+ validates_money :principal, :repaid, :npa, :allow_nil => true, :allowed_currency => %w[inr usd sgd]
67
+ }
68
+
69
+ loan = model.new
70
+ loan.name = "loan having nil values"
71
+ loan.principal = nil
72
+ loan.repaid = nil
73
+ loan.npa = nil
74
+ loan
75
+ end
76
+
77
+ it "is valid if currency is nil and allow_nil is true" do
78
+ subject.currency = nil
79
+ expect(subject.principal).to be_nil
80
+ expect(subject.attributes["currency"]).to be_nil
81
+
82
+ add_expectations subject, true
83
+ expect(subject).to be_valid
84
+ end
85
+
86
+ it "is in-valid if currency is not allowed" do
87
+ subject.currency = "foo"
88
+ add_expectations subject, true
89
+ expect(subject).not_to be_valid
90
+ end
91
+ end # context "allow nil"
92
+
93
+ pending "check lower-level validations"
94
+ end
95
+ end
@@ -0,0 +1,12 @@
1
+ class LoanWithCurrencyAndValidation < ActiveRecord::Base
2
+ self.table_name = "loans"
3
+ attr_accessible :name
4
+
5
+ with_currency(:inr) do
6
+ money :principal
7
+ money :repaid
8
+ money :npa
9
+ end
10
+
11
+ validates_money :principal, :repaid, :npa, :allow_nil => true, :allowed_currency => %w[inr usd sgd]
12
+ end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: easy_rails_money
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
5
- prerelease:
4
+ version: 0.0.9.pre
5
+ prerelease: 6
6
6
  platform: ruby
7
7
  authors:
8
8
  - Deepak Kannan
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-04-09 00:00:00.000000000 Z
12
+ date: 2013-04-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: money
@@ -195,13 +195,16 @@ files:
195
195
  - lib/easy_rails_money/active_record/money_dsl.rb
196
196
  - lib/easy_rails_money/configuration.rb
197
197
  - lib/easy_rails_money/money_dsl_helper.rb
198
+ - lib/easy_rails_money/money_validator.rb
198
199
  - lib/easy_rails_money/version.rb
199
200
  - spec/active_record/currency_persistence_spec.rb
200
201
  - spec/active_record/migration_spec.rb
201
202
  - spec/active_record/money_dsl_spec.rb
203
+ - spec/active_record/validates_money_spec.rb
202
204
  - spec/active_record_spec_helper.rb
203
205
  - spec/configuration_spec.rb
204
206
  - spec/loan_model_spec_helper.rb
207
+ - spec/loan_with_currency_and_validation_model_spec_helper.rb
205
208
  - spec/loan_with_currency_model_spec_helper.rb
206
209
  - spec/migration_factory_spec_helper.rb
207
210
  - spec/simplecov_helper.rb
@@ -244,16 +247,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
244
247
  version: '0'
245
248
  segments:
246
249
  - 0
247
- hash: -3822270686044656207
250
+ hash: 4030965021580027687
248
251
  required_rubygems_version: !ruby/object:Gem::Requirement
249
252
  none: false
250
253
  requirements:
251
- - - ! '>='
254
+ - - ! '>'
252
255
  - !ruby/object:Gem::Version
253
- version: '0'
254
- segments:
255
- - 0
256
- hash: -3822270686044656207
256
+ version: 1.3.1
257
257
  requirements: []
258
258
  rubyforge_project:
259
259
  rubygems_version: 1.8.24
@@ -264,9 +264,11 @@ test_files:
264
264
  - spec/active_record/currency_persistence_spec.rb
265
265
  - spec/active_record/migration_spec.rb
266
266
  - spec/active_record/money_dsl_spec.rb
267
+ - spec/active_record/validates_money_spec.rb
267
268
  - spec/active_record_spec_helper.rb
268
269
  - spec/configuration_spec.rb
269
270
  - spec/loan_model_spec_helper.rb
271
+ - spec/loan_with_currency_and_validation_model_spec_helper.rb
270
272
  - spec/loan_with_currency_model_spec_helper.rb
271
273
  - spec/migration_factory_spec_helper.rb
272
274
  - spec/simplecov_helper.rb