credy 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -1
- data/.travis.yml +6 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +13 -23
- data/Rakefile +1 -1
- data/bin/credy +4 -4
- data/credy.gemspec +6 -7
- data/data/americanexpress.yml +1 -1
- data/data/bankcard.yml +1 -1
- data/data/china-unionpay.yml +1 -1
- data/data/diners-club-carte-blanche.yml +1 -1
- data/data/diners-club-enroute.yml +1 -1
- data/data/diners-club-international.yml +1 -1
- data/data/diners-club-us-ca.yml +1 -1
- data/data/instapayment.yml +1 -1
- data/data/jcb.yml +1 -1
- data/data/laser.yml +1 -1
- data/data/maestro.yml +1 -1
- data/data/mastercard.yml +1 -1
- data/data/solo.yml +1 -1
- data/data/switch.yml +1 -1
- data/data/visa-electron.yml +1 -1
- data/data/visa.yml +1 -1
- data/lib/credy.rb +37 -28
- data/lib/credy/check.rb +3 -3
- data/lib/credy/rules.rb +34 -46
- data/lib/credy/string.rb +1 -1
- data/lib/credy/version.rb +2 -2
- data/readme.md +8 -6
- data/spec/bin/credy_spec.rb +37 -52
- data/spec/lib/credy/check_spec.rb +5 -5
- data/spec/lib/credy/rules_spec.rb +36 -67
- data/spec/lib/credy/version_spec.rb +2 -2
- data/spec/lib/credy_spec.rb +22 -22
- data/spec/spec_helper.rb +5 -1
- metadata +24 -64
- data/travis.yml +0 -10
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 25e3a3d043de72f875cd7a6405aa0f721cb00f61
|
4
|
+
data.tar.gz: 00f78e5960314b372e9d953b4ec546f991559d0a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e2a2b74deef424b8025408786abae8b644df82c458cdd4a6ce5493ec2a4553f5c2135e1b29050dd82f2b9ee09f1d18845b8dd8c4388a3d68ac07a350cb87d97d
|
7
|
+
data.tar.gz: f4006c3b5a2fbaa74c51ea8b4bfee9d64208cd0b8eb0de86ec658d47be112e55065e4765b90de9520468f24ba0ea20281f578fe24833c477b8c80ce3c0b9945b
|
data/.gitignore
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
*.gem
|
1
|
+
*.gem
|
2
|
+
.bundle
|
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -2,37 +2,27 @@ PATH
|
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
4
|
credy (0.1.1)
|
5
|
-
thor
|
5
|
+
thor (~> 0.18.1)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
|
11
|
-
debugger (1.3.0)
|
12
|
-
columnize (>= 0.3.1)
|
13
|
-
debugger-linecache (~> 1.1.1)
|
14
|
-
debugger-ruby_core_source (~> 1.1.7)
|
15
|
-
debugger-linecache (1.1.2)
|
16
|
-
debugger-ruby_core_source (>= 1.1.1)
|
17
|
-
debugger-ruby_core_source (1.1.7)
|
18
|
-
diff-lcs (1.1.3)
|
10
|
+
diff-lcs (1.2.5)
|
19
11
|
rake (10.0.3)
|
20
|
-
rspec (2.
|
21
|
-
rspec-core (~> 2.
|
22
|
-
rspec-expectations (~> 2.
|
23
|
-
rspec-mocks (~> 2.
|
24
|
-
rspec-core (2.
|
25
|
-
rspec-expectations (2.
|
26
|
-
diff-lcs (
|
27
|
-
rspec-mocks (2.
|
28
|
-
thor (0.
|
12
|
+
rspec (2.14.1)
|
13
|
+
rspec-core (~> 2.14.0)
|
14
|
+
rspec-expectations (~> 2.14.0)
|
15
|
+
rspec-mocks (~> 2.14.0)
|
16
|
+
rspec-core (2.14.7)
|
17
|
+
rspec-expectations (2.14.5)
|
18
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
19
|
+
rspec-mocks (2.14.5)
|
20
|
+
thor (0.18.1)
|
29
21
|
|
30
22
|
PLATFORMS
|
31
23
|
ruby
|
32
24
|
|
33
25
|
DEPENDENCIES
|
34
26
|
credy!
|
35
|
-
|
36
|
-
|
37
|
-
rspec
|
38
|
-
rspec-mocks
|
27
|
+
rake (~> 10.0.3)
|
28
|
+
rspec (~> 2.14.1)
|
data/Rakefile
CHANGED
data/bin/credy
CHANGED
@@ -19,14 +19,14 @@ module Credy
|
|
19
19
|
args[:country] = options[:country] unless options[:country] == 'all'
|
20
20
|
args[:type] = options[:type] unless options[:type] == 'all'
|
21
21
|
|
22
|
-
options[:number].times do
|
22
|
+
options[:number].times do
|
23
23
|
number = CreditCard.generate args
|
24
24
|
|
25
25
|
unless number
|
26
26
|
puts 'No rule found for those criteria.'
|
27
27
|
break
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
if details
|
31
31
|
d = [number[:type], number[:country]].compact
|
32
32
|
puts "#{number[:number]} (#{d.join(', ')})"
|
@@ -71,9 +71,9 @@ module Credy
|
|
71
71
|
end
|
72
72
|
puts "(#{details.join(', ')})"
|
73
73
|
end
|
74
|
-
|
74
|
+
|
75
75
|
end
|
76
76
|
|
77
77
|
end
|
78
78
|
|
79
|
-
Credy::CLI.start
|
79
|
+
Credy::CLI.start
|
data/credy.gemspec
CHANGED
@@ -6,7 +6,8 @@ Gem::Specification.new do |s|
|
|
6
6
|
s.authors = ['Tim Petricola']
|
7
7
|
s.email = ['hi@timpetricola.com']
|
8
8
|
s.summary = %q{A simple (but powerful) credit card number generator}
|
9
|
-
s.
|
9
|
+
s.license = 'MIT'
|
10
|
+
s.homepage = 'https://github.com/TimPetricola/Credy'
|
10
11
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
11
12
|
s.files = `git ls-files`.split "\n"
|
12
13
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split "\n"
|
@@ -14,9 +15,7 @@ Gem::Specification.new do |s|
|
|
14
15
|
s.require_paths = ['lib']
|
15
16
|
s.version = Credy::VERSION
|
16
17
|
|
17
|
-
s.add_development_dependency 'rspec'
|
18
|
-
s.add_development_dependency '
|
19
|
-
s.
|
20
|
-
|
21
|
-
s.add_runtime_dependency 'thor'
|
22
|
-
end
|
18
|
+
s.add_development_dependency 'rspec', '~> 2.14.1'
|
19
|
+
s.add_development_dependency 'rake', '~> 10.0.3'
|
20
|
+
s.add_runtime_dependency 'thor', '~> 0.18.1'
|
21
|
+
end
|
data/data/americanexpress.yml
CHANGED
data/data/bankcard.yml
CHANGED
data/data/china-unionpay.yml
CHANGED
data/data/diners-club-us-ca.yml
CHANGED
data/data/instapayment.yml
CHANGED
data/data/jcb.yml
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
jcb:
|
2
2
|
length: 16
|
3
|
-
prefix: ['3528', '3529', '3530', '3531', '3532', '3533', '3534', '3535', '3536', '3537', '3538', '3539', '3540', '3541', '3542', '3543', '3544', '3545', '3546', '3547', '3548', '3549', '3550', '3551', '3552', '3553', '3554', '3555', '3556', '3557', '3558', '3559', '3560', '3561', '3562', '3563', '3564', '3565', '3566', '3567', '3568', '3569', '3570', '3571', '3572', '3573', '3574', '3575', '3576', '3577', '3578', '3579', '3580', '3581', '3582', '3583', '3584', '3585', '3586', '3587', '3588', '3589']
|
3
|
+
prefix: ['3528', '3529', '3530', '3531', '3532', '3533', '3534', '3535', '3536', '3537', '3538', '3539', '3540', '3541', '3542', '3543', '3544', '3545', '3546', '3547', '3548', '3549', '3550', '3551', '3552', '3553', '3554', '3555', '3556', '3557', '3558', '3559', '3560', '3561', '3562', '3563', '3564', '3565', '3566', '3567', '3568', '3569', '3570', '3571', '3572', '3573', '3574', '3575', '3576', '3577', '3578', '3579', '3580', '3581', '3582', '3583', '3584', '3585', '3586', '3587', '3588', '3589']
|
data/data/laser.yml
CHANGED
data/data/maestro.yml
CHANGED
data/data/mastercard.yml
CHANGED
data/data/solo.yml
CHANGED
data/data/switch.yml
CHANGED
data/data/visa-electron.yml
CHANGED
data/data/visa.yml
CHANGED
data/lib/credy.rb
CHANGED
@@ -13,40 +13,19 @@ module Credy
|
|
13
13
|
|
14
14
|
# Generate a credit card number
|
15
15
|
def self.generate(options = {})
|
16
|
-
|
17
|
-
|
18
|
-
include_global_rules = options[:country].nil?
|
19
|
-
rule = Rules.filter(options, include_global_rules).sample
|
20
|
-
|
21
|
-
return nil unless rule
|
22
|
-
|
23
|
-
length = rule[:length].is_a?(Array) ? rule[:length].sample : rule[:length]
|
24
|
-
number = rule[:prefix]
|
25
|
-
|
26
|
-
# Generates n-1 digits
|
27
|
-
(length - number.length - 1).times do
|
28
|
-
number = number + rand(10).to_s
|
29
|
-
end
|
30
|
-
|
31
|
-
# Generates the last digit according to luhn algorithm
|
32
|
-
l = nil
|
33
|
-
digits = (0..9).to_a.map(&:to_s)
|
34
|
-
begin
|
35
|
-
l = digits.delete digits.sample
|
36
|
-
end while !Check.luhn number+l
|
37
|
-
|
38
|
-
number = number+l
|
16
|
+
rule = find_rule(options) || return
|
17
|
+
number = generate_from_rule(rule)
|
39
18
|
|
40
19
|
{
|
41
|
-
number:
|
42
|
-
type:
|
20
|
+
number: number,
|
21
|
+
type: rule[:type],
|
43
22
|
country: rule[:country]
|
44
23
|
}
|
45
24
|
end
|
46
25
|
|
47
26
|
# Returns information about a number
|
48
27
|
def self.infos(number)
|
49
|
-
rules = Rules.
|
28
|
+
rules = Rules.all.select do |rule|
|
50
29
|
valid = true
|
51
30
|
|
52
31
|
# Check number of digits
|
@@ -78,7 +57,37 @@ module Credy
|
|
78
57
|
details: criterii
|
79
58
|
}
|
80
59
|
end
|
81
|
-
|
60
|
+
|
61
|
+
def self.find_rule(options = {})
|
62
|
+
Rules.filter(options).sample
|
63
|
+
end
|
64
|
+
private_class_method :find_rule
|
65
|
+
|
66
|
+
def self.complete_number(number)
|
67
|
+
# Generates the last digit according to luhn algorithm
|
68
|
+
digits = (0..9).map(&:to_s)
|
69
|
+
begin
|
70
|
+
full = number + digits.delete(digits.sample)
|
71
|
+
end while !Check.luhn(full)
|
72
|
+
|
73
|
+
full
|
74
|
+
end
|
75
|
+
private_class_method :complete_number
|
76
|
+
|
77
|
+
def self.generate_from_rule(rule)
|
78
|
+
length = Array(rule[:length]).sample
|
79
|
+
number = rule[:prefix]
|
80
|
+
|
81
|
+
# Generates n-1 digits
|
82
|
+
(length - number.length - 1).times do
|
83
|
+
number += rand(10).to_s
|
84
|
+
end
|
85
|
+
|
86
|
+
# Append last digit
|
87
|
+
complete_number(number)
|
88
|
+
end
|
89
|
+
private_class_method :generate_from_rule
|
90
|
+
|
82
91
|
end
|
83
92
|
|
84
|
-
end
|
93
|
+
end
|
data/lib/credy/check.rb
CHANGED
@@ -4,9 +4,9 @@ module Credy
|
|
4
4
|
|
5
5
|
def self.luhn(code)
|
6
6
|
s1 = s2 = 0
|
7
|
-
code.to_s.reverse.chars.each_slice(2) do |odd, even|
|
7
|
+
code.to_s.reverse.chars.each_slice(2) do |odd, even|
|
8
8
|
s1 += odd.to_i
|
9
|
-
|
9
|
+
|
10
10
|
double = even.to_i * 2
|
11
11
|
double -= 9 if double >= 10
|
12
12
|
s2 += double
|
@@ -16,4 +16,4 @@ module Credy
|
|
16
16
|
|
17
17
|
end
|
18
18
|
|
19
|
-
end
|
19
|
+
end
|
data/lib/credy/rules.rb
CHANGED
@@ -5,67 +5,46 @@ module Credy
|
|
5
5
|
class Rules
|
6
6
|
|
7
7
|
# Return all the rules from yml files
|
8
|
-
def self.
|
9
|
-
@rules ||=
|
10
|
-
rules = {}
|
11
|
-
Dir.glob "#{Credy.root}/data/*.yml" do |filename|
|
12
|
-
r = YAML::load IO.read(filename)
|
13
|
-
rules.merge! r
|
14
|
-
end
|
15
|
-
rules
|
16
|
-
end
|
8
|
+
def self.raw
|
9
|
+
@rules ||= load_rules("#{Credy.root}/data/*.yml")
|
17
10
|
end
|
18
11
|
|
19
12
|
# Change hash format to process rules
|
20
|
-
def self.
|
13
|
+
def self.all
|
21
14
|
rules = []
|
22
15
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
global_prefixes.each do |prefix|
|
32
|
-
rules.push({
|
33
|
-
prefix: prefix.to_s,
|
34
|
-
length: details['length'],
|
35
|
-
type: type
|
36
|
-
})
|
37
|
-
end
|
38
|
-
end
|
16
|
+
raw.each do |type, details|
|
17
|
+
# Add general rules
|
18
|
+
Array(details['prefix']).each do |prefix|
|
19
|
+
rules.push({
|
20
|
+
prefix: prefix.to_s,
|
21
|
+
length: details['length'],
|
22
|
+
type: type
|
23
|
+
})
|
39
24
|
end
|
40
25
|
|
41
26
|
# Process each country
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
type: type,
|
52
|
-
country: country,
|
53
|
-
})
|
54
|
-
end
|
27
|
+
Array(details['countries']).each do |country, prefixes|
|
28
|
+
# Add a rule for each prefix
|
29
|
+
Array(prefixes).each do |prefix|
|
30
|
+
rules.push({
|
31
|
+
prefix: prefix.to_s,
|
32
|
+
length: details['length'],
|
33
|
+
type: type,
|
34
|
+
country: country,
|
35
|
+
})
|
55
36
|
end
|
56
37
|
end
|
57
38
|
|
58
39
|
end
|
59
40
|
|
60
|
-
# Sort
|
61
|
-
rules.sort
|
62
|
-
|
63
|
-
rules
|
41
|
+
# Sort by prefix length
|
42
|
+
rules.sort { |x, y| y[:prefix].length <=> x[:prefix].length }
|
64
43
|
end
|
65
44
|
|
66
45
|
# Returns rules according to given filters
|
67
|
-
def self.filter(filters = {}
|
68
|
-
|
46
|
+
def self.filter(filters = {})
|
47
|
+
all.select do |rule|
|
69
48
|
[:country, :type].each do |condition|
|
70
49
|
break false if filters[condition] && filters[condition] != rule[condition]
|
71
50
|
true
|
@@ -73,6 +52,15 @@ module Credy
|
|
73
52
|
end
|
74
53
|
end
|
75
54
|
|
55
|
+
def self.load_rules(files)
|
56
|
+
{}.tap do |rules|
|
57
|
+
Dir.glob(files) do |filename|
|
58
|
+
rules.merge! YAML::load IO.read(filename)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
private_class_method :load_rules
|
63
|
+
|
76
64
|
end
|
77
65
|
|
78
|
-
end
|
66
|
+
end
|
data/lib/credy/string.rb
CHANGED
data/lib/credy/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module Credy
|
2
|
-
VERSION = '0.
|
3
|
-
end
|
2
|
+
VERSION = '0.2.0'
|
3
|
+
end
|
data/readme.md
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
-
# Credy
|
1
|
+
# Credy [![Build Status](https://travis-ci.org/TimPetricola/Credy.png?branch=master)](https://travis-ci.org/TimPetricola/Credy) [![Gem Version](https://badge.fury.io/rb/credy.png)](http://badge.fury.io/rb/credy) [![Code Climate](https://codeclimate.com/github/TimPetricola/Credy.png)](https://codeclimate.com/github/TimPetricola/Credy)
|
2
2
|
|
3
|
-
A simple credit card generator.
|
3
|
+
A simple credit card generator/validator.
|
4
|
+
Need a valid credit card number to sign up on a site but you don't want to use your real card?
|
5
|
+
Need to validate your customers credit card?
|
4
6
|
|
5
|
-
##
|
7
|
+
## Functionalities
|
6
8
|
* Generates a valid number (per country/type)
|
7
9
|
* Get information for a number
|
8
10
|
* Check validity of a number
|
@@ -33,8 +35,8 @@ credy validate 5108756163954799
|
|
33
35
|
### Generate
|
34
36
|
``` ruby
|
35
37
|
options {
|
36
|
-
:
|
37
|
-
:
|
38
|
+
country: 'au',
|
39
|
+
type: 'mastercard'
|
38
40
|
}
|
39
41
|
Credy::CreditCard.generate options
|
40
42
|
```
|
@@ -89,4 +91,4 @@ At the moment, only a few types and countries are (partially) supported.
|
|
89
91
|
All data is coming from the [Bank card number](http://en.wikipedia.org/wiki/Bank_card_number) page and the [List of Issuer Identification Numbers](http://en.wikipedia.org/wiki/List_of_Issuer_Identification_Numbers) on [Wikipedia](http://wikipedia.org). I do not assume the responsibility for wrong data.
|
90
92
|
|
91
93
|
## License
|
92
|
-
Credy is released under the [MIT License](http://opensource.org/licenses/MIT).
|
94
|
+
Credy is released under the [MIT License](http://opensource.org/licenses/MIT).
|
data/spec/bin/credy_spec.rb
CHANGED
@@ -1,66 +1,61 @@
|
|
1
1
|
require_relative '../spec_helper'
|
2
|
-
|
3
2
|
silent { load 'bin/credy' }
|
4
3
|
|
5
4
|
describe Credy::CLI do
|
6
5
|
|
7
|
-
before
|
8
|
-
@stdout = $stdout
|
9
|
-
$stdout = StringIO.new
|
6
|
+
before(:all) do
|
7
|
+
@stdout, $stdout = $stdout, StringIO.new
|
10
8
|
end
|
11
9
|
|
12
10
|
describe 'generate' do
|
13
11
|
|
14
12
|
it 'works without options' do
|
15
|
-
Credy::CreditCard.
|
13
|
+
expect(Credy::CreditCard).to receive(:generate).with({})
|
16
14
|
r = Credy::CLI.start ['generate']
|
17
15
|
end
|
18
16
|
|
19
|
-
it '--country' do
|
20
|
-
Credy::CreditCard.
|
17
|
+
it '--country' do
|
18
|
+
expect(Credy::CreditCard).to receive(:generate).with(country: 'au').twice
|
21
19
|
Credy::CLI.start ['generate', '--country', 'au']
|
22
20
|
Credy::CLI.start ['generate', '-c', 'au']
|
23
21
|
end
|
24
22
|
|
25
|
-
it '--type' do
|
26
|
-
Credy::CreditCard.
|
23
|
+
it '--type' do
|
24
|
+
expect(Credy::CreditCard).to receive(:generate).with(type: 'visa').twice
|
27
25
|
Credy::CLI.start ['generate', '--type', 'visa']
|
28
26
|
Credy::CLI.start ['generate', '-t', 'visa']
|
29
27
|
end
|
30
28
|
|
31
29
|
it '--number' do
|
32
|
-
Credy::CreditCard.
|
30
|
+
expect(Credy::CreditCard).to receive(:generate).exactly(20).and_return({number: '50076645747856835'})
|
33
31
|
Credy::CLI.start ['generate', '--number', 10]
|
34
32
|
Credy::CLI.start ['generate', '-n', 10]
|
35
33
|
end
|
36
34
|
|
37
35
|
describe 'result' do
|
38
|
-
|
39
|
-
before :all do
|
40
|
-
$stdout = @stdout
|
41
|
-
end
|
42
|
-
|
43
36
|
it 'stops if no number is found' do
|
44
|
-
Credy::CreditCard.
|
45
|
-
|
46
|
-
|
37
|
+
expect(Credy::CreditCard).to receive(:generate).once.and_return(nil)
|
38
|
+
output = silent { Credy::CLI.start ['generate', '-n', 10] }
|
39
|
+
expect(output).to eq "No rule found for those criteria.\n"
|
47
40
|
end
|
48
41
|
|
49
42
|
describe '--details' do
|
50
43
|
before do
|
51
44
|
number = {number: '50076645747856835', type: 'visa', country: 'au'}
|
52
|
-
Credy::CreditCard.
|
45
|
+
allow(Credy::CreditCard).to receive(:generate).and_return number
|
53
46
|
end
|
54
47
|
|
55
48
|
it 'only returns the number' do
|
56
|
-
|
57
|
-
|
49
|
+
output = silent { Credy::CLI.start ['generate'] }
|
50
|
+
expect(output).to eq "50076645747856835\n"
|
58
51
|
end
|
59
52
|
|
60
53
|
it 'accepts to return more details' do
|
61
|
-
|
62
|
-
|
63
|
-
|
54
|
+
output = silent do
|
55
|
+
Credy::CLI.start ['generate', '--details']
|
56
|
+
Credy::CLI.start ['generate', '-d']
|
57
|
+
end
|
58
|
+
expect(output).to eq "50076645747856835 (visa, au)\n"*2
|
64
59
|
end
|
65
60
|
end
|
66
61
|
|
@@ -71,28 +66,24 @@ describe Credy::CLI do
|
|
71
66
|
describe 'infos' do
|
72
67
|
|
73
68
|
it 'calls the infos function' do
|
74
|
-
Credy::CreditCard.
|
75
|
-
|
69
|
+
expect(Credy::CreditCard).to receive(:infos).with '5108756163954799'
|
70
|
+
silent {
|
71
|
+
Credy::CLI.start ['infos', '5108756163954799']
|
72
|
+
}
|
76
73
|
end
|
77
74
|
|
78
75
|
describe 'result' do
|
79
|
-
before :all do
|
80
|
-
$stdout = @stdout
|
81
|
-
end
|
82
|
-
|
83
76
|
it 'shows error if nothing found' do
|
84
|
-
Credy::CreditCard.
|
85
|
-
|
86
|
-
|
77
|
+
expect(Credy::CreditCard).to receive(:infos).and_return nil
|
78
|
+
output = silent { Credy::CLI.start ['infos', '5108756163954799'] }
|
79
|
+
expect(output).to eq "No information available for this number.\n"
|
87
80
|
end
|
88
81
|
|
89
82
|
it 'shows the card informations' do
|
90
83
|
number = {number: '50076645747856835', type: 'visa', country: 'au'}
|
91
|
-
Credy::CreditCard.
|
92
|
-
|
93
|
-
|
94
|
-
STDOUT.should_receive(:puts).with 'Valid'
|
95
|
-
Credy::CLI.start ['infos', '50076645747856835']
|
84
|
+
expect(Credy::CreditCard).to receive(:infos).at_least(1).times.and_return number
|
85
|
+
output = silent { Credy::CLI.start ['infos', '50076645747856835'] }
|
86
|
+
expect(output).to eq "Type: visa\nCountry: au\nValid\n"
|
96
87
|
end
|
97
88
|
end
|
98
89
|
|
@@ -100,32 +91,26 @@ describe Credy::CLI do
|
|
100
91
|
|
101
92
|
describe 'validate' do
|
102
93
|
it 'calls the validate function' do
|
103
|
-
Credy::CreditCard.
|
94
|
+
expect(Credy::CreditCard).to receive(:validate).with('5108756163954799').and_return({valid: false, details: {}})
|
104
95
|
Credy::CLI.start ['validate', '5108756163954799']
|
105
96
|
end
|
106
97
|
|
107
98
|
describe 'result' do
|
108
|
-
before :all do
|
109
|
-
$stdout = @stdout
|
110
|
-
end
|
111
|
-
|
112
99
|
it 'shows card validity and details' do
|
113
100
|
validity = { valid: true, details: { luhn: true, type: true} }
|
114
|
-
Credy::CreditCard.
|
115
|
-
|
116
|
-
|
117
|
-
Credy::CLI.start ['validate', '50076645747856835']
|
101
|
+
expect(Credy::CreditCard).to receive(:validate).and_return validity
|
102
|
+
output = silent { Credy::CLI.start ['validate', '50076645747856835'] }
|
103
|
+
expect(output).to eq "This number is valid.\n(luhn: v, type: v)\n"
|
118
104
|
end
|
119
105
|
|
120
106
|
it 'shows card validity and details for invalid number' do
|
121
107
|
validity = { valid: false, details: { luhn: false, type: false} }
|
122
|
-
Credy::CreditCard.
|
123
|
-
|
124
|
-
|
125
|
-
Credy::CLI.start ['validate', '5108756163954799']
|
108
|
+
expect(Credy::CreditCard).to receive(:validate).and_return validity
|
109
|
+
output = silent { Credy::CLI.start ['validate', '5108756163954799'] }
|
110
|
+
expect(output).to eq "This number is not valid.\n(luhn: x, type: x)\n"
|
126
111
|
end
|
127
112
|
|
128
113
|
end
|
129
114
|
end
|
130
115
|
|
131
|
-
end
|
116
|
+
end
|
@@ -5,15 +5,15 @@ describe Credy::Check do
|
|
5
5
|
describe '.luhn' do
|
6
6
|
|
7
7
|
it 'returns true for correct data' do
|
8
|
-
Credy::Check.luhn(49927398716).
|
9
|
-
Credy::Check.luhn(1234567812345670).
|
8
|
+
expect(Credy::Check.luhn(49927398716)).to be_true
|
9
|
+
expect(Credy::Check.luhn(1234567812345670)).to be_true
|
10
10
|
end
|
11
11
|
|
12
12
|
it 'returns false for non correct data' do
|
13
|
-
Credy::Check.luhn(49927398717).
|
14
|
-
Credy::Check.luhn(1234567812345678).
|
13
|
+
expect(Credy::Check.luhn(49927398717)).to be_false
|
14
|
+
expect(Credy::Check.luhn(1234567812345678)).to be_false
|
15
15
|
end
|
16
16
|
|
17
17
|
end
|
18
18
|
|
19
|
-
end
|
19
|
+
end
|
@@ -4,22 +4,17 @@ describe Credy::Rules do
|
|
4
4
|
|
5
5
|
subject { Credy::Rules }
|
6
6
|
|
7
|
-
describe '.
|
8
|
-
|
9
|
-
|
10
|
-
its(:all) { should be_a Hash }
|
11
|
-
|
12
|
-
it 'should be tested more'
|
13
|
-
|
7
|
+
describe '.raw' do
|
8
|
+
it { should respond_to :raw }
|
9
|
+
its(:raw) { should be_a Hash }
|
14
10
|
end
|
15
11
|
|
16
|
-
describe '.
|
12
|
+
describe '.all' do
|
17
13
|
|
18
|
-
|
19
|
-
its(:flatten) { should be_a Array }
|
14
|
+
its(:all) { should be_a Array }
|
20
15
|
|
21
|
-
it '
|
22
|
-
subject.stub(:
|
16
|
+
it 'contains a set of rules' do
|
17
|
+
subject.stub(:raw).and_return({
|
23
18
|
'visa' => {
|
24
19
|
'length' => [13, 16],
|
25
20
|
'countries' => {
|
@@ -29,21 +24,19 @@ describe Credy::Rules do
|
|
29
24
|
},
|
30
25
|
'mastercard' => {
|
31
26
|
'length' => 16,
|
32
|
-
'
|
33
|
-
|
34
|
-
}
|
35
|
-
},
|
27
|
+
'prefix' => '51'
|
28
|
+
}
|
36
29
|
})
|
37
30
|
|
38
|
-
subject.
|
39
|
-
{:
|
40
|
-
{:
|
41
|
-
{:
|
31
|
+
expect(subject.all).to eq [
|
32
|
+
{prefix:"404159", length:[13, 16], type:"visa", country:"ch"},
|
33
|
+
{prefix:"401795", length:[13, 16], type:"visa", country:"au"},
|
34
|
+
{prefix:"51", length:16, type:"mastercard"}
|
42
35
|
]
|
43
36
|
end
|
44
37
|
|
45
38
|
it 'works with string prefixes' do
|
46
|
-
subject.stub(:
|
39
|
+
subject.stub(:raw).and_return({
|
47
40
|
'visa' => {
|
48
41
|
'length' => [13, 16],
|
49
42
|
'countries' => {
|
@@ -52,13 +45,13 @@ describe Credy::Rules do
|
|
52
45
|
}
|
53
46
|
})
|
54
47
|
|
55
|
-
subject.
|
56
|
-
{:
|
48
|
+
expect(subject.all).to eq [
|
49
|
+
{prefix:"401795", length:[13, 16], type:"visa", country:"au"}
|
57
50
|
]
|
58
51
|
end
|
59
52
|
|
60
53
|
it 'works with integer prefixes' do
|
61
|
-
subject.stub(:
|
54
|
+
subject.stub(:raw).and_return({
|
62
55
|
'visa' => {
|
63
56
|
'length' => [13, 16],
|
64
57
|
'countries' => {
|
@@ -67,13 +60,13 @@ describe Credy::Rules do
|
|
67
60
|
}
|
68
61
|
})
|
69
62
|
|
70
|
-
subject.
|
71
|
-
{:
|
63
|
+
expect(subject.all).to eq [
|
64
|
+
{prefix:"401795", length:[13, 16], type:"visa", country:"au"}
|
72
65
|
]
|
73
66
|
end
|
74
67
|
|
75
68
|
it 'works with an array of prefixes' do
|
76
|
-
subject.stub(:
|
69
|
+
subject.stub(:raw).and_return({
|
77
70
|
'visa' => {
|
78
71
|
'length' => [13, 16],
|
79
72
|
'countries' => {
|
@@ -82,42 +75,18 @@ describe Credy::Rules do
|
|
82
75
|
}
|
83
76
|
})
|
84
77
|
|
85
|
-
subject.
|
86
|
-
{:
|
87
|
-
{:
|
88
|
-
]
|
89
|
-
end
|
90
|
-
|
91
|
-
it 'includes global rules' do
|
92
|
-
subject.stub(:all).and_return({
|
93
|
-
'visa' => {
|
94
|
-
'length' => [13, 16],
|
95
|
-
'prefix' => '4',
|
96
|
-
'countries' => {
|
97
|
-
'ch' => '404159',
|
98
|
-
'au' => '401'
|
99
|
-
}
|
100
|
-
},
|
101
|
-
'mastercard' => {
|
102
|
-
'length' => 16,
|
103
|
-
'prefix' => '51'
|
104
|
-
},
|
105
|
-
})
|
106
|
-
|
107
|
-
subject.flatten(true).should == [
|
108
|
-
{:prefix=>"404159", :length=>[13, 16], :type=>"visa", :country=>"ch"},
|
109
|
-
{:prefix=>"401", :length=>[13, 16], :type=>"visa", :country=>"au"},
|
110
|
-
{:prefix=>"51", :length=>16, :type=>"mastercard"},
|
111
|
-
{:prefix=>"4", :length=>[13, 16], :type=>"visa"}
|
78
|
+
expect(subject.all).to eq [
|
79
|
+
{prefix:"401795", length:[13, 16], type:"visa", country:"au"},
|
80
|
+
{prefix:"404137", length:[13, 16], type:"visa", country:"au"}
|
112
81
|
]
|
113
82
|
end
|
114
83
|
|
115
84
|
end
|
116
85
|
|
117
|
-
describe '.filter' do
|
86
|
+
describe '.filter' do
|
118
87
|
|
119
|
-
before do
|
120
|
-
subject.stub(:
|
88
|
+
before do
|
89
|
+
subject.stub(:raw).and_return({
|
121
90
|
'visa' => {
|
122
91
|
'length' => [13, 16],
|
123
92
|
'countries' => {
|
@@ -137,31 +106,31 @@ describe Credy::Rules do
|
|
137
106
|
it { should respond_to :filter }
|
138
107
|
|
139
108
|
it 'returns everything if no filter is provided' do
|
140
|
-
subject.filter.
|
141
|
-
subject.filter.
|
109
|
+
expect(subject.filter).to be_a Array
|
110
|
+
expect(subject.filter).to eq subject.all
|
142
111
|
end
|
143
112
|
|
144
113
|
it 'filters by type' do
|
145
|
-
subject.filter(type: 'visa').
|
146
|
-
subject.filter(type: 'mastercard').
|
114
|
+
expect(subject.filter(type: 'visa')).to have(2).items
|
115
|
+
expect(subject.filter(type: 'mastercard')).to have(1).item
|
147
116
|
end
|
148
117
|
|
149
118
|
it 'accepts the :country option' do
|
150
|
-
subject.filter(country: 'ch').
|
151
|
-
subject.filter(country: 'au').
|
119
|
+
expect(subject.filter(country: 'ch')).to have(1).item
|
120
|
+
expect(subject.filter(country: 'au')).to have(2).items
|
152
121
|
end
|
153
122
|
|
154
123
|
it 'accepts several options at the same time' do
|
155
124
|
rules = subject.filter type: 'visa', country: 'au'
|
156
|
-
rules.
|
125
|
+
expect(rules).to have(1).item
|
157
126
|
end
|
158
127
|
|
159
128
|
it 'returns an empty array if nothing is found' do
|
160
129
|
rules = subject.filter type: 'foo', country: 'bar'
|
161
|
-
rules.
|
162
|
-
rules.
|
130
|
+
expect(rules).to be_a Array
|
131
|
+
expect(rules).to be_empty
|
163
132
|
end
|
164
133
|
|
165
134
|
end
|
166
135
|
|
167
|
-
end
|
136
|
+
end
|
data/spec/lib/credy_spec.rb
CHANGED
@@ -24,46 +24,46 @@ describe Credy::CreditCard do
|
|
24
24
|
end
|
25
25
|
|
26
26
|
before(:each) do
|
27
|
-
Credy::Rules.stub(:
|
27
|
+
Credy::Rules.stub(:raw).and_return rules
|
28
28
|
end
|
29
29
|
|
30
|
-
describe '.generate' do
|
30
|
+
describe '.generate' do
|
31
31
|
|
32
32
|
it 'returns a number, type and country' do
|
33
|
-
subject.generate[:number].
|
34
|
-
subject.generate[:type].
|
35
|
-
subject.generate[:country].
|
33
|
+
expect(subject.generate[:number]).not_to be_nil
|
34
|
+
expect(subject.generate[:type]).not_to be_nil
|
35
|
+
expect(subject.generate[:country]).not_to be_nil
|
36
36
|
end
|
37
37
|
|
38
38
|
it 'accepts the :type option' do
|
39
39
|
number = subject.generate type: 'visa'
|
40
|
-
number[:type].
|
40
|
+
expect(number[:type]).to eq 'visa'
|
41
41
|
end
|
42
42
|
|
43
43
|
it 'accepts the :country option' do
|
44
44
|
number = subject.generate country: 'ch'
|
45
|
-
number[:country].
|
45
|
+
expect(number[:country]).to eq 'ch'
|
46
46
|
end
|
47
47
|
|
48
48
|
it 'accepts several options at the same time' do
|
49
49
|
number = subject.generate type: 'mastercard', country: 'au'
|
50
|
-
number[:type].
|
51
|
-
number[:country].
|
50
|
+
expect(number[:type]).to eq 'mastercard'
|
51
|
+
expect(number[:country]).to eq 'au'
|
52
52
|
end
|
53
53
|
|
54
54
|
it 'generates the right number of digits' do
|
55
55
|
number = subject.generate type: 'mastercard'
|
56
|
-
number[:number].length.
|
56
|
+
expect(number[:number].length).to be 16
|
57
57
|
end
|
58
58
|
|
59
59
|
it 'generate a number with the right prefix' do
|
60
60
|
number = subject.generate type: 'mastercard', country: 'au'
|
61
|
-
number[:number].
|
61
|
+
expect(number[:number]).to match /^401795/
|
62
62
|
end
|
63
63
|
|
64
64
|
it 'returns nil if nothing is found' do
|
65
65
|
number = subject.generate type: 'foo', country: 'bar'
|
66
|
-
number.
|
66
|
+
expect(number).to be_nil
|
67
67
|
end
|
68
68
|
|
69
69
|
end
|
@@ -72,8 +72,8 @@ describe Credy::CreditCard do
|
|
72
72
|
|
73
73
|
it 'returns the correct information according to the card number' do
|
74
74
|
infos = subject.infos '5108756163954792'
|
75
|
-
infos[:type].
|
76
|
-
infos[:country].
|
75
|
+
expect(infos[:type]).to eq 'mastercard'
|
76
|
+
expect(infos[:country]).to eq 'us'
|
77
77
|
end
|
78
78
|
|
79
79
|
end
|
@@ -82,23 +82,23 @@ describe Credy::CreditCard do
|
|
82
82
|
|
83
83
|
it 'returns a hash' do
|
84
84
|
r = subject.validate '5108756163954792'
|
85
|
-
r[:valid].
|
86
|
-
r[:details][:luhn].
|
87
|
-
r[:details][:type].
|
85
|
+
expect(r[:valid]).to be_true
|
86
|
+
expect(r[:details][:luhn]).to be_true
|
87
|
+
expect(r[:details][:type]).to be_true
|
88
88
|
end
|
89
89
|
|
90
90
|
it 'checks against luhn algorithm' do
|
91
91
|
r = subject.validate '5108756163954791'
|
92
|
-
r[:valid].
|
93
|
-
r[:details][:luhn].
|
92
|
+
expect(r[:valid]).to be_false
|
93
|
+
expect(r[:details][:luhn]).to be_false
|
94
94
|
end
|
95
95
|
|
96
96
|
it 'checks against card type' do
|
97
97
|
r = subject.validate '99999999999999999999992'
|
98
|
-
r[:valid].
|
99
|
-
r[:details][:type].
|
98
|
+
expect(r[:valid]).to be_false
|
99
|
+
expect(r[:details][:type]).to be_false
|
100
100
|
end
|
101
101
|
|
102
102
|
end
|
103
103
|
|
104
|
-
end
|
104
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -5,12 +5,13 @@ require 'credy'
|
|
5
5
|
|
6
6
|
def silent
|
7
7
|
_stdout = $stdout
|
8
|
-
$stdout = StringIO.new
|
8
|
+
$stdout = fake = StringIO.new
|
9
9
|
begin
|
10
10
|
yield
|
11
11
|
ensure
|
12
12
|
$stdout = _stdout
|
13
13
|
end
|
14
|
+
fake.string
|
14
15
|
end
|
15
16
|
|
16
17
|
# Don't colorize strings in test environment
|
@@ -21,4 +22,7 @@ class String
|
|
21
22
|
end
|
22
23
|
|
23
24
|
RSpec.configure do |config|
|
25
|
+
config.expect_with :rspec do |c|
|
26
|
+
c.syntax = :expect
|
27
|
+
end
|
24
28
|
end
|
metadata
CHANGED
@@ -1,96 +1,57 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: credy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.2.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Tim Petricola
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2014-03-16 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rspec
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - "~>"
|
20
18
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
19
|
+
version: 2.14.1
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - "~>"
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
30
|
-
- !ruby/object:Gem::Dependency
|
31
|
-
name: rspec-mocks
|
32
|
-
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
|
-
requirements:
|
35
|
-
- - ! '>='
|
36
|
-
- !ruby/object:Gem::Version
|
37
|
-
version: '0'
|
38
|
-
type: :development
|
39
|
-
prerelease: false
|
40
|
-
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
|
-
requirements:
|
43
|
-
- - ! '>='
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
version: '0'
|
26
|
+
version: 2.14.1
|
46
27
|
- !ruby/object:Gem::Dependency
|
47
28
|
name: rake
|
48
29
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
|
-
requirements:
|
51
|
-
- - ! '>='
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version: '0'
|
54
|
-
type: :development
|
55
|
-
prerelease: false
|
56
|
-
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
|
-
requirements:
|
59
|
-
- - ! '>='
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
- !ruby/object:Gem::Dependency
|
63
|
-
name: debugger
|
64
|
-
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
30
|
requirements:
|
67
|
-
- -
|
31
|
+
- - "~>"
|
68
32
|
- !ruby/object:Gem::Version
|
69
|
-
version:
|
33
|
+
version: 10.0.3
|
70
34
|
type: :development
|
71
35
|
prerelease: false
|
72
36
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
37
|
requirements:
|
75
|
-
- -
|
38
|
+
- - "~>"
|
76
39
|
- !ruby/object:Gem::Version
|
77
|
-
version:
|
40
|
+
version: 10.0.3
|
78
41
|
- !ruby/object:Gem::Dependency
|
79
42
|
name: thor
|
80
43
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
44
|
requirements:
|
83
|
-
- -
|
45
|
+
- - "~>"
|
84
46
|
- !ruby/object:Gem::Version
|
85
|
-
version:
|
47
|
+
version: 0.18.1
|
86
48
|
type: :runtime
|
87
49
|
prerelease: false
|
88
50
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
51
|
requirements:
|
91
|
-
- -
|
52
|
+
- - "~>"
|
92
53
|
- !ruby/object:Gem::Version
|
93
|
-
version:
|
54
|
+
version: 0.18.1
|
94
55
|
description:
|
95
56
|
email:
|
96
57
|
- hi@timpetricola.com
|
@@ -99,7 +60,8 @@ executables:
|
|
99
60
|
extensions: []
|
100
61
|
extra_rdoc_files: []
|
101
62
|
files:
|
102
|
-
- .gitignore
|
63
|
+
- ".gitignore"
|
64
|
+
- ".travis.yml"
|
103
65
|
- Gemfile
|
104
66
|
- Gemfile.lock
|
105
67
|
- Rakefile
|
@@ -133,30 +95,29 @@ files:
|
|
133
95
|
- spec/lib/credy/version_spec.rb
|
134
96
|
- spec/lib/credy_spec.rb
|
135
97
|
- spec/spec_helper.rb
|
136
|
-
|
137
|
-
|
138
|
-
|
98
|
+
homepage: https://github.com/TimPetricola/Credy
|
99
|
+
licenses:
|
100
|
+
- MIT
|
101
|
+
metadata: {}
|
139
102
|
post_install_message:
|
140
103
|
rdoc_options: []
|
141
104
|
require_paths:
|
142
105
|
- lib
|
143
106
|
required_ruby_version: !ruby/object:Gem::Requirement
|
144
|
-
none: false
|
145
107
|
requirements:
|
146
|
-
- -
|
108
|
+
- - ">="
|
147
109
|
- !ruby/object:Gem::Version
|
148
110
|
version: '0'
|
149
111
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
150
|
-
none: false
|
151
112
|
requirements:
|
152
|
-
- -
|
113
|
+
- - ">="
|
153
114
|
- !ruby/object:Gem::Version
|
154
115
|
version: '0'
|
155
116
|
requirements: []
|
156
117
|
rubyforge_project:
|
157
|
-
rubygems_version:
|
118
|
+
rubygems_version: 2.2.0
|
158
119
|
signing_key:
|
159
|
-
specification_version:
|
120
|
+
specification_version: 4
|
160
121
|
summary: A simple (but powerful) credit card number generator
|
161
122
|
test_files:
|
162
123
|
- spec/bin/credy_spec.rb
|
@@ -165,4 +126,3 @@ test_files:
|
|
165
126
|
- spec/lib/credy/version_spec.rb
|
166
127
|
- spec/lib/credy_spec.rb
|
167
128
|
- spec/spec_helper.rb
|
168
|
-
has_rdoc:
|