assert-response 0.0.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/README.md +131 -0
  2. data/VERSION +1 -1
  3. data/lib/assert-response.rb +33 -30
  4. metadata +17 -17
  5. data/README.rdoc +0 -167
data/README.md ADDED
@@ -0,0 +1,131 @@
1
+ assert-response: sugar around Rack::Test
2
+ =================================================================================================
3
+
4
+ When it comes to **Rack::Test** there are two things that I don't like:
5
+
6
+ * If your rack app raises an error, it is not exposed as an error but hidden in last_response.errors
7
+ * Most of the time a status 404 should be considered as an error - the only exeption being that we expect a 404 status
8
+ * It's annoying to test for content-types
9
+
10
+ **assert-response** is there to address these issues:
11
+
12
+ * an error that occurs in your rack app will be raised (with original backtrace)
13
+ * you may test the error class and message
14
+ * a status 404 will raise an error everywhere execept from testing 404 responses
15
+ * you get a shortcut for all content-types that come with Rack::Mime and may register your own
16
+ * you get a little DSL to be able to do several test against the same response in a DRY way
17
+
18
+ Installation
19
+ ------------
20
+ _assert-response_ has been tested with _ruby 1.8.7_ and _1.9.2._ It should be usable with every
21
+ testing library and has been tested with _test/unit_ and _minitest_.
22
+
23
+ Install it as a gem:
24
+
25
+ sudo gem install assert-response
26
+
27
+ or in rvm:
28
+
29
+ gem install assert-response
30
+
31
+
32
+
33
+ Examples
34
+ --------
35
+ require 'minitest'
36
+ require 'rack/test'
37
+ require 'assert-reponse'
38
+
39
+ include Rack::Test::Methods
40
+
41
+ def app
42
+ MyApp
43
+ end
44
+
45
+ _(for usage without the inclusion of Rack::Test::Methods or with Test::Unit, see AssertResponse::Methods)_
46
+
47
+ And then in your test something like this:
48
+ get '/myroute'
49
+ assert_response_html 'my body'
50
+
51
+ This will
52
+
53
+ # raise the error, if an error occures in MyApp
54
+ raise AssertResponse::Status404 if last_response.status is not 404
55
+ assert_equal200, last_response.status
56
+ assert "test/html", last_response.headers['Content-Type']
57
+ assert_match /my\ body/, last_response.body
58
+
59
+ But you may also want to...
60
+ check just the mime type:
61
+ get '/myroute'
62
+ assert_response_is_html
63
+
64
+ check for a 404 page:
65
+ get '/myroute'
66
+ assert_response_not_found_html "Not found!"
67
+
68
+ This one does:
69
+
70
+ assert 404, last_response.status
71
+ assert "test/html", last_response.headers['Content-Type']
72
+ assert_match /Not\ found!/, last_response.body
73
+
74
+ For all mime types in Rack::Mime you get 3 methods, where [shortcut] is the file extension
75
+
76
+ assert_response_[shortcut] # checks for status 200, content-type and body matching
77
+ assert_response_is_[shortcut] # checks for content-type and status 200
78
+ assert_response_not_found_[shortcut] # checks for content-type, status 404 and body matching
79
+
80
+ You may define your own content-type with
81
+
82
+ AssertResponse.add_content_type :my_shortcut, "text/mymimetype"
83
+
84
+ # later...
85
+ assert_response_my_shortcut "here the body"
86
+ assert_response_is_my_shortcut
87
+ assert_response_not_found_my_shortcut "Not found but correct content-type"
88
+
89
+ There is some additional sugar like
90
+
91
+ assert_response_redirect
92
+ assert_response_raises
93
+ assert_response_body
94
+ assert_response_header
95
+ assert_response_not_found
96
+ assert_response_ok
97
+
98
+ Everything after _assert\_response\__ is the called method of _AssertResponse_, look them up in the documentation.
99
+
100
+ When using the _assert\_response\__ methods always the the *last_response* object is checked.
101
+
102
+ If you want to check a saved response instead, you may use the little DSL
103
+
104
+ get '/myroute'
105
+ my_response = last_response
106
+ get '/other'
107
+ assert_response my_response do
108
+ is_html # checks content-type
109
+ body 'my body' # same as 'body /my\ body/'
110
+ end
111
+
112
+ Now inside the code block you may use the methods of _AssertResponse_ (but without the *assert\_response\_* prefixes).
113
+
114
+
115
+ Contributing to assert-response
116
+ -------------------------------
117
+
118
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
119
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
120
+ * Fork the project
121
+ * Start a feature/bugfix branch
122
+ * Commit and push until you are happy with your contribution
123
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
124
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
125
+
126
+ Copyright
127
+ ---------
128
+
129
+ Copyright (c) 2011 Marc Rene Arns. See LICENSE.txt for
130
+ further details.
131
+
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.3
1
+ 1.0.0
@@ -1,28 +1,32 @@
1
1
  class AssertResponse
