purobu 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in purobu.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Harold Giménez
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,125 @@
1
+ # Purobu
2
+
3
+ Black-box integration test framework for components on the Heroku platform.
4
+
5
+ ## Installation
6
+
7
+ Install the gem
8
+
9
+ $ gem install purobu
10
+
11
+ ## Usage
12
+
13
+ Tests [go through four phases](http://xunitpatterns.com/Four%20Phase%20Test.html):
14
+
15
+ * _Setup_ the context for the test by creating test fixtures that are required
16
+ for the *System Under Test* (SUT) to expose the desired behavior.
17
+ * _Exercise_ the SUT
18
+ * _Verify_ the result to determine if the intended behavior was met.
19
+ * _Teardown_ the state of the system by removing all fixtures and test
20
+ artifacts so that there are no state spills or interdependencies across
21
+ tests.
22
+
23
+ Purobu recognizes and embraces this by defining these phases in implicit blocks
24
+ within your tests.
25
+
26
+ For example:
27
+
28
+ ```ruby
29
+ # test_can_create_crane_database.rb
30
+ test 'can create crane database' do
31
+ setup do
32
+ heroku "apps:create --name some-app"
33
+ end
34
+
35
+ exercise do
36
+ heroku "addons:add heroku-postgresql:crane some-app"
37
+ end
38
+
39
+ verify do
40
+ addons = heroku "addons --app some-app"
41
+ addons.include?("heroku-postgresql:crane") #return true or false
42
+ end
43
+
44
+ teardown do
45
+ heroku "apps:remove some-app"
46
+ end
47
+ end
48
+ ```
49
+
50
+ Then run it with 4 concurrent jobs:
51
+
52
+ $ purobu -j 4
53
+
54
+ Purobu will load any files that match `/test_.*\.rb/` recursively. An
55
+ alternative is to specify files to run:
56
+
57
+ $ purobu -j 4 -f test_one.rb,test_two.rb
58
+
59
+ For more command line switches, try `purobu -h`
60
+
61
+ ## Global setup
62
+
63
+ It can be useful to have global setups, for example, to create an app to run a
64
+ bunch of tests against.
65
+
66
+ You can create a ruby file called purobu_config.rb to set up a global context.
67
+ The global context will run once before the entire suite. Be sure to create a
68
+ global teardown as well:
69
+
70
+ ```ruby
71
+ # purobu_config.rb
72
+ Purobu::Configuration.run do |config|
73
+ config.global_setup do
74
+ heroku "apps:create harolds-test-app"
75
+ end
76
+ config.global_teardown do
77
+ heroku "apps:destroy harolds-test-app --confirm harolds-test-app"
78
+ end
79
+ end
80
+ ```
81
+
82
+ ## Interacting with heroku
83
+
84
+ Access to heroku is facilitated in two ways:
85
+
86
+ 1. The `heroku` helper is a wrapper around the latest version of the heroku
87
+ CLI. You give it a string, and it shells out to execute the given command.
88
+ For example:
89
+
90
+ ```ruby
91
+ heroku "addons:add heroku-postgresql:dev"
92
+ ```
93
+
94
+ 2. The `heroku_api` helper exposes the [heroku api
95
+ client](https://github.com/heroku/heroku.rb) for more convenient retreival
96
+ of information on heroku such as an app's config vars.
97
+
98
+ *Note*: To use it, set the HEROKU_API_KEY environment variable or set it in a
99
+ `Purobu::Configuration.run`
100
+
101
+ For example:
102
+
103
+ ```ruby
104
+ heroku_api.get_config_vars('some-app').body
105
+ # {"HEROKU_POSTGRESQL_PURPLE_URL"=>"postgres://user:pass@host:5732/database"}
106
+ heroku_api.get_addons('some-app').body
107
+ # [{"slug"=>"crane", "selective"=>false,
108
+ "configured"=>true,
109
+ "url"=>nil,
110
+ "state"=>"public",
111
+ "group_description"=>"Heroku Postgresql",
112
+ "consumes_dyno_hours"=>false,
113
+ "price"=>{"cents"=>0, "unit"=>"month"},
114
+ "attachment_name"=>"HEROKU_POSTGRESQL_TEAL",
115
+ "plan_description"=>"Crane",
116
+ "name"=>"heroku-postgresql:crane",
117
+ "beta"=>false,
118
+ "attachable"=>false,
119
+ "description"=>"Heroku Postgres Crane",
120
+ "terms_of_service"=>false}]
121
+ ```
122
+
123
+ ## Meta
124
+
125
+ purobu was written by Harold Giménez and is Copyright 2012 Heroku
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
data/bin/purobu ADDED
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "optparse"
4
+
5
+ options = {}
6
+ parser = OptionParser.new do |opts|
7
+ opts.banner = "usage: purobu [--file file1,file2,...]"
8
+ opts.on("-f", "--files f", Array, "File or files to load and run") do |fs|
9
+ options[:files] = fs
10
+ end
11
+ opts.on("-j", "--jobs j", Integer, "Number of jobs") do |j|
12
+ options[:thread_count] = j
13
+ end
14
+ opts.on("-v", "--verbose", "Run verbosely") do |v|
15
+ options[:verbose] = v
16
+ end
17
+ opts.on("-h", "--help", "Display this help") { abort(opts.to_s) }
18
+ end
19
+ parser.parse!
20
+
21
+ $:.unshift File.expand_path(File.join('..', 'lib'), File.dirname(__FILE__))
22
+
23
+ require 'purobu'
24
+
25
+ load './purobu_config.rb' if File.exists?('./purobu_config.rb')
26
+
27
+ Purobu::Configuration.run do |conf|
28
+ conf.verbose = options[:verbose] || false
29
+ conf.thread_count = options[:thread_count]
30
+ conf.files = options[:files]
31
+ end
32
+
33
+ Purobu::DSL.new(files: Purobu::Configuration.files).run
@@ -0,0 +1,57 @@
1
+ require 'singleton'
2
+ module Purobu
3
+ class Configuration
4
+ include Singleton
5
+
6
+ # Run verbosely
7
+ attr_accessor :verbose
8
+
9
+ # Concurrency
10
+ attr_accessor :thread_count
11
+
12
+ # Which test files to run
13
+ attr_accessor :files
14
+
15
+ # Global teardown to run after the entire suite
16
+ attr_accessor :global_teardown
17
+
18
+ # Heroku api key to be used by the heroku-api client
19
+ attr_accessor :heroku_api_key
20
+
21
+ def self.run(&block)
22
+ self.instance.heroku_api_key = ENV['HEROKU_API_KEY']
23
+
24
+ yield self.instance
25
+ end
26
+
27
+ def global_setup(&block)
28
+ if block_given?
29
+ @global_setup = block
30
+ else
31
+ @global_setup
32
+ end
33
+ end
34
+
35
+ def global_teardown(&block)
36
+ if block_given?
37
+ @global_teardown = block
38
+ else
39
+ @global_teardown
40
+ end
41
+ end
42
+
43
+ class << self
44
+ def method_missing(method)
45
+ if self.instance.respond_to?(method)
46
+ self.instance.send(method)
47
+ else
48
+ super
49
+ end
50
+ end
51
+
52
+ def respond_to?(method)
53
+ self.instance.respond_to?(method) || super
54
+ end
55
+ end
56
+ end
57
+ end
data/lib/purobu/dsl.rb ADDED
@@ -0,0 +1,26 @@
1
+ module Purobu
2
+ class DSL
3
+ attr_reader :runner, :files
4
+ def initialize(opts = {})
5
+ @runner = Runner.new
6
+ @files = opts[:files] || Dir['**/test_*.rb']
7
+ end
8
+
9
+ def test(name = nil, &block)
10
+ runner.tests.push( Test.new(name).tap { |t| t.instance_eval(&block) } )
11
+ end
12
+
13
+ def tests
14
+ runner.tests
15
+ end
16
+
17
+ def run
18
+ load_tests
19
+ runner.run
20
+ end
21
+
22
+ def load_tests
23
+ files.each { |f| instance_eval(File.read(f)) }
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,25 @@
1
+ require 'fileutils'
2
+ module Purobu
3
+ class Heroku
4
+ class FailedCommand < Exception; end
5
+
6
+ def self.run(command)
7
+ result = nil
8
+ Purobu.log(heroku: true, command: command) do
9
+ result = `#{heroku_path} #{command}`
10
+ end
11
+ raise FailedCommand.new(result) unless $?.exitstatus.zero?
12
+ result
13
+ end
14
+
15
+ def self.heroku_path
16
+ @heroku_path ||= begin
17
+ FileUtils.cd File.expand_path(File.join("..", ".."), File.dirname(__FILE__)) do
18
+ eval(File.read('purobu.gemspec'))
19
+ end
20
+ Gem.bin_path("heroku", "heroku")
21
+ end
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,12 @@
1
+ require 'heroku-api'
2
+ module Purobu
3
+ module HerokuHelpers
4
+ def heroku(*args)
5
+ ::Purobu::Heroku.run(*args)
6
+ end
7
+
8
+ def heroku_api
9
+ ::Heroku::API.new(api_key: Configuration.heroku_api_key)
10
+ end
11
+ end
12
+ end
data/lib/purobu/log.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'scrolls'
2
+ module Purobu
3
+ def self.log(data, &block)
4
+ if Configuration.verbose
5
+ Scrolls.log(data, &block)
6
+ else
7
+ yield
8
+ end
9
+ end
10
+
11
+ def self.log_context(data, &block)
12
+ if Configuration.verbose
13
+ Scrolls.context(data, &block)
14
+ else
15
+ yield
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,25 @@
1
+ module Purobu
2
+ class Reporter
3
+ attr_reader :test
4
+ def initialize(test)
5
+ @test = test
6
+ end
7
+
8
+ def report_pass
9
+ puts "#{green("PASS")} #{@test.name}"
10
+ end
11
+
12
+ def report_fail
13
+ puts "#{red("FAIL")} #{@test.name}"
14
+ end
15
+
16
+ private
17
+ def green(string)
18
+ "[\e[32m#{string}\e[0m]"
19
+ end
20
+
21
+ def red(string)
22
+ "[\e[31m#{string}\e[0m]"
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,49 @@
1
+ require 'thread'
2
+ module Purobu
3
+ class Runner
4
+ include HerokuHelpers
5
+
6
+ attr_reader :tests, :thread_count
7
+
8
+ def initialize
9
+ @tests = Queue.new
10
+ @thread_count = Configuration.thread_count || 1
11
+ end
12
+
13
+ def run
14
+ Purobu.log(global_setup: true) do
15
+ run_global_setup
16
+ end
17
+ pool = Array.new(thread_count) do
18
+ Thread.new do
19
+ loop do
20
+ begin
21
+ test = tests.pop(true)
22
+ test.run
23
+ test.report_result
24
+ rescue
25
+ Thread.exit
26
+ end
27
+ end
28
+ end
29
+ end
30
+ pool.each(&:join)
31
+ Purobu.log(global_teardown: true) do
32
+ run_global_teardown
33
+ end
34
+ end
35
+
36
+ private
37
+ def run_global_setup
38
+ if setup = Configuration.global_setup
39
+ instance_eval &setup
40
+ end
41
+ end
42
+
43
+ def run_global_teardown
44
+ if teardown = Configuration.global_teardown
45
+ instance_eval &teardown
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,77 @@
1
+ require 'heroku'
2
+ module Purobu
3
+ class Test
4
+ include HerokuHelpers
5
+
6
+ attr_reader :setups, :teardowns, :name
7
+ attr_writer :exercise, :verification
8
+
9
+ def initialize(name = nil)
10
+ @setups = []
11
+ @exercise = -> {}
12
+ @verification = -> {}
13
+ @teardowns = []
14
+ @fail = true
15
+ @name = name
16
+ end
17
+
18
+ def run
19
+ begin
20
+ Purobu.log_context(test: name) do
21
+ Purobu.log(setups: true) do
22
+ @setups.each { |s| s.call }
23
+ end
24
+ Purobu.log(exercise: true) do
25
+ @exercise.call
26
+ end
27
+ Purobu.log(verification: true) do
28
+ @fail = !@verification.call
29
+ end
30
+ Purobu.log(teardown: true) do
31
+ @teardowns.each { |s| s.call }
32
+ end
33
+ end
34
+ rescue => e
35
+ @fail = true
36
+ end
37
+ pass?
38
+ end
39
+
40
+ def pass?
41
+ !@fail
42
+ end
43
+
44
+ def setup(&block)
45
+ @setups << block
46
+ end
47
+
48
+ def exercise(&block)
49
+ @exercise = block
50
+ end
51
+
52
+ def verify(&block)
53
+ @verification = block
54
+ end
55
+
56
+ def teardown(&block)
57
+ @teardowns << block
58
+ end
59
+
60
+ def reporter
61
+ @reporter ||= Reporter.new(self)
62
+ end
63
+
64
+ def reporter=(new_reporter)
65
+ @reporter = new_reporter
66
+ end
67
+
68
+ def report_result
69
+ if pass?
70
+ reporter.report_pass
71
+ else
72
+ reporter.report_fail
73
+ end
74
+ end
75
+
76
+ end
77
+ end
@@ -0,0 +1,3 @@
1
+ module Purobu
2
+ VERSION = "0.0.1"
3
+ end
data/lib/purobu.rb ADDED
@@ -0,0 +1,9 @@
1
+ require "purobu/version"
2
+ require "purobu/log"
3
+ require "purobu/configuration"
4
+ require "purobu/heroku_helpers"
5
+ require "purobu/test"
6
+ require "purobu/runner"
7
+ require "purobu/dsl"
8
+ require "purobu/heroku"
9
+ require "purobu/reporter"
data/purobu.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/purobu/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Harold Giménez"]
6
+ gem.email = ["harold.gimenez@gmail.com"]
7
+ gem.description = %q{ Probe your production or staging environment for behavior correctness }
8
+ gem.summary = %q{ Black-box integration test framework for components on the Heroku platform. }
9
+ gem.homepage = "http://practiceovertheory.com"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "purobu"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Purobu::VERSION
17
+
18
+ gem.add_dependency "heroku", "2.28.2"
19
+ gem.add_dependency "heroku-api"
20
+ gem.add_dependency "scrolls", "0.2.1"
21
+ gem.add_development_dependency "rspec"
22
+ gem.add_development_dependency "fakefs"
23
+ end
@@ -0,0 +1,42 @@
1
+ require 'purobu'
2
+ require 'fakefs/safe'
3
+ require 'fakefs/spec_helpers'
4
+
5
+ describe Purobu::DSL do
6
+ let(:dsl) { Purobu::DSL.new }
7
+ it 'adds tests to the runner' do
8
+ dsl.test do
9
+ verify { true }
10
+ end
11
+
12
+ dsl.tests.size.should == 1
13
+ test = dsl.tests.pop
14
+ test.should be_a Purobu::Test
15
+ end
16
+
17
+ it 'supports adding names to tests' do
18
+ dsl.test 'a name' do
19
+ verify { true }
20
+ end
21
+ end
22
+ end
23
+
24
+ describe Purobu::DSL, 'loading tests files' do
25
+ include FakeFS::SpecHelpers
26
+
27
+ before { FakeFS.activate! }
28
+ after { FakeFS.deactivate! }
29
+
30
+ it 'loads tests' do
31
+ 2.times do |i|
32
+ File.open("test_#{i}.rb", 'w') do |file|
33
+ file << "test { verify { true } }"
34
+ end
35
+ end
36
+
37
+ dsl = Purobu::DSL.new
38
+ dsl.load_tests
39
+
40
+ dsl.tests.size.should == 2
41
+ end
42
+ end
File without changes
@@ -0,0 +1,39 @@
1
+ require 'purobu'
2
+
3
+ describe Purobu::Runner, 'running tests' do
4
+ let(:runner) { Purobu::Runner.new }
5
+ it 'invokes each test and reports its result' do
6
+ test = Purobu::Test.new
7
+
8
+ test.should_receive(:run).once
9
+ test.should_receive(:report_result).once
10
+
11
+ runner.tests.push(test)
12
+
13
+ runner.run
14
+ end
15
+
16
+ it 'invokes the global setup before running any test' do
17
+ setup = nil
18
+ Purobu::Configuration.run do |config|
19
+ config.global_setup do
20
+ setup = :global_setup
21
+ end
22
+ end
23
+ setup.should be_nil
24
+ runner.run
25
+ setup.should == :global_setup
26
+ end
27
+
28
+ it 'invokes the global teardown before running any test' do
29
+ teardown = nil
30
+ Purobu::Configuration.run do |config|
31
+ config.global_teardown do
32
+ teardown = :global_teardown
33
+ end
34
+ end
35
+ teardown.should be_nil
36
+ runner.run
37
+ teardown.should == :global_teardown
38
+ end
39
+ end
@@ -0,0 +1,100 @@
1
+ require 'purobu'
2
+
3
+ describe Purobu::Test, '#run' do
4
+ it 'sets up' do
5
+ test = Purobu::Test.new
6
+ test.setup { throw :setup }
7
+ -> { test.run }.should throw_symbol :setup
8
+ end
9
+
10
+ it 'exercises' do
11
+ test = Purobu::Test.new
12
+ test.exercise { throw :exercise }
13
+
14
+ -> { test.run }.should throw_symbol :exercise
15
+ end
16
+
17
+ it 'verifies' do
18
+ test = Purobu::Test.new
19
+ test.verify { throw :validation }
20
+
21
+ -> { test.run }.should throw_symbol :validation
22
+ end
23
+
24
+ it 'tears down' do
25
+ test = Purobu::Test.new
26
+ test.teardown { throw :teardown }
27
+
28
+ -> { test.run }.should throw_symbol :teardown
29
+ end
30
+ end
31
+
32
+ describe Purobu::Test, 'pass/fail' do
33
+ it 'is failing be default' do
34
+ test = Purobu::Test.new
35
+ test.pass?.should be_false
36
+ end
37
+ it 'passes if the validation returns true' do
38
+ test = Purobu::Test.new
39
+ test.verification = -> { true }
40
+
41
+ test.run.should be_true
42
+ test.pass?.should be_true
43
+ end
44
+
45
+ it 'fails when validation returns false' do
46
+ test = Purobu::Test.new
47
+ test.verification = -> { false }
48
+
49
+ test.run.should be_false
50
+ test.pass?.should be_false
51
+ end
52
+
53
+ it 'fails when anything raises' do
54
+ test = Purobu::Test.new
55
+ test.verification = -> { raise "waa" }
56
+
57
+ test.run.should be_false
58
+ test.pass?.should be_false
59
+ end
60
+ end
61
+
62
+ describe Purobu::Test, '#heroku' do
63
+ it 'delegates to the heroku run command' do
64
+ Purobu::Heroku.should_receive(:run).with('addons')
65
+
66
+ Purobu::Test.new.heroku 'addons'
67
+ end
68
+ end
69
+
70
+ describe Purobu::Test, '#report_result' do
71
+ it 'reports to the reporter whether it passed or failed' do
72
+ reporter = double(:reporter)
73
+ reporter.should_receive(:report_pass).once
74
+ test = Purobu::Test.new
75
+ test.reporter = reporter
76
+
77
+ test.verify { true }
78
+ test.run
79
+
80
+ test.report_result
81
+
82
+
83
+ reporter.should_receive(:report_fail).once
84
+ test.verify { false }
85
+ test.run
86
+
87
+ test.report_result
88
+ end
89
+ end
90
+
91
+ describe Purobu::Test, '#heroku_api' do
92
+ it 'exposes the heroku api' do
93
+ test = Purobu::Test.new
94
+ heroku_api = double
95
+ heroku_api.should_receive(:something).once
96
+ Heroku::API.stub(new: heroku_api)
97
+
98
+ test.heroku_api.something
99
+ end
100
+ end
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: purobu
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Harold Giménez
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-26 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: heroku
16
+ requirement: &70132005273080 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - =
20
+ - !ruby/object:Gem::Version
21
+ version: 2.28.2
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70132005273080
25
+ - !ruby/object:Gem::Dependency
26
+ name: heroku-api
27
+ requirement: &70132005172240 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70132005172240
36
+ - !ruby/object:Gem::Dependency
37
+ name: scrolls
38
+ requirement: &70132005159400 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - =
42
+ - !ruby/object:Gem::Version
43
+ version: 0.2.1
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70132005159400
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec
49
+ requirement: &70132005150920 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70132005150920
58
+ - !ruby/object:Gem::Dependency
59
+ name: fakefs
60
+ requirement: &70132005148440 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70132005148440
69
+ description: ! ' Probe your production or staging environment for behavior correctness '
70
+ email:
71
+ - harold.gimenez@gmail.com
72
+ executables:
73
+ - purobu
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - .gitignore
78
+ - Gemfile
79
+ - LICENSE
80
+ - README.md
81
+ - Rakefile
82
+ - bin/purobu
83
+ - lib/purobu.rb
84
+ - lib/purobu/configuration.rb
85
+ - lib/purobu/dsl.rb
86
+ - lib/purobu/heroku.rb
87
+ - lib/purobu/heroku_helpers.rb
88
+ - lib/purobu/log.rb
89
+ - lib/purobu/reporter.rb
90
+ - lib/purobu/runner.rb
91
+ - lib/purobu/test.rb
92
+ - lib/purobu/version.rb
93
+ - purobu.gemspec
94
+ - spec/purobu/dsl_spec.rb
95
+ - spec/purobu/reporter_spec.rb
96
+ - spec/purobu/runner_spec.rb
97
+ - spec/purobu/test_spec.rb
98
+ homepage: http://practiceovertheory.com
99
+ licenses: []
100
+ post_install_message:
101
+ rdoc_options: []
102
+ require_paths:
103
+ - lib
104
+ required_ruby_version: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
+ none: false
112
+ requirements:
113
+ - - ! '>='
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ requirements: []
117
+ rubyforge_project:
118
+ rubygems_version: 1.8.10
119
+ signing_key:
120
+ specification_version: 3
121
+ summary: Black-box integration test framework for components on the Heroku platform.
122
+ test_files:
123
+ - spec/purobu/dsl_spec.rb
124
+ - spec/purobu/reporter_spec.rb
125
+ - spec/purobu/runner_spec.rb
126
+ - spec/purobu/test_spec.rb