testbot 0.6.5 → 0.6.6
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/CHANGELOG +12 -0
- data/README.markdown +1 -2
- data/lib/requester/requester.rb +10 -2
- data/lib/runner/job.rb +33 -10
- data/lib/runner/runner.rb +10 -4
- data/lib/shared/adapters/helpers/ruby_env.rb +1 -1
- data/lib/shared/version.rb +1 -1
- data/lib/tasks/testbot.rake +1 -1
- data/test/requester/requester_test.rb +3 -2
- data/test/runner/runner_test.rb +29 -1
- data/test/shared/adapters/helpers/ruby_env_test.rb +3 -4
- data/testbot.gemspec +2 -0
- metadata +35 -19
    
        data/CHANGELOG
    CHANGED
    
    | @@ -1,3 +1,15 @@ | |
| 1 | 
            +
            0.6.6
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            The runner will now run config/testbot/before_run.rb if it exists.
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            Replaced the old process code with the posix-spawn gem's methods. This fixed
         | 
| 6 | 
            +
            process shutdown in my current setup. Hopefully more stable overall.
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            The requester will now request that the build is stopped when exiting early (like when killed),
         | 
| 9 | 
            +
            and not only on ctrl+c (SIGINT).
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            Most of this was based on a fork by https://github.com/Skalar.
         | 
| 12 | 
            +
             | 
| 1 13 | 
             
            0.6.5
         | 
| 2 14 |  | 
| 3 15 | 
             
            Fixed test unit require path so that it works with ruby 1.9.
         | 
    
        data/README.markdown
    CHANGED
    
    | @@ -67,7 +67,7 @@ Using testbot with Rails 2: | |
| 67 67 |  | 
| 68 68 | 
             
                # Add testbot to your Gemfile if you use bundler. You also need the plugin because
         | 
| 69 69 | 
             
                # Rails 2 does not load raketasks from gems.
         | 
| 70 | 
            -
                ruby script/plugin install git://github.com/joakimk/testbot.git -r 'refs/tags/v0.6. | 
| 70 | 
            +
                ruby script/plugin install git://github.com/joakimk/testbot.git -r 'refs/tags/v0.6.6'
         | 
| 71 71 | 
             
                script/generate testbot --connect 192.168.0.100
         | 
| 72 72 |  | 
| 73 73 | 
             
                rake testbot:spec (or :rspec, :test, :features)
         | 
| @@ -140,4 +140,3 @@ More | |
| 140 140 | 
             
            ----
         | 
