keybox 1.1.0 → 1.1.1

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.
@@ -1,63 +1,63 @@
1
1
  require 'keybox/storage'
2
2
 
3
- context 'a storage record entry' do
4
- setup do
3
+ describe 'a storage record entry' do
4
+ before(:each) do
5
5
  @data_fields = %w(title username password url additional_data)
6
6
  end
7
- specify 'has a creation date set on instantiation' do
7
+ it 'has a creation date set on instantiation' do
8
8
  e = Keybox::Storage::Record.new
9
- e.creation_time.should_be_instance_of(Time)
9
+ e.creation_time.should be_instance_of(Time)
10
10
  end
11
11
 
12
- specify "assigning to a non-existant field creates the appropriate member " do
12
+ it "assigning to a non-existant field creates the appropriate member " do
13
13
  e = Keybox::Storage::Record.new
14
14
  e.junk = "junk"
15
15
  e.junk.should == "junk"
16
16
  end
17
17
 
18
- specify 'default values for non-existant fields is nil' do
18
+ it 'default values for non-existant fields is nil' do
19
19
  e = Keybox::Storage::Record.new
20
20
  @data_fields.each do |f|
21
- e.send(f).should_be nil
21
+ e.send(f).should == nil
22
22
  end
23
23
  end
24
24
 
25
- specify "assigning to a field makes the modification time > creation time" do
25
+ it "assigning to a field makes the modification time > creation time" do
26
26
  e = Keybox::Storage::Record.new
27
27
  sleep 1
28
28
  e.testing = "testing"
29
- e.modification_time.should_satisfy { |m| m > e.creation_time }
29
+ e.modification_time.should > e.creation_time
30
30
  e.last_access_time.should == e.modification_time
31
31
  end
32
32
 
33
- specify "reading a field after assignment the access time > modification time " do
33
+ it "reading a field after assignment the access time > modification time " do
34
34
  e = Keybox::Storage::Record.new
35
35
  e.testing = "testing"
36
36
  sleep 1
37
37
  e.testing
38
- e.last_access_time.should_satisfy { |la| la > e.creation_time }
39
- e.last_access_time.should_satisfy { |la| la > e.modification_time }
38
+ e.last_access_time.should > e.creation_time
39
+ e.last_access_time.should > e.modification_time
40
40
  end
41
41
 
42
- specify "assigning to a modification, creation or acces_time should raise and exception " do
42
+ it "assigning to a modification, creation or acces_time should raise and exception " do
43
43
  e = Keybox::Storage::Record.new
44
- lambda {e.modification_time = Time.now}.should_raise NoMethodError
44
+ lambda {e.modification_time = Time.now}.should raise_error(NoMethodError)
45
45
  end
46
46
 
47
- specify "assiging multiple items should raise an argument exception" do
47
+ it "assiging multiple items should raise an argument exception" do
48
48
  e = Keybox::Storage::Record.new
49
- lambda {e.send(:stuff=,1,2)}.should_raise ArgumentError
49
+ lambda {e.send(:stuff=,1,2)}.should raise_error(ArgumentError)
50
50
  end
51
51
 
52
- specify "calling a method with arguments should raise exception" do
52
+ it "calling a method with arguments should raise exception" do
53
53
  e = Keybox::Storage::Record.new
54
- lambda {e.stuff(1,2)}.should_raise NoMethodError
54
+ lambda {e.stuff(1,2)}.should raise_error(NoMethodError)
55
55
  end
56
56
 
57
- specify "comparison between records is valid" do
57
+ it "comparison between records is valid" do
58
58
  e = Keybox::Storage::Record.new
59
59
  f = e.dup
60
- e.should_eql e.uuid
61
- e.should_eql f
60
+ e.should == e.uuid
61
+ e.should == f
62
62
  end
63
63
  end
@@ -1,114 +1,112 @@
1
1
  require 'keybox'
2
- context "string generator" do
3
- setup do
2
+ describe Keybox::StringGenerator do
3
+ before(:each) do
4
4
  @generator = Keybox::StringGenerator.new
5
5
  end
6
6
 
7
- specify "should not be used alone" do
8
- lambda { @generator.generate }.should_raise Keybox::KeyboxError
7
+ it "should not be used alone" do
8
+ lambda { @generator.generate }.should raise_error(Keybox::KeyboxError)
9
9
  end
10
10
 
11
- specify "cannot have a min length greater than a max length" do
11
+ it "cannot have a min length greater than a max length" do
12
12
  @generator.min_length = 90
13
- lambda { @generator.generate }.should_raise Keybox::ValidationError
14
- @generator.min_length = 8
13
+ lambda { @generator.generate }.should raise_error(Keybox::ValidationError)
15
14
  end
16
15
 
