diff --git a/Changelog.md b/Changelog.md index 3e4eeea3..3620cba5 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,6 +1,8 @@ ## development - Add your change HERE + - Add FFaker::Bank.accounting_number [@professor] + - Add FFaker::Bank.routing_number [@professor] - Adds FFaker::Crypto.sha256 [@professor] - Update README [@professor] - Adds FFaker::Number.between [@professor] diff --git a/REFERENCE.md b/REFERENCE.md index 98951b88..136de92e 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -38,6 +38,7 @@ * [FFaker::Avatar](#ffakeravatar) * [FFaker::BaconIpsum](#ffakerbaconipsum) * [FFaker::Bank](#ffakerbank) + * [FFaker::BankUS](#ffakerbankus) * [FFaker::Book](#ffakerbook) * [FFaker::Boolean](#ffakerboolean) * [FFaker::CheesyLingo](#ffakercheesylingo) @@ -932,6 +933,13 @@ | `card_type` | mastercard, maestro, solo | | `iban` | DO50GCBH29467231689551372717, LU338569240126150859, BE89929107166643 | +## FFaker::BankUS + +| Method | Example | +| ------ | ------- | +| `account_number(min_digits:, max_digits:)` | "2140767894", "30434706933238021" | +| `rounting_number` | "270510171" | + ## FFaker::Book | Method | Example | diff --git a/lib/ffaker.rb b/lib/ffaker.rb index 6937c5a0..db92bf53 100644 --- a/lib/ffaker.rb +++ b/lib/ffaker.rb @@ -66,6 +66,7 @@ def self.bothify(masks) autoload :AWS, 'ffaker/aws' autoload :BaconIpsum, 'ffaker/bacon_ipsum' autoload :Bank, 'ffaker/bank' + autoload :BankUS, 'ffaker/bank_us' autoload :Book, 'ffaker/book' autoload :Boolean, 'ffaker/boolean' autoload :CheesyLingo, 'ffaker/cheesy_lingo' diff --git a/lib/ffaker/bank_us.rb b/lib/ffaker/bank_us.rb new file mode 100644 index 00000000..6a5e8ac5 --- /dev/null +++ b/lib/ffaker/bank_us.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +module FFaker + module BankUS + extend ModuleUtils + extend self + + def account_number(min_digits: 9 , max_digits: 17) + FFaker.numerify('#' * rand(min_digits..max_digits)) + end + + def routing_number + partial_routing_number = FFaker.numerify('########') + ninth_digit = generate_checksum_digit(partial_routing_number) + + "#{partial_routing_number}#{ninth_digit}" + end + + private + + def generate_checksum_digit(num_string) + num_array = num_string.chars.map(&:to_i) + ( + 7 * (num_array[0] + num_array[3] + num_array[6]) + + 3 * (num_array[1] + num_array[4] + num_array[7]) + + 9 * (num_array[2] + num_array[5]) + ) % 10 + end + end +end diff --git a/test/test_bank.rb b/test/test_bank.rb index 416e7b63..584ad44a 100644 --- a/test/test_bank.rb +++ b/test/test_bank.rb @@ -7,7 +7,7 @@ class TestBank < Test::Unit::TestCase assert_methods_are_deterministic( FFaker::Bank, - :iban, :card_number, :card_expiry_date, :card_type + :iban, :card_number, :card_expiry_date, :card_type, :account_number, :routing_number ) def setup diff --git a/test/test_bank_us.rb b/test/test_bank_us.rb new file mode 100644 index 00000000..2802ab90 --- /dev/null +++ b/test/test_bank_us.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require_relative 'helper' + +class TestBankUS < Test::Unit::TestCase + include DeterministicHelper + + assert_methods_are_deterministic( + FFaker::Bank, + :account_number, :routing_number + ) + + def setup + @tester = FFaker::BankUS + end + + def test_account_number + assert_instance_of String, @tester.account_number + assert_match(/\A\d{8}\z/, @tester.account_number(min_digits: 8, max_digits: 8)) + assert_match(/\A\d{12}\z/, @tester.account_number(min_digits: 12, max_digits: 12)) + end + + def test_routing_number + routing_number = @tester.routing_number + assert_match(/\A\d{9}\z/, routing_number) + + checksum = ( + 7 * (routing_number[0].to_i + routing_number[3].to_i + routing_number[6].to_i) + + 3 * (routing_number[1].to_i + routing_number[4].to_i + routing_number[7].to_i) + + 9 * (routing_number[2].to_i + routing_number[5].to_i + routing_number[8].to_i) + ) % 10 + + assert_equal(0, checksum) + end +end