2
+
3
+ # error class, raised when a 404 status but another status was expected
2
4
  class Status404 < Exception ; end
3
- # for each content-type there is a method
4
- # * +is_[content_type]+ that checks if the response has the content-type
5
- # * +[content_type]+ that checks the content-type and matches the body against the given pattern and checks for status 200
6
- # * +not_found_[content_type]+ that checks the content-type, matches the body against the pattern and checks for status 404
7
- # see method_missing
8
- CONTENT_TYPES = {}
9
- CONTENT_TYPES[:html] = 'text/html'
10
- CONTENT_TYPES[:css] = 'text/css'
11
- CONTENT_TYPES[:js] = 'application/javascript'
12
- CONTENT_TYPES[:json] = 'application/json'
13
- CONTENT_TYPES[:text] = 'text/plain'
14
5
 
15
- # Adds custom content_types to AssertResponse::CONTENT_TYPES. We would then have all the test methods for the content-type
6
+ # Hash to collection available content-types (prefilled with the Rack::Mime::MIME_TYPES)
16
7
  #
8
+ # @see AssertResponse#method_missing
9
+ CONTENT_TYPES = {}
10
+
11
+ # Adds custom content_types to
12
+ # {AssertResponse::CONTENT_TYPES}. We would then have all the test methods for the content-type
17
13
  # @param [Symbol] name name of the content_type
18
14
  # @param [String] content_type content_type (mime type, eg. "text/html")
19
15
  def AssertResponse.add_content_type(name, content_type)
20
- CONTENT_TYPES.update name, content_type
16
+ CONTENT_TYPES.update(name => content_type)
17
+ end
18
+
19
+ # add all Rack::Mime::MIME_TYPES as content_types
20
+ Rack::Mime::MIME_TYPES.each do |fileext,mime|
21
+ AssertResponse.add_content_type fileext.sub(/^\./, '').to_sym, mime
21
22
  end
22
23
 
24
+ # add content_type 'text/plain' as :text
25
+ AssertResponse.add_content_type :text, 'text/plain'
26
+
23
27
  # Creates a new {AssertResponse} Object. Usually you will want to +instance_exec+ some code on it.
24
28
  #
25
- # @param [Object] delegate_to the test object that has all the assert_xxx methods that we want to call
29
+ # @param [Object] delegate_to the test object that has all the +assert_equal+, +assert_match+ and +assert+ methods that we need
26
30
  # @param [MockResponse, Response] response the response object that is checked
27
31
  def initialize(delegate_to, response, &code)
28
32
  @delegate_to = delegate_to
@@ -31,10 +35,11 @@ class AssertResponse
31
35
  check_for_error()
32
36
  end
33
37
 
