keyrack 0.3.1 → 0.3.2
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/.altrc +4 -0
- data/LICENSE.txt +2 -2
- data/keyrack.gemspec +1 -0
- data/lib/keyrack/group.rb +20 -1
- data/lib/keyrack/runner.rb +7 -1
- data/lib/keyrack/ui/console.rb +77 -20
- data/lib/keyrack/version.rb +1 -1
- data/test/unit/test_group.rb +20 -0
- data/test/unit/test_runner.rb +15 -1
- data/test/unit/ui/test_console.rb +84 -23
- metadata +24 -38
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c899e9fa3abeb7e46c4774a0852f6c0b7304a00b
|
4
|
+
data.tar.gz: 97aaad1cb5d2f3ca9396360508449d29737933fb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 658fb34bcb9dd875725135a614a5e626a0f911052594ac2e3cee0513bea1ebeb1ac20cf5c1696cca021944e9c5e6eca77fb57050b08538b745c481e9b67c0093
|
7
|
+
data.tar.gz: 00e69ca428ed8e7dafb04186dad25bb69f220e453e92864051e09bd762ca20037d0a78227796b32843cccd625f5b212600f28545428327ebf756238caee7e017
|
data/.altrc
ADDED
data/LICENSE.txt
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright (c) 2012 Jeremy Stephens
|
1
|
+
Copyright (c) 2012-2013 Jeremy Stephens
|
2
2
|
|
3
3
|
MIT License
|
4
4
|
|
@@ -19,4 +19,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
19
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
20
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
21
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/keyrack.gemspec
CHANGED
@@ -11,6 +11,7 @@ Gem::Specification.new do |gem|
|
|
11
11
|
gem.description = %q{Simple password manager with local/remote database storage and scrypt encryption.}
|
12
12
|
gem.summary = %q{Simple password manager}
|
13
13
|
gem.homepage = "http://github.com/viking/keyrack"
|
14
|
+
gem.license = "MIT"
|
14
15
|
|
15
16
|
gem.files = `git ls-files`.split($/)
|
16
17
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
data/lib/keyrack/group.rb
CHANGED
@@ -190,7 +190,17 @@ module Keyrack
|
|
190
190
|
raise GroupError,
|
191
191
|
"site (#{site.name.inspect}, #{site.username.inspect}) already exists"
|
192
192
|
end
|
193
|
-
|
193
|
+
|
194
|
+
index = sites.length
|
195
|
+
sites.each_with_index do |other, i|
|
196
|
+
if other.name > site.name ||
|
197
|
+
(other.name == site.name && other.username > site.username)
|
198
|
+
index = i
|
199
|
+
break
|
200
|
+
end
|
201
|
+
end
|
202
|
+
sites.insert(index, site)
|
203
|
+
|
194
204
|
add_site_hooks_for(site)
|
195
205
|
end
|
196
206
|
|
@@ -201,7 +211,16 @@ module Keyrack
|
|
201
211
|
if groups.has_key?(group.name)
|
202
212
|
raise GroupError, "group already exists"
|
203
213
|
end
|
214
|
+
|
215
|
+
# wasteful but easy hash ordering
|
204
216
|
groups[group.name] = group
|
217
|
+
keys = groups.keys.sort!
|
218
|
+
new_groups = keys.inject({}) do |hsh, key|
|
219
|
+
hsh[key] = groups[key]
|
220
|
+
hsh
|
221
|
+
end
|
222
|
+
@attributes['groups'] = new_groups
|
223
|
+
|
205
224
|
add_group_hooks_for(group)
|
206
225
|
end
|
207
226
|
|
data/lib/keyrack/runner.rb
CHANGED
@@ -50,17 +50,23 @@ module Keyrack
|
|
50
50
|
|
51
51
|
def main_loop
|
52
52
|
group_tree = [@database.top_group]
|
53
|
+
open = false
|
53
54
|
loop do
|
54
55
|
current_group = group_tree.last
|
55
56
|
menu_options = {
|
56
57
|
:group => current_group,
|
57
58
|
:at_top => at_top?(current_group),
|
58
59
|
:dirty => @database.dirty?,
|
59
|
-
:enable_up => group_tree.length > 2
|
60
|
+
:enable_up => group_tree.length > 2,
|
61
|
+
:open => open
|
60
62
|
}
|
61
63
|
choice = @ui.menu(menu_options)
|
62
64
|
|
63
65
|
case choice
|
66
|
+
when :open
|
67
|
+
open = true
|
68
|
+
when :collapse
|
69
|
+
open = false
|
64
70
|
when :new
|
65
71
|
result = @ui.get_new_entry
|
66
72
|
next if result.nil?
|
data/lib/keyrack/ui/console.rb
CHANGED
@@ -16,14 +16,31 @@ module Keyrack
|
|
16
16
|
current_group = options[:group]
|
17
17
|
dirty = options[:dirty]
|
18
18
|
at_top = options[:at_top]
|
19
|
+
open = options[:open]
|
19
20
|
|
20
21
|
choices = {'n' => :new, 'q' => :quit, 'm' => :mode}
|
21
|
-
entry_choices = print_entries(
|
22
|
-
|
22
|
+
entry_choices = print_entries({
|
23
|
+
:group => current_group,
|
24
|
+
:title => at_top ? "Keyrack Main Menu" : current_group.name,
|
25
|
+
:open => open
|
26
|
+
})
|
23
27
|
choices.update(entry_choices)
|
24
28
|
|
25
29
|
@highline.say("Mode: #{@mode}")
|
26
|
-
commands = "Commands:
|
30
|
+
commands = "Commands:"
|
31
|
+
|
32
|
+
if at_top
|
33
|
+
if open
|
34
|
+
choices['c'] = :collapse
|
35
|
+
commands << " [c]ollapse"
|
36
|
+
else
|
37
|
+
choices['o'] = :open
|
38
|
+
commands << " [o]pen"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
commands << " [n]ew"
|
43
|
+
|
27
44
|
if !current_group.sites.empty?
|
28
45
|
choices['e'] = :edit
|
29
46
|
commands << " [e]dit"
|
@@ -133,7 +150,10 @@ module Keyrack
|
|
133
150
|
|
134
151
|
def choose_entry_to_edit(group)
|
135
152
|
choices = {'c' => :cancel}
|
136
|
-
entry_choices = print_entries(
|
153
|
+
entry_choices = print_entries({
|
154
|
+
:group => group,
|
155
|
+
:title => "Choose entry"
|
156
|
+
})
|
137
157
|
choices.update(entry_choices)
|
138
158
|
|
139
159
|
@highline.say("c. Cancel")
|
@@ -232,31 +252,68 @@ module Keyrack
|
|
232
252
|
|
233
253
|
private
|
234
254
|
|
235
|
-
def print_entries(
|
255
|
+
def print_entries(options)
|
256
|
+
group = options[:group]
|
257
|
+
title = options[:title]
|
258
|
+
open = options[:open]
|
259
|
+
|
236
260
|
selections = []
|
237
261
|
max_width = 0
|
238
262
|
choices = {}
|
239
263
|
selection_index = 1
|
240
|
-
group.group_names.each do |group_name|
|
241
|
-
choices[selection_index.to_s] = {:group => group_name}
|
242
264
|
|
243
|
-
|
244
|
-
|
245
|
-
|
265
|
+
if open
|
266
|
+
queue = [group]
|
267
|
+
sites = []
|
268
|
+
until queue.empty?
|
269
|
+
group = queue.shift
|
270
|
+
group.group_names.each do |group_name|
|
271
|
+
queue.push(group.group(group_name))
|
272
|
+
end
|
273
|
+
group.sites.each do |site|
|
274
|
+
sites.push([group.name, site])
|
275
|
+
end
|
276
|
+
end
|
277
|
+
sites.sort! do |a, b|
|
278
|
+
if a[1].name == b[1].name
|
279
|
+
a[1].username <=> b[1].username
|
280
|
+
else
|
281
|
+
a[1].name <=> b[1].name
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
sites.each do |(group, site)|
|
286
|
+
choices[selection_index.to_s] = {:site => site}
|
246
287
|
|
247
|
-
|
248
|
-
|
249
|
-
|
288
|
+
text = "%s [%s] (%s)" % [site.name, site.username, group]
|
289
|
+
width = text.length
|
290
|
+
selections.push({:width => width, :text => text})
|
250
291
|
|
251
|
-
|
252
|
-
|
292
|
+
max_width = width if width > max_width
|
293
|
+
selection_index += 1
|
294
|
+
end
|
295
|
+
else
|
296
|
+
group.group_names.each do |group_name|
|
297
|
+
choices[selection_index.to_s] = {:group => group_name}
|
253
298
|
|
254
|
-
|
255
|
-
|
256
|
-
|
299
|
+
text = @highline.color(group_name, :green)
|
300
|
+
width = group_name.length
|
301
|
+
selections.push({:width => width, :text => text})
|
257
302
|
|
258
|
-
|
259
|
-
|
303
|
+
max_width = width if width > max_width
|
304
|
+
selection_index += 1
|
305
|
+
end
|
306
|
+
|
307
|
+
group.sites.each do |site|
|
308
|
+
choices[selection_index.to_s] = {:site => site}
|
309
|
+
|
310
|
+
text = "%s [%s]" % [site.name, site.username]
|
311
|
+
width = text.length
|
312
|
+
selections.push({:width => width, :text => text})
|
313
|
+
|
314
|
+
max_width = width if width > max_width
|
315
|
+
selection_index += 1
|
316
|
+
end
|
260
317
|
end
|
261
318
|
|
262
319
|
title = {
|
data/lib/keyrack/version.rb
CHANGED
data/test/unit/test_group.rb
CHANGED
@@ -702,4 +702,24 @@ class TestGroup < Test::Unit::TestCase
|
|
702
702
|
}
|
703
703
|
assert_equal expected, group.to_h
|
704
704
|
end
|
705
|
+
|
706
|
+
test "auto-sort sites" do
|
707
|
+
group = new_group("Starships")
|
708
|
+
site_1 = new_site("Enterprise", "riker", "minuet")
|
709
|
+
site_2 = new_site("Enterprise", "picard", "livingston")
|
710
|
+
site_3 = new_site("Bortas", "gowron", "bat'leth")
|
711
|
+
group.add_site(site_1)
|
712
|
+
group.add_site(site_2)
|
713
|
+
group.add_site(site_3)
|
714
|
+
assert_equal([site_3, site_2, site_1], group.sites)
|
715
|
+
end
|
716
|
+
|
717
|
+
test "auto-sort groups" do
|
718
|
+
group = new_group("Starships")
|
719
|
+
subgroup_1 = new_group("Klingon")
|
720
|
+
subgroup_2 = new_group("Federation")
|
721
|
+
group.add_group(subgroup_1)
|
722
|
+
group.add_group(subgroup_2)
|
723
|
+
assert_equal([subgroup_2, subgroup_1], group.groups.values)
|
724
|
+
end
|
705
725
|
end
|
data/test/unit/test_runner.rb
CHANGED
@@ -20,7 +20,7 @@ class TestRunner < Test::Unit::TestCase
|
|
20
20
|
|
21
21
|
@menu_options = {
|
22
22
|
:group => @top_group, :at_top => true,
|
23
|
-
:enable_up => false, :dirty => false
|
23
|
+
:enable_up => false, :dirty => false, :open => false
|
24
24
|
}
|
25
25
|
end
|
26
26
|
|
@@ -52,6 +52,20 @@ class TestRunner < Test::Unit::TestCase
|
|
52
52
|
runner = Keyrack::Runner.new(["-d", @keyrack_dir])
|
53
53
|
end
|
54
54
|
|
55
|
+
test "opening and collapsing" do
|
56
|
+
setup_config
|
57
|
+
|
58
|
+
seq = SequenceHelper.new('ui sequence')
|
59
|
+
seq << @database.expects(:dirty?).returns(false)
|
60
|
+
seq << @console.expects(:menu).with(@menu_options).returns(:open)
|
61
|
+
seq << @database.expects(:dirty?).returns(false)
|
62
|
+
seq << @console.expects(:menu).with(@menu_options.merge(:open => true)).returns(:collapse)
|
63
|
+
seq << @database.expects(:dirty?).returns(false)
|
64
|
+
seq << @console.expects(:menu).with(@menu_options).returns(:quit)
|
65
|
+
|
66
|
+
runner = Keyrack::Runner.new(["-d", @keyrack_dir])
|
67
|
+
end
|
68
|
+
|
55
69
|
test "add site" do
|
56
70
|
setup_config
|
57
71
|
|
@@ -19,7 +19,7 @@ class TestConsole < Test::Unit::TestCase
|
|
19
19
|
})
|
20
20
|
@top_group = stub('top group', {
|
21
21
|
:sites => [@twitter, @google_1, @google_2],
|
22
|
-
:group_names => []
|
22
|
+
:group_names => [], :name => 'top'
|
23
23
|
})
|
24
24
|
@top_group.stubs(:site).with(0).returns(@twitter)
|
25
25
|
@top_group.stubs(:site).with(1).returns(@google_1)
|
@@ -42,10 +42,10 @@ class TestConsole < Test::Unit::TestCase
|
|
42
42
|
@highline.expects(:say).with("2. Google [catfan]")
|
43
43
|
@highline.expects(:say).with("3. Google [dogfan]")
|
44
44
|
@highline.expects(:say).with("Mode: copy")
|
45
|
-
@highline.expects(:say).with("Commands: [n]ew [e]dit [g]roup [m]ode [q]uit")
|
45
|
+
@highline.expects(:say).with("Commands: [o]pen [n]ew [e]dit [g]roup [m]ode [q]uit")
|
46
46
|
|
47
47
|
question = mock('question')
|
48
|
-
@highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 e g}) }).returns('1')
|
48
|
+
@highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 o e g}) }).returns('1')
|
49
49
|
Clipboard.expects(:copy).with('secret')
|
50
50
|
@highline.expects(:say).with("The password has been copied to your clipboard.")
|
51
51
|
assert_nil @console.menu(:group => @top_group, :at_top => true)
|
@@ -59,9 +59,9 @@ class TestConsole < Test::Unit::TestCase
|
|
59
59
|
@highline.expects(:say).with("2. Google [catfan]")
|
60
60
|
@highline.expects(:say).with("3. Google [dogfan]")
|
61
61
|
@highline.expects(:say).with("Mode: print")
|
62
|
-
@highline.expects(:say).with("Commands: [n]ew [e]dit [g]roup [m]ode [q]uit")
|
62
|
+
@highline.expects(:say).with("Commands: [o]pen [n]ew [e]dit [g]roup [m]ode [q]uit")
|
63
63
|
|
64
|
-
@highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 e g}) }).returns('1')
|
64
|
+
@highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 o e g}) }).returns('1')
|
65
65
|
@highline.expects(:color).with('secret', instance_of(Symbol)).
|
66
66
|
returns('secret').in_sequence(seq)
|
67
67
|
question = mock do
|
@@ -79,14 +79,75 @@ class TestConsole < Test::Unit::TestCase
|
|
79
79
|
assert_nil @console.menu(:group => @top_group, :at_top => true)
|
80
80
|
end
|
81
81
|
|
82
|
+
test "select open from menu" do
|
83
|
+
@highline.expects(:say).with("=== Keyrack Main Menu ===")
|
84
|
+
@highline.expects(:say).with("1. Twitter [tweeb]")
|
85
|
+
@highline.expects(:say).with("2. Google [catfan]")
|
86
|
+
@highline.expects(:say).with("3. Google [dogfan]")
|
87
|
+
@highline.expects(:say).with("Mode: copy")
|
88
|
+
@highline.expects(:say).with("Commands: [o]pen [n]ew [e]dit [g]roup [m]ode [q]uit")
|
89
|
+
@highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 o e g}) }).returns('o')
|
90
|
+
assert_equal :open, @console.menu(:group => @top_group, :at_top => true)
|
91
|
+
end
|
92
|
+
|
93
|
+
test "select collapse from menu" do
|
94
|
+
@highline.expects(:say).with("=== Keyrack Main Menu ===")
|
95
|
+
@highline.expects(:say).with("1. Google [catfan] (top)")
|
96
|
+
@highline.expects(:say).with("2. Google [dogfan] (top)")
|
97
|
+
@highline.expects(:say).with("3. Twitter [tweeb] (top)")
|
98
|
+
@highline.expects(:say).with("Mode: copy")
|
99
|
+
@highline.expects(:say).with("Commands: [c]ollapse [n]ew [e]dit [g]roup [m]ode [q]uit")
|
100
|
+
@highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 c e g}) }).returns('c')
|
101
|
+
assert_equal :collapse, @console.menu(:group => @top_group, :at_top => true, :open => true)
|
102
|
+
end
|
103
|
+
|
104
|
+
test "open menu" do
|
105
|
+
site_1 = stub('site 1', {
|
106
|
+
:name => 'Yo',
|
107
|
+
:username => 'Dawg',
|
108
|
+
:password => 'Xzibit'
|
109
|
+
})
|
110
|
+
group_1 = stub('group 1', {
|
111
|
+
:sites => [site_1], :group_names => [],
|
112
|
+
:name => 'Sup'
|
113
|
+
})
|
114
|
+
site_2 = stub('site 2', {
|
115
|
+
:name => "Don't",
|
116
|
+
:username => 'Taze',
|
117
|
+
:password => 'mebro'
|
118
|
+
})
|
119
|
+
group_2 = stub('group 2', {
|
120
|
+
:sites => [site_2], :group_names => [],
|
121
|
+
:name => 'Holmes'
|
122
|
+
})
|
123
|
+
@top_group.stubs(:group_names).returns(['Sup', 'Holmes'])
|
124
|
+
@top_group.stubs(:group).with('Sup').returns(group_1)
|
125
|
+
@top_group.stubs(:group).with('Holmes').returns(group_2)
|
126
|
+
|
127
|
+
@highline.expects(:say).with("=== Keyrack Main Menu ===")
|
128
|
+
@highline.expects(:say).with("1. Don't [Taze] (Holmes)")
|
129
|
+
@highline.expects(:say).with("2. Google [catfan] (top)")
|
130
|
+
@highline.expects(:say).with("3. Google [dogfan] (top)")
|
131
|
+
@highline.expects(:say).with("4. Twitter [tweeb] (top)")
|
132
|
+
@highline.expects(:say).with("5. Yo [Dawg] (Sup)")
|
133
|
+
@highline.expects(:say).with("Mode: copy")
|
134
|
+
@highline.expects(:say).with("Commands: [c]ollapse [n]ew [e]dit [g]roup [m]ode [q]uit")
|
135
|
+
|
136
|
+
@highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 4 5 c e g}) }).returns('1')
|
137
|
+
Clipboard.expects(:copy).with('mebro')
|
138
|
+
@highline.expects(:say).with("The password has been copied to your clipboard.")
|
139
|
+
|
140
|
+
assert_nil(@console.menu(:group => @top_group, :at_top => true, :open => true))
|
141
|
+
end
|
142
|
+
|
82
143
|
test "select new from menu" do
|
83
144
|
@highline.expects(:say).with("=== Keyrack Main Menu ===")
|
84
145
|
@highline.expects(:say).with("1. Twitter [tweeb]")
|
85
146
|
@highline.expects(:say).with("2. Google [catfan]")
|
86
147
|
@highline.expects(:say).with("3. Google [dogfan]")
|
87
148
|
@highline.expects(:say).with("Mode: copy")
|
88
|
-
@highline.expects(:say).with("Commands: [n]ew [e]dit [g]roup [m]ode [q]uit")
|
89
|
-
@highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 e g}) }).returns('n')
|
149
|
+
@highline.expects(:say).with("Commands: [o]pen [n]ew [e]dit [g]roup [m]ode [q]uit")
|
150
|
+
@highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 o e g}) }).returns('n')
|
90
151
|
assert_equal :new, @console.menu(:group => @top_group, :at_top => true)
|
91
152
|
end
|
92
153
|
|
@@ -96,9 +157,9 @@ class TestConsole < Test::Unit::TestCase
|
|
96
157
|
@highline.expects(:say).with("2. Google [catfan]")
|
97
158
|
@highline.expects(:say).with("3. Google [dogfan]")
|
98
159
|
@highline.expects(:say).with("Mode: copy")
|
99
|
-
@highline.expects(:say).with("Commands: [n]ew [e]dit [g]roup [m]ode [q]uit")
|
160
|
+
@highline.expects(:say).with("Commands: [o]pen [n]ew [e]dit [g]roup [m]ode [q]uit")
|
100
161
|
question = mock('question')
|
101
|
-
question.expects(:in=).with(%w{n q m 1 2 3 e g})
|
162
|
+
question.expects(:in=).with(%w{n q m 1 2 3 o e g})
|
102
163
|
@highline.expects(:ask).yields(question).returns('e')
|
103
164
|
assert_equal :edit, @console.menu(:group => @top_group, :at_top => true)
|
104
165
|
end
|
@@ -109,8 +170,8 @@ class TestConsole < Test::Unit::TestCase
|
|
109
170
|
@highline.expects(:say).with("2. Google [catfan]")
|
110
171
|
@highline.expects(:say).with("3. Google [dogfan]")
|
111
172
|
@highline.expects(:say).with("Mode: copy")
|
112
|
-
@highline.expects(:say).with("Commands: [n]ew [e]dit [g]roup [m]ode [q]uit")
|
113
|
-
@highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 e g}) }).returns('q')
|
173
|
+
@highline.expects(:say).with("Commands: [o]pen [n]ew [e]dit [g]roup [m]ode [q]uit")
|
174
|
+
@highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 o e g}) }).returns('q')
|
114
175
|
assert_equal :quit, @console.menu(:group => @top_group, :at_top => true)
|
115
176
|
end
|
116
177
|
|
@@ -120,8 +181,8 @@ class TestConsole < Test::Unit::TestCase
|
|
120
181
|
@highline.expects(:say).with("2. Google [catfan]")
|
121
182
|
@highline.expects(:say).with("3. Google [dogfan]")
|
122
183
|
@highline.expects(:say).with("Mode: copy")
|
123
|
-
@highline.expects(:say).with("Commands: [n]ew [e]dit [g]roup [s]ave [m]ode [q]uit")
|
124
|
-
@highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 e g s}) }).returns('q')
|
184
|
+
@highline.expects(:say).with("Commands: [o]pen [n]ew [e]dit [g]roup [s]ave [m]ode [q]uit")
|
185
|
+
@highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 o e g s}) }).returns('q')
|
125
186
|
@highline.expects(:agree).with("Really quit? You have unsaved changes! [yn] ").returns(false)
|
126
187
|
assert_equal nil, @console.menu(:group => @top_group, :at_top => true, :dirty => true)
|
127
188
|
end
|
@@ -132,8 +193,8 @@ class TestConsole < Test::Unit::TestCase
|
|
132
193
|
@highline.expects(:say).with("2. Google [catfan]")
|
133
194
|
@highline.expects(:say).with("3. Google [dogfan]")
|
134
195
|
@highline.expects(:say).with("Mode: copy")
|
135
|
-
@highline.expects(:say).with("Commands: [n]ew [e]dit [g]roup [s]ave [m]ode [q]uit")
|
136
|
-
@highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 e g s}) }).returns('s')
|
196
|
+
@highline.expects(:say).with("Commands: [o]pen [n]ew [e]dit [g]roup [s]ave [m]ode [q]uit")
|
197
|
+
@highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 o e g s}) }).returns('s')
|
137
198
|
assert_equal :save, @console.menu(:group => @top_group, :at_top => true, :dirty => true)
|
138
199
|
end
|
139
200
|
|
@@ -150,8 +211,8 @@ class TestConsole < Test::Unit::TestCase
|
|
150
211
|
@highline.expects(:say).with("3. Google [catfan]")
|
151
212
|
@highline.expects(:say).with("4. Google [dogfan]")
|
152
213
|
@highline.expects(:say).with("Mode: copy")
|
153
|
-
@highline.expects(:say).with("Commands: [n]ew [e]dit [g]roup [m]ode [q]uit")
|
154
|
-
@highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 4 e g}) }).returns('1')
|
214
|
+
@highline.expects(:say).with("Commands: [o]pen [n]ew [e]dit [g]roup [m]ode [q]uit")
|
215
|
+
@highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 4 o e g}) }).returns('1')
|
155
216
|
assert_equal({:group => blargh}, @console.menu(:group => @top_group, :at_top => true))
|
156
217
|
end
|
157
218
|
|
@@ -415,8 +476,8 @@ class TestConsole < Test::Unit::TestCase
|
|
415
476
|
@highline.expects(:say).with("2. Google [catfan]")
|
416
477
|
@highline.expects(:say).with("3. Google [dogfan]")
|
417
478
|
@highline.expects(:say).with("Mode: copy")
|
418
|
-
@highline.expects(:say).with("Commands: [n]ew [e]dit [g]roup [m]ode [q]uit")
|
419
|
-
@highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 e g}) }).returns('m')
|
479
|
+
@highline.expects(:say).with("Commands: [o]pen [n]ew [e]dit [g]roup [m]ode [q]uit")
|
480
|
+
@highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 o e g}) }).returns('m')
|
420
481
|
assert_nil @console.menu(:group => @top_group, :at_top => true)
|
421
482
|
assert_equal :print, @console.mode
|
422
483
|
end
|
@@ -472,9 +533,9 @@ class TestConsole < Test::Unit::TestCase
|
|
472
533
|
@highline.expects(:say).with("2. Google [catfan]")
|
473
534
|
@highline.expects(:say).with("3. Google [dogfan]")
|
474
535
|
@highline.expects(:say).with("Mode: copy")
|
475
|
-
@highline.expects(:say).with("Commands: [n]ew [e]dit [g]roup [m]ode [q]uit")
|
536
|
+
@highline.expects(:say).with("Commands: [o]pen [n]ew [e]dit [g]roup [m]ode [q]uit")
|
476
537
|
|
477
|
-
@highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 e g}) }).returns('q')
|
538
|
+
@highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 o e g}) }).returns('q')
|
478
539
|
assert_equal :quit, @console.menu(:group => @top_group, :at_top => true)
|
479
540
|
end
|
480
541
|
|
@@ -487,9 +548,9 @@ class TestConsole < Test::Unit::TestCase
|
|
487
548
|
@highline.expects(:say).with("2. Google [catfan] ")
|
488
549
|
@highline.expects(:say).with("3. Google [dogfan]")
|
489
550
|
@highline.expects(:say).with("Mode: copy")
|
490
|
-
@highline.expects(:say).with("Commands: [n]ew [e]dit [g]roup [m]ode [q]uit")
|
551
|
+
@highline.expects(:say).with("Commands: [o]pen [n]ew [e]dit [g]roup [m]ode [q]uit")
|
491
552
|
|
492
|
-
@highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 e g}) }).returns('q')
|
553
|
+
@highline.expects(:ask).yields(mock { expects(:in=).with(%w{n q m 1 2 3 o e g}) }).returns('q')
|
493
554
|
assert_equal :quit, @console.menu(:group => @top_group, :at_top => true)
|
494
555
|
end
|
495
556
|
end
|
metadata
CHANGED
@@ -1,126 +1,111 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: keyrack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
5
|
-
prerelease:
|
4
|
+
version: 0.3.2
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Jeremy Stephens
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-11-
|
11
|
+
date: 2013-11-16 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: net-scp
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :runtime
|
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
26
|
version: '0'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: highline
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - '>='
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '0'
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - '>='
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '0'
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: clipboard
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - '>='
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: '0'
|
54
48
|
type: :runtime
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - '>='
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: '0'
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: scrypty
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
|
-
- -
|
59
|
+
- - '>='
|
68
60
|
- !ruby/object:Gem::Version
|
69
61
|
version: '0'
|
70
62
|
type: :runtime
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
|
-
- -
|
66
|
+
- - '>='
|
76
67
|
- !ruby/object:Gem::Version
|
77
68
|
version: '0'
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
70
|
name: bundler
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
|
-
- -
|
73
|
+
- - '>='
|
84
74
|
- !ruby/object:Gem::Version
|
85
75
|
version: '0'
|
86
76
|
type: :development
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
|
-
- -
|
80
|
+
- - '>='
|
92
81
|
- !ruby/object:Gem::Version
|
93
82
|
version: '0'
|
94
83
|
- !ruby/object:Gem::Dependency
|
95
84
|
name: mocha
|
96
85
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
86
|
requirements:
|
99
|
-
- -
|
87
|
+
- - '>='
|
100
88
|
- !ruby/object:Gem::Version
|
101
89
|
version: '0'
|
102
90
|
type: :development
|
103
91
|
prerelease: false
|
104
92
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
93
|
requirements:
|
107
|
-
- -
|
94
|
+
- - '>='
|
108
95
|
- !ruby/object:Gem::Version
|
109
96
|
version: '0'
|
110
97
|
- !ruby/object:Gem::Dependency
|
111
98
|
name: test-unit
|
112
99
|
requirement: !ruby/object:Gem::Requirement
|
113
|
-
none: false
|
114
100
|
requirements:
|
115
|
-
- -
|
101
|
+
- - '>='
|
116
102
|
- !ruby/object:Gem::Version
|
117
103
|
version: '0'
|
118
104
|
type: :development
|
119
105
|
prerelease: false
|
120
106
|
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
none: false
|
122
107
|
requirements:
|
123
|
-
- -
|
108
|
+
- - '>='
|
124
109
|
- !ruby/object:Gem::Version
|
125
110
|
version: '0'
|
126
111
|
description: Simple password manager with local/remote database storage and scrypt
|
@@ -132,6 +117,7 @@ executables:
|
|
132
117
|
extensions: []
|
133
118
|
extra_rdoc_files: []
|
134
119
|
files:
|
120
|
+
- .altrc
|
135
121
|
- .document
|
136
122
|
- .gitignore
|
137
123
|
- .rvmrc
|
@@ -175,28 +161,28 @@ files:
|
|
175
161
|
- test/unit/test_utils.rb
|
176
162
|
- test/unit/ui/test_console.rb
|
177
163
|
homepage: http://github.com/viking/keyrack
|
178
|
-
licenses:
|
164
|
+
licenses:
|
165
|
+
- MIT
|
166
|
+
metadata: {}
|
179
167
|
post_install_message:
|
180
168
|
rdoc_options: []
|
181
169
|
require_paths:
|
182
170
|
- lib
|
183
171
|
required_ruby_version: !ruby/object:Gem::Requirement
|
184
|
-
none: false
|
185
172
|
requirements:
|
186
|
-
- -
|
173
|
+
- - '>='
|
187
174
|
- !ruby/object:Gem::Version
|
188
175
|
version: '0'
|
189
176
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
190
|
-
none: false
|
191
177
|
requirements:
|
192
|
-
- -
|
178
|
+
- - '>='
|
193
179
|
- !ruby/object:Gem::Version
|
194
180
|
version: '0'
|
195
181
|
requirements: []
|
196
182
|
rubyforge_project:
|
197
|
-
rubygems_version:
|
183
|
+
rubygems_version: 2.0.3
|
198
184
|
signing_key:
|
199
|
-
specification_version:
|
185
|
+
specification_version: 4
|
200
186
|
summary: Simple password manager
|
201
187
|
test_files:
|
202
188
|
- test/fixtures/database-3.dat
|