Skip to content

Commit e8539d3

Browse files
committed
Add comprehensive tests for Data class
Created test suite for previously untested Data class covering: Initialization: - Dictionary loading (5 expected dictionaries) - Adjacency graph loading (4 expected graphs) - Trie building for all dictionaries - Graph statistics pre-computation Graph statistics: - Verification of average_degree values - Verification of starting_positions values - Correctness checks for qwerty and keypad Ranked dictionaries: - Word ranking verification - Common password frequency checks Custom word lists: - Dictionary addition via add_word_list - Trie generation for custom dictionaries - Word searchability via tries - Empty list handling Test count increased from 271 to 291 examples (20 new tests).
1 parent 13496b2 commit e8539d3

File tree

1 file changed

+130
-0
lines changed

1 file changed

+130
-0
lines changed

spec/data_spec.rb

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# frozen_string_literal: true
2+
3+
require 'spec_helper'
4+
5+
RSpec.describe Zxcvbn::Data do
6+
let(:data) { described_class.new }
7+
8+
describe '#initialize' do
9+
it 'loads ranked dictionaries' do
10+
expect(data.ranked_dictionaries).to be_a(Hash)
11+
expect(data.ranked_dictionaries).not_to be_empty
12+
end
13+
14+
it 'loads all expected dictionaries' do
15+
expect(data.ranked_dictionaries.keys).to include('english', 'female_names', 'male_names', 'passwords', 'surnames')
16+
end
17+
18+
it 'loads adjacency graphs' do
19+
expect(data.adjacency_graphs).to be_a(Hash)
20+
expect(data.adjacency_graphs).not_to be_empty
21+
end
22+
23+
it 'loads expected adjacency graphs' do
24+
expect(data.adjacency_graphs.keys).to include('qwerty', 'dvorak', 'keypad', 'mac_keypad')
25+
end
26+
27+
it 'builds dictionary tries' do
28+
expect(data.dictionary_tries).to be_a(Hash)
29+
expect(data.dictionary_tries).not_to be_empty
30+
end
31+
32+
it 'builds tries for all dictionaries' do
33+
expect(data.dictionary_tries.keys).to match_array(data.ranked_dictionaries.keys)
34+
end
35+
36+
it 'creates Trie objects' do
37+
data.dictionary_tries.each_value do |trie|
38+
expect(trie).to be_a(Zxcvbn::Trie)
39+
end
40+
end
41+
42+
it 'computes graph statistics' do
43+
expect(data.graph_stats).to be_a(Hash)
44+
expect(data.graph_stats).not_to be_empty
45+
end
46+
47+
it 'computes stats for all graphs' do
48+
expect(data.graph_stats.keys).to match_array(data.adjacency_graphs.keys)
49+
end
50+
51+
it 'includes average_degree in graph stats' do
52+
data.graph_stats.each_value do |stats|
53+
expect(stats).to have_key(:average_degree)
54+
expect(stats[:average_degree]).to be_a(Float)
55+
expect(stats[:average_degree]).to be > 0
56+
end
57+
end
58+
59+
it 'includes starting_positions in graph stats' do
60+
data.graph_stats.each_value do |stats|
61+
expect(stats).to have_key(:starting_positions)
62+
expect(stats[:starting_positions]).to be_a(Integer)
63+
expect(stats[:starting_positions]).to be > 0
64+
end
65+
end
66+
end
67+
68+
describe '#ranked_dictionaries' do
69+
it 'returns dictionaries with word rankings' do
70+
dict = data.ranked_dictionaries['english']
71+
expect(dict).to be_a(Hash)
72+
expect(dict.values.first).to be_a(Integer)
73+
end
74+
75+
it 'ranks common words lower (more frequent)' do
76+
dict = data.ranked_dictionaries['passwords']
77+
# Common passwords should have low rank numbers
78+
expect(dict['password']).to be_a(Integer)
79+
expect(dict['password']).to be < 100
80+
end
81+
end
82+
83+
describe '#add_word_list' do
84+
it 'adds a custom dictionary' do
85+
data.add_word_list('custom', %w[foo bar baz])
86+
expect(data.ranked_dictionaries).to have_key('custom')
87+
end
88+
89+
it 'ranks the custom dictionary' do
90+
data.add_word_list('custom', %w[foo bar baz])
91+
dict = data.ranked_dictionaries['custom']
92+
expect(dict['foo']).to be_a(Integer)
93+
expect(dict['bar']).to be_a(Integer)
94+
expect(dict['baz']).to be_a(Integer)
95+
end
96+
97+
it 'builds a trie for the custom dictionary' do
98+
data.add_word_list('custom', %w[foo bar baz])
99+
expect(data.dictionary_tries).to have_key('custom')
100+
expect(data.dictionary_tries['custom']).to be_a(Zxcvbn::Trie)
101+
end
102+
103+
it 'makes custom words searchable via trie' do
104+
data.add_word_list('custom', %w[test])
105+
trie = data.dictionary_tries['custom']
106+
results = trie.search_prefixes('testing', 0)
107+
expect(results).not_to be_empty
108+
expect(results.first[0]).to eq('test')
109+
end
110+
111+
it 'handles empty word lists' do
112+
data.add_word_list('empty', [])
113+
expect(data.ranked_dictionaries['empty']).to be_empty
114+
end
115+
end
116+
117+
describe '#graph_stats' do
118+
it 'has correct values for qwerty keyboard' do
119+
stats = data.graph_stats['qwerty']
120+
expect(stats[:average_degree]).to be_within(0.01).of(4.6)
121+
expect(stats[:starting_positions]).to eq(94)
122+
end
123+
124+
it 'has correct values for keypad' do
125+
stats = data.graph_stats['keypad']
126+
expect(stats[:average_degree]).to be_within(0.01).of(5.07)
127+
expect(stats[:starting_positions]).to eq(15)
128+
end
129+
end
130+
end

0 commit comments

Comments
 (0)