mtbb 0.1.0
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 +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
|
+
[](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
|