elfproef 0.0.3 → 0.1.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/Guardfile ADDED
@@ -0,0 +1,19 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec', :version => 2 do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+
9
+ # Rails example
10
+ watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
11
+ watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
12
+ watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
13
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
14
+ watch('config/routes.rb') { "spec/routing" }
15
+ watch('app/controllers/application_controller.rb') { "spec/controllers" }
16
+ # Capybara request specs
17
+ watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
18
+ end
19
+
data/README.md CHANGED
@@ -2,12 +2,10 @@
2
2
 
3
3
  [![Build Status](https://secure.travis-ci.org/sytzeloor/elfproef.png?branch=master)](http://travis-ci.org/sytzeloor/elfproef)
4
4
 
5
- This gem adds a validation method for Dutch bank account numbers and
6
- Citizen Service Numbers (BSN). These can be validated using the
7
- so-called Elfproef.
5
+ This gem adds two validators to your arsenal:
8
6
 
9
- Based on:
10
- [Elfproef](https://github.com/tilsammans/elfproef/) by tilsammans
7
+ * BsnValidator will validate Burgerservicenummers (Dutch social security numbers). It accepts both 8 and 9 digit BSN numbers.
8
+ * BankAccountValidator will validate ING accounts (1-7 digits), and 9 or 10 digit bank account numbers using the elven-test.
11
9
 
12
10
  ## Installation
13
11
 
@@ -25,16 +23,25 @@ and run
25
23
 
26
24
  ## Usage
27
25
 
28
- Simply add "validates_elfproef_of" to your model class.
26
+ Using the BsnValidator
29
27
 
30
- class User < ActiveRecord::Base
31
- # Validate with 11-test, do not allow 7 digit ING account numbers
32
- validates :bsn, elfproef: true
28
+ class User < ActiveRecord::Base
29
+ validates :bsn_number, bsn: true
30
+ end
33
31
 
34
- # Validate bank account numbers with 11-test, allow 7 digit ING account numbers
35
- validates :bank_account, elfproef: { allow_ing: true }
32
+ Using the BankAccountValidator
33
+
34
+ class User < ActiveRecord::Base
35
+ validates :account_number, bank_account: true
36
36
  end
37
37
 
38
+ You can also use these validators without `ActiveRecord` by including `ActiveModel::Validations`.
39
+
40
+ class AwesomeDutchPerson
41
+ include ActiveModel::Validations
42
+ validates :bsn, bsn: true
43
+ end
44
+
38
45
  ## Bugs / Feature Requests
39
46
 
40
47
  Please post them to
data/elfproef.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  $:.push File.expand_path("../lib", __FILE__)
3
- require "version"
3
+ require "elfproef/version"
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "elfproef"
data/lib/elfproef.rb CHANGED
@@ -1,30 +1,3 @@
1
- require "active_model"
2
- require "active_model/validations"
3
-
4
- # define my validator
5
- class ElfproefValidator < ActiveModel::EachValidator
6
- # implement the method where the validation logic must reside
7
- def validate_each(record, attribute, value)
8
- record.errors.add(attribute, options[:message] || "is not valid") unless Elfproef.elfproef(value, options)
9
- end
10
- end
11
-
12
-
13
- # Elfproef.
14
- module Elfproef
15
- # Calculates the elfproef of a Dutch bank account number or Citizen Service Number (BSN).
16
- # Return value should be 0 (proof succeeded). Any other value means faillure.
17
- # Postbank bank accounts (7 digits) cannot be validated using the elfproef and
18
- # will always return 0 (success).
19
- # http://nl.wikipedia.org/wiki/Elfproef
20
- def self.elfproef(number, options = {})
21
- number, sum = number.to_s, 0
22
- number.gsub!(/\D/, '') # strip out any non-digit character.
23
- return true if options[:allow_ing] && (1..7).include?(number.length) # always pass ING accounts (between 1 and 7 digits)
24
- return false unless (9..10).include?(number.length) # account should be exactly 9 or 10 digits
25
- (1..number.length).each do |c|
26
- sum += number[-c].chr.to_i * c
27
- end
28
- sum % 11 == 0
29
- end
30
- end
1
+ require 'elfproef/version'
2
+ require 'elfproef/bsn_validator'
3
+ require 'elfproef/bank_account_validator'
@@ -0,0 +1,56 @@
1
+ require "active_model"
2
+ require "active_model/validations"
3
+
4
+ # Validates if the specified value is a valid
5
+ # bank account number using the 11-test
6
+ class BankAccountValidator < ActiveModel::EachValidator
7
+ def validate_each(record, attribute, value)
8
+ record.errors.add(attribute, options[:message] || "is not valid") unless validate_account_number(value, options)
9
+ end
10
+
11
+ private
12
+
13
+ # Takes the bank account number and returns true if:
14
+ #
15
+ # * The number is 1...7 digit ING account number (no verification is possible)
16
+ # * Is 9 or 10 digits and passes the 11-test
17
+ #
18
+ def validate_account_number(value, options = {})
19
+ number = value.to_s.gsub(/\D/, '').strip
20
+
21
+ # Not valid if length is 0, 8 or > 10
22
+ return false if number.length == 0 || number.length == 8 || number.length > 10
23
+
24
+ # ING account numbers
25
+ return true if (1..7).include?(number.length)
26
+
27
+ # Validate length 9 and 10 numbers as bank accounts
28
+ validate_with_eleven_test(number)
29
+ end
30
+
31
+ # Performs the actual 11-test on a
32
+ # 9 or 10 digit account number
33
+ #
34
+ # For 10 digits (prefix with a 0 for 9 digits):
35
+ #
36
+ # 0123456789
37
+ # ABCDEFGHIJ
38
+ #
39
+ # sum = 1*A + 2*B + 3*C + 4*D + 5*E + 6*F + 7*G + 8*H + 9*I + 10*J
40
+ #
41
+ # If sum % 11 is 0, the number is valid, otherwise
42
+ # a typo has been made or the number is outright invalid.
43
+ def validate_with_eleven_test(number)
44
+ # Make sure we have a 10 digit account number,
45
+ # Prefix with a 0 if necessary
46
+ number = "0#{number}" if number.length == 9
47
+
48
+ # Calculate the sum
49
+ sum = 0
50
+ number.split("").each_with_index do |char, i|
51
+ sum += char.to_i * (i+1)
52
+ end
53
+
54
+ sum % 11 == 0
55
+ end
56
+ end
@@ -0,0 +1,41 @@
1
+ require "active_model"
2
+ require "active_model/validations"
3
+
4
+ # Validates if the specified value is a valid
5
+ # Burgerservicenummer (Dutch social security number)
6
+ class BsnValidator < ActiveModel::EachValidator
7
+ def validate_each(record, attribute, value)
8
+ record.errors.add(attribute, options[:message] || "is not valid") unless validate_bsn(value, options)
9
+ end
10
+
11
+ private
12
+
13
+ # A BSN is an 8 or 9 digit Dutch social security
14
+ # number.
15
+ def validate_bsn(value, options = {})
16
+ bsn = value.to_s.gsub(/\D/, '').strip
17
+
18
+ # Only allow 8 or 9 digits
19
+ return false if bsn.length < 8 || bsn.length > 9
20
+
21
+ # Validate with the advanced eleven test
22
+ validate_with_advanced_eleven_test(bsn)
23
+ end
24
+
25
+ def validate_with_advanced_eleven_test(number)
26
+ # Make sure we have 9 digits
27
+ number = "0#{number}" if number.size == 8
28
+
29
+ numbers = number.split("").map(&:to_i)
30
+ control, numbers = numbers.pop, numbers.reverse
31
+
32
+
33
+ sum = 0
34
+ numbers.each_with_index do |digit, i|
35
+ sum += digit * (i+2)
36
+ end
37
+
38
+ sum.remainder(11) == control
39
+ end
40
+ end
41
+
@@ -1,3 +1,3 @@
1
1
  module Elfproef
2
- VERSION= "0.0.3"
2
+ VERSION= "0.1.0"
3
3
  end
@@ -0,0 +1,76 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe BankAccountValidator do
4
+ subject {
5
+ Class.new do
6
+ include ActiveModel::Validations
7
+ attr_accessor :account
8
+ validates :account, :bank_account => true
9
+ end.new
10
+ }
11
+
12
+ let(:errors) { ["is not valid"] }
13
+
14
+ it "accepts 1 digit ING accounts" do
15
+ subject.account = "1"
16
+ subject.should be_valid
17
+ end
18
+
19
+ it "accepts 2 digit ING accounts" do
20
+ subject.account = "12"
21
+ subject.should be_valid
22
+ end
23
+
24
+ it "accepts 3 digit ING accounts" do
25
+ subject.account = "3"
26
+ subject.should be_valid
27
+ end
28
+
29
+ it "accepts 4 digit ING accounts" do
30
+ subject.account = "4"
31
+ subject.should be_valid
32
+ end
33
+
34
+ it "accepts 5 digit ING accounts" do
35
+ subject.account = "5"
36
+ subject.should be_valid
37
+ end
38
+
39
+ it "accepts 6 digit ING accounts" do
40
+ subject.account = "6"
41
+ subject.should be_valid
42
+ end
43
+
44
+ it "accepts 7 digit ING accounts" do
45
+ subject.account = "7"
46
+ subject.should be_valid
47
+ end
48
+
49
+ it "accepts a valid 9 digit bank account number" do
50
+ subject.account = "123456789"
51
+ subject.should be_valid
52
+ end
53
+
54
+ it "accepts a valid 10 digit bank account number" do
55
+ subject.account = "0123456789"
56
+ subject.should be_valid
57
+ end
58
+
59
+ it "fails on an 8 digit number" do
60
+ subject.account = "12345678"
61
+ subject.should_not be_valid
62
+ subject.errors[:account].should == errors
63
+ end
64
+
65
+ it "fails on obviously wrong numbers" do
66
+ subject.account = "CHUCKNORRIS"
67
+ subject.should_not be_valid
68
+ subject.errors[:account].should == errors
69
+ end
70
+
71
+ it "fails on 1 digit errors" do
72
+ subject.account = "133456789"
73
+ subject.should_not be_valid
74
+ subject.errors[:account].should == errors
75
+ end
76
+ end
@@ -0,0 +1,47 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe BsnValidator do
4
+ subject {
5
+ Class.new do
6
+ include ActiveModel::Validations
7
+ attr_accessor :number
8
+ validates :number, :bsn => true
9
+ end.new
10
+ }
11
+
12
+ let(:errors) { ["is not valid"] }
13
+
14
+ it "accepts an 8 digit bsn" do
15
+ subject.number = "12345672"
16
+ subject.should be_valid
17
+ end
18
+
19
+ it "accepts a 9 digit bsn" do
20
+ subject.number = "123456782"
21
+ subject.should be_valid
22
+ end
23
+
24
+ it "rejects too short bsn numbers" do
25
+ subject.number = "123"
26
+ subject.should_not be_valid
27
+ subject.errors[:number].should == errors
28
+ end
29
+
30
+ it "rejects too long bsn numbers" do
31
+ subject.number = "123456789012345"
32
+ subject.should_not be_valid
33
+ subject.errors[:number].should == errors
34
+ end
35
+
36
+ it "rejects obvious incorrect bsn numbers" do
37
+ subject.number = "NOTAXES"
38
+ subject.should_not be_valid
39
+ subject.errors[:number].should == errors
40
+ end
41
+
42
+ it "rejects mistyped bsn numbers" do
43
+ subject.number = "123456789012345"
44
+ subject.should_not be_valid
45
+ subject.errors[:number].should == errors
46
+ end
47
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elfproef
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-03-13 00:00:00.000000000 Z
13
+ date: 2012-03-14 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake
17
- requirement: &70105363295440 !ruby/object:Gem::Requirement
17
+ requirement: &70122195961320 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: '0'
23
23
  type: :development
24
24
  prerelease: false
25
- version_requirements: *70105363295440
25
+ version_requirements: *70122195961320
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: rspec
28
- requirement: &70105363294960 !ruby/object:Gem::Requirement
28
+ requirement: &70122195960660 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
- version_requirements: *70105363294960
36
+ version_requirements: *70122195960660
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: guard-rspec
39
- requirement: &70105363294520 !ruby/object:Gem::Requirement
39
+ requirement: &70122195959980 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ! '>='
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: '0'
45
45
  type: :development
46
46
  prerelease: false
47
- version_requirements: *70105363294520
47
+ version_requirements: *70122195959980
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: activemodel
50
- requirement: &70105363293980 !ruby/object:Gem::Requirement
50
+ requirement: &70122195959000 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ! '>='
@@ -55,7 +55,7 @@ dependencies:
55
55
  version: '0'
56
56
  type: :runtime
57
57
  prerelease: false
58
- version_requirements: *70105363293980
58
+ version_requirements: *70122195959000
59
59
  description: Validation for Dutch bank account numbers and Citizen Service Numbers
60
60
  (BSN)
61
61
  email:
@@ -68,12 +68,16 @@ files:
68
68
  - .gitignore
69
69
  - .travis.yml
70
70
  - Gemfile
71
+ - Guardfile
71
72
  - README.md
72
73
  - Rakefile
73
74
  - elfproef.gemspec
74
75
  - lib/elfproef.rb
75
- - lib/version.rb
76
- - spec/elfproef_spec.rb
76
+ - lib/elfproef/bank_account_validator.rb
77
+ - lib/elfproef/bsn_validator.rb
78
+ - lib/elfproef/version.rb
79
+ - spec/bank_account_validator_spec.rb
80
+ - spec/bsn_validator_spec.rb
77
81
  - spec/spec_helper.rb
78
82
  homepage: https://github.com/sytzeloor/elfproef
79
83
  licenses: []
@@ -87,18 +91,25 @@ required_ruby_version: !ruby/object:Gem::Requirement
87
91
  - - ! '>='
88
92
  - !ruby/object:Gem::Version
89
93
  version: '0'
94
+ segments:
95
+ - 0
96
+ hash: -1515901023488646711
90
97
  required_rubygems_version: !ruby/object:Gem::Requirement
91
98
  none: false
92
99
  requirements:
93
100
  - - ! '>='
94
101
  - !ruby/object:Gem::Version
95
102
  version: '0'
103
+ segments:
104
+ - 0
105
+ hash: -1515901023488646711
96
106
  requirements: []
97
107
  rubyforge_project: elfproef
98
- rubygems_version: 1.8.17
108
+ rubygems_version: 1.8.11
99
109
  signing_key:
100
110
  specification_version: 3
101
111
  summary: Validation for Dutch bank account numbers and Citizen Service Numbers (BSN)
102
112
  test_files:
103
- - spec/elfproef_spec.rb
113
+ - spec/bank_account_validator_spec.rb
114
+ - spec/bsn_validator_spec.rb
104
115
  - spec/spec_helper.rb
@@ -1,160 +0,0 @@
1
- require File.dirname(__FILE__) + '/spec_helper'
2
-
3
- describe Elfproef do
4
- account_class = Class.new do
5
- include ActiveModel::Validations
6
- attr_accessor :account
7
- validates :account, :elfproef => { :allow_ing => true }
8
- end
9
-
10
- bank_only_class = Class.new do
11
- include ActiveModel::Validations
12
- attr_accessor :account
13
- validates :account, :elfproef => true
14
- end
15
-
16
- # Nine digets are not allowed
17
- it "tests account format" do
18
- Elfproef.elfproef(123456).should == false
19
- Elfproef.elfproef(1234567890).should == false
20
- Elfproef.elfproef('12345678a').should == false
21
- end
22
-
23
- # Invalid accounts will a value greather then 0
24
- it "tests invalid accounts" do
25
- Elfproef.elfproef(999999999).should == false
26
- Elfproef.elfproef('99.99.99.999').should == false
27
- Elfproef.elfproef('99 99 99 999').should == false
28
- end
29
-
30
- # Valid accounts will return 0
31
- it "tests valid accounts" do
32
- Elfproef.elfproef(123456789).should == true
33
- Elfproef.elfproef('12.34.56.789').should == true
34
- Elfproef.elfproef('12 34 56 789').should == true
35
- end
36
-
37
- it "tests valid ING accounts" do
38
- opts = { :allow_ing => true }
39
- Elfproef.elfproef(1234567, opts).should == true
40
- Elfproef.elfproef('1234567', opts).should == true
41
- end
42
-
43
- shared_examples_for "elfproef validations" do
44
- subject { account_class.new }
45
-
46
- it "fails when empty" do
47
- subject.should_not be_valid
48
- subject.errors[:account].should == errors
49
- end
50
-
51
- it "fails with an obviously wrong number" do
52
- subject.account = "12345678901"
53
- subject.should_not be_valid
54
- subject.errors[:account].should == errors
55
- end
56
-
57
- it "passes with a 7-diget ING number" do
58
- subject.account = "1234567"
59
- subject.should be_valid
60
- end
61
-
62
- it "passes with a 6-digit ING number" do
63
- subject.account = "123456"
64
- subject.should be_valid
65
- end
66
-
67
- it "passes with a 5-digit ING number" do
68
- subject.account = "12345"
69
- subject.should be_valid
70
- end
71
-
72
- it "passes with a 4-digit ING number" do
73
- subject.account = "1234"
74
- subject.should be_valid
75
- end
76
-
77
- it "passes with a 3-digit ING number" do
78
- subject.account = "123"
79
- subject.should be_valid
80
- end
81
-
82
- it "passes with a 2-digit ING number" do
83
- subject.account = "12"
84
- subject.should be_valid
85
- end
86
-
87
- it "passes with a 1-digit ING number" do
88
- subject.account = "1"
89
- subject.should be_valid
90
- end
91
-
92
- it "passes with a ING number starting with a P (from Postbank)" do
93
- subject.account = "P1234567"
94
- subject.should be_valid
95
- end
96
-
97
- it "passes with a valid 9-digit bank number" do
98
- subject.account = "123456789"
99
- subject.should be_valid
100
- end
101
-
102
- it "passes with a valid 10-digit bank number" do
103
- subject.account = "0123456789"
104
- subject.should be_valid
105
- end
106
-
107
- it "fails with an wrong bank number" do
108
- subject.account = "999999999"
109
- subject.should_not be_valid
110
- subject.errors[:account].should == errors
111
- end
112
- end
113
-
114
- shared_examples_for "elfproef, bank accounts only validations" do
115
- subject { bank_only_class.new }
116
-
117
- it "fails when empty" do
118
- subject.should_not be_valid
119
- subject.errors[:account].should == errors
120
- end
121
-
122
- it "fails with an obviously wrong number" do
123
- subject.account = "666"
124
- subject.should_not be_valid
125
- subject.errors[:account].should == errors
126
- end
127
-
128
- it "fails with a ING number" do
129
- subject.account = "1234567"
130
- subject.should_not be_valid
131
- subject.errors[:account].should == errors
132
- end
133
-
134
- it "passes with a valid 9-digit bank number" do
135
- subject.account = "123456789"
136
- subject.should be_valid
137
- end
138
-
139
- it "passes with a valid 10-digit bank number" do
140
- subject.account = "0123456789"
141
- subject.should be_valid
142
- end
143
-
144
- it "fails with an wrong bank number" do
145
- subject.account = "999999999"
146
- subject.should_not be_valid
147
- subject.errors[:account].should == errors
148
- end
149
- end
150
-
151
- describe "bank + ing validations" do
152
- let!(:errors) { [ "is not valid"] }
153
- it_should_behave_like "elfproef validations"
154
- end
155
-
156
- describe "bank only validations" do
157
- let!(:errors) { [ "is not valid"] }
158
- it_should_behave_like "elfproef, bank accounts only validations"
159
- end
160
- end