sesame-cli 0.2.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7e9e49b899f85759b86942eb6a051205e3db2f5adef20d6026ca31862b2724af
4
- data.tar.gz: 84ae67770bb80de8854a1044b35f4b19364715383b18065507ba5cc5c8e9e183
3
+ metadata.gz: 5f22b05a9ccfb4ed20090fe15a4688435773a2fc75dc45c6360f184806a1e0b7
4
+ data.tar.gz: 02ff7c0924ce62da164a8b2243292d6fa2db0c5c729d0eb48840956de7854467
5
5
  SHA512:
6
- metadata.gz: '07078b42b50a933caeb46187d494fb0981439a963d48e3445e0b3b6c6ef3e8328460ea39baa994152dd28c319d44aebf9f7a46b6b486f245de16b62b3e113834'
7
- data.tar.gz: 14607f8208e44a33833ca234ebf5c441a0e2bdca8e3eb02336a70cd14ec63260979f06a83ef7e85d76f2da25332598238a3a7ddd0d4f08589a60c330fe91e3ac
6
+ metadata.gz: 710f4c9022e30461b894edb497d956a0be95e0235756b3e27ffb0921efc7e744fb2edc607987b5b887d25bbf39152eec6a064b6b420a0fdb3b28c9fdcc5ef327
7
+ data.tar.gz: cd10c77c1879a964ab3998b22e705efd63663127629d93505d713fe86f89a37670950b99f7908bfbf05fcbd28e1fee7c490a067cfb38b5705ff111f90374c27e
data/README.md CHANGED
@@ -42,7 +42,7 @@ mammal glue wage paper store detail weave date
42
42
 
43
43
  > exit
44
44
  🧞 - "I have secured your treasure with this key..."