17
- specify "cannot have a max length less than a min length" do
16
+ it "cannot have a max length less than a min length" do
18
17
  @generator.max_length = 2
19
- lambda { @generator.generate }.should_raise Keybox::ValidationError
20
- @generator.max_length = 10
18
+ lambda { @generator.generate }.should raise_error(Keybox::ValidationError)
21
19
  end
22
20
 
23
- specify "initially there are no chunks" do
24
- @generator.chunks.should_have(0).entries
21
+ it "initially there are no chunks" do
22
+ @generator.chunks.should have(0).entries
25
23
  end
26
24
  end
27
25
 
28
- context "chargram generator" do
29
- setup do
26
+ describe "chargram generator" do
27
+ before(:each) do
30
28
  @generator = Keybox::CharGramGenerator.new
31
29
  end
32
30
 
33
- specify "should have a positive size" do
34
- @generator.size.should_be > 26
31
+ it "should have a positive size" do
32
+ @generator.size.should > 26
35
33
  end
36
34
 
37
- specify "should emit a string with length > 0" do
38
- @generator.generate_chunk.size.should_be > 0
35
+ it "should emit a string with length > 0" do
36
+ @generator.generate_chunk.size.should > 0
39
37
  end
40
38
 
41
- specify "should emit an array " do
42
- @generator.generate_chunk.should_be_instance_of String
39
+ it "should emit an array " do
40
+ @generator.generate_chunk.should be_instance_of(String)
43
41
  end
44
42
 
45
- specify "2 succesive emits should have a common first and last character" do
43
+ it "2 succesive emits should have a common first and last character" do
46
44
  one = @generator.generate_chunk
47
45
  two = @generator.generate_chunk
48
46
  one[-1].should == two[0]
49
47
  end
50
48
 
51
- specify "2 calls to generate_chunk should have a string that is 1 less than the 2 chunks" do
49
+ it "2 calls to generate_chunk should have a string that is 1 less than the 2 chunks" do
52
50
  one = @generator.generate_chunk
53
51
  two = @generator.generate_chunk
54
52
  @generator.to_s.length.should == (one.length + two.length - 1)
55
53
  end
56
54
  end
57
55
 
58
- context "SymbolSetGenerator" do
59
- setup do
56
+ describe "SymbolSetGenerator" do
57
+ before(:each) do
60
58
  @generator = Keybox::SymbolSetGenerator.new
61
59
  end
62
60
 
63
- specify "symbol sets have the right number or characters" do
61
+ it "symbol sets have the right number or characters" do
64
62
  Keybox::SymbolSetGenerator::ALL.size.should == 92
65
63
  end
66
64
 
67
- specify "generating chunks should produce an array" do
65
+ it "generating chunks should produce an array" do
68
66
  12.times do
69
67
  @generator.generate_chunk
70
68
  end
71
- @generator.chunks.should_have(12).entries
69
+ @generator.chunks.should have(12).entries
72
70
  end
73
71
 
74
- specify "generate should produce a string" do
75
- @generator.generate.should_be_instance_of(String)
76
- @generator.to_s.size.should_be > 0
72
+ it "generate should produce a string" do
73
+ @generator.generate.should be_instance_of(String)
74
+ @generator.to_s.size.should > 0
77
75
  end
78
76
 
79
- specify "generating chunks can be cleared" do
77
+ it "generating chunks can be cleared" do
80
78
  @generator.generate
81
79
  @generator.clear
82
- @generator.chunks.should_have(0).entries
80
+ @generator.chunks.should have(0).entries
83
81
  end
84
82
 
85
- specify "min and max lengths are respected" do
83
+ it "min and max lengths are respected" do
86
84
  @generator.max_length = 25
87
85
  @generator.min_length = 25
88
- @generator.generate.size.should_be == 25
86
+ @generator.generate.size.should == 25
89
87
  end
90
88
 
91
- specify "required sets are utilized" do
89
+ it "required sets are utilized" do
92
90
  gen = Keybox::SymbolSetGenerator.new([Keybox::SymbolSet::NUMERAL_ASCII, Keybox::SymbolSet::LOWER_ASCII])
93
91
  gen.required_sets << Keybox::SymbolSet::UPPER_ASCII
94
92
  p = gen.generate
95
- gen.required_sets.flatten.uniq.should_include(p[0].chr)
93
+ gen.required_sets.flatten.uniq.should be_include(p[0].chr)
96
94
  end
97
- specify "required sets are merged with symbol sets" do
95
+ it "required sets are merged with symbol sets" do
98
96
  gen = Keybox::SymbolSetGenerator.new([Keybox::SymbolSet::NUMERAL_ASCII, Keybox::SymbolSet::LOWER_ASCII])
99
97
  gen.required_sets << Keybox::SymbolSet::UPPER_ASCII
100
98
  gen.required_sets.flatten.uniq.each do |c|
