mtbb 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +19 -0
- data/.travis.yml +10 -0
- data/AUTHORS.md +4 -0
- data/CONTRIBUTING.md +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +37 -0
- data/Rakefile +1 -0
- data/bin/mtbb +3 -0
- data/lib/mtbb.rb +335 -0
- data/lib/mtbb/version.rb +3 -0
- data/mtbb.gemspec +25 -0
- data/test/navel +63 -0
- data/test/navel_test.rb +39 -0
- data/test/vanilla_test.rb +14 -0
- metadata +135 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/AUTHORS.md
ADDED
data/CONTRIBUTING.md
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 ModCloth, Inc.
|
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,37 @@
|
|
1
|
+
`mtbb`
|
2
|
+
======
|
3
|
+
|
4
|
+
[![Build Status](https://travis-ci.org/modcloth-labs/mtbb.png)](https://travis-ci.org/modcloth-labs/mtbb)
|
5
|
+
|
6
|
+
Minitest-based black box testing thing.
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Download the whole thing as a standalone executable:
|
11
|
+
|
12
|
+
``` bash
|
13
|
+
curl -s -o mtbb https://raw.github.com/modcloth-labs/mtbb/master/lib/mtbb.rb
|
14
|
+
chmod +x mtbb
|
15
|
+
```
|
16
|
+
|
17
|
+
Or install via `gem`:
|
18
|
+
|
19
|
+
``` bash
|
20
|
+
gem install mtbb
|
21
|
+
```
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
Given a `test` directory containing minitest files of the format
|
26
|
+
`*_test.rb`, run the `mtbb` executable over them:
|
27
|
+
|
28
|
+
``` bash
|
29
|
+
mtbb
|
30
|
+
```
|
31
|
+
|
32
|
+
An alternate test discovery glob may be given a la:
|
33
|
+
|
34
|
+
``` bash
|
35
|
+
MTBB_TEST_GLOB='./black-box-tests/**/*_test.rb' mtbb
|
36
|
+
```
|
37
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/mtbb
ADDED
data/lib/mtbb.rb
ADDED
@@ -0,0 +1,335 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# vim:fileencoding=utf-8
|
3
|
+
#
|
4
|
+
# Copyright (c) 2013 ModCloth, Inc.
|
5
|
+
#
|
6
|
+
# MIT License
|
7
|
+
#
|
8
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
9
|
+
# a copy of this software and associated documentation files (the
|
10
|
+
# "Software"), to deal in the Software without restriction, including
|
11
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
12
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
13
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
14
|
+
# the following conditions:
|
15
|
+
#
|
16
|
+
# The above copyright notice and this permission notice shall be
|
17
|
+
# included in all copies or substantial portions of the Software.
|
18
|
+
#
|
19
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
20
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
21
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
22
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
23
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
24
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
25
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
26
|
+
#
|
27
|
+
|
28
|
+
require 'fileutils'
|
29
|
+
require 'json'
|
30
|
+
require 'minitest/spec'
|
31
|
+
require 'net/http'
|
32
|
+
require 'time'
|
33
|
+
require 'uri'
|
34
|
+
|
35
|
+
begin
|
36
|
+
require_relative 'mtbb/version'
|
37
|
+
rescue LoadError
|
38
|
+
end
|
39
|
+
|
40
|
+
module Mtbb
|
41
|
+
VERSION = '0.1.0' unless defined?(VERSION)
|
42
|
+
|
43
|
+
YELLOW = "\033\[33m"
|
44
|
+
RESET = "\033\[0m"
|
45
|
+
GREEN = "\033\[32m"
|
46
|
+
RED = "\033\[31m"
|
47
|
+
MAGENTA = "\033\[35m"
|
48
|
+
BRIGHT_GREEN = "\033\[32;1m"
|
49
|
+
BRIGHT_RED = "\033\[31;1m"
|
50
|
+
BRIGHT_MAGENTA = "\033\[35;1m"
|
51
|
+
BRIGHT_YELLOW = "\033\[33;1m"
|
52
|
+
|
53
|
+
SERVERS = {}
|
54
|
+
|
55
|
+
def register(server_name, server_config)
|
56
|
+
SERVERS[server_name.to_sym] = Mtbb::ServerRunner.new(server_config)
|
57
|
+
end
|
58
|
+
|
59
|
+
def server(server_name)
|
60
|
+
SERVERS[server_name.to_sym]
|
61
|
+
end
|
62
|
+
|
63
|
+
module_function :register, :server
|
64
|
+
|
65
|
+
class TestRunner
|
66
|
+
def self.main(argv = [].freeze)
|
67
|
+
mtbb_test_glob = ENV['MTBB_TEST_GLOB'] || "#{Dir.pwd}/test/**/*_test.rb"
|
68
|
+
Dir.glob(mtbb_test_glob).each do |f|
|
69
|
+
require f
|
70
|
+
end
|
71
|
+
|
72
|
+
unless argv.include?('-h') || argv.include?('--help')
|
73
|
+
ServerControl.start_servers
|
74
|
+
Mtbb.announce! 'Started servers'
|
75
|
+
at_exit do
|
76
|
+
ServerControl.stop_servers
|
77
|
+
Mtbb.announce! 'Stopped servers'
|
78
|
+
end
|
79
|
+
|
80
|
+
MiniTest::Unit.output = MiniTestReporter.new
|
81
|
+
end
|
82
|
+
|
83
|
+
exit_code = MiniTest::Unit.new.run(argv) || 1
|
84
|
+
|
85
|
+
if exit_code == 0
|
86
|
+
$stderr.puts BRIGHT_GREEN
|
87
|
+
$stderr.puts <<-EOF.gsub(/^ {8}/, '')
|
88
|
+
✓✓ ✓✓ ✓✓✓✓ ✓✓ ✓✓
|
89
|
+
✓✓ ✓✓ ✓✓ ✓✓ ✓✓✓ ✓✓
|
90
|
+
✓✓ ✓✓ ✓✓ ✓✓ ✓✓✓✓ ✓✓
|
91
|
+
✓✓ ✓✓ ✓✓ ✓✓ ✓✓ ✓✓ ✓✓
|
92
|
+
✓✓ ✓✓ ✓✓ ✓✓ ✓✓ ✓✓✓✓
|
93
|
+
✓✓ ✓✓ ✓✓ ✓✓ ✓✓ ✓✓✓
|
94
|
+
✓✓✓ ✓✓✓ ✓✓✓✓ ✓✓ ✓✓
|
95
|
+
EOF
|
96
|
+
$stderr.puts RESET
|
97
|
+
else
|
98
|
+
$stderr.puts BRIGHT_RED
|
99
|
+
$stderr.puts <<-EOF.gsub(/^ {8}/, '')
|
100
|
+
✘✘✘✘✘✘✘✘ ✘✘✘ ✘✘✘✘ ✘✘
|
101
|
+
✘✘ ✘✘ ✘✘ ✘✘ ✘✘
|
102
|
+
✘✘ ✘✘ ✘✘ ✘✘ ✘✘
|
103
|
+
✘✘✘✘✘✘ ✘✘ ✘✘ ✘✘ ✘✘
|
104
|
+
✘✘ ✘✘✘✘✘✘✘✘✘ ✘✘ ✘✘
|
105
|
+
✘✘ ✘✘ ✘✘ ✘✘ ✘✘
|
106
|
+
✘✘ ✘✘ ✘✘ ✘✘✘✘ ✘✘✘✘✘✘✘✘
|
107
|
+
EOF
|
108
|
+
$stderr.puts RESET
|
109
|
+
Mtbb::SERVERS.each do |_, server|
|
110
|
+
Mtbb.announce! "Dumping stdout for #{server.description}:"
|
111
|
+
server.dump(:stdout)
|
112
|
+
Mtbb.announce! "Dumping stderr for #{server.description}:"
|
113
|
+
server.dump(:stderr)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
if ENV['HOLD_ON_A_SEC']
|
118
|
+
print 'Holding on a sec... [Enter] '
|
119
|
+
gets
|
120
|
+
end
|
121
|
+
exit exit_code
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def announce!(something)
|
126
|
+
$stderr.puts "#{BRIGHT_GREEN}mtbb#{RESET}: #{BRIGHT_YELLOW}#{something}#{RESET}"
|
127
|
+
end
|
128
|
+
|
129
|
+
module_function :announce!
|
130
|
+
|
131
|
+
class ServerRunner
|
132
|
+
attr_reader :executable, :server_name, :argv, :port, :working_dir, :start_time
|
133
|
+
attr_reader :server_pid, :stdout_file, :stderr_file, :server_exit_code
|
134
|
+
attr_reader :options
|
135
|
+
|
136
|
+
def initialize(options = {})
|
137
|
+
@options = options
|
138
|
+
@executable = options.fetch(:executable)
|
139
|
+
options.delete(:executable)
|
140
|
+
@argv = options.delete(:argv) || []
|
141
|
+
|
142
|
+
@server_name = options.delete(:server_name) || "mtbb-server-#{Time.now.utc.to_i}"
|
143
|
+
@start_time = options.delete(:start) || Time.now.utc
|
144
|
+
@port = options.delete(:port)
|
145
|
+
@working_dir = options.delete(:working_dir) || default_working_dir
|
146
|
+
@stdout_file = options.delete(:stdout_file) || default_stdout_file
|
147
|
+
@stderr_file = options.delete(:stderr_file) || default_stderr_file
|
148
|
+
|
149
|
+
if !File.exist?(executable)
|
150
|
+
raise "Can't locate `#{File.basename(executable).inspect}` executable! " <<
|
151
|
+
"(it's not here: #{executable.inspect})"
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def start
|
156
|
+
FileUtils.mkdir_p(working_dir)
|
157
|
+
process_command = command
|
158
|
+
spawn_args = process_command + [
|
159
|
+
out: [stdout_file, 'w'], err: [stderr_file, 'w']
|
160
|
+
]
|
161
|
+
Mtbb.announce! "Starting #{description}"
|
162
|
+
Mtbb.announce! " ---> #{process_command.join(' ')}"
|
163
|
+
Mtbb.announce! " (#{config_details.inspect})"
|
164
|
+
@server_pid = Process.spawn(*spawn_args)
|
165
|
+
server_pid
|
166
|
+
end
|
167
|
+
|
168
|
+
def stop
|
169
|
+
return if !server_pid
|
170
|
+
Mtbb.announce! "Stopping #{description} (PID=#{server_pid})"
|
171
|
+
Process.kill(:TERM, server_pid)
|
172
|
+
begin
|
173
|
+
wait_for_server_process(Integer(ENV['MTBB_PROCESS_EXIT_TIMEOUT'] || 3))
|
174
|
+
rescue TimeoutError
|
175
|
+
end
|
176
|
+
Process.kill(:KILL, server_pid)
|
177
|
+
_, status = Process.waitpid2(server_pid)
|
178
|
+
@server_exit_code = status.exitstatus || status.termsig
|
179
|
+
rescue Errno::ECHILD, Errno::ESRCH
|
180
|
+
true
|
181
|
+
end
|
182
|
+
|
183
|
+
def description
|
184
|
+
"#{server_name} on port #{port}"
|
185
|
+
end
|
186
|
+
|
187
|
+
def config_details
|
188
|
+
{
|
189
|
+
argv: argv,
|
190
|
+
working_dir: working_dir,
|
191
|
+
start_time: start_time,
|
192
|
+
stdout_file: stdout_file,
|
193
|
+
stderr_file: stderr_file,
|
194
|
+
}
|
195
|
+
end
|
196
|
+
|
197
|
+
def command
|
198
|
+
cmd = [executable] + argv
|
199
|
+
options.each do |k,v|
|
200
|
+
if v.nil?
|
201
|
+
cmd << k
|
202
|
+
next
|
203
|
+
end
|
204
|
+
cmd << k << v.inspect
|
205
|
+
end
|
206
|
+
cmd
|
207
|
+
end
|
208
|
+
|
209
|
+
def dump(which = :stdout)
|
210
|
+
$stderr.puts File.read(send(:"#{which.to_s}_file"))
|
211
|
+
end
|
212
|
+
|
213
|
+
private
|
214
|
+
|
215
|
+
def wait_for_server_process(timeout)
|
216
|
+
toolate = Time.now + timeout
|
217
|
+
unless (done = server_exited?) || Time.now > toolate
|
218
|
+
sleep Float(ENV['MTBB_PROCESS_EXIT_POLL_INTERVAL'] || 0.1)
|
219
|
+
end
|
220
|
+
|
221
|
+
unless done
|
222
|
+
raise TimeoutError
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
# Largely inspired by ChildProcess::Unix::Process#exited?
|
227
|
+
def server_exited?
|
228
|
+
return true if server_exit_code
|
229
|
+
|
230
|
+
pid, status = Process.waitpid2(server_pid, Process::WNOHANG)
|
231
|
+
pid = pid == 0 ? nil : pid
|
232
|
+
|
233
|
+
if pid
|
234
|
+
@server_exit_code = status.exitstatus || status.termsig
|
235
|
+
end
|
236
|
+
|
237
|
+
!!pid
|
238
|
+
end
|
239
|
+
|
240
|
+
def default_working_dir
|
241
|
+
File.join(Dir.pwd, '.mtbb-artifacts')
|
242
|
+
end
|
243
|
+
|
244
|
+
def default_stdout_file
|
245
|
+
File.join(working_dir, "#{server_name}.out")
|
246
|
+
end
|
247
|
+
|
248
|
+
def default_stderr_file
|
249
|
+
File.join(working_dir, "#{server_name}.err")
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
class MiniTestReporter
|
254
|
+
def puts(*args)
|
255
|
+
args.each { |arg| Mtbb.announce! arg }
|
256
|
+
end
|
257
|
+
|
258
|
+
alias print puts
|
259
|
+
end
|
260
|
+
|
261
|
+
module NetThings
|
262
|
+
def http(method_name, path, options = {})
|
263
|
+
options[:path] ||= path
|
264
|
+
send("#{method_name.downcase}_request", options)
|
265
|
+
end
|
266
|
+
|
267
|
+
def post_request(options = {})
|
268
|
+
request = Net::HTTP::Post.new(options[:path] || '/')
|
269
|
+
request.content_type = 'application/x-www-form-urlencoded'
|
270
|
+
request.body = options.fetch(:body)
|
271
|
+
perform_request(request, options.fetch(:port))
|
272
|
+
end
|
273
|
+
|
274
|
+
def get_request(options = {})
|
275
|
+
perform_request(
|
276
|
+
Net::HTTP::Get.new(options[:path] || '/'),
|
277
|
+
options.fetch(:port)
|
278
|
+
)
|
279
|
+
end
|
280
|
+
|
281
|
+
def delete_request(options = {})
|
282
|
+
perform_request(
|
283
|
+
Net::HTTP::Delete.new(options[:path] || '/'),
|
284
|
+
options.fetch(:port)
|
285
|
+
)
|
286
|
+
end
|
287
|
+
|
288
|
+
private
|
289
|
+
|
290
|
+
def perform_request(request, port)
|
291
|
+
Net::HTTP.start(ENV['MTBB_SERVER_HOST'] || 'localhost', port) do |http|
|
292
|
+
http.open_timeout = Integer(ENV['MTBB_HTTP_OPEN_TIMEOUT'] || 1)
|
293
|
+
http.read_timeout = Integer(ENV['MTBB_HTTP_READ_TIMEOUT'] || 3)
|
294
|
+
response = http.request(request)
|
295
|
+
response
|
296
|
+
end
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
class ServerControl
|
301
|
+
def self.stop_servers
|
302
|
+
Mtbb::SERVERS.each do |_,server|
|
303
|
+
server.stop
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
def self.start_servers
|
308
|
+
Dir.chdir(File.expand_path('../', __FILE__)) do
|
309
|
+
FileUtils.mkdir_p('./.mtbb-artifacts')
|
310
|
+
Mtbb::SERVERS.each do |_,runner|
|
311
|
+
runner.start
|
312
|
+
wait_for_server(runner.port)
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
def self.wait_for_server(http_port)
|
318
|
+
maxloops = 10
|
319
|
+
curloop = 0
|
320
|
+
begin
|
321
|
+
TCPSocket.new(ENV['MTBB_SERVER_HOST'] || 'localhost', http_port).close
|
322
|
+
rescue
|
323
|
+
curloop += 1
|
324
|
+
if curloop < maxloops
|
325
|
+
sleep 0.5
|
326
|
+
retry
|
327
|
+
end
|
328
|
+
end
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
if __FILE__ == $0
|
334
|
+
Mtbb::TestRunner.main(ARGV)
|
335
|
+
end
|
data/lib/mtbb/version.rb
ADDED
data/mtbb.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# vim:fileencoding=utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'mtbb/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'mtbb'
|
8
|
+
spec.version = Mtbb::VERSION
|
9
|
+
spec.authors = ['Dan Buch']
|
10
|
+
spec.email = ['d.buch@modcloth.com']
|
11
|
+
spec.description = %q{Minitest-based black box testing thing}
|
12
|
+
spec.summary = %q{Minitest-based black box testing thing}
|
13
|
+
spec.homepage = 'https://github.com/modcloth-labs/mtbb'
|
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{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_development_dependency 'bundler'
|
22
|
+
spec.add_development_dependency 'rack'
|
23
|
+
spec.add_development_dependency 'rake'
|
24
|
+
spec.add_development_dependency 'thin'
|
25
|
+
end
|
data/test/navel
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rack'
|
4
|
+
require 'time'
|
5
|
+
|
6
|
+
class NavelApp
|
7
|
+
def call(env)
|
8
|
+
send(:"handle_#{env['REQUEST_METHOD'].downcase}", Rack::Request.new(env))
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def handle_get(request)
|
14
|
+
case request.path_info
|
15
|
+
when '/affirmation'
|
16
|
+
return [200, {'Content-Type' => 'text/plain'}, ["yup\n"]]
|
17
|
+
else
|
18
|
+
handle_404(request)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def handle_post(request)
|
23
|
+
case request.path_info
|
24
|
+
when '/dinner/new'
|
25
|
+
body = request.body.read
|
26
|
+
if body.split("\n").include?('soup=splitpea')
|
27
|
+
return [201, {'Content-Type' => 'text/plain'}, ["soup is on!\n"]]
|
28
|
+
else
|
29
|
+
return [
|
30
|
+
400,
|
31
|
+
{'Content-Type' => 'text/plain'},
|
32
|
+
["invalid dinner:\n" << body << "\n"]
|
33
|
+
]
|
34
|
+
end
|
35
|
+
else
|
36
|
+
handle_404(request)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def handle_delete(request)
|
41
|
+
case request.path_info
|
42
|
+
when '/pestilence'
|
43
|
+
return [204, {'Content-Type' => 'text/plain'}, ["orphanage saved!\n"]]
|
44
|
+
else
|
45
|
+
handle_404(client)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def handle_404(client)
|
50
|
+
[404, {'Content-Type' => 'text/plain'} ["nope\n"]]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def main(argv = [])
|
55
|
+
port = Integer(argv.first || 19080)
|
56
|
+
$stdout.sync = true
|
57
|
+
$stderr.sync = true
|
58
|
+
Rack::Handler::Thin.run(NavelApp.new, Port: port)
|
59
|
+
end
|
60
|
+
|
61
|
+
if __FILE__ == $0
|
62
|
+
main(ARGV)
|
63
|
+
end
|
data/test/navel_test.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'tmpdir'
|
2
|
+
require 'minitest/unit'
|
3
|
+
|
4
|
+
Mtbb.register(:navel,
|
5
|
+
executable: File.expand_path('../navel', __FILE__),
|
6
|
+
argv: %w(9899),
|
7
|
+
server_name: 'mtbb-navel',
|
8
|
+
port: 9899,
|
9
|
+
working_dir: Dir.mktmpdir('mtbb-navel'),
|
10
|
+
)
|
11
|
+
|
12
|
+
describe 'navel test' do
|
13
|
+
include Mtbb::NetThings
|
14
|
+
|
15
|
+
it 'supports HTTP GET' do
|
16
|
+
response = http('GET', '/affirmation', port: Mtbb.server(:navel).port)
|
17
|
+
response.code.must_equal '200'
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'supports HTTP POST' do
|
21
|
+
response = http('POST', '/dinner/new',
|
22
|
+
port: Mtbb.server(:navel).port, body: "soup=splitpea\n")
|
23
|
+
response.code.must_equal '201'
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'supports HTTP DELETE' do
|
27
|
+
response = http('DELETE', '/pestilence', port: Mtbb.server(:navel).port)
|
28
|
+
response.code.must_equal '204'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class NavelTest < MiniTest::Unit
|
33
|
+
include Mtbb::NetThings
|
34
|
+
|
35
|
+
def test_works_with_unit_tests_too
|
36
|
+
response = http('GET', '/nerp', port: Mtbb.server(:navel).port)
|
37
|
+
response.code.must_equal '404'
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'minitest/spec'
|
2
|
+
require 'minitest/unit'
|
3
|
+
|
4
|
+
describe 'vanilla' do
|
5
|
+
it 'supports regular old minitest specs' do
|
6
|
+
(1 + 1).must_equal 2
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class TestVanilla < MiniTest::Unit
|
11
|
+
def test_supports_regular_old_minitest_tests
|
12
|
+
(1 - 1).must_equal 0
|
13
|
+
end
|
14
|
+
end
|
metadata
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mtbb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Dan Buch
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-08-25 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
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: rack
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
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: '0'
|
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: thin
|
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
|
+
description: Minitest-based black box testing thing
|
79
|
+
email:
|
80
|
+
- d.buch@modcloth.com
|
81
|
+
executables:
|
82
|
+
- mtbb
|
83
|
+
extensions: []
|
84
|
+
extra_rdoc_files: []
|
85
|
+
files:
|
86
|
+
- .gitignore
|
87
|
+
- .travis.yml
|
88
|
+
- AUTHORS.md
|
89
|
+
- CONTRIBUTING.md
|
90
|
+
- Gemfile
|
91
|
+
- LICENSE.txt
|
92
|
+
- README.md
|
93
|
+
- Rakefile
|
94
|
+
- bin/mtbb
|
95
|
+
- lib/mtbb.rb
|
96
|
+
- lib/mtbb/version.rb
|
97
|
+
- mtbb.gemspec
|
98
|
+
- test/navel
|
99
|
+
- test/navel_test.rb
|
100
|
+
- test/vanilla_test.rb
|
101
|
+
homepage: https://github.com/modcloth-labs/mtbb
|
102
|
+
licenses:
|
103
|
+
- MIT
|
104
|
+
post_install_message:
|
105
|
+
rdoc_options: []
|
106
|
+
require_paths:
|
107
|
+
- lib
|
108
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
109
|
+
none: false
|
110
|
+
requirements:
|
111
|
+
- - ! '>='
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
114
|
+
segments:
|
115
|
+
- 0
|
116
|
+
hash: 4294838388783584232
|
117
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
|
+
none: false
|
119
|
+
requirements:
|
120
|
+
- - ! '>='
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
segments:
|
124
|
+
- 0
|
125
|
+
hash: 4294838388783584232
|
126
|
+
requirements: []
|
127
|
+
rubyforge_project:
|
128
|
+
rubygems_version: 1.8.23
|
129
|
+
signing_key:
|
130
|
+
specification_version: 3
|
131
|
+
summary: Minitest-based black box testing thing
|
132
|
+
test_files:
|
133
|
+
- test/navel
|
134
|
+
- test/navel_test.rb
|
135
|
+
- test/vanilla_test.rb
|