34
- alias :_old_method_missing :method_missing
35
-
36
- # handles is_[content_type], not_found_[content_type] and [content_type] methods
37
- # Delegates unknown methods to +@delegate_to+
38
+ # for each content-type in {AssertResponse::CONTENT_TYPES} these methods are served by method_missing
39
+ # * +is_[content_type]+ that checks if the response has the content-type
40
+ # * +[content_type]+ that checks the content-type and matches the body against the given pattern and checks for status 200
41
+ # * +not_found_[content_type]+ that checks the content-type, matches the body against the pattern and checks for status 404
42
+ # further unknown methods are delegated to +@delegate_to+
38
43
  def method_missing(meth, *args, &code)
39
44
  case meth.to_s
40
45
  when /^(is|found)_(.+)$/ # is_[content_type] methods
@@ -148,11 +153,11 @@ class AssertResponse
148
153
 
149
154
  # these methods are included in Rack::Test::Methods to be used in a Test Class
150
155
  #
151
- # call assert_response with a code block to use the DSL (methods from AssertResponse)
152
- # or use a method like assert_response_xxx where xxx is the name of the method from AssertResponse you want to call
156
+ # call assert_response with a code block to use the DSL (methods from {AssertResponse})
157
+ # or use a method like assert_response_xxx where xxx is the name of the method from {AssertResponse} you want to call
158
+ # @see AssertResponse
153
159
  #
154
- # *Test::Unit*
155
- # simple
160
+ # @example with Test::Unit, simple
156
161
  # require 'rack/test'
157
162
  # require 'assert-response'
158
163
  #
@@ -168,8 +173,7 @@ class AssertResponse
168
173
  # end
169
174
  # end
170
175
  #
171
- # without including +Rack::Test::Methods+
172
- #
176
+ # @example without including +Rack::Test::Methods+
173
177
  # require 'rack/test'
174
178
  # require 'assert-response'
175
179
  #
@@ -192,8 +196,7 @@ class AssertResponse
192
196
  # end
193
197
  # end
194
198
  #
195
- # *Minitest*
196
- # simple
199
+ # @example with *Minitest*, simple
197
200
  # require 'rack/test'
198
201
  # require 'assert-response'
199
202
  # include Rack::Test::Methods
@@ -204,7 +207,7 @@ class AssertResponse
204
207
  # assert_response_html "should really work"
205
208
  # end
206
209
  #
207
- # without including +Rack::Test::Methods+
210
+ # @example without including +Rack::Test::Methods+
208
211
  # require 'rack/test'
209
212
  # require 'assert-response'
210
213
  #
@@ -230,9 +233,8 @@ class AssertResponse
230
233
  # end
231
234
  # end
232
235
  module Methods
233
- alias_method :__assert_response_method_missing, :method_missing
234
-
235
- # route assert_response_ methods to AssertResponse
236
+ # route assert_response_ methods to {AssertResponse}
237
+ # @see AssertResponse
236
238
  def method_missing(meth, *args, &code)
237
239
  if meth.to_s =~ /^assert_response_(.+)$/
238
240
  AssertResponse.new(self, last_response).send($1.to_sym, *args)
@@ -242,6 +244,7 @@ class AssertResponse
242
244
  end
243
245
 
244
246
  # creates an {AssertResponse} Object and +instance_exec+ the code (DSL) in it
247
+ # @see AssertResponse
245
248
  def assert_response(response=last_response, &code)
246
249
  file, line, rest = caller[0].split(':', 3)
247
250
  AssertResponse.new(self, response).instance_exec(file, line.to_i, &code)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: assert-response
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 1.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-12-13 00:00:00.000000000Z
12
+ date: 2011-12-15 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack-test
16
- requirement: &24401940 !ruby/object:Gem::Requirement
16
+ requirement: &16339740 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *24401940
24
+ version_requirements: *16339740
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: yard
27
- requirement: &24401460 !ruby/object:Gem::Requirement
27
+ requirement: &16337540 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *24401460
35
+ version_requirements: *16337540
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: bundler
38
- requirement: &24400980 !ruby/object:Gem::Requirement
38
+ requirement: &16336000 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 1.0.0
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *24400980
46
+ version_requirements: *16336000
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: jeweler
49
- requirement: &24400500 !ruby/object:Gem::Requirement
49
+ requirement: &16333600 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 1.5.2
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *24400500
57
+ version_requirements: *16333600
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rcov
60
- requirement: &24400020 !ruby/object:Gem::Requirement
60
+ requirement: &16332240 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *24400020
68
+ version_requirements: *16332240
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rack-test
71
- requirement: &24399540 !ruby/object:Gem::Requirement
71
+ requirement: &16329940 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,7 +76,7 @@ dependencies:
76
76
  version: '0'
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *24399540
79
+ version_requirements: *16329940
80
80
  description:
