eol_rackbox 1.1.7

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2009 ryan "remi" Taylor
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,88 @@
1
+ = RackBox
2
+
3
+ RackBox adds Merb-style blackbox testing]blackbox] to Rack apps (including Rails)
4
+
5
+ This currently only works with RSpec.
6
+
7
+ == Screencast
8
+
9
+ Watch the Screencast[http://remi.org/2009/01/29/introducing-rackbox_merb-esque-blackbox-testing-for-rack-and-rails-apps.html]
10
+
11
+ == Installation
12
+
13
+ $ sudo gem install remi-rackbox -s http://gems.github.com
14
+
15
+ NOTE: right now, RackBox requires thin. Soon, I'll likely remove thin as
16
+ a dependency and will only require rack.
17
+
18
+ == Rails (fast!)
19
+
20
+ $ sudo gem install rspec rspec-rails thin
21
+ $ sudo gem install remi-rackbox -s http://gems.github.com
22
+
23
+ $ rails new_app
24
+ $ cd new_app
25
+ $ ./script/generate rspec
26
+ $ ./script/generate blackbox_spec Home Page
27
+
28
+ $ rake spec
29
+
30
+
31
+ == Rails (manual)
32
+
33
+ To write RackBox tests in Rails apps, make a `blackbox` directory under your `spec` directory
34
+ and add this to the Spec configure block in your `spec_helper.rb` file:
35
+
36
+ config.use_blackbox = true
37
+
38
+ Also, add `require 'rackbox'` to the top of your `spec_helper.rb`
39
+
40
+ You can see a working example of blackbox testing a Rails application here: examples/rails](http://github.com/remi/rackbox/tree/master/examples/rails)
41
+
42
+ == Rack
43
+
44
+ To write RackBox tests in Rack apps, I'm currently assuming that you have a `config.ru` rackup file.
45
+ If so, your app should load, otherwise you can explicitly configure RackBox to read your Rack app:
46
+
47
+ RackBox.app = your Rack app]
48
+
49
+ Basides that, the configuration is the same as Rails. Make a `blackbox` directory under your
50
+ `spec` directory and add this to the Spec configure block in your `spec_helper.rb` file:
51
+
52
+ config.use_blackbox = true
53
+
54
+ Also, add `require 'rackbox'` to the top of your `spec_helper.rb`
55
+
56
+ You can see a working example of blackbox testing a Rack application here: examples/rack](http://github.com/remi/rackbox/tree/master/examples/rack)
57
+
58
+ NOTE: If you want to be able to use nice RSpec matchers like `request('/').should have_tag('p')` in your
59
+ blackbox specs in your Rack apps, you should `sudo gem install webrat` and RackBox will include
60
+ Webrat's helpers in your specs.
61
+
62
+ == Usage
63
+
64
+ Ideally, the usage of RackBox should be identical to Merb-style blackbox testing. I need to find good documentation
65
+ on how things work in Merb so I can duplicate any functionality I'm missing. For now, it's really simple!
66
+
67
+ describe Foo do
68
+
69
+ it 'should have foxes on the home page' do
70
+ request('/').body.should include('Foxes')
71
+ end
72
+
73
+ it 'should let me know that I was logged in' do
74
+ response = request(login_path, :method => :post, :params => { 'user' => 'bob', :password => 'secret' })
75
+ response.body.should include('Welcome bob, you were successfully logged in!')
76
+ end
77
+
78
+ end
79
+
80
+ `request` gives you a `Rack::Response`](http://rack.rubyforge.org/doc/classes/Rack/Response.html) which has
81
+ `body`, `headers`, `status` methods (and more](http://rack.rubyforge.org/doc/classes/Rack/Response.html))
82
+
83
+ == TODO
84
+
85
+ * request('/', :data => 'some XML or something')
86
+ * request('/', :format => :json) # simple helpers for content type request accepts
87
+ * request('/', 'Content-Length' => 'x') # anything passed in that we don't handle, throw into the request ENV ... but :content_length should work too?
88
+ * get usage documentation working for `./script/generate blackbox_spec`
@@ -0,0 +1,134 @@
1
+ RackBox
2
+ =======
3
+
4
+ [RackBox][] adds [Merb][]-style [blackbox testing][blackbox] to [Rack][] apps (including [Rails][])
5
+
6
+ This currently only works with [RSpec][].
7
+
8
+ DEPRECATED
9
+ ----------
10
+
11
+ **NOTE**: Although I really love the RackBox syntax (which was stolen from Merb's request spec),
12
+ rack-test has gotten much more love than RackBox and I haven't had time to refactor RackBox.
13
+
14
+ I recommend using rack-test instead! RackBox will likely be ported to a rack-test extension
15
+ that provides the syntax I enjoy.
16
+
17
+ Screencast
18
+ ----------
19
+
20
+ [Watch the 'Screencast'][screencast]
21
+
22
+ Installation
23
+ ------------
24
+
25
+ $ sudo gem install remi-rackbox -s http://gems.github.com
26
+
27
+ NOTE: right now, [RackBox][] requires [thin][]. Soon, I'll likely remove [thin][] as
28
+ a dependency and will only require [rack][].
29
+
30
+ Rails (fast!)
31
+ -------------
32
+
33
+ $ sudo gem install rspec rspec-rails thin
34
+ $ sudo gem install remi-rackbox -s http://gems.github.com
35
+
36
+ $ rails new_app
37
+ $ cd new_app
38
+ $ ./script/generate rspec
39
+ $ ./script/generate blackbox_spec Home Page
40
+
41
+ $ rake spec
42
+
43
+
44
+ Rails (manual)
45
+ --------------
46
+
47
+ To write [RackBox][] tests in [Rails][] apps, make a `blackbox` directory under your `spec` directory
48
+ and add this to the Spec configure block in your `spec_helper.rb` file:
49
+
50
+ config.use_blackbox = true
51
+
52
+ Also, add `require 'rackbox'` to the top of your `spec_helper.rb`
53
+
54
+ You can see a working example of blackbox testing a [Rails][] application here: [examples/rails](http://github.com/remi/rackbox/tree/master/examples/rails)
55
+
56
+ Rack
57
+ ----
58
+
59
+ To write [RackBox][] tests in [Rack][] apps, I'm currently assuming that you have a `config.ru` rackup file.
60
+ If so, your app should load, otherwise you can explicitly configure [RackBox][] to read your [Rack][] app:
61
+
62
+ RackBox.app = [your Rack app]
63
+
64
+ Basides that, the configuration is the same as [Rails][]. Make a `blackbox` directory under your
65
+ `spec` directory and add this to the Spec configure block in your `spec_helper.rb` file:
66
+
67
+ config.use_blackbox = true
68
+
69
+ Also, add `require 'rackbox'` to the top of your `spec_helper.rb`
70
+
71
+ You can see a working example of blackbox testing a [Rack][] application here: [examples/rack](http://github.com/remi/rackbox/tree/master/examples/rack)
72
+
73
+ NOTE: If you want to be able to use nice RSpec matchers like `request('/').should have_tag('p')` in your
74
+ blackbox specs in your [Rack][] apps, you should `sudo gem install webrat` and [RackBox][] will include
75
+ [Webrat][]'s helpers in your specs.
76
+
77
+ Usage
78
+ -----
79
+
80
+ Ideally, the usage of [RackBox][] should be identical to [Merb][]-style blackbox testing. I need to find good documentation
81
+ on how things work in [Merb][] so I can duplicate any functionality I'm missing. For now, it's really simple!
82
+
83
+ describe Foo do
84
+
85
+ it 'should have foxes on the home page' do
86
+ request('/').body.should include('Foxes')
87
+ end
88
+
89
+ it 'should let me know that I was logged in' do
90
+ response = request(login_path, :method => :post, :params => { 'user' => 'bob', :password => 'secret' })
91
+ response.body.should include('Welcome bob, you were successfully logged in!')
92
+ end
93
+
94
+ end
95
+
96
+ `request` gives you a [`Rack::Response`](http://rack.rubyforge.org/doc/classes/Rack/Response.html) which has
97
+ `body`, `headers`, `status` methods ([and more](http://rack.rubyforge.org/doc/classes/Rack/Response.html))
98
+
99
+ Script
100
+ ------
101
+
102
+ [RackBox][] also comes with a `rackbox` script.
103
+
104
+ # prints usage ... this is all you really need :)
105
+ $ rackbox
106
+
107
+ # prints out information about the app in the current directory (if found).
108
+ # this looks like a config.ru or a Rails environment
109
+ $ rackbox info
110
+
111
+ # prints out the response for a call to GET '/' on your application
112
+ $ rackbox request --method get /foo
113
+ $ rackbox get /foo
114
+ $ rackbox /foo
115
+
116
+ TODO
117
+ ----
118
+
119
+ see [RackBox][]'s [Lighthouse Tickets](http://remitaylor.lighthouseapp.com/projects/27570-rackbox)
120
+ * look at using Rack::Cookies as a cookie jar instead of doing it ourselves
121
+ * look at Rack::NestedParams and see if it can replace our own logic
122
+
123
+
124
+ [rackbox]: http://github.com/remi/rackbox
125
+ [merb]: http://merbivore.com
126
+ [rack]: http://rack.rubyforge.org
127
+ [rails]: http://rubyonrails.org
128
+ [rspec]: http://rspec.info
129
+ [webrat]: http://github.com/brynary/webrat
130
+ [thin]: http://code.macournoyer.com/thin
131
+ [screencast]: http://remi.org/2009/01/29/introducing-rackbox_merb-esque-blackbox-testing-for-rack-and-rails-apps.html
132
+ [rubygem]: http://www.rubygems.org
133
+ [blackbox]: http://en.wikipedia.org/wiki/Black_box_testing
134
+ [sinatra]: http://sinatra.github.com
@@ -0,0 +1,17 @@
1
+ = eol_rackbox
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2010 Jeremy Rice. See LICENSE for details.
@@ -0,0 +1,59 @@
1
+ require 'rake'
2
+ require 'rubygems'
3
+ require 'rake/rdoctask'
4
+ require 'spec/rake/spectask'
5
+
6
+ begin
7
+ require 'jeweler'
8
+ Jeweler::Tasks.new do |s|
9
+ s.name = "eol_rackbox"
10
+ s.summary = "Merb-like BlackBox testing for Rack apps, including Rails"
11
+ s.email = "jrice.blue@gmail.com"
12
+ s.homepage = "http://github.com/JRice/eol_rackbox"
13
+ s.description = "Merb-like BlackBox testing for Rack apps, including Rails; requires two rare dependencies: remi-rails-rack-adapter and remi-simplecli, which we available on github"
14
+ s.authors = ["Jeremy Rice"]
15
+ s.files = FileList["[A-Z]*", "{bin,lib,spec,examples,rails_generators}/**/*"]
16
+ # s.add_dependency 'remi-rails-rack-adapter'
17
+ # s.add_dependency 'remi-simplecli'
18
+ s.executables = "rackbox"
19
+ end
20
+ Jeweler::GemcutterTasks.new
21
+ rescue LoadError
22
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
23
+ end
24
+
25
+ Spec::Rake::SpecTask.new do |t|
26
+ t.spec_files = FileList['spec/**/*_spec.rb']
27
+ end
28
+
29
+ desc "Run all examples with RCov"
30
+ Spec::Rake::SpecTask.new('rcov') do |t|
31
+ t.spec_files = FileList['spec/**/*_spec.rb']
32
+ t.rcov = true
33
+ end
34
+
35
+ Rake::RDocTask.new do |rdoc|
36
+ rdoc.rdoc_dir = 'rdoc'
37
+ rdoc.title = 'rackbox'
38
+ rdoc.options << '--line-numbers' << '--inline-source'
39
+ rdoc.rdoc_files.include('RDOC_README.rdoc')
40
+ rdoc.rdoc_files.include('lib/**/*.rb')
41
+ end
42
+
43
+ desc 'Confirm that gemspec is $SAFE'
44
+ task :safe do
45
+ require 'yaml'
46
+ require 'rubygems/specification'
47
+ data = File.read('rackbox.gemspec')
48
+ spec = nil
49
+ if data !~ %r{!ruby/object:Gem::Specification}
50
+ Thread.new { spec = eval("$SAFE = 3\n#{data}") }.join
51
+ else
52
+ spec = YAML.load(data)
53
+ end
54
+ spec.validate
55
+ puts spec
56
+ puts "OK"
57
+ end
58
+
59
+ task :default => :spec
@@ -0,0 +1,5 @@
1
+ ---
2
+ :major: 1
3
+ :minor: 1
4
+ :build:
5
+ :patch: 7
@@ -0,0 +1,4 @@
1
+ #! /usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../lib/rackbox'
3
+ require 'rackbox/bin'
4
+ RackBox::Bin.new( ARGV ).run
@@ -0,0 +1,18 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ require 'rubygems'
4
+ require 'rack'
5
+ require 'rails-rack-adapter' # update this so it's only loaded when/if needed
6
+
7
+ require 'rackbox/rack/content_length_fix'
8
+ require 'rackbox/rack/sticky_sessions'
9
+ require 'rackbox/rack/extensions_for_rspec'
10
+
11
+ require 'rackbox/rackbox'
12
+ require 'rackbox/app'
13
+
14
+ require 'rspec/custom_matcher'
15
+ require 'rackbox/matchers'
16
+
17
+ require 'rackbox/spec/helpers'
18
+ require 'rackbox/spec/configuration'
@@ -0,0 +1,30 @@
1
+ class RackBox
2
+
3
+ # represents a rack appliction
4
+ #
5
+ # gives us some helpers on a rack app
6
+ # like the ability to use the #request
7
+ # method on it easily
8
+ #
9
+ class App
10
+ attr_accessor :rack_app, :mock_request
11
+
12
+ def initialize rack_app
13
+ @rack_app = rack_app
14
+ reset_request
15
+ end
16
+
17
+ def reset_request
18
+ @mock_request = Rack::MockRequest.new @rack_app
19
+ end
20
+ alias reset reset_request
21
+
22
+ # sessions are sticky!
23
+ #
24
+ # to reset, @rackbox_app.reset
25
+ def request url, options = {}
26
+ RackBox.request @mock_request, url, options
27
+ end
28
+ end
29
+
30
+ end
@@ -0,0 +1 @@
1
+ # this should get you up and running for using RackBox with Bacon
@@ -0,0 +1,183 @@
1
+ require 'optparse'
2
+ require 'simplecli'
3
+
4
+ class String
5
+ def indent number_of_spaces = 1
6
+ self.gsub(/^(.*)$/, (' ' * number_of_spaces) + '\1')
7
+ end
8
+ end
9
+
10
+ class RackBox::Bin
11
+ include SimpleCLI
12
+
13
+ def initialize *args
14
+ @default_command = :request
15
+ super
16
+ end
17
+
18
+ def usage *args
19
+ puts <<doco
20
+
21
+ rackbox == %{ For hitting your Rack applications }
22
+
23
+ Usage:
24
+ rackbox command [options]
25
+
26
+ Examples:
27
+ rackbox info # prints app info
28
+ rackbox commands # list commands
29
+ rackbox get / # request / path
30
+ rackbox post -d '<XML>' / # POST data to / path
31
+ rackbox / # GET /
32
+ rackbox --data '<XML>' # POST data to / path
33
+ rackbox /dogs --xml # get /dogs, accepting xml
34
+
35
+ Options:
36
+ -a, --app "MyApp.new" # ruby to eval to get Rack app
37
+ -r, --require file[.rb] # ruby file(s) to require
38
+
39
+ Further help:
40
+ rackbox commands # list all available commands
41
+ rackbox help <COMMAND> # show help for COMMAND
42
+ rackbox help # show this help message
43
+
44
+ doco
45
+ end
46
+
47
+ %w( get post put delete ).each do |http_method|
48
+ define_method(http_method) do |*args|
49
+ request *( ['-m', http_method] + args )
50
+ end
51
+ define_method("#{http_method}_help") do
52
+ <<doco
53
+ Usage: #{ script_name } #{ http_method } '/some/path'
54
+
55
+ Summary:
56
+ Run a #{ http_method.upcase } request against a Rack app
57
+ end
58
+ doco
59
+ end
60
+ end
61
+
62
+ def request_help
63
+ <<doco
64
+ Usage: #{ script_name } request '/some/path'
65
+
66
+ Options:
67
+ -m, --method The HTTP method to use, default: get
68
+ -d, --data Data to that you can PUT/POST, eg. -d '<XML>'
69
+ -s, --show What to show, eg. -s body,headers,status or
70
+ call multiple times, eg. -s body -s headers
71
+ -h, --header Add header to request, eg. -h accept=text/plain
72
+ -j, --json Sets 'Accept' header to 'application/json'
73
+ -x, --xml Sets 'Accept' header to 'application/xml'
74
+
75
+ Summary:
76
+ Run a request against a Rack app
77
+ end
78
+ doco
79
+ end
80
+ def request *args
81
+
82
+ # if args is ampty, we likely just called: $ rackbox
83
+ # which came to #request because it's the default command,
84
+ # so we should print out the usage for rackbox and exit
85
+ if args.empty?
86
+ usage
87
+ exit
88
+ end
89
+
90
+ set_rackbox_app args
91
+
92
+ options = {
93
+ :show => [],
94
+ :headers => {}
95
+ }
96
+ opts = OptionParser.new do |opts|
97
+ opts.on('-j', '--json'){ options[:headers]['Accept'] = 'application/json' }
98
+ opts.on('-x', '--xml'){ options[:headers]['Accept'] = 'application/xml' }
99
+ opts.on('-m','--method [m]'){|m| options[:method] = m }
100
+ opts.on('-d','--data [d]'){|d| options[:data] = d }
101
+ opts.on('-s','--show [s]'){|s| options[:show] += s.split(',') }
102
+ opts.on('-h','--header [h]'){|h|
103
+ name,value = h.split('=')
104
+ options[:headers][name] = value
105
+ }
106
+ end
107
+ opts.parse! args
108
+
109
+ rackbox_options = { }
110
+ rackbox_options[:method] = options[:method] if options[:method]
111
+ rackbox_options[:data] = options[:data] if options[:data]
112
+
113
+ options[:headers].each do |name, value|
114
+ rackbox_options[name] = value
115
+ end
116
+
117
+ url = args.pop
118
+
119
+ response = RackBox.request url, rackbox_options
120
+ options[:show] = %w( body headers status ) if options[:show].empty?
121
+
122
+ if options[:show].include? 'body'
123
+ body_text = ''
124
+ response.body.each {|str| body_text << str }
125
+ end
126
+
127
+ output = "Response:\n"
128
+ output << " Status: #{ response.status }\n" if options[:show].include? 'status'
129
+ output << " Headers: \n#{ response.headers.to_yaml.strip.indent(4) }\n" if options[:show].include? 'headers'
130
+ output << " Body: \n#{ body_text.indent(4) }\n" if options[:show].include? 'body'
131
+
132
+ puts output
133
+ end
134
+
135
+ def info_help
136
+ <<doco
137
+ Usage: #{ script_name } info
138
+
139
+ Summary:
140
+ Display information about the current Rack application
141
+ end
142
+ doco
143
+ end
144
+ def info *args
145
+ set_rackbox_app args
146
+ puts "RackBox.app => #{ RackBox.app( :silent => true ).inspect }"
147
+ end
148
+
149
+ private
150
+
151
+ #
152
+ # we let users pass a ruby string that will return
153
+ # the rack app to be used, eg.
154
+ #
155
+ # you can also set files to be required ( -r )
156
+ #
157
+ # $ rackbox -r myapp.rb --app 'lambda {|env| [200, {}, "hi!"] }' info
158
+ # $ rackbox -r myapp.rb,another-file.rb --app 'Sinatra::Application' get '/'
159
+ # $ rackbox -r myapp --app 'MyApp.new' '/'
160
+ #
161
+ def set_rackbox_app args
162
+ files_to_require = []
163
+ ruby_to_run = nil
164
+
165
+ opts = OptionParser.new do |opts|
166
+ opts.on('-r', '--require [file]') {|x| files_to_require << x }
167
+ opts.on('-a', '--app [ruby]') {|x| ruby_to_run = x }
168
+ end
169
+ opts.parse! args
170
+
171
+ files_to_require.each {|file| require file }
172
+
173
+ if ruby_to_run
174
+ begin
175
+ RackBox.app = eval(ruby_to_run)
176
+ rescue Exception => ex
177
+ puts "tried running Ruby code to set RackBox app: #{ ruby_to_run.inspect }"
178
+ raise ex
179
+ end
180
+ end
181
+ end
182
+
183
+ end