keybox 1.1.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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