zxcvbn-ruby 0.1.0 → 1.2.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.
- checksums.yaml +7 -0
- data/.github/workflows/ci.yml +23 -0
- data/CHANGELOG.md +58 -0
- data/CODE_OF_CONDUCT.md +130 -0
- data/Gemfile +8 -1
- data/Guardfile +26 -0
- data/{LICENSE → LICENSE.txt} +0 -0
- data/README.md +152 -12
- data/Rakefile +5 -1
- data/lib/zxcvbn/entropy.rb +1 -1
- data/lib/zxcvbn/feedback.rb +10 -0
- data/lib/zxcvbn/feedback_giver.rb +133 -0
- data/lib/zxcvbn/matchers/l33t.rb +2 -2
- data/lib/zxcvbn/password_strength.rb +2 -0
- data/lib/zxcvbn/score.rb +1 -1
- data/lib/zxcvbn/tester.rb +13 -5
- data/lib/zxcvbn/version.rb +3 -1
- data/spec/dictionary_ranker_spec.rb +2 -2
- data/spec/feedback_giver_spec.rb +212 -0
- data/spec/matchers/date_spec.rb +8 -8
- data/spec/matchers/dictionary_spec.rb +25 -14
- data/spec/matchers/digits_spec.rb +3 -3
- data/spec/matchers/l33t_spec.rb +14 -12
- data/spec/matchers/repeat_spec.rb +6 -6
- data/spec/matchers/sequences_spec.rb +5 -5
- data/spec/matchers/spatial_spec.rb +7 -7
- data/spec/matchers/year_spec.rb +3 -3
- data/spec/omnimatch_spec.rb +1 -1
- data/spec/scoring/crack_time_spec.rb +13 -13
- data/spec/scoring/entropy_spec.rb +24 -24
- data/spec/scoring/math_spec.rb +18 -18
- data/spec/support/js_helpers.rb +3 -4
- data/spec/support/matcher.rb +1 -1
- data/spec/tester_spec.rb +75 -27
- data/zxcvbn-ruby.gemspec +14 -1
- metadata +34 -33
data/spec/matchers/date_spec.rb
CHANGED
@@ -15,16 +15,16 @@ describe Zxcvbn::Matchers::Date do
|
|
15
15
|
let(:matches) { matcher.matches(password) }
|
16
16
|
|
17
17
|
it 'finds matches' do
|
18
|
-
matches.
|
18
|
+
expect(matches).not_to be_empty
|
19
19
|
end
|
20
20
|
|
21
21
|
it 'finds the correct matches' do
|
22
|
-
matches.count.
|
23
|
-
matches[0].token.
|
24
|
-
matches[0].separator.
|
25
|
-
matches[0].day.
|
26
|
-
matches[0].month.
|
27
|
-
matches[0].year.
|
22
|
+
expect(matches.count).to eq 1
|
23
|
+
expect(matches[0].token).to eq %w[ 02 12 1997 ].join(separator)
|
24
|
+
expect(matches[0].separator).to eq separator
|
25
|
+
expect(matches[0].day).to eq 2
|
26
|
+
expect(matches[0].month).to eq 12
|
27
|
+
expect(matches[0].year).to eq 1997
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
@@ -103,7 +103,7 @@ describe Zxcvbn::Matchers::Date do
|
|
103
103
|
let(:matches) { matcher.matches('testing0.x.1997') }
|
104
104
|
|
105
105
|
it 'doesnt match' do
|
106
|
-
matches.
|
106
|
+
expect(matches).to be_empty
|
107
107
|
end
|
108
108
|
end
|
109
109
|
end
|
@@ -1,19 +1,30 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
2
4
|
|
3
5
|
describe Zxcvbn::Matchers::Dictionary do
|
4
|
-
|
5
|
-
let(:dictionary) { Zxcvbn::Data.new.ranked_dictionaries['english'] }
|
6
|
+
subject(:matcher) { described_class.new("Test dictionary", dictionary) }
|
6
7
|
|
7
|
-
|
8
|
-
matches
|
9
|
-
matches.
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
describe "#matches" do
|
9
|
+
let(:matches) { matcher.matches(password) }
|
10
|
+
let(:matched_words) { matches.map(&:matched_word) }
|
11
|
+
|
12
|
+
context "Given a dictionary of English words" do
|
13
|
+
let(:dictionary) { Zxcvbn::Data.new.ranked_dictionaries["english"] }
|
14
|
+
let(:password) { "whatisinit" }
|
15
|
+
|
16
|
+
it "finds all the matches" do
|
17
|
+
expect(matched_words).to match_array %w[wha what ha hat a at tis i is sin i in i it]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "Given a custom dictionary" do
|
22
|
+
let(:dictionary) { Zxcvbn::DictionaryRanker.rank_dictionary(%w[test AB10CD]) }
|
23
|
+
let(:password) { "AB10CD" }
|
14
24
|
|
15
|
-
|
16
|
-
|
17
|
-
|
25
|
+
it "matches uppercase passwords with normalised dictionary entries" do
|
26
|
+
expect(matched_words).to match_array(%w[ab10cd])
|
27
|
+
end
|
28
|
+
end
|
18
29
|
end
|
19
|
-
end
|
30
|
+
end
|
@@ -5,11 +5,11 @@ describe Zxcvbn::Matchers::Digits do
|
|
5
5
|
let(:matches) { matcher.matches('testing1239xx9712') }
|
6
6
|
|
7
7
|
it 'sets the pattern name' do
|
8
|
-
matches.all? { |m| m.pattern == 'digits' }.
|
8
|
+
expect(matches.all? { |m| m.pattern == 'digits' }).to eql(true)
|
9
9
|
end
|
10
10
|
|
11
11
|
it 'finds the correct matches' do
|
12
|
-
matches.count.
|
13
|
-
matches[0].token.
|
12
|
+
expect(matches.count).to eq(2)
|
13
|
+
expect(matches[0].token).to eq '1239'
|
14
14
|
end
|
15
15
|
end
|
data/spec/matchers/l33t_spec.rb
CHANGED
@@ -7,7 +7,7 @@ describe Zxcvbn::Matchers::L33t do
|
|
7
7
|
|
8
8
|
describe '#relevant_l33t_substitutions' do
|
9
9
|
it 'returns relevant l33t substitutions' do
|
10
|
-
matcher.relevent_l33t_subtable('p@ssw1rd24').
|
10
|
+
expect(matcher.relevent_l33t_subtable('p@ssw1rd24')).to eq(
|
11
11
|
{'a' => ['4', '@'], 'i' => ['1'], 'l' => ['1'], 'z' => ['2']}
|
12
12
|
)
|
13
13
|
end
|
@@ -17,14 +17,14 @@ describe Zxcvbn::Matchers::L33t do
|
|
17
17
|
context 'with 2 possible substitutions' do
|
18
18
|
it 'returns the correct possible substitutions' do
|
19
19
|
substitutions = {'a' => ['@'], 'i' => ['1']}
|
20
|
-
matcher.l33t_subs(substitutions).
|
20
|
+
expect(matcher.l33t_subs(substitutions)).to match_array([
|
21
21
|
{'@' => 'a', '1' => 'i'}
|
22
22
|
])
|
23
23
|
end
|
24
24
|
|
25
25
|
it 'returns the correct possible substitutions with multiple options' do
|
26
26
|
substitutions = {'a' => ['@', '4'], 'i' => ['1']}
|
27
|
-
matcher.l33t_subs(substitutions).
|
27
|
+
expect(matcher.l33t_subs(substitutions)).to match_array([
|
28
28
|
{'@' => 'a', '1' => 'i'},
|
29
29
|
{'4' => 'a', '1' => 'i'}
|
30
30
|
])
|
@@ -34,7 +34,7 @@ describe Zxcvbn::Matchers::L33t do
|
|
34
34
|
context 'with 3 possible substitutions' do
|
35
35
|
it 'returns the correct possible substitutions' do
|
36
36
|
substitutions = {'a' => ['@'], 'i' => ['1'], 'z' => ['3']}
|
37
|
-
matcher.l33t_subs(substitutions).
|
37
|
+
expect(matcher.l33t_subs(substitutions)).to match_array([
|
38
38
|
{'@' => 'a', '1' => 'i', '3' => 'z'}
|
39
39
|
])
|
40
40
|
end
|
@@ -43,7 +43,7 @@ describe Zxcvbn::Matchers::L33t do
|
|
43
43
|
context 'with 4 possible substitutions' do
|
44
44
|
it 'returns the correct possible substitutions' do
|
45
45
|
substitutions = {'a' => ['@'], 'i' => ['1'], 'z' => ['3'], 'b' => ['8']}
|
46
|
-
matcher.l33t_subs(substitutions).
|
46
|
+
expect(matcher.l33t_subs(substitutions)).to match_array([
|
47
47
|
{'@' => 'a', '1' => 'i', '3' => 'z', '8' => 'b'}
|
48
48
|
])
|
49
49
|
end
|
@@ -51,12 +51,14 @@ describe Zxcvbn::Matchers::L33t do
|
|
51
51
|
end
|
52
52
|
|
53
53
|
describe '#matches' do
|
54
|
-
|
55
|
-
|
56
|
-
|
54
|
+
subject(:matches) { matcher.matches('p@ssword') }
|
55
|
+
|
56
|
+
it "doesn't find 'password' because it's not in english.txt" do
|
57
|
+
expect(matches.map(&:matched_word)).not_to include "password"
|
58
|
+
end
|
57
59
|
|
58
60
|
it 'finds the correct matches' do
|
59
|
-
matches.map(&:matched_word).
|
61
|
+
expect(matches.map(&:matched_word)).to match_array([
|
60
62
|
'pas',
|
61
63
|
'a',
|
62
64
|
'as',
|
@@ -65,7 +67,7 @@ describe Zxcvbn::Matchers::L33t do
|
|
65
67
|
end
|
66
68
|
|
67
69
|
it 'sets the token correctly on those matches' do
|
68
|
-
matches.map(&:token).
|
70
|
+
expect(matches.map(&:token)).to match_array([
|
69
71
|
'p@s',
|
70
72
|
'@',
|
71
73
|
'@s',
|
@@ -74,7 +76,7 @@ describe Zxcvbn::Matchers::L33t do
|
|
74
76
|
end
|
75
77
|
|
76
78
|
it 'sets the substituions used' do
|
77
|
-
matches.map(&:sub).
|
79
|
+
expect(matches.map(&:sub)).to match_array([
|
78
80
|
{'@' => 'a'},
|
79
81
|
{'@' => 'a'},
|
80
82
|
{'@' => 'a'},
|
@@ -82,4 +84,4 @@ describe Zxcvbn::Matchers::L33t do
|
|
82
84
|
])
|
83
85
|
end
|
84
86
|
end
|
85
|
-
end
|
87
|
+
end
|
@@ -5,14 +5,14 @@ describe Zxcvbn::Matchers::Repeat do
|
|
5
5
|
let(:matches) { matcher.matches('bbbbbtestingaaa') }
|
6
6
|
|
7
7
|
it 'sets the pattern name' do
|
8
|
-
matches.all? { |m| m.pattern == 'repeat' }.
|
8
|
+
expect(matches.all? { |m| m.pattern == 'repeat' }).to eql(true)
|
9
9
|
end
|
10
10
|
|
11
11
|
it 'finds the repeated patterns' do
|
12
|
-
matches.count.
|
13
|
-
matches[0].token.
|
14
|
-
matches[0].repeated_char.
|
15
|
-
matches[1].token.
|
16
|
-
matches[1].repeated_char.
|
12
|
+
expect(matches.count).to eq 2
|
13
|
+
expect(matches[0].token).to eq 'bbbbb'
|
14
|
+
expect(matches[0].repeated_char).to eq 'b'
|
15
|
+
expect(matches[1].token).to eq 'aaa'
|
16
|
+
expect(matches[1].repeated_char).to eq 'a'
|
17
17
|
end
|
18
18
|
end
|
@@ -5,17 +5,17 @@ describe Zxcvbn::Matchers::Sequences do
|
|
5
5
|
let(:matches) { matcher.matches('abcde87654') }
|
6
6
|
|
7
7
|
it 'sets the pattern name' do
|
8
|
-
matches.all? { |m| m.pattern == 'sequence' }.
|
8
|
+
expect(matches.all? { |m| m.pattern == 'sequence' }).to eql(true)
|
9
9
|
end
|
10
10
|
|
11
11
|
it 'finds the correct matches' do
|
12
|
-
matches.count.
|
13
|
-
matches[0].token.
|
14
|
-
matches[1].token.
|
12
|
+
expect(matches.count).to eq(2)
|
13
|
+
expect(matches[0].token).to eq 'abcde'
|
14
|
+
expect(matches[1].token).to eq '87654'
|
15
15
|
end
|
16
16
|
|
17
17
|
it 'finds overlapping matches' do
|
18
18
|
matches = matcher.matches('abcba')
|
19
|
-
matches.map(&:token).
|
19
|
+
expect(matches.map(&:token)).to eq ['abc', 'cba']
|
20
20
|
end
|
21
21
|
end
|
@@ -8,13 +8,13 @@ describe Zxcvbn::Matchers::Spatial do
|
|
8
8
|
let(:matches) { matcher.matches('rtyikm') }
|
9
9
|
|
10
10
|
it 'finds the correct of matches' do
|
11
|
-
matches.count.
|
12
|
-
matches[0].token.
|
13
|
-
matches[0].graph.
|
14
|
-
matches[1].token.
|
15
|
-
matches[1].graph.
|
16
|
-
matches[2].token.
|
17
|
-
matches[2].graph.
|
11
|
+
expect(matches.count).to eq 3
|
12
|
+
expect(matches[0].token).to eq 'rty'
|
13
|
+
expect(matches[0].graph).to eq 'qwerty'
|
14
|
+
expect(matches[1].token).to eq 'ikm'
|
15
|
+
expect(matches[1].graph).to eq 'qwerty'
|
16
|
+
expect(matches[2].token).to eq 'yik'
|
17
|
+
expect(matches[2].graph).to eq 'dvorak'
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
data/spec/matchers/year_spec.rb
CHANGED
@@ -5,11 +5,11 @@ describe Zxcvbn::Matchers::Year do
|
|
5
5
|
let(:matches) { matcher.matches('testing1998') }
|
6
6
|
|
7
7
|
it 'sets the pattern name' do
|
8
|
-
matches.all? { |m| m.pattern == 'year' }.
|
8
|
+
expect(matches.all? { |m| m.pattern == 'year' }).to eql(true)
|
9
9
|
end
|
10
10
|
|
11
11
|
it 'finds the correct matches' do
|
12
|
-
matches.count.
|
13
|
-
matches[0].token.
|
12
|
+
expect(matches.count).to eq(1)
|
13
|
+
expect(matches[0].token).to eq '1998'
|
14
14
|
end
|
15
15
|
end
|
data/spec/omnimatch_spec.rb
CHANGED
@@ -5,38 +5,38 @@ describe Zxcvbn::CrackTime do
|
|
5
5
|
|
6
6
|
describe '#entropy_to_crack_time' do
|
7
7
|
specify do
|
8
|
-
entropy_to_crack_time(15.433976574415976).
|
8
|
+
expect(entropy_to_crack_time(15.433976574415976)).to eq 2.2134000000000014
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
12
|
describe '#crack_time_to_score' do
|
13
13
|
context 'crack time less than 10 to the power 2' do
|
14
14
|
it 'returns 0' do
|
15
|
-
crack_time_to_score(90).
|
15
|
+
expect(crack_time_to_score(90)).to eq 0
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
19
|
context 'crack time in between 10**2 and 10**4' do
|
20
20
|
it 'returns 1' do
|
21
|
-
crack_time_to_score(5000).
|
21
|
+
expect(crack_time_to_score(5000)).to eq 1
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
25
|
context 'crack time in between 10**4 and 10**6' do
|
26
26
|
it 'returns 2' do
|
27
|
-
crack_time_to_score(500_000).
|
27
|
+
expect(crack_time_to_score(500_000)).to eq 2
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
31
|
context 'crack time in between 10**6 and 10**8' do
|
32
32
|
it 'returns 3' do
|
33
|
-
crack_time_to_score(50_000_000).
|
33
|
+
expect(crack_time_to_score(50_000_000)).to eq 3
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
37
|
context 'crack time above 10**8' do
|
38
38
|
it 'returns 4' do
|
39
|
-
crack_time_to_score(110_000_000).
|
39
|
+
expect(crack_time_to_score(110_000_000)).to eq 4
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
@@ -52,7 +52,7 @@ describe Zxcvbn::CrackTime do
|
|
52
52
|
context 'when less than a minute' do
|
53
53
|
it 'should return instant' do
|
54
54
|
[0, minute_to_seconds - 1].each do |seconds|
|
55
|
-
display_time(seconds).
|
55
|
+
expect(display_time(seconds)).to eql 'instant'
|
56
56
|
end
|
57
57
|
end
|
58
58
|
end
|
@@ -60,7 +60,7 @@ describe Zxcvbn::CrackTime do
|
|
60
60
|
context 'when less than an hour' do
|
61
61
|
it 'should return a readable time in minutes' do
|
62
62
|
[60, (hour_to_seconds - 1)].each do |seconds|
|
63
|
-
display_time(seconds).
|
63
|
+
expect(display_time(seconds)).to match(/[0-9]+ minutes$/)
|
64
64
|
end
|
65
65
|
end
|
66
66
|
end
|
@@ -68,7 +68,7 @@ describe Zxcvbn::CrackTime do
|
|
68
68
|
context 'when less than a day' do
|
69
69
|
it 'should return a readable time in hours' do
|
70
70
|
[hour_to_seconds, (day_to_seconds - 1)].each do |seconds|
|
71
|
-
display_time(seconds).
|
71
|
+
expect(display_time(seconds)).to match(/[0-9]+ hours$/)
|
72
72
|
end
|
73
73
|
end
|
74
74
|
end
|
@@ -76,7 +76,7 @@ describe Zxcvbn::CrackTime do
|
|
76
76
|
context 'when less than 31 days' do
|
77
77
|
it 'should return a readable time in days' do
|
78
78
|
[day_to_seconds, month_to_seconds - 1].each do |seconds|
|
79
|
-
display_time(seconds).
|
79
|
+
expect(display_time(seconds)).to match(/[0-9]+ days$/)
|
80
80
|
end
|
81
81
|
end
|
82
82
|
end
|
@@ -84,7 +84,7 @@ describe Zxcvbn::CrackTime do
|
|
84
84
|
context 'when less than 1 year' do
|
85
85
|
it 'should return a readable time in days' do
|
86
86
|
[month_to_seconds, (year_to_seconds - 1)].each do |seconds|
|
87
|
-
display_time(seconds).
|
87
|
+
expect(display_time(seconds)).to match(/[0-9]+ months$/)
|
88
88
|
end
|
89
89
|
end
|
90
90
|
end
|
@@ -92,14 +92,14 @@ describe Zxcvbn::CrackTime do
|
|
92
92
|
context 'when less than a century' do
|
93
93
|
it 'should return a readable time in days' do
|
94
94
|
[year_to_seconds, (century_to_seconds - 1)].each do |seconds|
|
95
|
-
display_time(seconds).
|
95
|
+
expect(display_time(seconds)).to match(/[0-9]+ years$/)
|
96
96
|
end
|
97
97
|
end
|
98
98
|
end
|
99
99
|
|
100
100
|
context 'when a century or more' do
|
101
101
|
it 'should return centuries' do
|
102
|
-
display_time(century_to_seconds).
|
102
|
+
expect(display_time(century_to_seconds)).to eql 'centuries'
|
103
103
|
end
|
104
104
|
end
|
105
105
|
end
|
@@ -15,7 +15,7 @@ describe Zxcvbn::Entropy do
|
|
15
15
|
describe '#repeat_entropy' do
|
16
16
|
it 'returns the correct value' do
|
17
17
|
match = Zxcvbn::Match.new(:token => '2222')
|
18
|
-
entropy.repeat_entropy(match).
|
18
|
+
expect(entropy.repeat_entropy(match)).to eq 5.321928094887363
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
@@ -27,7 +27,7 @@ describe Zxcvbn::Entropy do
|
|
27
27
|
let(:token) { token }
|
28
28
|
|
29
29
|
it 'returns the correct value' do
|
30
|
-
entropy.sequence_entropy(match).
|
30
|
+
expect(entropy.sequence_entropy(match)).to eq 3.807354922057604
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
@@ -36,7 +36,7 @@ describe Zxcvbn::Entropy do
|
|
36
36
|
let(:token) { '23456' }
|
37
37
|
|
38
38
|
it 'returns the correct value' do
|
39
|
-
entropy.sequence_entropy(match).
|
39
|
+
expect(entropy.sequence_entropy(match)).to eq 5.643856189774725
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -44,7 +44,7 @@ describe Zxcvbn::Entropy do
|
|
44
44
|
let(:token) { 'bcdef' }
|
45
45
|
|
46
46
|
it 'returns the correct value' do
|
47
|
-
entropy.sequence_entropy(match).
|
47
|
+
expect(entropy.sequence_entropy(match)).to eq 7.022367813028454
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
@@ -52,7 +52,7 @@ describe Zxcvbn::Entropy do
|
|
52
52
|
let(:token) { 'BCDEF' }
|
53
53
|
|
54
54
|
it 'returns the correct value' do
|
55
|
-
entropy.sequence_entropy(match).
|
55
|
+
expect(entropy.sequence_entropy(match)).to eq 8.022367813028454
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
@@ -61,7 +61,7 @@ describe Zxcvbn::Entropy do
|
|
61
61
|
let(:token) { 'bcdef' }
|
62
62
|
|
63
63
|
it 'returns the correct value' do
|
64
|
-
entropy.sequence_entropy(match).
|
64
|
+
expect(entropy.sequence_entropy(match)).to eq 8.022367813028454
|
65
65
|
end
|
66
66
|
end
|
67
67
|
end
|
@@ -69,13 +69,13 @@ describe Zxcvbn::Entropy do
|
|
69
69
|
describe '#digits_entropy' do
|
70
70
|
it 'returns the correct value' do
|
71
71
|
match = Zxcvbn::Match.new(:token => '12345678')
|
72
|
-
entropy.digits_entropy(match).
|
72
|
+
expect(entropy.digits_entropy(match)).to eq 26.5754247590989
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
76
76
|
describe '#year_entropy' do
|
77
77
|
it 'returns the correct value' do
|
78
|
-
entropy.year_entropy(nil).
|
78
|
+
expect(entropy.year_entropy(nil)).to eq 6.894817763307944
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
@@ -83,21 +83,21 @@ describe Zxcvbn::Entropy do
|
|
83
83
|
context 'with a two digit year' do
|
84
84
|
it 'returns the correct value' do
|
85
85
|
match = Zxcvbn::Match.new(:year => 98)
|
86
|
-
entropy.date_entropy(match).
|
86
|
+
expect(entropy.date_entropy(match)).to eq 15.183015000882756
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
90
|
context 'with a four digit year' do
|
91
91
|
it 'returns the correct value' do
|
92
92
|
match = Zxcvbn::Match.new(:year => 2012)
|
93
|
-
entropy.date_entropy(match).
|
93
|
+
expect(entropy.date_entropy(match)).to eq 15.433976574415976
|
94
94
|
end
|
95
95
|
end
|
96
96
|
|
97
97
|
context 'with a separator' do
|
98
98
|
it 'returns the correct value' do
|
99
99
|
match = Zxcvbn::Match.new(:year => 2012, :separator => '/')
|
100
|
-
entropy.date_entropy(match).
|
100
|
+
expect(entropy.date_entropy(match)).to eq 17.433976574415976
|
101
101
|
end
|
102
102
|
end
|
103
103
|
end
|
@@ -112,42 +112,42 @@ describe Zxcvbn::Entropy do
|
|
112
112
|
let(:token) { 'you' }
|
113
113
|
let(:rank) { 1 }
|
114
114
|
|
115
|
-
specify { calculated_entropy.
|
115
|
+
specify { expect(calculated_entropy).to eq 0 }
|
116
116
|
end
|
117
117
|
|
118
118
|
context 'with all upper case characters' do
|
119
119
|
let(:token) { 'YOU' }
|
120
120
|
let(:rank) { 1 }
|
121
121
|
|
122
|
-
specify { calculated_entropy.
|
122
|
+
specify { expect(calculated_entropy).to eq 1 }
|
123
123
|
end
|
124
124
|
|
125
125
|
context 'starting with uppercase' do
|
126
126
|
let(:token) { 'You' }
|
127
127
|
let(:rank) { 1 }
|
128
128
|
|
129
|
-
specify { calculated_entropy.
|
129
|
+
specify { expect(calculated_entropy).to eq 1 }
|
130
130
|
end
|
131
131
|
|
132
132
|
context 'starting with uppercase' do
|
133
133
|
let(:token) { 'yoU' }
|
134
134
|
let(:rank) { 1 }
|
135
135
|
|
136
|
-
specify { calculated_entropy.
|
136
|
+
specify { expect(calculated_entropy).to eq 1 }
|
137
137
|
end
|
138
138
|
|
139
139
|
context 'mixed upper and lower' do
|
140
140
|
let(:token) { 'tEsTiNg' }
|
141
141
|
let(:rank) { 1 }
|
142
142
|
|
143
|
-
specify { calculated_entropy.
|
143
|
+
specify { expect(calculated_entropy).to eq 6 }
|
144
144
|
end
|
145
145
|
|
146
146
|
context 'starting with digits' do
|
147
147
|
let(:token) { '12345' }
|
148
148
|
let(:rank) { 1 }
|
149
149
|
|
150
|
-
specify { calculated_entropy.
|
150
|
+
specify { expect(calculated_entropy).to eq 0 }
|
151
151
|
end
|
152
152
|
|
153
153
|
context 'extra l33t entropy' do
|
@@ -156,7 +156,7 @@ describe Zxcvbn::Entropy do
|
|
156
156
|
let(:l33t) { true }
|
157
157
|
let(:sub) { {'3' => 'e', '0' => 'o'} }
|
158
158
|
|
159
|
-
specify { calculated_entropy.
|
159
|
+
specify { expect(calculated_entropy).to eq 1 }
|
160
160
|
end
|
161
161
|
end
|
162
162
|
|
@@ -167,7 +167,7 @@ describe Zxcvbn::Entropy do
|
|
167
167
|
it 'should return the correct entropy' do
|
168
168
|
match.graph = 'qwerty'
|
169
169
|
|
170
|
-
entropy.spatial_entropy(match).
|
170
|
+
expect(entropy.spatial_entropy(match)).to eql 11.562242424221074
|
171
171
|
end
|
172
172
|
end
|
173
173
|
|
@@ -175,7 +175,7 @@ describe Zxcvbn::Entropy do
|
|
175
175
|
it 'should return the correct entropy' do
|
176
176
|
match.graph = 'dvorak'
|
177
177
|
|
178
|
-
entropy.spatial_entropy(match).
|
178
|
+
expect(entropy.spatial_entropy(match)).to eql 11.562242424221074
|
179
179
|
end
|
180
180
|
end
|
181
181
|
|
@@ -183,7 +183,7 @@ describe Zxcvbn::Entropy do
|
|
183
183
|
it 'should return the correct entropy' do
|
184
184
|
match.graph = 'keypad'
|
185
185
|
|
186
|
-
entropy.spatial_entropy(match).
|
186
|
+
expect(entropy.spatial_entropy(match)).to eql 9.05528243550119
|
187
187
|
end
|
188
188
|
end
|
189
189
|
|
@@ -191,7 +191,7 @@ describe Zxcvbn::Entropy do
|
|
191
191
|
it 'should return the correct entropy' do
|
192
192
|
match.turns = 5
|
193
193
|
|
194
|
-
entropy.spatial_entropy(match).
|
194
|
+
expect(entropy.spatial_entropy(match)).to eql 21.761397858718993
|
195
195
|
end
|
196
196
|
end
|
197
197
|
|
@@ -199,7 +199,7 @@ describe Zxcvbn::Entropy do
|
|
199
199
|
it 'should return the correct entropy' do
|
200
200
|
match.shiffted_count = 5
|
201
201
|
|
202
|
-
entropy.spatial_entropy(match).
|
202
|
+
expect(entropy.spatial_entropy(match)).to eql 9.05528243550119
|
203
203
|
end
|
204
204
|
end
|
205
205
|
|
@@ -208,7 +208,7 @@ describe Zxcvbn::Entropy do
|
|
208
208
|
match.shiffted_count = 5
|
209
209
|
match.turns = 5
|
210
210
|
|
211
|
-
entropy.spatial_entropy(match).
|
211
|
+
expect(entropy.spatial_entropy(match)).to eql 21.761397858718993
|
212
212
|
end
|
213
213
|
end
|
214
214
|
end
|