highline-test 0.0.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.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +84 -0
- data/Rakefile +9 -0
- data/highline-test.gemspec +29 -0
- data/lib/highline/test.rb +11 -0
- data/lib/highline/test/client.rb +90 -0
- data/lib/highline/test/driver.rb +26 -0
- data/lib/highline/test/partial_reader.rb +15 -0
- data/lib/highline/test/version.rb +5 -0
- data/spec/lib/highline/test/client_spec.rb +215 -0
- data/spec/lib/highline/test/driver_spec.rb +75 -0
- data/spec/lib/highline/test/partial_reader_spec.rb +42 -0
- data/spec/spec_helper.rb +12 -0
- metadata +162 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Joe Yates
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
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.
|
data/README.md
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
# Highline::Test
|
2
|
+
|
3
|
+
A micro framework to help you test your HighLine applications.
|
4
|
+
|
5
|
+
HighLine allows you to supply your own input and output streams (instead of the
|
6
|
+
default STDIN and STDOUT). This fact facilitates testing, allowing you to use
|
7
|
+
StringIO objects for input and output.
|
8
|
+
|
9
|
+
The problem with this approach is that it is hard to seperate the test, which pushes
|
10
|
+
data to the input stream, and the application which reads that data.
|
11
|
+
|
12
|
+
HighLine::Test resolves this problem by forking the test process.
|
13
|
+
One fork runs the tests, the other runs the application.
|
14
|
+
The two processes communicate via pipes.
|
15
|
+
|
16
|
+
HighLine::test can be used with any testing framework, e.g.
|
17
|
+
|
18
|
+
* RSpec
|
19
|
+
* Test::Unit
|
20
|
+
* Cucumber
|
21
|
+
|
22
|
+
## Installation
|
23
|
+
|
24
|
+
Add this line to your application's Gemfile:
|
25
|
+
|
26
|
+
gem 'highline-test'
|
27
|
+
|
28
|
+
And then execute:
|
29
|
+
|
30
|
+
$ bundle
|
31
|
+
|
32
|
+
Or install it yourself as:
|
33
|
+
|
34
|
+
$ gem install highline-test
|
35
|
+
|
36
|
+
## Usage
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
require 'highline/test'
|
40
|
+
|
41
|
+
before do
|
42
|
+
# Before running a test, create a HighLine::Test::Client
|
43
|
+
@client = HighLine::Test::Client.new
|
44
|
+
|
45
|
+
# The application itself is started in a block passed to the #run method
|
46
|
+
@client.run do |driver|
|
47
|
+
# This block is run in a child process
|
48
|
+
|
49
|
+
# The HighLine instance used by the application *must* be the one supplied by
|
50
|
+
# the client.
|
51
|
+
HighLine.stub(:new).and_return(@client.high_line)
|
52
|
+
|
53
|
+
# Do any other setup (e.g. stubbing) here
|
54
|
+
|
55
|
+
# Start the application under test
|
56
|
+
MyApp.new.run
|
57
|
+
|
58
|
+
# If this block ever completes, the child process will be killed by
|
59
|
+
# HighLine::Test
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
after do
|
64
|
+
# Ensure the child process is cleaned up
|
65
|
+
@client.cleanup
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'says Hello' do
|
69
|
+
# Send text input to the application
|
70
|
+
@client.type 'Fred'
|
71
|
+
|
72
|
+
# Test application output
|
73
|
+
expect(@client.output).to include('Hello Fred!')
|
74
|
+
end
|
75
|
+
```
|
76
|
+
|
77
|
+
## Contributing
|
78
|
+
|
79
|
+
1. Fork it
|
80
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
81
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
82
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
83
|
+
5. Create new Pull Request
|
84
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'highline/test/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'highline-test'
|
8
|
+
spec.version = Highline::Test::VERSION
|
9
|
+
spec.authors = ['Joe Yates']
|
10
|
+
spec.email = ['joe.g.yates@gmail.com']
|
11
|
+
spec.description = %q{Test HighLine applications}
|
12
|
+
spec.summary = %q{A micro framework that sets up tests for HighLine applications}
|
13
|
+
spec.homepage = ''
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(spec)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_dependency 'highline'
|
22
|
+
|
23
|
+
spec.add_development_dependency 'bundler', '~> 1.3'
|
24
|
+
spec.add_development_dependency 'rake'
|
25
|
+
spec.add_development_dependency 'rspec'
|
26
|
+
spec.add_development_dependency 'bourne'
|
27
|
+
spec.add_development_dependency 'shoulda-matchers'
|
28
|
+
end
|
29
|
+
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module HighLine::Test
|
2
|
+
class Client
|
3
|
+
DEFAULT_POST_INPUT_DELAY = 0.1
|
4
|
+
|
5
|
+
# The delay in milliseconds that the client waits after sending text via
|
6
|
+
# the #type method
|
7
|
+
attr_accessor :delay
|
8
|
+
attr_accessor :child_pid
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@delay = DEFAULT_POST_INPUT_DELAY
|
12
|
+
setup
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
raise "Supply a block to provide a context in which the application is run" unless block_given?
|
17
|
+
|
18
|
+
create_pipes
|
19
|
+
|
20
|
+
@child_pid = fork
|
21
|
+
|
22
|
+
if child_pid.nil?
|
23
|
+
partial_reader = PartialReader.new(@input_read)
|
24
|
+
driver = Driver.new(partial_reader, @output_write)
|
25
|
+
yield driver
|
26
|
+
|
27
|
+
# if the subject ever returns, kill the child process
|
28
|
+
Process.kill(:KILL, Process.pid)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def cleanup
|
33
|
+
return unless running?
|
34
|
+
|
35
|
+
kill_child_process
|
36
|
+
close_pipes
|
37
|
+
setup
|
38
|
+
end
|
39
|
+
|
40
|
+
def running?
|
41
|
+
not child_pid.nil?
|
42
|
+
end
|
43
|
+
|
44
|
+
def type(text)
|
45
|
+
raise 'Client is not running' unless running?
|
46
|
+
|
47
|
+
@input_write << "#{text}\n"
|
48
|
+
sleep delay
|
49
|
+
end
|
50
|
+
|
51
|
+
def output
|
52
|
+
return @output if @output
|
53
|
+
@output_write.close unless @output_write.closed?
|
54
|
+
@output = @output_read.readpartial(PIPE_BUFFER_SIZE)
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def setup
|
60
|
+
@input_read = nil
|
61
|
+
@input_write = nil
|
62
|
+
@output_read = nil
|
63
|
+
@output_write = nil
|
64
|
+
@output = nil
|
65
|
+
@child_pid = nil
|
66
|
+
end
|
67
|
+
|
68
|
+
def create_pipes
|
69
|
+
@input_read, @input_write = IO.pipe
|
70
|
+
@output_read, @output_write = IO.pipe
|
71
|
+
end
|
72
|
+
|
73
|
+
def kill_child_process
|
74
|
+
return if child_pid.nil?
|
75
|
+
|
76
|
+
Process.kill(:KILL, child_pid)
|
77
|
+
rescue Errno::ESRCH => e
|
78
|
+
# swallow errors if the child process has already been killed
|
79
|
+
ensure
|
80
|
+
@child_pid = nil
|
81
|
+
end
|
82
|
+
|
83
|
+
def close_pipes
|
84
|
+
[@input_read, @input_write, @output_read, @output_write].each do |stream|
|
85
|
+
stream.close unless stream.closed?
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'highline'
|
2
|
+
|
3
|
+
module HighLine::Test
|
4
|
+
class Driver
|
5
|
+
attr_reader :input_stream
|
6
|
+
attr_reader :output_stream
|
7
|
+
|
8
|
+
def initialize(input_stream, output_stream)
|
9
|
+
@input_stream = input_stream
|
10
|
+
@output_stream = output_stream
|
11
|
+
end
|
12
|
+
|
13
|
+
# Creates and returns a HighLine instance, set up to use the supplied streams
|
14
|
+
def high_line
|
15
|
+
return @high_line if @high_line
|
16
|
+
HighLine.track_eof = false
|
17
|
+
@high_line = HighLine.new(input_stream, output_stream)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Adds text to the output stream
|
21
|
+
def inject(text)
|
22
|
+
@output_stream << text
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module HighLine::Test
|
2
|
+
# Wraps a pipe, supplying a non-blocking #gets method
|
3
|
+
class PartialReader
|
4
|
+
attr_reader :stream
|
5
|
+
|
6
|
+
def initialize(stream)
|
7
|
+
@stream = stream
|
8
|
+
end
|
9
|
+
|
10
|
+
def gets
|
11
|
+
stream.readpartial(PIPE_BUFFER_SIZE)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
@@ -0,0 +1,215 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module HighLine::Test
|
4
|
+
describe Client do
|
5
|
+
let(:input_read) { double('IO input pipe - read end', closed?: true) }
|
6
|
+
let(:input_write) { double('IO input pipe - write end', closed?: true) }
|
7
|
+
let(:output_read) { double('IO output pipe - read end', closed?: true) }
|
8
|
+
let(:output_write) { double('IO output pipe - write end', closed?: true) }
|
9
|
+
let(:input_pipe) { [input_read, input_write] }
|
10
|
+
let(:output_pipe) { [output_read, output_write] }
|
11
|
+
let(:streams) { input_pipe + output_pipe }
|
12
|
+
let(:child_pid) { 'child_pid' }
|
13
|
+
let(:running_subject) do
|
14
|
+
subject.run {}
|
15
|
+
subject
|
16
|
+
end
|
17
|
+
|
18
|
+
before do
|
19
|
+
subject.stub(:fork).and_return(child_pid)
|
20
|
+
IO.stub(:pipe).and_return(input_pipe, output_pipe)
|
21
|
+
Process.stub(:kill)
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#delay' do
|
25
|
+
it 'defaults to 0.1' do
|
26
|
+
expect(subject.delay).to eq(0.1)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#delay=' do
|
31
|
+
it 'sets the delay value' do
|
32
|
+
subject.delay = 0.3
|
33
|
+
|
34
|
+
expect(subject.delay).to eq(0.3)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#run' do
|
39
|
+
it 'fails if no block is passed' do
|
40
|
+
expect {
|
41
|
+
subject.run
|
42
|
+
}.to raise_error(RuntimeError, /Supply a block/)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'creates two pipes' do
|
46
|
+
subject.run {}
|
47
|
+
|
48
|
+
expect(IO).to have_received(:pipe).twice
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'forks' do
|
52
|
+
subject.run {}
|
53
|
+
|
54
|
+
expect(subject).to have_received(:fork)
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'child process' do
|
58
|
+
let(:partial_reader) { double('PartialReader') }
|
59
|
+
let(:driver) { double('Driver') }
|
60
|
+
|
61
|
+
before do
|
62
|
+
subject.stub(:fork).and_return(nil)
|
63
|
+
PartialReader.stub(:new).and_return(partial_reader)
|
64
|
+
Driver.stub(:new).with(partial_reader, output_write).and_return(driver)
|
65
|
+
Process.stub(:pid).and_return(child_pid)
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'wraps the input stream in a class with a non-blocking #gets method' do
|
69
|
+
subject.run {}
|
70
|
+
|
71
|
+
expect(PartialReader).to have_received(:new).with(input_read)
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'sets up a driver' do
|
75
|
+
subject.run {}
|
76
|
+
|
77
|
+
expect(Driver).to have_received(:new).with(partial_reader, output_write)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'calls the block' do
|
81
|
+
calls = 0
|
82
|
+
p = proc { calls += 1 }
|
83
|
+
|
84
|
+
subject.run(&p)
|
85
|
+
|
86
|
+
expect(calls).to eq(1)
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'kills the child process if the block returns' do
|
90
|
+
subject.run {}
|
91
|
+
|
92
|
+
expect(Process).to have_received(:pid)
|
93
|
+
expect(Process).to have_received(:kill).with(:KILL, child_pid)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'parent process' do
|
98
|
+
before do
|
99
|
+
PartialReader.stub(:new)
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'returns immediately' do
|
103
|
+
subject.run {}
|
104
|
+
|
105
|
+
expect(PartialReader).to_not have_received(:new)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe '#cleanup' do
|
111
|
+
it 'kills the child process' do
|
112
|
+
running_subject.cleanup
|
113
|
+
|
114
|
+
expect(Process).to have_received(:kill).with(:KILL, child_pid)
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'does nothing if not running' do
|
118
|
+
subject.cleanup
|
119
|
+
|
120
|
+
expect(Process).to_not have_received(:kill)
|
121
|
+
end
|
122
|
+
|
123
|
+
it "doesn't fail if the child process has terminated" do
|
124
|
+
Process.stub(:kill).and_raise(Errno::ESRCH)
|
125
|
+
|
126
|
+
expect {
|
127
|
+
running_subject.cleanup
|
128
|
+
}.not_to raise_error
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'closes pipes' do
|
132
|
+
streams.each do |stream|
|
133
|
+
stream.stub(closed?: false)
|
134
|
+
stream.stub(:close)
|
135
|
+
end
|
136
|
+
|
137
|
+
running_subject.cleanup
|
138
|
+
|
139
|
+
streams.each do |stream|
|
140
|
+
expect(stream).to have_received(:close)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe '#running?' do
|
146
|
+
it 'is true in the parent after #run is called' do
|
147
|
+
expect(running_subject.running?).to be_true
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'is false after #cleanup' do
|
151
|
+
running_subject.cleanup
|
152
|
+
|
153
|
+
expect(subject.running?).to be_false
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe '#type' do
|
158
|
+
before do
|
159
|
+
input_write.stub(:<<)
|
160
|
+
subject.stub(:sleep)
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'expects a parameter' do
|
164
|
+
expect {
|
165
|
+
subject.type
|
166
|
+
}.to raise_error(ArgumentError, /0 for 1/)
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'fails if not running' do
|
170
|
+
expect {
|
171
|
+
subject.type 'Ciao'
|
172
|
+
}.to raise_error(RuntimeError, /not running/)
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'appends the text and a new line to the input write stream' do
|
176
|
+
running_subject.type 'Ciao'
|
177
|
+
|
178
|
+
expect(input_write).to have_received(:<<).with("Ciao\n")
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'sleeps for #delay seconds' do
|
182
|
+
running_subject.type 'Ciao'
|
183
|
+
|
184
|
+
expect(running_subject).to have_received(:sleep).with(0.1)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
describe '#output' do
|
189
|
+
before do
|
190
|
+
streams.each do |stream|
|
191
|
+
stream.stub(closed?: false)
|
192
|
+
stream.stub(:close)
|
193
|
+
end
|
194
|
+
output_read.stub(:readpartial).with(4096).and_return('Foo')
|
195
|
+
end
|
196
|
+
|
197
|
+
it 'closes the output write stream' do
|
198
|
+
running_subject.output
|
199
|
+
|
200
|
+
expect(output_write).to have_received(:close)
|
201
|
+
end
|
202
|
+
|
203
|
+
it 'gets the output from HighLine' do
|
204
|
+
running_subject.output
|
205
|
+
|
206
|
+
expect(output_read).to have_received(:readpartial).with(4096)
|
207
|
+
end
|
208
|
+
|
209
|
+
it 'returns the output' do
|
210
|
+
expect(running_subject.output).to eq('Foo')
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module HighLine::Test
|
4
|
+
describe Driver do
|
5
|
+
let(:input_stream) { double('IO input') }
|
6
|
+
let(:output_stream) { double('IO output') }
|
7
|
+
|
8
|
+
subject { Driver.new(input_stream, output_stream) }
|
9
|
+
|
10
|
+
describe '#initialize' do
|
11
|
+
it 'expects an input and an output stream' do
|
12
|
+
expect {
|
13
|
+
Driver.new
|
14
|
+
}.to raise_error(ArgumentError, /0 for 2/)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#input_stream' do
|
19
|
+
it 'returns the supplied input stream' do
|
20
|
+
expect(subject.input_stream).to eq(input_stream)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#output_stream' do
|
25
|
+
it 'returns the supplied output stream' do
|
26
|
+
expect(subject.output_stream).to eq(output_stream)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#high_line' do
|
31
|
+
let(:high_line) { double('HighLine') }
|
32
|
+
|
33
|
+
before do
|
34
|
+
HighLine.stub(:track_eof=)
|
35
|
+
HighLine.stub(:new).and_return(high_line)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'stops HighLine tracking eof' do
|
39
|
+
subject.high_line
|
40
|
+
|
41
|
+
expect(HighLine).to have_received(:track_eof=).with(false)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'sets up a HighLine instance with the supplied streams' do
|
45
|
+
subject.high_line
|
46
|
+
|
47
|
+
expect(HighLine).to have_received(:new).with(input_stream, output_stream)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'returns the HighLine instance' do
|
51
|
+
expect(subject.high_line).to eq(high_line)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'only creates one instance' do
|
55
|
+
subject.high_line
|
56
|
+
subject.high_line
|
57
|
+
|
58
|
+
expect(HighLine).to have_received(:new).once.with(input_stream, output_stream)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe '#inject' do
|
63
|
+
before do
|
64
|
+
output_stream.stub(:<<)
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'adds text to the output stream' do
|
68
|
+
subject.inject('foo')
|
69
|
+
|
70
|
+
expect(output_stream).to have_received(:<<).with('foo')
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module HighLine::Test
|
4
|
+
describe PartialReader do
|
5
|
+
let(:stream) { double('IO') }
|
6
|
+
|
7
|
+
subject { PartialReader.new(stream) }
|
8
|
+
|
9
|
+
describe '#initialize' do
|
10
|
+
it 'expects a stream parameter' do
|
11
|
+
expect {
|
12
|
+
PartialReader.new
|
13
|
+
}.to raise_error(ArgumentError, /0 for 1/)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#stream' do
|
18
|
+
it 'returns the stream' do
|
19
|
+
expect(subject.stream).to eq(stream)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#gets' do
|
24
|
+
let(:output) { 'Hi there' }
|
25
|
+
|
26
|
+
before do
|
27
|
+
stream.stub(:readpartial).and_return(output)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'performs a non-blocking read' do
|
31
|
+
subject.gets
|
32
|
+
|
33
|
+
expect(stream).to have_received(:readpartial).with(4096)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'returns the result' do
|
37
|
+
expect(subject.gets).to eq(output)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'bourne'
|
3
|
+
require 'highline/test'
|
4
|
+
|
5
|
+
RSpec.configure do |config|
|
6
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
7
|
+
config.run_all_when_everything_filtered = true
|
8
|
+
config.filter_run :focus
|
9
|
+
|
10
|
+
config.order = 'random'
|
11
|
+
end
|
12
|
+
|
metadata
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: highline-test
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Joe Yates
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-07-07 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: highline
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: bundler
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '1.3'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '1.3'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rake
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rspec
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: bourne
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: shoulda-matchers
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
description: Test HighLine applications
|
111
|
+
email:
|
112
|
+
- joe.g.yates@gmail.com
|
113
|
+
executables: []
|
114
|
+
extensions: []
|
115
|
+
extra_rdoc_files: []
|
116
|
+
files:
|
117
|
+
- .gitignore
|
118
|
+
- Gemfile
|
119
|
+
- LICENSE.txt
|
120
|
+
- README.md
|
121
|
+
- Rakefile
|
122
|
+
- highline-test.gemspec
|
123
|
+
- lib/highline/test.rb
|
124
|
+
- lib/highline/test/client.rb
|
125
|
+
- lib/highline/test/driver.rb
|
126
|
+
- lib/highline/test/partial_reader.rb
|
127
|
+
- lib/highline/test/version.rb
|
128
|
+
- spec/lib/highline/test/client_spec.rb
|
129
|
+
- spec/lib/highline/test/driver_spec.rb
|
130
|
+
- spec/lib/highline/test/partial_reader_spec.rb
|
131
|
+
- spec/spec_helper.rb
|
132
|
+
homepage: ''
|
133
|
+
licenses:
|
134
|
+
- MIT
|
135
|
+
post_install_message:
|
136
|
+
rdoc_options: []
|
137
|
+
require_paths:
|
138
|
+
- lib
|
139
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
140
|
+
none: false
|
141
|
+
requirements:
|
142
|
+
- - ! '>='
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
|
+
none: false
|
147
|
+
requirements:
|
148
|
+
- - ! '>='
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: '0'
|
151
|
+
requirements: []
|
152
|
+
rubyforge_project:
|
153
|
+
rubygems_version: 1.8.23
|
154
|
+
signing_key:
|
155
|
+
specification_version: 3
|
156
|
+
summary: A micro framework that sets up tests for HighLine applications
|
157
|
+
test_files:
|
158
|
+
- spec/lib/highline/test/client_spec.rb
|
159
|
+
- spec/lib/highline/test/driver_spec.rb
|
160
|
+
- spec/lib/highline/test/partial_reader_spec.rb
|
161
|
+
- spec/spec_helper.rb
|
162
|
+
has_rdoc:
|