81
81
  email: ! 'Base64.decode64(''bGludXhAbWFyY3JlbmVhcm5zLmRl
82
82
 
@@ -85,12 +85,12 @@ executables: []
85
85
  extensions: []
86
86
  extra_rdoc_files:
87
87
  - LICENSE.txt
88
- - README.rdoc
88
+ - README.md
89
89
  files:
90
90
  - .document
91
91
  - Gemfile
92
92
  - LICENSE.txt
93
- - README.rdoc
93
+ - README.md
94
94
  - Rakefile
95
95
  - VERSION
96
96
  - lib/assert-response.rb
@@ -111,7 +111,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
111
111
  version: '0'
112
112
  segments:
113
113
  - 0
114
- hash: 652417119344286028
114
+ hash: -850628618767669317
115
115
  required_rubygems_version: !ruby/object:Gem::Requirement
116
116
  none: false
117
117
  requirements:
data/README.rdoc DELETED
@@ -1,167 +0,0 @@
1
- = assert-response
2
- == Description
3
-
4
- Assert-methods (sugar) and a tiny DSL to facilitate testing of rack apps with {Rack::Test}.
5
- The idea is that an error on the server side should be exposed to the tests as a real error (not hidden inside
6
- last_response.errors). +assert-response+ raises the correct error and gives us the backtrace back in our tests.
7
-
8
- Most of the time we check for the body of the response and then almost always a 404 - Not found is regarded as an error.
9
- Further we mostly want to check against Strings that are contained in the response body, while in some cases we need Regexps.
10
-
11
- So this methods and DSL makes the normal cases easier while making special cases possible.
12
-
13
- To use it in your tests:
14
- require 'rack/test'
15
- require 'assert-reponse'
16
- include Rack::Test::Methods
17
-
18
- (for usage without the inclusion of Rack::Test::Methods, see {AssertResponse::Methods}
19
-
20
- And then to test do something like this:
21
- get '/myroute'
22
- assert_response do
23
- is_html # checks content-type
24
- body 'my body' # same as 'body /my\ body/'
25
- end
26
-
27
- the same could be shorter:
28
- get '/myroute'
29
- assert_response do
30
- html 'my body'
31
- end
32
-
33
- or even:
34
- get '/myroute'
35
- assert_response_html 'my body'
36
-
37
- Predefined are the content types of html, css, js and json. But you may register your own by calling {AssertResponse.add_content_type}. Then you get all that assert_response_[your_content_type], assert_response_is_[your_content_type] and assert_response_not_found_[your_content_type] methods for granted.
38
-
39
- == Installation
40
- gem install assert-response
41
-
42
- Usually +assert_response+ checks +last_response+, but you could also pass a response Object:
43
- get '/a'
44
- a = last_response
45
- get '/b'
46
- assert_response a do # checks /a
47
- html 'body of a'
48
- end
49
-
50
- Inside the code block use the methods of {AssertResponse}.
51
-
52
- == Usage
53
- There are two ways to use assert-response: You could use the DSL or the assert_response_xxx methods.
54
- === DSL
55
- The DSL mode is handy if you want to perform several tests against the same response.
56
- You call +asser_response+ and give it a code block.
57
- All methods of the DSL are methods of {AssertResponse} so have a look there.
58
- get '/hello_world'
59
- assert_response do
60
- body '<body>body of hello_world</body>'
61
- ok # same as "status 200"
62
- is_html
63
- end
64
- === assert_response_xxx methods
65
- Some of the checks could be done simpler since some assertions imply other.
66
- The code above could be simplified to
67
- get '/hello_world'
68
- assert_response_html '<body>body of hello_world</body>'
69
- A call to assert_response_[method] will be forwarded to the according method of {AssertResponse}.
70
- But it checks always +last_response+, so if you need to pass the response object you will have to use the DSL.
71
-
72
- == Examples
73
-
74
- === HTML and other content
75
- lets see what the following does
76
- get '/myroute'
77
- assert_response { html 'my body' }
78
- or shorter:
79
- get '/myroute'
80
- assert_response_html 'my body' # with the cousins assert_response_css, assert_response_js and assert_response_json
81
-
82
- * It checks if +"/myroute"+ has the +Content-Type+ +"text/html"+ and the +body+ matches /my\ body/.
83
- * It also checks if +status+ of the response is +200+.
84
- * If the +status+ of the response is +500+ the original error of the rack app is raised (with original message and backtrace!)
85
- * If +status+ is +404+ an error of class {AssertResponse::Status404} is raised.
86
-
87
- === Redirects
88
- To check if "/myredirect" returns +status+ 302 and the header +Location+ matches /\/mytarget/, try
89
- get '/myredirect'
90
- assert_response do
91
- status 302
92
- header 'Location', '/mytarget'
93
- end
94
- or shorter:
95
- get '/myredirect'
96
- assert_response_redirect '/mytarget'
97
-
98
-
99
- === Server Errors
100
- Server errors should not happen, but if they do we want them to show up as errors in our test cases.
101
-
102
- The following checks if the route +"/error"+ raises an error of class +RuntimeError+ with a message that matches +/my\ error\ message/+
103
- get '/error'
104
- assert_response { raises RuntimeError, "my error message" }
105
- or shorter
106
- get '/error'
107
- assert_response_raises RuntimeError, "my error message"
108
-
109
- If we are not interested in the error class or message we omit them.
110
- get '/error'
111
- assert_response_raises
112
-
113
- === 404 - not found
114
- If we expect a status 404, we could do
115
- get '/not-existant'
116
- assert_response_status 404
117
- or
118
- get '/not-existant'
119
- assert_response { not_found }
120
- or
121
- get '/not-existant'
122
- assert_response_not_found
123
-
124
- Most of the time we don't want a 404 response in our tests, so it's an error.
125
- If we test for a body of a known content-type (eg. with assert_html, assert_js and friends) it is assumed that we don't want a 404 response, so an error will be thrown if we get some.
126
- So to be able to check the body too to test a customer 404 page, we could do:
127
- get '/not-existant'
128
- assert_response do
129
- not_found
130
- header('Content-Type', 'text/html') # {AssertResponse#is_html} could not be used since it implies a status 200
131
- body "Page could not be found" # {AssertResponse#html} could not be used since it implies a status 200
132
- end
133
- or
134
- get '/not-existant'
135
- assert_response_not_found_html "Page could not be found" # also 'assert_not_found_js' and friends
136
-
137
- === Custom Headers
138
- get '/special'
139
- assert_response_header 'my_header', 'my header value'
140
-
141
- === Custom Content-Types
142
- get '/special'
143
- assert_response_content_type 'my/contenttype'
144
-
145
- or
146
- AssertResponse.add_content_type :my_type, 'my/contenttype'
147
- # and then
148
- get '/special'
149
- assert_response_my_type 'here the body of my type'
150
-
151
-
152
-
153
- == Contributing to assert-response
154
-
155
- * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
156
- * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
157
- * Fork the project
158
- * Start a feature/bugfix branch
159
- * Commit and push until you are happy with your contribution
160
- * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
161
- * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
162
-
163
- == Copyright
164
-
165
- Copyright (c) 2011 Marc Rene Arns. See LICENSE.txt for
166
- further details.
167
-