101
- gen.symbols.should_include(c)
99
+ gen.symbols.should be_include(c)
102
100
  end
103
101
  end
104
102
 
105
- specify "generated passwords autoclear" do
103
+ it "generated passwords autoclear" do
106
104
  @generator.generate.should_not == @generator.generate
107
105
  end
108
106
 
109
- specify "setting min and max should not affect " do
107
+ it "setting min and max should not affect " do
110
108
  g = Keybox::SymbolSetGenerator.new(Keybox::SymbolSet::ALL)
111
- g.generate.should_be_instance_of(String)
109
+ g.generate.should be_instance_of(String)
112
110
  end
113
111
 
114
112
  end
@@ -1,29 +1,30 @@
1
1
  require 'keybox/uuid'
2
- context "UUID class" do
3
- specify "should have 16 bytes" do
2
+ describe "UUID class" do
3
+ it "should have 16 bytes" do
4
4
  uuid = Keybox::UUID.new
5
5
  uuid.bytes.size.should == 16
6
6
  end
7
7
 
8
- specify "as an array should have 16 members" do
8
+ it "as an array should have 16 members" do
9
9
  uuid = Keybox::UUID.new
10
10
  uuid.to_a.size.should == 16
11
11
  end
12
12
 
13
- specify "array elements should have values between 0 and 256 " do
13
+ it "array elements should have values between 0 and 256 " do
14
14
  uuid = Keybox::UUID.new
15
15
  uuid.to_a.each do |b|
16
- b.should_satisfy { |s| s.between?(0,256) }
16
+ b.should >= 0
17
+ b.should <= 256
17
18
  end
18
19
  end
19
20
 
20
- specify "as a string should match regex" do
21
+ it "as a string should match regex" do
21
22
  regex = Keybox::UUID::REGEX
22
23
  uuid = Keybox::UUID.new
23
- uuid.to_s.should_match(regex)
24
+ uuid.to_s.should =~ regex
24
25
  end
25
26
 
26
- specify "initialized with a string should give a valid uuid" do
27
+ it "initialized with a string should give a valid uuid" do
27
28
  s = "0123456789abcdef"
28
29
  s_a = s.unpack("C*")
29
30
  s_uuid = sprintf(Keybox::UUID::FORMAT,*s_a)
@@ -31,44 +32,44 @@ context "UUID class" do
31
32
  uuid.to_s.should == s_uuid
32
33
  end
33
34
 
34
- specify "initialized with a string in the format of a uuid is valid " do
35
+ it "initialized with a string in the format of a uuid is valid " do
35
36
  s = "c8b5a23a-2507-4834-ab19-60f2cb2a5271"
36
37
  uuid = Keybox::UUID.new(s)
37
38
  uuid.to_s.should == s
38
39
  end
39
40
 
40
- specify "not enough bytes should throw an expeption" do
41
+ it "not enough bytes should throw an expeption" do
41
42
  s = "0123456789"
42
- lambda { Keybox::UUID.new(s) }.should_raise ArgumentError
43
+ lambda { Keybox::UUID.new(s) }.should raise_error(ArgumentError)
43
44
  end
44
45
 
45
- specify "invalid uuid string should throw an exception" do
46
+ it "invalid uuid string should throw an exception" do
46
47
  s = "z8b5a23a-2507-4834-ab19-60f2cb2a5271"
47
- lambda { Keybox::UUID.new(s) }.should_raise ArgumentError
48
+ lambda { Keybox::UUID.new(s) }.should raise_error(ArgumentError)
48
49
  end
49
50
 
50
- specify "initialing with a non-string raises an exception" do
51
- lambda { Keybox::UUID.new(42) }.should_raise ArgumentError
51
+ it "initialing with a non-string raises an exception" do
52
+ lambda { Keybox::UUID.new(42) }.should raise_error(ArgumentError)
52
53
  end
53
54
 
54
- specify "should equal another keybox created with same data" do
55
+ it "should equal another keybox created with same data" do
55
56
  s = "c8b5a23a-2507-4834-ab19-60f2cb2a5271"
56
57
  one = Keybox::UUID.new(s)
57
58
  two = Keybox::UUID.new(s)
58
59
  one.should == two
59
60
  end
60
61
 
61
- specify "should equal a string that is the same uuid" do
62
+ it "should equal a string that is the same uuid" do
62
63
  s = "c8b5a23a-2507-4834-ab19-60f2cb2a5271"
63
64
  one = Keybox::UUID.new(s)
64
65
  one.should == s
65
66
  end
66
67
 
67
- specify "should not equal some other uuid or random string" do
68
+ it "should not equal some other uuid or random string" do
68
69
  s = "c8b5a23a-2507-4834-ab19-60f2cb2a5271"
69
70
  one = Keybox::UUID.new(s)