| 141 141 |  | 
| 142 142 | 
             
            * Check the [wiki](http://github.com/joakimk/testbot/wiki) for more info.
         | 
| 143 | 
            -
            * Chat: [https://convore.com/github/testbot](https://convore.com/github/testbot)
         | 
    
        data/lib/requester/requester.rb
    CHANGED
    
    | @@ -43,7 +43,8 @@ module Testbot::Requester | |
| 43 43 |  | 
| 44 44 | 
             
                  log "Syncing files" do
         | 
| 45 45 | 
             
                    rsync_ignores = config.rsync_ignores.to_s.split.map { |pattern| "--exclude='#{pattern}'" }.join(' ')
         | 
| 46 | 
            -
                     | 
| 46 | 
            +
                    # todo: exit when this fails
         | 
| 47 | 
            +
                    system "rsync -az --delete --delete-excluded -e ssh #{rsync_ignores} . #{rsync_uri}"
         | 
| 47 48 | 
             
                  end
         | 
| 48 49 |  | 
| 49 50 | 
             
                  files = adapter.test_files(dir) 
         | 
| @@ -70,7 +71,13 @@ module Testbot::Requester | |
| 70 71 | 
             
                    end
         | 
| 71 72 | 
             
                  end
         | 
| 72 73 |  | 
| 73 | 
            -
                   | 
| 74 | 
            +
                  at_exit do
         | 
| 75 | 
            +
                    unless ENV['IN_TEST'] || @done
         | 
| 76 | 
            +
                      log "Notifying server we want to stop the run" do
         | 
| 77 | 
            +
                        HTTParty.delete("#{server_uri}/builds/#{build_id}")
         | 
| 78 | 
            +
                      end
         | 
| 79 | 
            +
                    end
         | 
| 80 | 
            +
                  end
         | 
| 74 81 |  | 
| 75 82 | 
             
                  puts if config.logging
         | 
| 76 83 |  | 
| @@ -114,6 +121,7 @@ module Testbot::Requester | |
| 114 121 | 
             
                    puts "\n" + adapter.sum_results(@build['results'])
         | 
| 115 122 | 
             
                  end
         | 
| 116 123 |  | 
| 124 | 
            +
                  @done = true
         | 
| 117 125 | 
             
                  @build["success"]
         | 
| 118 126 | 
             
                end
         | 
| 119 127 |  | 
    
        data/lib/runner/job.rb
    CHANGED
    
    | @@ -1,5 +1,6 @@ | |
| 1 1 | 
             
            require File.expand_path(File.join(File.dirname(__FILE__), 'runner.rb'))
         | 
| 2 2 | 
             
            require File.expand_path(File.join(File.dirname(__FILE__), 'safe_result_text.rb'))
         | 
| 3 | 
            +
            require 'posix/spawn'
         | 
| 3 4 |  | 
| 4 5 | 
             
            module Testbot::Runner
         | 
| 5 6 | 
             
              class Job
         | 
| @@ -8,6 +9,7 @@ module Testbot::Runner | |
| 8 9 | 
             
                def initialize(runner, id, build_id, project, root, type, ruby_interpreter, files)
         | 
| 9 10 | 
             
                  @runner, @id, @build_id, @project, @root, @type, @ruby_interpreter, @files =
         | 
| 10 11 | 
             
                    runner, id, build_id, project, root, type, ruby_interpreter, files
         | 
| 12 | 
            +
                  @success = true
         | 
| 11 13 | 
             
                end
         | 
| 12 14 |  | 
| 13 15 | 
             
                def jruby?
         | 
| @@ -31,15 +33,19 @@ module Testbot::Runner | |
| 31 33 | 
             
                end
         | 
| 32 34 |  | 
| 33 35 | 
             
                def kill!(build_id)
         | 
| 34 | 
            -
                  if @build_id == build_id && @ | 
| 35 | 
            -
                     | 
| 36 | 
            -
                    system("pkill -KILL -P #{@test_process.pid}")
         | 
| 36 | 
            +
                  if @build_id == build_id && @pid
         | 
| 37 | 
            +
                    kill_processes
         | 
| 37 38 | 
             
                    @killed = true
         | 
| 38 39 | 
             
                  end
         | 
| 39 40 | 
             
                end
         | 
| 40 41 |  | 
| 41 42 | 
             
                private
         | 
| 42 43 |  | 
| 44 | 
            +
                def kill_processes
         | 
| 45 | 
            +
                  # Kill process and its children (processes in the same group)
         | 
| 46 | 
            +
                  Process.kill('KILL', -@pid) rescue :failed_to_kill_process
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
             | 
| 43 49 | 
             
                def status
         | 
| 44 50 | 
             
                  success? ? "successful" : "failed"
         | 
| 45 51 | 
             
                end
         | 
| @@ -55,23 +61,40 @@ module Testbot::Runner | |
| 55 61 | 
             
                end
         | 
| 56 62 |  | 
| 57 63 | 
             
                def run_and_return_result(command)
         | 
| 58 | 
            -
                   | 
| 64 | 
            +
                  read_pipe = spawn_process(command)
         | 
| 65 | 
            +
                  
         | 
| 59 66 | 
             
                  output = ""
         | 
| 60 | 
            -
                   | 
| 61 | 
            -
                  while char =  | 
| 67 | 
            +
                  last_post_time = Time.now
         | 
| 68 | 
            +
                  while char = read_pipe.getc
         | 
| 62 69 | 
             
                    char = (char.is_a?(Fixnum) ? char.chr : char) # 1.8 <-> 1.9
         | 
| 63 70 | 
             
                    output << char
         | 
| 64 | 
            -
                    if Time.now -  | 
| 71 | 
            +
                    if Time.now - last_post_time > 0.5
         | 
| 65 72 | 
             
                      post_results(output)
         | 
| 66 | 
            -
                       | 
| 73 | 
            +
                      last_post_time = Time.now
         | 
| 67 74 | 
             
                    end
         | 
| 68 75 | 
             
                  end
         | 
| 69 | 
            -
             | 
| 76 | 
            +
             | 
| 77 | 
            +
                  # Kill child processes, if any
         | 
| 78 | 
            +
                  kill_processes
         | 
| 79 | 
            +
             | 
| 70 80 | 
             
                  output
         | 
| 71 81 | 
             
                end
         | 
| 72 82 |  | 
| 83 | 
            +
                def spawn_process(command)
         | 
| 84 | 
            +
                  read_pipe, write_pipe = IO.pipe
         | 
| 85 | 
            +
                  @pid = POSIX::Spawn::spawn(command, :err => write_pipe, :out => write_pipe, :pgroup => true)
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                  Thread.new do
         | 
| 88 | 
            +
                    Process.waitpid(@pid)
         | 
| 89 | 
            +
                    @success = ($?.exitstatus == 0)
         | 
| 90 | 
            +
                    write_pipe.close
         | 
| 91 | 
            +
                  end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                  read_pipe
         | 
| 94 | 
            +
                end
         | 
| 95 | 
            +
             | 
| 73 96 | 
             
                def success?
         | 
| 74 | 
            -
                   | 
| 97 | 
            +
                  @success
         | 
| 75 98 | 
             
                end
         | 
| 76 99 |  | 
| 77 100 | 
             
                def ruby_cmd
         | 
    
        data/lib/runner/runner.rb
    CHANGED
    
    | @@ -104,7 +104,7 @@ module Testbot::Runner | |
| 104 104 | 
             
                    job = Job.new(*([ self, next_job.split(',') ].flatten))
         | 
| 105 105 | 
             
                    if first_job_from_build?
         | 
| 106 106 | 
             
                      fetch_code(job)
         | 
| 107 | 
            -
                      before_run(job) | 
| 107 | 
            +
                      before_run(job)
         | 
| 108 108 | 
             
                    end
         | 
| 109 109 |  | 
| 110 110 | 
             
                    @last_build_id = job.build_id
         | 
| @@ -123,12 +123,18 @@ module Testbot::Runner | |
| 123 123 | 
             
                end
         | 
| 124 124 |  | 
| 125 125 | 
             
                def fetch_code(job)
         | 
| 126 | 
            -
                  system "rsync -az --delete -e ssh #{job.root}/ #{job.project}"
         | 
| 126 | 
            +
                  system "rsync -az --delete --delete-excluded -e ssh #{job.root}/ #{job.project}"
         | 
| 127 127 | 
             
                end
         | 
| 128 128 |  | 
| 129 129 | 
             
                def before_run(job)
         | 
| 130 | 
            -
                   | 
| 131 | 
            -
                   | 
| 130 | 
            +
                  using_bundler = RubyEnv.bundler?(job.project)
         | 
| 131 | 
            +
                  bundler_cmd = using_bundler ? "bundle exec" : ""
         | 
| 132 | 
            +
                  command_prefix = "cd #{job.project}; RAILS_ENV=test TEST_INSTANCES=#{@config.max_instances} #{bundler_cmd}"
         | 
| 133 | 
            +
             | 
| 134 | 
            +
                  # todo: exit if this fails, report back, etc.
         | 
| 135 | 
            +
                  system("cd #{job.project}; bundle") if using_bundler
         | 
| 136 | 
            +
                  system "#{command_prefix} rake testbot:before_run" if File.exists?("#{job.project}/lib/tasks/testbot.rake")
         | 
| 137 | 
            +
                  system "#{command_prefix} ruby config/testbot/before_run.rb" if File.exists?("#{job.project}/config/testbot/before_run.rb")
         | 
| 132 138 | 
             
                end
         | 
| 133 139 |  | 
| 134 140 | 
             
                def first_job_from_build?
         | 
| @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            class RubyEnv
         | 
| 2 2 |  | 
| 3 3 | 
             
              def self.bundler?(project_path)
         | 
| 4 | 
            -
                Gem. | 
| 4 | 
            +
                Gem::Specification.find_by_name("bundler") && File.exists?("#{project_path}/Gemfile") rescue false
         | 
| 5 5 | 
             
              end
         | 
| 6 6 |  | 
| 7 7 | 
             
              def self.ruby_command(project_path, opts = {})
         | 
    
        data/lib/shared/version.rb
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            module Testbot
         | 
| 2 2 | 
             
              # Don't forget to update readme and changelog
         | 
| 3 3 | 
             
              def self.version
         | 
| 4 | 
            -
                version = "0.6. | 
| 4 | 
            +
                version = "0.6.6"
         | 
| 5 5 | 
             
                dev_version_file = File.join(File.dirname(__FILE__), '..', '..', 'DEV_VERSION')
         | 
| 6 6 | 
             
                if File.exists?(dev_version_file)
         | 
| 7 7 | 
             
                  version += File.read(dev_version_file)
         | 
    
        data/lib/tasks/testbot.rake
    CHANGED
    
    | @@ -3,7 +3,7 @@ require File.dirname(__FILE__) + '/../shared/adapters/adapter' | |
| 3 3 | 
             
            namespace :testbot do
         | 
| 4 4 |  | 
| 5 5 | 
             
              def run_and_show_results(adapter, custom_path)
         | 
| 6 | 
            -
                Rake::Task[ | 
| 6 | 
            +
                'testbot:before_request'.tap { |t| Rake::Task.task_defined?(t) && Rake::Task[t].invoke }
         | 
| 7 7 |  | 
| 8 8 | 
             
                require File.expand_path(File.join(File.dirname(__FILE__), '..', 'requester', 'requester.rb'))
         | 
| 9 9 | 
             
                requester = Testbot::Requester::Requester.create_by_config("#{Rails.root}/config/testbot.yml")
         | 
| @@ -41,6 +41,7 @@ module Testbot::Requester | |
| 41 41 |  | 
| 42 42 | 
             
                def setup
         | 
| 43 43 | 
             
                  ENV['USE_JRUBY'] = nil
         | 
| 44 | 
            +
                  ENV['IN_TEST'] = 'true'
         | 
| 44 45 | 
             
                end
         | 
| 45 46 |  | 
| 46 47 | 
             
                def mock_file_sizes
         | 
| @@ -233,7 +234,7 @@ module Testbot::Requester | |
| 233 234 | 
             
                    flexmock(HTTParty).should_receive(:get).once.with("http://192.168.1.100:#{Testbot::SERVER_PORT}/builds/5",
         | 
| 234 235 | 
             
                                                                      :format => :json).and_return({ "done" => true, "results" => "" })
         | 
| 235 236 |  | 
| 236 | 
            -
                    flexmock(requester).should_receive('system').with("rsync -az --delete -e ssh --exclude='.git' --exclude='tmp' . testbot@192.168.1.100:/path")
         | 
| 237 | 
            +
                    flexmock(requester).should_receive('system').with("rsync -az --delete --delete-excluded -e ssh --exclude='.git' --exclude='tmp' . testbot@192.168.1.100:/path")
         | 
| 237 238 | 
             
                    mock_file_sizes
         | 
| 238 239 |  | 
| 239 240 | 
             
                    requester.run_tests(RspecAdapter, 'spec')
         | 
| @@ -336,7 +337,7 @@ module Testbot::Requester | |
| 336 337 | 
             
                    flexmock(requester).should_receive(:print)
         | 
| 337 338 | 
             
                    flexmock(requester).should_receive(:puts)
         | 
| 338 339 |  | 
| 339 | 
            -
                    flexmock(requester).should_receive('system').with("rsync -az --delete -e ssh  . cruise@somewhere:/tmp/testbot/foo")
         | 
| 340 | 
            +
                    flexmock(requester).should_receive('system').with("rsync -az --delete --delete-excluded -e ssh  . cruise@somewhere:/tmp/testbot/foo")
         | 
| 340 341 | 
             
                    mock_file_sizes
         | 
| 341 342 |  | 
| 342 343 | 
             
                    requester.run_tests(RspecAdapter, 'spec')
         | 
    
        data/test/runner/runner_test.rb
    CHANGED
    
    | @@ -12,10 +12,38 @@ module Testbot::Runner | |
| 12 12 | 
             
                  flexmock(RubyEnv).should_receive(:bundler?).with("/path").returns(true)
         | 
| 13 13 |  | 
| 14 14 | 
             
                  runner = Runner.new({:max_instances => 1})
         | 
| 15 | 
            +
                  flexmock(File).should_receive(:exists?).with("/path/lib/tasks/testbot.rake").and_return(true)
         | 
| 16 | 
            +
                  flexmock(File).should_receive(:exists?).with("/path/config/testbot/before_run.rb").and_return(false)
         | 
| 15 17 | 
             
                  flexmock(runner)
         | 
| 16 | 
            -
                  flexmock(runner).should_receive(:system).with(" | 
| 18 | 
            +
                  flexmock(runner).should_receive(:system).with("cd /path; bundle").once
         | 
| 19 | 
            +
                  flexmock(runner).should_receive(:system).with("cd /path; RAILS_ENV=test TEST_INSTANCES=1 bundle exec rake testbot:before_run").once
         | 
| 17 20 | 
             
                  runner.send(:before_run, job)
         | 
| 18 21 | 
             
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                should "be able to use a plain ruby before_run file" do
         | 
| 24 | 
            +
                  job = flexmock(:job, :project => "/path")
         | 
| 25 | 
            +
                  flexmock(RubyEnv).should_receive(:bundler?).with("/path").returns(true)
         | 
| 26 | 
            +
                  
         | 
| 27 | 
            +
                  runner = Runner.new({:max_instances => 1})
         | 
| 28 | 
            +
                  flexmock(File).should_receive(:exists?).with("/path/lib/tasks/testbot.rake").and_return(false)
         | 
| 29 | 
            +
                  flexmock(File).should_receive(:exists?).with("/path/config/testbot/before_run.rb").and_return(true)
         | 
| 30 | 
            +
                  flexmock(runner)
         | 
| 31 | 
            +
                  flexmock(runner).should_receive(:system).with("cd /path; bundle").once
         | 
| 32 | 
            +
                  flexmock(runner).should_receive(:system).with("cd /path; RAILS_ENV=test TEST_INSTANCES=1 bundle exec ruby config/testbot/before_run.rb").once
         | 
| 33 | 
            +
                  runner.send(:before_run, job)
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                should "be able to run without bundler" do
         | 
| 37 | 
            +
                  job = flexmock(:job, :project => "/path")
         | 
| 38 | 
            +
                  flexmock(RubyEnv).should_receive(:bundler?).with("/path").returns(false)
         | 
| 39 | 
            +
                  
         | 
| 40 | 
            +
                  runner = Runner.new({:max_instances => 1})
         | 
| 41 | 
            +
                  flexmock(File).should_receive(:exists?).with("/path/lib/tasks/testbot.rake").and_return(false)
         | 
| 42 | 
            +
                  flexmock(File).should_receive(:exists?).with("/path/config/testbot/before_run.rb").and_return(true)
         | 
| 43 | 
            +
                  flexmock(runner)
         | 
| 44 | 
            +
                  flexmock(runner).should_receive(:system).with("cd /path; RAILS_ENV=test TEST_INSTANCES=1  ruby config/testbot/before_run.rb").once
         | 
| 45 | 
            +
                  runner.send(:before_run, job)
         | 
| 46 | 
            +
                end 
         | 
| 19 47 | 
             
              end
         | 
| 20 48 | 
             
            end
         | 
| 21 49 |  | 
| @@ -8,19 +8,19 @@ class RubyEnvTest < Test::Unit::TestCase | |
| 8 8 | 
             
              context "self.bundler?" do
         | 
| 9 9 |  | 
| 10 10 | 
             
                should "return true if bundler is installed and there is a Gemfile" do
         | 
| 11 | 
            -
                  flexmock(Gem).should_receive(: | 
| 11 | 
            +
                  flexmock(Gem::Specification).should_receive(:find_by_name).with("bundler").once.and_return(true)
         | 
| 12 12 | 
             
                  flexmock(File).should_receive(:exists?).with("path/to/project/Gemfile").once.and_return(true)
         | 
| 13 13 | 
             
                  assert_equal true, RubyEnv.bundler?("path/to/project")
         | 
| 14 14 | 
             
                end
         | 
| 15 15 |  | 
| 16 16 | 
             
                should "return false if bundler is installed but there is no Gemfile" do
         | 
| 17 | 
            -
                  flexmock(Gem).should_receive(: | 
| 17 | 
            +
                  flexmock(Gem::Specification).should_receive(:find_by_name).with("bundler").once.and_return(true)
         | 
| 18 18 | 
             
                  flexmock(File).should_receive(:exists?).and_return(false)
         | 
| 19 19 | 
             
                  assert_equal false, RubyEnv.bundler?("path/to/project")
         | 
| 20 20 | 
             
                end
         | 
| 21 21 |  | 
| 22 22 | 
             
                should "return false if bundler is not installed" do
         | 
| 23 | 
            -
                  flexmock(Gem).should_receive(: | 
| 23 | 
            +
                  flexmock(Gem::Specification).should_receive(:find_by_name).with("bundler").once.and_return(false)
         | 
| 24 24 | 
             
                  assert_equal false, RubyEnv.bundler?("path/to/project")
         | 
| 25 25 | 
             
                end
         | 
| 26 26 |  | 
| @@ -53,7 +53,6 @@ class RubyEnvTest < Test::Unit::TestCase | |
| 53 53 | 
             
                end
         | 
| 54 54 |  | 
| 55 55 | 
             
                should "not look for a script when none is provided" do
         | 
| 56 | 
            -
                  flexmock(File).should_receive(:exists?).once # Once for bundler check
         | 
| 57 56 | 
             
                  assert_equal 'ruby -S rspec', RubyEnv.ruby_command("path/to/project", :bin => "rspec")  
         | 
| 58 57 | 
             
                end
         | 
| 59 58 |  | 
    
        data/testbot.gemspec
    CHANGED
    
    | @@ -13,6 +13,7 @@ Gem::Specification.new do |s| | |
| 13 13 | 
             
              s.executables = [ "testbot" ]
         | 
| 14 14 | 
             
              s.files       = Dir.glob("lib/**/*") + Dir.glob("test/**/*") + %w(Gemfile .gemtest Rakefile testbot.gemspec CHANGELOG README.markdown bin/testbot) +
         | 
| 15 15 | 
             
                              (File.exists?("DEV_VERSION") ? [ "DEV_VERSION" ] : [])
         | 
| 16 | 
            +
             | 
| 16 17 | 
             
              s.add_dependency('sinatra', '>=1.0.0')
         | 
| 17 18 | 
             
              s.add_dependency('httparty', '>= 0.6.1')
         | 
| 18 19 | 
             
              s.add_dependency('macaddr', '>= 1.0.0')
         | 
| @@ -20,6 +21,7 @@ Gem::Specification.new do |s| | |
| 20 21 | 
             
              s.add_dependency('json_pure', '>= 1.4.6')
         | 
| 21 22 | 
             
              s.add_dependency('daemons', '>= 1.0.10')
         | 
| 22 23 | 
             
              s.add_dependency('acts_as_rails3_generator')
         | 
| 24 | 
            +
              s.add_dependency('posix-spawn', '>= 0.3.6')
         | 
| 23 25 |  | 
| 24 26 | 
             
              s.add_development_dependency("shoulda")
         | 
| 25 27 | 
             
              s.add_development_dependency("rack-test")
         | 
    
        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: 11
         | 
| 5 5 | 
             
              prerelease: 
         | 
| 6 6 | 
             
              segments: 
         | 
| 7 7 | 
             
              - 0
         | 
| 8 8 | 
             
              - 6
         | 
| 9 | 
            -
              -  | 
| 10 | 
            -
              version: 0.6. | 
| 9 | 
            +
              - 6
         | 
| 10 | 
            +
              version: 0.6.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: 2012-04- | 
| 18 | 
            +
            date: 2012-04-27 00:00:00 +02:00
         | 
| 19 19 | 
             
            default_executable: 
         | 
| 20 20 | 
             
            dependencies: 
         | 
| 21 21 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| @@ -129,21 +129,23 @@ dependencies: | |
| 129 129 | 
             
              type: :runtime
         | 
| 130 130 | 
             
              version_requirements: *id007
         | 
| 131 131 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| 132 | 
            -
              name:  | 
| 132 | 
            +
              name: posix-spawn
         | 
| 133 133 | 
             
              prerelease: false
         | 
| 134 134 | 
             
              requirement: &id008 !ruby/object:Gem::Requirement 
         | 
| 135 135 | 
             
                none: false
         | 
| 136 136 | 
             
                requirements: 
         | 
| 137 137 | 
             
                - - ">="
         | 
| 138 138 | 
             
                  - !ruby/object:Gem::Version 
         | 
| 139 | 
            -
                    hash:  | 
| 139 | 
            +
                    hash: 31
         | 
| 140 140 | 
             
                    segments: 
         | 
| 141 141 | 
             
                    - 0
         | 
| 142 | 
            -
                     | 
| 143 | 
            -
             | 
| 142 | 
            +
                    - 3
         | 
| 143 | 
            +
                    - 6
         | 
| 144 | 
            +
                    version: 0.3.6
         | 
| 145 | 
            +
              type: :runtime
         | 
| 144 146 | 
             
              version_requirements: *id008
         | 
| 145 147 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| 146 | 
            -
              name:  | 
| 148 | 
            +
              name: shoulda
         | 
| 147 149 | 
             
              prerelease: false
         | 
| 148 150 | 
             
              requirement: &id009 !ruby/object:Gem::Requirement 
         | 
| 149 151 | 
             
                none: false
         | 
| @@ -157,7 +159,7 @@ dependencies: | |
| 157 159 | 
             
              type: :development
         | 
| 158 160 | 
             
              version_requirements: *id009
         | 
| 159 161 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| 160 | 
            -
              name:  | 
| 162 | 
            +
              name: rack-test
         | 
| 161 163 | 
             
              prerelease: false
         | 
| 162 164 | 
             
              requirement: &id010 !ruby/object:Gem::Requirement 
         | 
| 163 165 | 
             
                none: false
         | 
| @@ -171,7 +173,7 @@ dependencies: | |
| 171 173 | 
             
              type: :development
         | 
| 172 174 | 
             
              version_requirements: *id010
         | 
| 173 175 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| 174 | 
            -
              name:  | 
| 176 | 
            +
              name: flexmock
         | 
| 175 177 | 
             
              prerelease: false
         | 
| 176 178 | 
             
              requirement: &id011 !ruby/object:Gem::Requirement 
         | 
| 177 179 | 
             
                none: false
         | 
| @@ -185,9 +187,23 @@ dependencies: | |
| 185 187 | 
             
              type: :development
         | 
| 186 188 | 
             
              version_requirements: *id011
         | 
| 187 189 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| 188 | 
            -
              name:  | 
| 190 | 
            +
              name: rvm
         | 
| 189 191 | 
             
              prerelease: false
         | 
| 190 192 | 
             
              requirement: &id012 !ruby/object:Gem::Requirement 
         | 
| 193 | 
            +
                none: false
         | 
| 194 | 
            +
                requirements: 
         | 
| 195 | 
            +
                - - ">="
         | 
| 196 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 197 | 
            +
                    hash: 3
         | 
| 198 | 
            +
                    segments: 
         | 
| 199 | 
            +
                    - 0
         | 
| 200 | 
            +
                    version: "0"
         | 
| 201 | 
            +
              type: :development
         | 
| 202 | 
            +
              version_requirements: *id012
         | 
| 203 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 204 | 
            +
              name: rake
         | 
| 205 | 
            +
              prerelease: false
         | 
| 206 | 
            +
              requirement: &id013 !ruby/object:Gem::Requirement 
         | 
| 191 207 | 
             
                none: false
         | 
| 192 208 | 
             
                requirements: 
         | 
| 193 209 | 
             
                - - "="
         | 
| @@ -199,11 +215,11 @@ dependencies: | |
| 199 215 | 
             
                    - 7
         | 
| 200 216 | 
             
                    version: 0.8.7
         | 
| 201 217 | 
             
              type: :development
         | 
| 202 | 
            -
              version_requirements: * | 
| 218 | 
            +
              version_requirements: *id013
         | 
| 203 219 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| 204 220 | 
             
              name: bundler
         | 
| 205 221 | 
             
              prerelease: false
         | 
| 206 | 
            -
              requirement: & | 
| 222 | 
            +
              requirement: &id014 !ruby/object:Gem::Requirement 
         | 
| 207 223 | 
             
                none: false
         | 
| 208 224 | 
             
                requirements: 
         | 
| 209 225 | 
             
                - - ">="
         | 
| @@ -213,11 +229,11 @@ dependencies: | |
| 213 229 | 
             
                    - 0
         | 
| 214 230 | 
             
                    version: "0"
         | 
| 215 231 | 
             
              type: :development
         | 
| 216 | 
            -
              version_requirements: * | 
| 232 | 
            +
              version_requirements: *id014
         | 
| 217 233 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| 218 234 | 
             
              name: guard
         | 
| 219 235 | 
             
              prerelease: false
         | 
| 220 | 
            -
              requirement: & | 
| 236 | 
            +
              requirement: &id015 !ruby/object:Gem::Requirement 
         | 
| 221 237 | 
             
                none: false
         | 
| 222 238 | 
             
                requirements: 
         | 
| 223 239 | 
             
                - - ">="
         | 
| @@ -227,11 +243,11 @@ dependencies: | |
| 227 243 | 
             
                    - 0
         | 
| 228 244 | 
             
                    version: "0"
         | 
| 229 245 | 
             
              type: :development
         | 
| 230 | 
            -
              version_requirements: * | 
| 246 | 
            +
              version_requirements: *id015
         | 
| 231 247 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| 232 248 | 
             
              name: guard-test
         | 
| 233 249 | 
             
              prerelease: false
         | 
| 234 | 
            -
              requirement: & | 
| 250 | 
            +
              requirement: &id016 !ruby/object:Gem::Requirement 
         | 
| 235 251 | 
             
                none: false
         | 
| 236 252 | 
             
                requirements: 
         | 
| 237 253 | 
             
                - - ">="
         | 
| @@ -241,7 +257,7 @@ dependencies: | |
| 241 257 | 
             
                    - 0
         | 
| 242 258 | 
             
                    version: "0"
         | 
| 243 259 | 
             
              type: :development
         | 
| 244 | 
            -
              version_requirements: * | 
| 260 | 
            +
              version_requirements: *id016
         | 
| 245 261 | 
             
            description: Testbot is a test distribution tool that works with Rails, RSpec, RSpec2, Test::Unit and Cucumber.
         | 
| 246 262 | 
             
            email: 
         | 
| 247 263 | 
             
            - joakim.kolsjo@gmail.com
         |