45
- sky tea ant ice
45
+ tea old ant ice
46
46
  ```
47
47
 
48
48
  You will notice that Sesame enters interactive mode when the `--interactive`
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 1.0.0
data/lib/sesame/cave.rb CHANGED
@@ -121,6 +121,7 @@ module Sesame
121
121
  @item = nil
122
122
  @store = nil
123
123
  @secret = nil
124
+ @dirty = false
124
125
  end
125
126
 
126
127
  # Lock the cave by encrypting and saving the secret to a lock file, and then
@@ -212,11 +213,11 @@ module Sesame
212
213
  # True if a particular service has exactly one username.
213
214
  def unique?(service)
214
215
  raise Fail, 'Cannot test service uniqueness; store not open' unless open?
215
- return if @store[service].nil?
216
+ raise Fail, 'No such service' if @store[service].nil?
216
217
  @store[service].count < 2
217
218
  end
218
219
 
219
- # Generate and return the passpgrase for a service and username.
220
+ # Generate and return the passphrase for a service and username.
220
221
  def get(service, user = nil, index = nil)
221
222
  raise Fail, 'Cannot get service details; store not open' unless open?
222
223
  raise Fail, 'Cannot get the sesame service' if service.casecmp('sesame').zero?
@@ -233,8 +234,7 @@ module Sesame
233
234
  end
234
235
  raise Fail, 'Service cannot be empty' if service.strip.length.zero?
235
236
  raise Fail, 'User cannot be empty' if user.nil? || user.strip.length.zero?
236
- item = _find(service, user)
237
- raise Fail, 'Service and/or user already exists' unless item.nil?
237
+ raise Fail, 'User already exists for that service' unless @store[service].nil? || @store[service][user].nil?
238
238
  @store[service] ||= {}
239
239
  @store[service][user] = index || 0
240
240
  @dirty = true
@@ -248,7 +248,6 @@ module Sesame
248
248
  def update(service, user = nil, index = nil)
249
249
  raise Fail, 'Cannot update service details; store not open' unless open?
250
250
  item = _find(service, user)
251
- raise Fail, 'Unable to find that service and/or user' if item.nil?
252
251
  index = item[:index] + 1 if index.nil?
253
252
  index = 0 if index.negative?
254
253
  user = item[:user]
@@ -263,7 +262,6 @@ module Sesame
263
262
  raise Fail, 'Cannot delete service details; store not open' unless open?
264
263
  raise Fail, 'Cannot delete the sesame service' if service.casecmp('sesame').zero?
265
264
  item = _find(service, user)
266
- raise Fail, 'Unable to find that service and/or user' if item.nil?
267
265
  user = item[:user]
268
266
  @store[service].delete(user)
269
267
  @store.delete(service) if @store[service].count.zero?
@@ -284,9 +282,10 @@ module Sesame
284
282
  end
285
283
 
286
284
  def _find(service, user)
287
- return nil if service.nil? || @store[service].nil?
285
+ raise Fail, 'No such service' if service.nil? || @store[service].nil?
288
286
  @item =
289
287
  if user.nil?
288
+ raise Fail, 'No unique user for service' unless unique?(service)
290
289
  item = @store[service].first
291
290
  {
292
291
  service: service,
@@ -294,7 +293,7 @@ module Sesame
294
293
  index: item.last
295
294
  }
296
295
  elsif @store[service][user].nil?
297
- nil
296
+ raise Fail, 'No such service or user'
298
297
  else
299
298
  index = @store[service][user]
300
299
  {
data/lib/sesame/jinn.rb CHANGED
@@ -7,39 +7,40 @@ require 'clipboard'
7
7
  module Sesame
8
8
  # The Jinn class is wholly responsible for interacting with the terminal.
9
9
  class Jinn
10
- # Pass in parsed command-line options as a Slop instance.
11
- def initialize(opts)
10
+ # Pass in parsed command-line options as a Slop instance. The optional pow
11
+ # parameter should only be used to speed up tests.
12
+ def initialize(opts, pow = 30)
12
13
  I18n.load_path = Dir[File.join(File.dirname(__FILE__), 'lang', '*yml')]
13
14
  @opts = opts
14
15
  _config
15
16
  _parse
16
17
  _welcome
17
- @sesame = Cave.new(@opts[:path])
18
+ @cave = Cave.new(@opts[:path], pow)
18
19
  rescue Fail => e
19
20
  _error(e.message)
20
21
  end
21
22
 
22
23
  # Process the users request, possibly starting an interactive session.
23
24
  def process!
24
- return if @sesame.nil?
25
+ return if @cave.nil?
25
26
  @was_locked = false
26
27
  raise Fail, 'Cannot lock and expunge simultaneously' if @opts.lock? && @opts.expunge?
27
- if @sesame.exists?
28
+ if @cave.exists?
28
29
  raise Fail, 'Please remove the cave before attempting to reconstruct' if @opts.reconstruct?
29
- raise Fail, 'Cannot expunge lock; it doesn\'t exist' if @opts.expunge? && !@sesame.locked?
30
+ raise Fail, 'Cannot expunge lock; it doesn\'t exist' if @opts.expunge? && !@cave.locked?
30
31
  raise Fail, 'Please specify a command (or use interactive mode)' if !@opts.interactive? && @opts[:command].nil? && !@opts.lock? && !@opts.expunge?
31
- if @sesame.locked? && @opts.expunge?
32
- @sesame.forget
32
+ if @cave.locked? && @opts.expunge?
33
+ @cave.forget
33
34
  _warn('Lock expunged')
34
35
  end
35
- if @sesame.locked?
36
+ if @cave.locked?
36
37
  _unlock
37
38
  @was_locked = true
38
39
  else
39
40
  _open
40
41
  end
41
42
  else
42
- @sesame.forget if @sesame.locked?
43
+ @cave.forget if @cave.locked?
43
44
  _new
44
45
  end
45
46
  _process(@opts[:command])
@@ -49,12 +50,12 @@ module Sesame
49
50
  break if _prompt
50
51
  end
51
52
  if @opts.expunge?
52
- @sesame.close
53
+ @cave.close
53
54
  else
54
55
  _lock
55
56
  end
56
57
  elsif @opts.expunge? || (!@was_locked && !@opts.lock?)
57
- @sesame.close
58
+ @cave.close
58
59
  else
59
60
  _lock
60
61
  end
@@ -203,7 +204,7 @@ module Sesame
203
204
  _info('reconstruct')
204
205
  words = ask('🔑 ') { |q| q.echo = '*' }
205
206
  end
206
- phrase = @sesame.create!(words)
207
+ phrase = @cave.create!(words)
207
208
  if words.nil?
208
209
  _info('new')
209
210
  _show(phrase)
@@ -215,26 +216,26 @@ module Sesame
215
216
  def _open
216
217
  _info('open')
217
218
  words = ask('🔑 ') { |q| q.echo = '*' }
218
- @sesame.open(words)
219
- _info('path', path: @sesame.path)
219
+ @cave.open(words)
220
+ _info('path', path: @cave.path)
220
221
  end
221
222
 
222
223
  def _unlock
223
224
  _info('unlock')
224
225
  key = ask('🔑 ') { |q| q.echo = '*' }
225
- @sesame.unlock(key)
226
- _info('path', path: @sesame.path)
226
+ @cave.unlock(key)
227
+ _info('path', path: @cave.path)
227
228
  end
228
229
 
229
230
  def _forget
230
231
  _info('forgot')
231
- @sesame.forget
232
+ @cave.forget
232
233
  end
233
234
 
234
235
  def _list
235
236
  _info('list')
236
237
  if @opts[:service].nil? || @opts[:service].length.zero?
237
- @sesame.index.each do |service, users|
238
+ @cave.index.each do |service, users|
238
239
  next if service == 'sesame'
239
240
  if users.count > 1
240
241
  say("#{service} (#{users.count})")
@@ -243,7 +244,7 @@ module Sesame
243
244
  end
244
245
  end
245
246
  else
246
- users = @sesame.index[@opts[:service]]
247
+ users = @cave.index[@opts[:service]]
247
248
  raise Fail, 'No such service found, you must be thinking of some other cave' if users.nil? || @opts[:service] == 'sesame'
248
249
  users.sort.each do |user, _|
249
250
  say(user)
@@ -252,37 +253,37 @@ module Sesame
252
253
  end
253
254
 
254
255
  def _get
255
- phrase = @sesame.get(*_question, @opts[:offset])
256
- _info('get', @sesame.item)
256
+ phrase = @cave.get(*_question, @opts[:offset])
257
+ _info('get', @cave.item)
257
258
  _show(phrase)
258
259
  end
259
260
 
260
261
  def _add
261
- phrase = @sesame.insert(*_question(true), @opts[:offset])
262
- _info('add', @sesame.item)
262
+ phrase = @cave.insert(*_question(true), @opts[:offset])
263
+ _info('add', @cave.item)
263
264
  _show(phrase)
264
265
  end
265
266
 
266
267
  def _next
267
- phrase = @sesame.update(*_question, @opts[:offset])
268
+ phrase = @cave.update(*_question, @opts[:offset])
268
269
  if phrase.nil?
269
270
  _info('next_key')
270
271
  @was_locked = false
271
272
  _set_opt(:lock, true)
272
273
  else
273
- _info('next', @sesame.item)
274
+ _info('next', @cave.item)
274
275
  _show(phrase)
275
276
  end
276
277
  end
277
278
 
278
279
  def _delete
279
- phrase = @sesame.delete(*_question)
280
+ phrase = @cave.delete(*_question)
280
281
  _info('delete')
281
282
  _show(phrase)
282
283
  end
283
284
 
284
285
  def _lock
285
- key = @sesame.lock
286
+ key = @cave.lock
286
287
  return if @was_locked
287
288
  _info('lock')
288
289
  _show(key)
@@ -348,7 +349,7 @@ module Sesame
348
349
  _info('service')
349
350
  service = ask('🏷 ')
350
351
  end
351
- if user.nil? && (user_required || !@sesame.unique?(service))
352
+ if user.nil? && (user_required || !@cave.unique?(service))
352
353
  _info('user')
353
354
  user = ask('👤 ')
354
355
  end
data/sesame-cli.gemspec CHANGED
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: sesame-cli 0.2.0 ruby lib
5
+ # stub: sesame-cli 1.0.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "sesame-cli".freeze
9
- s.version = "0.2.0"
9
+ s.version = "1.0.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
13
13
  s.authors = ["Jason Hutchens".freeze, "Jack Casey".freeze]
14
- s.date = "2018-04-24"
14
+ s.date = "2018-04-25"
15
15
  s.description = "\u{1F9DE} - \"Sesame is a simple password manager for the command-line!\"".freeze
16
16
  s.email = "jasonhutchens@gmail.com".freeze
17
17
  s.executables = ["sesame".freeze]
data/spec/cave_spec.rb CHANGED
@@ -4,11 +4,15 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
4
4
 
5
5
  describe Sesame::Cave do
6
6
  let(:cave) { Sesame::Cave.new(Dir.tmpdir, 20) }
7
+ let(:deep_cave) { Sesame::Cave.new(Dir.tmpdir) }
7
8
 
8
9
  after do
9
10
  cave.close if cave.open?
10
11
  cave.forget if cave.locked?
11
12
  File.delete(cave.path) if cave.exists?
13
+ deep_cave.close if deep_cave.open?
14
+ deep_cave.forget if deep_cave.locked?
15
+ File.delete(deep_cave.path) if deep_cave.exists?
12
16
  end
13
17
 
14
18
  describe '#path' do
@@ -145,44 +149,349 @@ describe Sesame::Cave do
145
149
  end
146
150
 
147
151
  describe '#open?' do
152
+ context 'by default' do
153
+ it 'returns false' do
154
+ expect(cave.open?).to be false
155
+ end
156
+ end
157
+
158
+ context 'after #create!' do
159
+ before do
160
+ cave.create!
161
+ end
162
+ it 'returns true' do
163
+ expect(cave.open?).to be true
164
+ end
165
+ end
166
+
167
+ context 'after #create! and #close' do
168
+ before do
169
+ cave.create!
170
+ cave.close
171
+ end
172
+ it 'returns false' do
173
+ expect(cave.open?).to be false
174
+ end
175
+ end
176
+
177
+ context 'after #create! and #lock' do
178
+ before do
179
+ cave.create!
180
+ cave.lock
181
+ end
182
+ it 'returns false' do
183
+ expect(cave.open?).to be false
184
+ end
185
+ end
186
+
187
+ context 'after @create! and #close and #open' do
188
+ before do
189
+ phrase = cave.create!
190
+ cave.insert('foo', 'bar')
191
+ cave.close
192
+ cave.open(phrase)
193
+ end
194
+ it 'returns true' do
195
+ expect(cave.open?).to be true
196
+ end
197
+ end
148
198
  end
149
199
 
150
200
  describe '#dirty?' do
201
+ context 'by default' do
202
+ it 'returns false' do
203
+ expect(cave.dirty?).to be false
204
+ end
205
+ end
206
+
207
+ context 'after #create!' do
208
+ before do
209
+ cave.create!
210
+ end
211
+ it 'returns true' do
212
+ expect(cave.dirty?).to be true
213
+ end
214
+ end
215
+
216
+ context 'after #create! and #close' do
217
+ before do
218
+ cave.create!
219
+ cave.close
220
+ end
221
+ it 'returns false' do
222
+ expect(cave.dirty?).to be false
223
+ end
224
+ end
225
+
226
+ context 'after #create! and #lock' do
227
+ before do
228
+ cave.create!
229
+ cave.lock
230
+ end
231
+ it 'returns false' do
232
+ expect(cave.dirty?).to be false
233
+ end
234
+ end
235
+
236
+ context 'after @create! and #close and #open' do
237
+ before do
238
+ phrase = cave.create!
239
+ cave.insert('foo', 'bar')
240
+ cave.close
241
+ cave.open(phrase)
242
+ end
243
+ it 'returns false' do
244
+ expect(cave.dirty?).to be false
245
+ end
246
+ end
247
+
248
+ context 'after #open and #insert' do
249
+ before do
250
+ phrase = cave.create!
251
+ cave.insert('foo', 'bar')
252
+ cave.close
253
+ cave.open(phrase)
254
+ cave.insert('bar', 'foo')
255
+ end
256
+ it 'returns true' do
257
+ expect(cave.dirty?).to be true
258
+ end
259
+ end
260
+
261
+ context 'after #open and #update' do
262
+ before do
263
+ phrase = cave.create!
264
+ cave.insert('foo', 'bar')
265
+ cave.close
266
+ cave.open(phrase)
267
+ cave.update('foo', 'bar')
268
+ end
269
+ it 'returns true' do
270
+ expect(cave.dirty?).to be true
271
+ end
272
+ end
273
+
274
+ context 'after #open and #delete' do
275
+ before do
276
+ phrase = cave.create!
277
+ cave.insert('foo', 'bar')
278
+ cave.close
279
+ cave.open(phrase)
280
+ cave.delete('foo', 'bar')
281
+ end
282
+ it 'returns true' do
283
+ expect(cave.dirty?).to be true
284
+ end
285
+ end
151
286
  end
152
287
 
153
288
  describe '#create!' do
289
+ context 'by default' do
290
+ before do
291
+ cave.create!
292
+ end
293
+
294
+ it 'creates a new cave' do
295
+ expect(cave.exists?).to be false
296
+ expect(cave.locked?).to be false
297
+ expect(cave.open?).to be true
298
+ end
299
+ end
300
+
301
+ context 'with a pass phrase' do
302
+ before do
303
+ deep_cave.create!('mammal glue wage paper store detail weave date')
304
+ deep_cave.insert('twitter', 'kranzky')
305
+ end
306
+
307
+ it 'reconstructs an old cave' do
308
+ expect(deep_cave.exists?).to be false
309
+ expect(deep_cave.locked?).to be false
310
+ expect(deep_cave.open?).to be true
311
+ expect(deep_cave.get('twitter')).to eq('nylon sand slice party')
312
+ end
313
+ end
154
314
  end
155
315
 
156
316
  describe '#open' do
317
+ before do
318
+ phrase = cave.create!
319
+ cave.insert('foo', 'bar')
320
+ cave.close
321
+ cave.open(phrase)
322
+ cave.get('foo')
323
+ end
324
+ it 'opens an existing cave' do
325
+ expect(cave.exists?).to be true
326
+ expect(cave.locked?).to be false
327
+ expect(cave.open?).to be true
328
+ expect(cave.item[:user]).to eq('bar')
329
+ end
157
330
  end
158
331
 
159
332
  describe '#close' do
333
+ before do
334
+ cave.create!
335
+ cave.insert('foo', 'bar')
336
+ cave.close
337
+ end
338
+ it 'closes a cave' do
339
+ expect(cave.exists?).to be true
340
+ expect(cave.locked?).to be false
341
+ expect(cave.open?).to be false
342
+ end
160
343
  end
161
344
 
162
345
  describe '#lock' do
346
+ before do
347
+ cave.create!
348
+ cave.insert('foo', 'bar')
349
+ cave.lock
350
+ end
351
+ it 'locks a cave' do
352
+ expect(cave.exists?).to be true
353
+ expect(cave.locked?).to be true
354
+ expect(cave.open?).to be false
355
+ end
163
356
  end
164
357
 
165
358
  describe '#unlock' do
359
+ context 'with a word phrase' do
360
+ before do
361
+ cave.create!
362
+ cave.insert('foo', 'bar')
363
+ phrase = cave.lock
364
+ cave.unlock(phrase)
365
+ cave.get('foo')
366
+ end
367
+ it 'unlocks a cave' do
368
+ expect(cave.exists?).to be true
369
+ expect(cave.locked?).to be false
370
+ expect(cave.open?).to be true
371
+ expect(cave.item[:user]).to eq('bar')
372
+ end
373
+ end
374
+
375
+ context 'with a character code' do
376
+ before do
377
+ cave.create!
378
+ cave.insert('foo', 'bar')
379
+ code = cave.lock.split(' ').map { |w| w[0] }.join
380
+ cave.unlock(code)
381
+ cave.get('foo')
382
+ end
383
+ it 'unlocks a cave' do
384
+ expect(cave.exists?).to be true
385
+ expect(cave.locked?).to be false
386
+ expect(cave.open?).to be true
387
+ expect(cave.item[:user]).to eq('bar')
388
+ end
389
+ end
166
390
  end
167
391
 
168
392
  describe '#forget' do
393
+ before do
394
+ cave.create!
395
+ cave.insert('foo', 'bar')
396
+ cave.lock
397
+ cave.forget
398
+ end
399
+ it 'removes the lock file' do
400
+ expect(cave.exists?).to be true
401
+ expect(cave.locked?).to be false
402
+ expect(cave.open?).to be false
403
+ end
169
404
  end
170
405
 
171
406
  describe '#index' do
407
+ before do
408
+ cave.create!
409
+ cave.insert('foo', 'bar')
410
+ cave.insert('foo', 'xxx')
411
+ cave.insert('bar', 'foo')
412
+ end
413
+ let(:index) { cave.index }
414
+ it 'returns the contents of the cave' do
415
+ expect(index.count).to eq(3)
416
+ expect(index.keys[0]).to eq('bar')
417
+ expect(index.keys[2]).to eq('sesame')
418
+ expect(index['foo'].count).to eq(2)
419
+ expect(index['foo']['xxx']).to eq(0)
420
+ end
172
421
  end
173
422
 
174
423
  describe '#unique?' do
424
+ before do
425
+ cave.create!
426
+ cave.insert('foo', 'bar')
427
+ cave.insert('foo', 'xxx')
428
+ cave.insert('bar', 'foo')
429
+ end
430
+ it 'returns true for services that contain exactly one user' do
431
+ expect(cave.unique?('foo')).to be false
432
+ expect(cave.unique?('bar')).to be true
433
+ expect { cave.unique?('xxx') }.to raise_error(Sesame::Fail)
434
+ end
175
435
  end
176
436
 
177
437
  describe '#get' do
438
+ before do
439
+ cave.create!
440
+ cave.insert('foo', 'bar')
441
+ cave.insert('foo', 'xxx')
442
+ end
443
+ let!(:phrase) { cave.insert('bar', 'foo') }
444
+ it 'returns the phrase' do
445
+ expect(cave.item[:index]).to eq(0)
446
+ expect(cave.get('bar')).to eq(phrase)
447
+ expect(cave.get('bar', 'foo')).to eq(phrase)
448
+ expect { cave.get('foo') }.to raise_error(Sesame::Fail)
449
+ expect { cave.get('xxx') }.to raise_error(Sesame::Fail)
450
+ expect(cave.get('foo', 'xxx').split(' ').count).to eq(4)
451
+ end
178
452
  end
179
453
 
180
454
  describe '#insert' do
455
+ before do
456
+ cave.create!
457
+ cave.insert('foo', 'bar')
458
+ end
459
+ it 'inserts the item' do
460
+ expect(cave.item[:service]).to eq('foo')
461
+ expect(cave.item[:user]).to eq('bar')
462
+ expect(cave.item[:index]).to eq(0)
463
+ expect { cave.insert('foo', 'bar') }.to raise_error(Sesame::Fail)
464
+ expect(cave.insert('foo', 'xxx').split(' ').count).to eq(4)
465
+ expect(cave.item[:user]).to eq('xxx')
466
+ end
181
467
  end
182
468
 
183
469
  describe '#update' do
470
+ before do
471
+ cave.create!
472
+ end
473
+ let!(:phrase) { cave.insert('foo', 'bar') }
474
+ it 'updates the item' do
475
+ expect(cave.item[:index]).to eq(0)
476
+ expect(cave.get('foo')).to eq(phrase)
477
+ expect(cave.update('foo')).not_to eq(phrase)
478
+ expect(cave.item[:index]).to eq(1)
479
+ expect(cave.get('foo')).not_to eq(phrase)
480
+ end
184
481
  end
185
482
 
186
483
  describe '#delete' do
484
+ before do
485
+ cave.create!
486
+ cave.insert('foo', 'bar')
487
+ end
488
+ let!(:phrase) { cave.insert('bar', 'foo') }
489
+ it 'deletes the item' do
490
+ expect(cave.get('bar')).to eq(phrase)
491
+ expect(cave.delete('bar')).to eq(phrase)
492
+ expect { cave.get('bar') }.to raise_error(Sesame::Fail)
493
+ expect(cave.item[:service]).to eq('bar')
494
+ expect { cave.get('xxx') }.to raise_error(Sesame::Fail)
495
+ end
187
496
  end
188
497
  end
data/spec/jinn_spec.rb CHANGED
@@ -3,5 +3,39 @@
3
3
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
4
4
 
5
5
  describe Sesame::Jinn do
6
- let(:jinn) { Sesame::Jinn.new(opts) }
6
+ let(:opts) { double('opts') }
7
+ let(:jinn) { Sesame::Jinn.new(opts, 20) }
8
+
9
+ before do
10
+ option = double('option')
11
+ allow(opts).to receive(:echo?) { true }
12
+ allow(opts).to receive(:interactive?) { false }
13
+ allow(opts).to receive(:quiet?) { true }
14
+ allow(opts).to receive(:list?) { false }
15
+ allow(opts).to receive(:add?) { false }
16
+ allow(opts).to receive(:get?) { false }
17
+ allow(opts).to receive(:next?) { false }
18
+ allow(opts).to receive(:delete?) { false }
19
+ allow(opts).to receive(:lock?) { false }
20
+ allow(opts).to receive(:expunge?) { false }
21
+ allow(opts).to receive(:reconstruct?) { false }
22
+ allow(opts).to receive(:[]) { '/tmp' }
23
+ allow(opts).to receive(:option) { option }
24
+ allow(option).to receive(:ensure_call)
25
+ end
26
+
27
+ after do
28
+ cave = jinn.instance_variable_get(:@cave)
29
+ cave.close if cave.open?
30
+ cave.forget if cave.locked?
31
+ File.delete(cave.path) if cave.exists?
32
+ end
33
+
34
+ describe '#process!' do
35
+ context 'no arguments supplied' do
36
+ it 'exits with an error message' do
37
+ jinn.process!
38
+ end
39
+ end
40
+ end
7
41
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sesame-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Hutchens
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-04-24 00:00:00.000000000 Z
12
+ date: 2018-04-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bases