70
- one.should_not_eql Keybox::UUID.new
71
- one.should_not_eql "i love ruby"
72
- one.should_not_eql 4
71
+ one.should_not == Keybox::UUID.new
72
+ one.should_not == "i love ruby"
73
+ one.should_not == 4
73
74
  end
74
75
  end
@@ -29,7 +29,7 @@ require "abbrev"
29
29
  #
30
30
  class HighLine
31
31
  # The version of the installed library.
32
- VERSION = "1.2.6".freeze
32
+ VERSION = "1.2.9".freeze
33
33
 
34
34
  # An internal HighLine error. User code does not need to trap this.
35
35
  class QuestionError < StandardError
@@ -48,6 +48,19 @@ class HighLine
48
48
  def self.use_color?
49
49
  @@use_color
50
50
  end
51
+
52
+ # The setting used to disable EOF tracking.
53
+ @@track_eof = true
54
+
55
+ # Pass +false+ to _setting_ to turn off HighLine's EOF tracking.
56
+ def self.track_eof=( setting )
57
+ @@track_eof = setting
58
+ end
59
+
60
+ # Returns true if HighLine is currently tracking EOF for input.
61
+ def self.track_eof?
62
+ @@track_eof
63
+ end
51
64
 
52
65
  # The setting used to control color schemes.
53
66
  @@color_scheme = nil
@@ -75,7 +88,9 @@ class HighLine
75
88
  # An alias for CLEAR.
76
89
  RESET = CLEAR
77
90
  # Erase the current line of terminal output.
78
- ERASE_LINE = "\e[K"
91
+ ERASE_LINE = "\e[K"
92
+ # Erase the character under the cursor.
93
+ ERASE_CHAR = "\e[P"
79
94
  # The start of an ANSI bold sequence.
80
95
  BOLD = "\e[1m"
81
96
  # The start of an ANSI dark sequence. (Terminal support uncommon.)
@@ -189,9 +204,11 @@ class HighLine
189
204
  @question ||= Question.new(question, answer_type, &details)
190
205
 
191
206
  return gather if @question.gather
192
-
193
- # readline() needs to handle it's own output
194
- say(@question) unless @question.readline
207
+
208
+ # readline() needs to handle it's own output, but readline only supports
209
+ # full line reading. Therefore if @question.echo is anything but true,
210
+ # the prompt will not be issued. And we have to account for that now.
211
+ say(@question) unless (@question.readline and @question.echo == true)
195
212
  begin
196
213
  @answer = @question.answer_or_default(get_response)
197
214
  unless @question.valid_answer?(@answer)
@@ -573,7 +590,8 @@ class HighLine
573
590
 
574
591
  answer
575
592
  else
576
- raise EOFError, "The input stream is exhausted." if @input.eof?
593
+ raise EOFError, "The input stream is exhausted." if @@track_eof and
594
+ @input.eof?
577
595
 
578
596
  @question.change_case(@question.remove_whitespace(@input.gets))
579
597
  end
@@ -598,24 +616,46 @@ class HighLine
598
616
  raw_no_echo_mode if stty = CHARACTER_MODE == "stty"
599
617
 
600
618
  line = ""
619
+ backspace_limit = 0
601
620
  begin
621
+
602
622
  while character = (stty ? @input.getc : get_character(@input))
603
- line << character.chr
623
+ # honor backspace and delete
624
+ if character == 127 or character == 8
625
+ line.slice!(-1, 1)
626
+ backspace_limit -= 1
627
+ else
628
+ line << character.chr
629
+ backspace_limit = line.size
630
+ end
604
631
  # looking for carriage return (decimal 13) or
605
632
  # newline (decimal 10) in raw input
606
633
  break if character == 13 or character == 10 or
607
634
  (@question.limit and line.size == @question.limit)
608
- @output.print(@question.echo) if @question.echo != false
609
- end
610
- if @question.overwrite
611
- @output.print("\r#{ERASE_LINE}")
612
- @output.flush
613
- else
614
- say("\n")
635
+ if @question.echo != false
636
+ if character == 127 or character == 8
637
+ # only backspace if we have characters on the line to
638
+ # eliminate, otherwise we'll tromp over the prompt
639
+ if backspace_limit >= 0 then
640
+ @output.print("\b#{ERASE_CHAR}")
641
+ else
642
+ # do nothing
643
+ end
644
+ else
645
+ @output.print(@question.echo)
646
+ end
647
+ @output.flush
648
+ end
615
649
  end
616
650
  ensure
617
651
  restore_mode if stty
618
652
  end
653
+ if @question.overwrite
654
+ @output.print("\r#{ERASE_LINE}")
655
+ @output.flush
656
+ else
657
+ say("\n")
658
+ end
619
659
 
620
660
  @question.change_case(@question.remove_whitespace(line))
621
661
  end