testbot 0.3.5 → 0.3.6
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +4 -0
- data/README.markdown +2 -5
- data/lib/adapters/cucumber_adapter.rb +13 -4
- data/lib/adapters/rspec_adapter.rb +13 -3
- data/lib/adapters/test_unit_adapter.rb +12 -2
- data/lib/generators/testbot/templates/testbot.rake.erb +3 -3
- data/lib/generators/testbot/templates/testbot.yml.erb +10 -10
- data/lib/generators/testbot/testbot_generator.rb +8 -4
- data/lib/requester.rb +2 -10
- data/lib/testbot.rb +121 -118
- data/testbot.gemspec +1 -0
- metadata +22 -8
data/CHANGELOG
CHANGED
data/README.markdown
CHANGED
@@ -68,11 +68,8 @@ Using testbot with Rails 3:
|
|
68
68
|
|
69
69
|
Using testbot with Rails 2:
|
70
70
|
|
71
|
-
ruby script/plugin install git://github.com/joakimk/testbot.git -r 'refs/tags/v0.3.
|
72
|
-
|
73
|
-
The rails 2 config generator isn't done yet so you can look at the following examples instead:
|
74
|
-
[lib/tasks/testbot.rake](https://gist.github.com/715836) and
|
75
|
-
[config/testbot.yml](https://gist.github.com/715839).
|
71
|
+
ruby script/plugin install git://github.com/joakimk/testbot.git -r 'refs/tags/v0.3.6'
|
72
|
+
script/generate testbot --connect 192.168.0.100
|
76
73
|
|
77
74
|
rake testbot:spec (or :test, :features)
|
78
75
|
|
@@ -3,11 +3,15 @@ class CucumberAdapter
|
|
3
3
|
def self.command(ruby_interpreter, files)
|
4
4
|
"export AUTOTEST=1; #{ruby_interpreter} script/cucumber -f progress --backtrace -r features/support -r features/step_definitions #{files} -t ~@disabled_in_cruise"
|
5
5
|
end
|
6
|
-
|
7
|
-
def self.
|
8
|
-
|
6
|
+
|
7
|
+
def self.test_files(dir)
|
8
|
+
Dir["#{dir}/#{file_pattern}"]
|
9
9
|
end
|
10
10
|
|
11
|
+
def self.get_sizes(files)
|
12
|
+
files.map { |file| File.stat(file).size }
|
13
|
+
end
|
14
|
+
|
11
15
|
def self.requester_port
|
12
16
|
2230
|
13
17
|
end
|
@@ -27,5 +31,10 @@ class CucumberAdapter
|
|
27
31
|
def self.type
|
28
32
|
pluralized
|
29
33
|
end
|
30
|
-
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def self.file_pattern
|
38
|
+
'**/**/*.feature'
|
39
|
+
end
|
31
40
|
end
|
@@ -4,8 +4,12 @@ class RSpecAdapter
|
|
4
4
|
"export RSPEC_COLOR=true; #{ruby_interpreter} script/spec -O spec/spec.opts #{files}"
|
5
5
|
end
|
6
6
|
|
7
|
-
def self.
|
8
|
-
|
7
|
+
def self.test_files(dir)
|
8
|
+
Dir["#{dir}/#{file_pattern}"]
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.get_sizes(files)
|
12
|
+
files.map { |file| File.stat(file).size }
|
9
13
|
end
|
10
14
|
|
11
15
|
def self.requester_port
|
@@ -27,5 +31,11 @@ class RSpecAdapter
|
|
27
31
|
def self.type
|
28
32
|
'spec'
|
29
33
|
end
|
30
|
-
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def self.file_pattern
|
38
|
+
'**/**/*_spec.rb'
|
39
|
+
end
|
40
|
+
|
31
41
|
end
|
@@ -4,8 +4,12 @@ class TestUnitAdapter
|
|
4
4
|
"#{ruby_interpreter} -Itest -e '%w(#{files}).each { |file| require(file) }'"
|
5
5
|
end
|
6
6
|
|
7
|
-
def self.
|
8
|
-
|
7
|
+
def self.test_files(dir)
|
8
|
+
Dir["#{dir}/#{file_pattern}"]
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.get_sizes(files)
|
12
|
+
files.map { |file| File.stat(file).size }
|
9
13
|
end
|
10
14
|
|
11
15
|
def self.requester_port
|
@@ -28,4 +32,10 @@ class TestUnitAdapter
|
|
28
32
|
'test'
|
29
33
|
end
|
30
34
|
|
35
|
+
private
|
36
|
+
|
37
|
+
def self.file_pattern
|
38
|
+
'**/**/*_test.rb'
|
39
|
+
end
|
40
|
+
|
31
41
|
end
|
@@ -11,7 +11,7 @@ namespace :testbot do
|
|
11
11
|
test:
|
12
12
|
adapter: mysql
|
13
13
|
encoding: utf8
|
14
|
-
database: <%= options
|
14
|
+
database: <%= options[:project] %>_testbot_test<%%= ENV['TEST_ENV_NUMBER'] %>
|
15
15
|
username: root
|
16
16
|
password:
|
17
17
|
host: localhost
|
@@ -23,8 +23,8 @@ DB_CONFIG
|
|
23
23
|
# # Setup databases for all instances
|
24
24
|
# 0.upto(ENV['TEST_INSTANCES'].to_i - 1) do |instance|
|
25
25
|
# test_env_number = (instance == 0) ? '' : instance + 1
|
26
|
-
# system "mysqladmin -u root -f drop <%= options
|
27
|
-
# system "mysqladmin -u root -f create <%= options
|
26
|
+
# system "mysqladmin -u root -f drop <%= options[:project] %>_testbot_test#{test_env_number} > /dev/null 2>&1"
|
27
|
+
# system "mysqladmin -u root -f create <%= options[:project] %>_testbot_test#{test_env_number} > /dev/null 2>&1"
|
28
28
|
# system "export RAILS_ENV=test; export TEST_ENV_NUMBER=#{test_env_number}; rake db:test:load"
|
29
29
|
# end
|
30
30
|
|
@@ -1,34 +1,34 @@
|
|
1
1
|
# Which server to use.
|
2
|
-
server_host: <%= options
|
3
|
-
<%- if options
|
4
|
-
server_user: <%= options
|
2
|
+
server_host: <%= options[:connect] %>
|
3
|
+
<%- if options[:user] -%>
|
4
|
+
server_user: <%= options[:user] %>
|
5
5
|
<%- else -%>
|
6
6
|
# server_user: <%= Testbot::DEFAULT_USER %>
|
7
7
|
<%- end -%>
|
8
8
|
|
9
9
|
# Project prefix. Used for prefixing project files
|
10
10
|
# so that you can run multiple projects in the same testbot network.
|
11
|
-
<%- if options
|
12
|
-
project: <%= options
|
11
|
+
<%- if options[:project] %>
|
12
|
+
project: <%= options[:project] %>
|
13
13
|
<%- else -%>
|
14
14
|
# project: <%= Testbot::DEFAULT_PROJECT %>
|
15
15
|
<%- end -%>
|
16
16
|
|
17
17
|
# RSync settings. The folder where your files are synced to
|
18
18
|
# and then fetched from before running the tests.
|
19
|
-
<%- if options
|
20
|
-
rsync_path: <%= options
|
19
|
+
<%- if options[:rsync_path] -%>
|
20
|
+
rsync_path: <%= options[:rsync_path] %>
|
21
21
|
<%- else -%>
|
22
22
|
# rsync_path: <%= Testbot::DEFAULT_SERVER_PATH %>
|
23
23
|
<%- end -%>
|
24
|
-
<%- if options
|
25
|
-
rsync_ignores: <%= options
|
24
|
+
<%- if options[:rsync_ignores] -%>
|
25
|
+
rsync_ignores: <%= options[:rsync_ignores] %>
|
26
26
|
<%- else -%>
|
27
27
|
# rsync_ignores:
|
28
28
|
<%- end -%>
|
29
29
|
|
30
30
|
# To tunnel traffic through SSH
|
31
|
-
<%- if options
|
31
|
+
<%- if options[:ssh_tunnel] -%>
|
32
32
|
ssh_tunnel: true
|
33
33
|
<%- else -%>
|
34
34
|
# ssh_tunnel: true
|
@@ -1,9 +1,12 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../../testbot")
|
2
|
+
require "acts_as_rails3_generator"
|
3
|
+
|
1
4
|
class TestbotGenerator < Rails::Generators::Base
|
2
5
|
source_root File.expand_path('../templates', __FILE__)
|
3
|
-
|
4
|
-
class_option :connect, :type => :string, :required => true, :desc => "Which server to use (required)"
|
5
|
-
class_option :project, :type => :string, :default => nil, :desc => "The name of your project (default: #{Testbot::DEFAULT_PROJECT})"
|
6
|
-
class_option :rsync_path, :type => :string, :default => nil, :desc => "Sync path on the server (default: #{Testbot::DEFAULT_SERVER_PATH})"
|
6
|
+
|
7
|
+
class_option :connect, :type => :string, :required => true, :desc => "Which server to use (required)"
|
8
|
+
class_option :project, :type => :string, :default => nil, :desc => "The name of your project (default: #{Testbot::DEFAULT_PROJECT})"
|
9
|
+
class_option :rsync_path, :type => :string, :default => nil, :desc => "Sync path on the server (default: #{Testbot::DEFAULT_SERVER_PATH})"
|
7
10
|
class_option :rsync_ignores, :type => :string, :default => nil, :desc => "Files to rsync_ignores when syncing (default: include all)"
|
8
11
|
class_option :ssh_tunnel, :type => :boolean, :default => nil, :desc => "Use a ssh tunnel"
|
9
12
|
class_option :user, :type => :string, :default => nil, :desc => "Use a custom rsync / ssh tunnel user (default: #{Testbot::DEFAULT_USER})"
|
@@ -13,3 +16,4 @@ class TestbotGenerator < Rails::Generators::Base
|
|
13
16
|
template "testbot.rake.erb", "lib/tasks/testbot.rake"
|
14
17
|
end
|
15
18
|
end
|
19
|
+
|
data/lib/requester.rb
CHANGED
@@ -41,8 +41,8 @@ class Requester
|
|
41
41
|
rsync_ignores = config.rsync_ignores.to_s.split.map { |pattern| "--exclude='#{pattern}'" }.join(' ')
|
42
42
|
system "rsync -az --delete -e ssh #{rsync_ignores} . #{rsync_uri}"
|
43
43
|
|
44
|
-
files =
|
45
|
-
sizes =
|
44
|
+
files = adapter.test_files(dir)
|
45
|
+
sizes = adapter.get_sizes(files)
|
46
46
|
|
47
47
|
build_id = HTTParty.post("#{server_uri}/builds", :body => { :root => root,
|
48
48
|
:type => adapter.type.to_s,
|
@@ -132,14 +132,6 @@ class Requester
|
|
132
132
|
line =~ /(\d{2,}|[1-9]) (fail|error)/
|
133
133
|
end
|
134
134
|
|
135
|
-
def find_tests(adapter, dir)
|
136
|
-
Dir["#{dir}/#{adapter.file_pattern}"]
|
137
|
-
end
|
138
|
-
|
139
|
-
def find_sizes(files)
|
140
|
-
files.map { |file| File.stat(file).size }
|
141
|
-
end
|
142
|
-
|
143
135
|
def jruby?
|
144
136
|
RUBY_PLATFORM =~ /java/ || !!ENV['USE_JRUBY']
|
145
137
|
end
|
data/lib/testbot.rb
CHANGED
@@ -1,128 +1,131 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require '
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
1
|
+
# Because rails 2 autoloads constrants even if they already exists?...
|
2
|
+
unless defined?(Testbot)
|
3
|
+
require File.join(File.dirname(__FILE__), '/shared/simple_daemonize')
|
4
|
+
require File.join(File.dirname(__FILE__), '/adapters/adapter')
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
module Testbot
|
8
|
+
require 'railtie' if defined?(Rails)
|
9
|
+
|
10
|
+
# Don't forget to update readme and changelog
|
11
|
+
VERSION = "0.3.6"
|
12
|
+
|
13
|
+
SERVER_PID = "/tmp/testbot_server.pid"
|
14
|
+
RUNNER_PID = "/tmp/testbot_runner.pid"
|
15
|
+
DEFAULT_WORKING_DIR = "/tmp/testbot"
|
16
|
+
DEFAULT_SERVER_PATH = "/tmp/testbot/#{ENV['USER']}"
|
17
|
+
DEFAULT_USER = "testbot"
|
18
|
+
DEFAULT_PROJECT = "project"
|
19
|
+
DEFAULT_RUNNER_USAGE = "100%"
|
20
|
+
SERVER_PORT = ENV['INTEGRATION_TEST'] ? 22880 : 2288
|
21
|
+
|
22
|
+
class CLI
|
23
|
+
|
24
|
+
def self.run(argv)
|
25
|
+
return false if argv == []
|
26
|
+
opts = parse_args(argv)
|
27
|
+
|
28
|
+
if opts[:help]
|
29
|
+
return false
|
30
|
+
elsif opts[:version]
|
31
|
+
puts "Testbot #{Testbot::VERSION}"
|
32
|
+
elsif [ true, 'run', 'start' ].include?(opts[:server])
|
33
|
+
start_server(opts[:server])
|
34
|
+
elsif opts[:server] == 'stop'
|
35
|
+
stop('server', Testbot::SERVER_PID)
|
36
|
+
elsif [ true, 'run', 'start' ].include?(opts[:runner])
|
37
|
+
require File.join(File.dirname(__FILE__), '/runner')
|
38
|
+
return false unless valid_runner_opts?(opts)
|
39
|
+
start_runner(opts)
|
40
|
+
elsif opts[:runner] == 'stop'
|
41
|
+
stop('runner', Testbot::RUNNER_PID)
|
42
|
+
elsif adapter = Adapter.all.find { |adapter| opts[adapter.type.to_sym] }
|
43
|
+
require File.join(File.dirname(__FILE__), '/requester')
|
44
|
+
start_requester(opts, adapter)
|
45
|
+
end
|
46
|
+
|
47
|
+
true
|
43
48
|
end
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
str += ' ' + arg
|
59
|
-
hash[last_setter] = str.strip
|
49
|
+
|
50
|
+
def self.parse_args(argv)
|
51
|
+
last_setter = nil
|
52
|
+
hash = {}
|
53
|
+
str = ''
|
54
|
+
argv.each_with_index do |arg, i|
|
55
|
+
if arg.include?('--')
|
56
|
+
str = ''
|
57
|
+
last_setter = arg.split('--').last.to_sym
|
58
|
+
hash[last_setter] = true if (i == argv.size - 1) || argv[i+1].include?('--')
|
59
|
+
else
|
60
|
+
str += ' ' + arg
|
61
|
+
hash[last_setter] = str.strip
|
62
|
+
end
|
60
63
|
end
|
64
|
+
hash
|
61
65
|
end
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
puts "Testbot runner started (pid: #{pid})"
|
66
|
+
|
67
|
+
def self.start_runner(opts)
|
68
|
+
stop('runner', Testbot::RUNNER_PID)
|
69
|
+
|
70
|
+
proc = lambda {
|
71
|
+
working_dir = opts[:working_dir] || Testbot::DEFAULT_WORKING_DIR
|
72
|
+
FileUtils.mkdir_p(working_dir)
|
73
|
+
Dir.chdir(working_dir)
|
74
|
+
runner = Runner.new(:server_host => opts[:connect],
|
75
|
+
:auto_update => opts[:auto_update], :max_instances => opts[:cpus],
|
76
|
+
:ssh_tunnel => opts[:ssh_tunnel], :server_user => opts[:user],
|
77
|
+
:max_jruby_instances => opts[:max_jruby_instances],
|
78
|
+
:jruby_opts => opts[:jruby_opts])
|
79
|
+
runner.run!
|
80
|
+
}
|
81
|
+
|
82
|
+
if opts[:runner] == 'run'
|
83
|
+
proc.call
|
84
|
+
else
|
85
|
+
pid = SimpleDaemonize.start(proc, Testbot::RUNNER_PID)
|
86
|
+
puts "Testbot runner started (pid: #{pid})"
|
87
|
+
end
|
85
88
|
end
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
if type == 'run'
|
92
|
-
require File.join(File.dirname(__FILE__), '/server')
|
93
|
-
Sinatra::Application.run! :environment => "production"
|
94
|
-
else
|
95
|
-
pid = SimpleDaemonize.start(lambda {
|
96
|
-
ENV['DISABLE_LOGGING'] = "true"
|
89
|
+
|
90
|
+
def self.start_server(type)
|
91
|
+
stop('server', Testbot::SERVER_PID)
|
92
|
+
|
93
|
+
if type == 'run'
|
97
94
|
require File.join(File.dirname(__FILE__), '/server')
|
98
95
|
Sinatra::Application.run! :environment => "production"
|
99
|
-
|
100
|
-
|
96
|
+
else
|
97
|
+
pid = SimpleDaemonize.start(lambda {
|
98
|
+
ENV['DISABLE_LOGGING'] = "true"
|
99
|
+
require File.join(File.dirname(__FILE__), '/server')
|
100
|
+
Sinatra::Application.run! :environment => "production"
|
101
|
+
}, Testbot::SERVER_PID)
|
102
|
+
puts "Testbot server started (pid: #{pid})"
|
103
|
+
end
|
101
104
|
end
|
105
|
+
|
106
|
+
def self.stop(name, pid)
|
107
|
+
puts "Testbot #{name} stopped" if SimpleDaemonize.stop(pid)
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.start_requester(opts, adapter)
|
111
|
+
requester = Requester.new(:server_host => opts[:connect],
|
112
|
+
:rsync_path => opts[:rsync_path],
|
113
|
+
:rsync_ignores => opts[:rsync_ignores].to_s,
|
114
|
+
:available_runner_usage => nil,
|
115
|
+
:project => opts[:project],
|
116
|
+
:ssh_tunnel => opts[:ssh_tunnel], :server_user => opts[:user])
|
117
|
+
requester.run_tests(adapter, adapter.base_path)
|
118
|
+
end
|
119
|
+
|
120
|
+
def self.valid_runner_opts?(opts)
|
121
|
+
opts[:connect].is_a?(String)
|
122
|
+
end
|
123
|
+
|
124
|
+
def self.lib_path
|
125
|
+
File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
126
|
+
end
|
127
|
+
|
102
128
|
end
|
103
|
-
|
104
|
-
def self.stop(name, pid)
|
105
|
-
puts "Testbot #{name} stopped" if SimpleDaemonize.stop(pid)
|
106
|
-
end
|
107
|
-
|
108
|
-
def self.start_requester(opts, adapter)
|
109
|
-
requester = Requester.new(:server_host => opts[:connect],
|
110
|
-
:rsync_path => opts[:rsync_path],
|
111
|
-
:rsync_ignores => opts[:rsync_ignores].to_s,
|
112
|
-
:available_runner_usage => nil,
|
113
|
-
:project => opts[:project],
|
114
|
-
:ssh_tunnel => opts[:ssh_tunnel], :server_user => opts[:user])
|
115
|
-
requester.run_tests(adapter, adapter.base_path)
|
116
|
-
end
|
117
|
-
|
118
|
-
def self.valid_runner_opts?(opts)
|
119
|
-
opts[:connect].is_a?(String)
|
120
|
-
end
|
121
|
-
|
122
|
-
def self.lib_path
|
123
|
-
File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
124
|
-
end
|
125
|
-
|
126
|
-
end
|
127
129
|
|
130
|
+
end
|
128
131
|
end
|
data/testbot.gemspec
CHANGED
@@ -19,6 +19,7 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.add_dependency('net-ssh', '>= 2.0.23')
|
20
20
|
s.add_dependency('sequel', '>= 3.16.0')
|
21
21
|
s.add_dependency('json', '>= 1.4.6')
|
22
|
+
s.add_dependency('acts_as_rails3_generator')
|
22
23
|
|
23
24
|
# Could work with older versions, but not newer (when deploying on debian)
|
24
25
|
s.add_dependency('sqlite3-ruby', '= 1.2.5')
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: testbot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 31
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 0.3.
|
9
|
+
- 6
|
10
|
+
version: 0.3.6
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- "Joakim Kolsj\xC3\xB6"
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-11-
|
18
|
+
date: 2010-11-28 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -115,9 +115,23 @@ dependencies:
|
|
115
115
|
type: :runtime
|
116
116
|
version_requirements: *id006
|
117
117
|
- !ruby/object:Gem::Dependency
|
118
|
-
name:
|
118
|
+
name: acts_as_rails3_generator
|
119
119
|
prerelease: false
|
120
120
|
requirement: &id007 !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
hash: 3
|
126
|
+
segments:
|
127
|
+
- 0
|
128
|
+
version: "0"
|
129
|
+
type: :runtime
|
130
|
+
version_requirements: *id007
|
131
|
+
- !ruby/object:Gem::Dependency
|
132
|
+
name: sqlite3-ruby
|
133
|
+
prerelease: false
|
134
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
121
135
|
none: false
|
122
136
|
requirements:
|
123
137
|
- - "="
|
@@ -129,11 +143,11 @@ dependencies:
|
|
129
143
|
- 5
|
130
144
|
version: 1.2.5
|
131
145
|
type: :runtime
|
132
|
-
version_requirements: *
|
146
|
+
version_requirements: *id008
|
133
147
|
- !ruby/object:Gem::Dependency
|
134
148
|
name: mongrel
|
135
149
|
prerelease: false
|
136
|
-
requirement: &
|
150
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
137
151
|
none: false
|
138
152
|
requirements:
|
139
153
|
- - "="
|
@@ -146,7 +160,7 @@ dependencies:
|
|
146
160
|
- pre2
|
147
161
|
version: 1.2.0.pre2
|
148
162
|
type: :runtime
|
149
|
-
version_requirements: *
|
163
|
+
version_requirements: *id009
|
150
164
|
description: Testbot is a test distribution tool that works with Rails, RSpec, Test::Unit and Cucumber.
|
151
165
|
email:
|
152
166
|
- joakim.kolsjo@gmail.com
|