fakettp 0.3.6 → 0.3.7
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/README.rdoc +7 -0
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/features/control.feature +2 -2
- data/features/dashboard.feature +26 -3
- data/features/expectations.feature +3 -3
- data/features/step_definitions/http.rb +28 -13
- data/features/step_definitions/webrat_steps.rb +7 -7
- data/features/support/paths.rb +4 -4
- data/lib/fakettp/commands/fakettp_command.rb +4 -4
- data/lib/fakettp/config.ru +3 -3
- data/lib/fakettp/error.rb +1 -1
- data/lib/fakettp/expectation.rb +13 -13
- data/lib/fakettp/expectation_helper.rb +1 -1
- data/lib/fakettp/public/fakettp.css +37 -5
- data/lib/fakettp/simulator.rb +6 -6
- data/lib/fakettp/views/index.erb +10 -3
- data/spec/fakettp/controller_spec.rb +48 -22
- data/spec/fakettp/error_spec.rb +7 -7
- data/spec/fakettp/expectation_helper_spec.rb +3 -3
- data/spec/fakettp/expectation_spec.rb +46 -44
- data/spec/fakettp/simulator_spec.rb +26 -26
- metadata +12 -2
data/README.rdoc
CHANGED
@@ -146,6 +146,8 @@ was received, to assist debugging.
|
|
146
146
|
Point your browser at http://fakettp.local/
|
147
147
|
|
148
148
|
Currently this is very basic, just showing the expectations from the last run.
|
149
|
+
Expectations are colour-coded according to status, and any error messages are
|
150
|
+
shown.
|
149
151
|
|
150
152
|
=== Multiple faked hosts
|
151
153
|
|
@@ -157,6 +159,11 @@ _ServerAlias_ entry to the virtual host config, under the _ServerName_ line, eg:
|
|
157
159
|
|
158
160
|
== Change log
|
159
161
|
|
162
|
+
0.3.7 (19 November 2009)
|
163
|
+
|
164
|
+
* Show error messages in console.
|
165
|
+
* Use nokogiri instead of hpricot for testing.
|
166
|
+
|
160
167
|
0.3.6 (3 November 2009)
|
161
168
|
|
162
169
|
* Properly include rspec as a *runtime* dependency.
|
data/Rakefile
CHANGED
@@ -23,6 +23,7 @@ begin
|
|
23
23
|
gem.add_development_dependency 'rcov'
|
24
24
|
gem.add_development_dependency 'rack-test'
|
25
25
|
gem.add_development_dependency 'cucumber'
|
26
|
+
gem.add_development_dependency 'nokogiri'
|
26
27
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
27
28
|
end
|
28
29
|
Jeweler::GemcutterTasks.new
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.7
|
data/features/control.feature
CHANGED
@@ -2,11 +2,11 @@ Feature: Controlling the simulator
|
|
2
2
|
Scenario: Attempting to reset the simulator using the wrong host
|
3
3
|
When we post to /reset on foo.fakettp.fake.local
|
4
4
|
Then the response body should contain 'Simulator received mismatched request'
|
5
|
-
|
5
|
+
|
6
6
|
Scenario: Attempting to create an expectation using the wrong host
|
7
7
|
When we post to /expect on foo.fakettp.fake.local
|
8
8
|
Then the response body should contain 'Simulator received mismatched request'
|
9
|
-
|
9
|
+
|
10
10
|
Scenario: Attempting to verify the simulator using the wrong host
|
11
11
|
When we get /verify on foo.fakettp.fake.local
|
12
12
|
Then the response body should contain 'Simulator received mismatched request'
|
data/features/dashboard.feature
CHANGED
@@ -9,26 +9,49 @@ Feature: Dashboard for debugging failures
|
|
9
9
|
And there are 3 expectations
|
10
10
|
When we get / on fakettp.local
|
11
11
|
Then there should be 3 /html/body/div elements in the response
|
12
|
-
|
12
|
+
|
13
13
|
Scenario: Show expectation heading and contents
|
14
14
|
Given the simulator is reset
|
15
15
|
And we expect get_root
|
16
16
|
When we get / on fakettp.local
|
17
17
|
Then //h1[1] in the response should be '1'
|
18
|
-
And //div[1]/pre in the response should be:
|
18
|
+
And //div[1]/div/pre in the response should be:
|
19
19
|
"""
|
20
20
|
expect "GET /" do
|
21
21
|
request.path_info.should == '/'
|
22
22
|
end
|
23
23
|
"""
|
24
24
|
|
25
|
+
Scenario: Show expectation status
|
26
|
+
Given the simulator is reset
|
27
|
+
And we expect get_root
|
28
|
+
And we expect get_root
|
29
|
+
And we expect get_root
|
30
|
+
And we get / on foo.fakettp.fake.local
|
31
|
+
And we get /foo on foo.fakettp.fake.local
|
32
|
+
When we get / on fakettp.local
|
33
|
+
Then //body/div[1]/@class in the response should be 'request pass'
|
34
|
+
Then //body/div[2]/@class in the response should be 'request fail'
|
35
|
+
Then //body/div[3]/@class in the response should be 'request pending'
|
36
|
+
|
37
|
+
Scenario: Show error message for failed expectation
|
38
|
+
Given the simulator is reset
|
39
|
+
And we expect get_root
|
40
|
+
And we get /foo on foo.fakettp.fake.local
|
41
|
+
When we get / on fakettp.local
|
42
|
+
Then //body/div/div[@class='error']/pre in the response should be:
|
43
|
+
"""
|
44
|
+
Error in GET /: expected: "/",
|
45
|
+
got: "/foo" (using ==)
|
46
|
+
"""
|
47
|
+
|
25
48
|
@wip
|
26
49
|
Scenario: Highlight passed and failed lines
|
27
50
|
Given the simulator is reset
|
28
51
|
And we expect pass_and_fail
|
29
52
|
And we get / on foo.fakettp.fake.local
|
30
53
|
When we get / on fakettp.local
|
31
|
-
Then //div[
|
54
|
+
Then //div/div[@class='expectation']/pre in the response should be:
|
32
55
|
"""
|
33
56
|
<span class="pass">expect "pass and fail" do
|
34
57
|
(2 + 2).should == 4</span>
|
@@ -4,21 +4,21 @@ Feature: Expectations
|
|
4
4
|
And we expect expect_get
|
5
5
|
And we get / on foo.fakettp.fake.local
|
6
6
|
Then verifying the simulator should report success
|
7
|
-
|
7
|
+
|
8
8
|
Scenario: Setting response headers
|
9
9
|
Given the simulator is reset
|
10
10
|
And we expect set_response
|
11
11
|
And we get / on foo.fakettp.fake.local
|
12
12
|
Then the response should have a 'foo' header with a value of 'bar'
|
13
13
|
And verifying the simulator should report success
|
14
|
-
|
14
|
+
|
15
15
|
Scenario: Setting response content-type
|
16
16
|
Given the simulator is reset
|
17
17
|
And we expect set_response
|
18
18
|
And we get / on foo.fakettp.fake.local
|
19
19
|
Then the response should have a content type of 'application/xml'
|
20
20
|
And verifying the simulator should report success
|
21
|
-
|
21
|
+
|
22
22
|
Scenario: Setting response code
|
23
23
|
Given the simulator is reset
|
24
24
|
And we expect set_response
|
@@ -1,28 +1,47 @@
|
|
1
|
-
require '
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
module HttpHelper
|
4
|
+
def check_value locator, value
|
5
|
+
node = Nokogiri::XML(@response.body).xpath(locator).first
|
6
|
+
contents = case node
|
7
|
+
when Nokogiri::XML::Element then node.inner_html
|
8
|
+
when Nokogiri::XML::Attr then node.to_s
|
9
|
+
when nil then ''
|
10
|
+
else raise 'Unexpected node type'
|
11
|
+
end
|
12
|
+
contents.should == value
|
13
|
+
end
|
14
|
+
end
|
15
|
+
World HttpHelper
|
2
16
|
|
3
17
|
When /^we get (\S*) on (\S*)$/ do |path, host|
|
4
18
|
req = Net::HTTP::Get.new path
|
5
|
-
|
19
|
+
@response = Net::HTTP.new(host).start {|http| http.request(req) }
|
6
20
|
end
|
21
|
+
|
7
22
|
When /^we post to (\S*) on (\S*)$/ do |path, host|
|
8
23
|
req = Net::HTTP::Post.new path
|
9
|
-
|
24
|
+
@response = Net::HTTP.new(host).start {|http| http.request(req) }
|
25
|
+
end
|
26
|
+
|
27
|
+
When /^we print the response$/ do
|
28
|
+
puts @response
|
10
29
|
end
|
11
30
|
|
12
31
|
Then /^the response should have a '(.*)' header with a value of '(.*)'$/ do |name, value|
|
13
|
-
|
32
|
+
@response[name].should == value
|
14
33
|
end
|
15
34
|
|
16
35
|
Then /^the response should have a content type of '(.*)'$/ do |value|
|
17
|
-
|
36
|
+
@response.content_type.should == value
|
18
37
|
end
|
19
38
|
|
20
39
|
Then /^the response body should be '(.*)'$/ do |value|
|
21
|
-
|
40
|
+
@response.body.should == value
|
22
41
|
end
|
23
42
|
|
24
43
|
Then /^the response body should contain '(.*)'$/ do |value|
|
25
|
-
|
44
|
+
@response.body.should include(value)
|
26
45
|
end
|
27
46
|
|
28
47
|
Then /^(\S*) in the response should be '(.*)'$/ do |locator, value|
|
@@ -33,10 +52,6 @@ Then /^(\S*) in the response should be:$/ do |locator, value|
|
|
33
52
|
check_value locator, value
|
34
53
|
end
|
35
54
|
|
36
|
-
def check_value locator, value
|
37
|
-
(Hpricot(@@response.body)/locator).inner_html.should == value
|
38
|
-
end
|
39
|
-
|
40
55
|
Then /^there should be (\d*) (.*) elements in the response$/ do |count, locator|
|
41
|
-
|
42
|
-
end
|
56
|
+
Nokogiri::XML(@response.body).xpath(locator).size.should == count.to_i
|
57
|
+
end
|
@@ -16,20 +16,20 @@ When /^I follow "(.*)"$/ do |link|
|
|
16
16
|
end
|
17
17
|
|
18
18
|
When /^I fill in "(.*)" with "(.*)"$/ do |field, value|
|
19
|
-
fill_in(field, :with => value)
|
19
|
+
fill_in(field, :with => value)
|
20
20
|
end
|
21
21
|
|
22
22
|
When /^I select "(.*)" from "(.*)"$/ do |value, field|
|
23
|
-
select(value, :from => field)
|
23
|
+
select(value, :from => field)
|
24
24
|
end
|
25
25
|
|
26
26
|
# Use this step in conjunction with Rail's datetime_select helper. For example:
|
27
|
-
# When I select "December 25, 2008 10:00" as the date and time
|
27
|
+
# When I select "December 25, 2008 10:00" as the date and time
|
28
28
|
When /^I select "(.*)" as the date and time$/ do |time|
|
29
29
|
select_datetime(time)
|
30
30
|
end
|
31
31
|
|
32
|
-
# Use this step when using multiple datetime_select helpers on a page or
|
32
|
+
# Use this step when using multiple datetime_select helpers on a page or
|
33
33
|
# you want to specify which datetime to select. Given the following view:
|
34
34
|
# <%= f.label :preferred %><br />
|
35
35
|
# <%= f.datetime_select :preferred %>
|
@@ -45,7 +45,7 @@ end
|
|
45
45
|
# Use this step in conjuction with Rail's time_select helper. For example:
|
46
46
|
# When I select "2:20PM" as the time
|
47
47
|
# Note: Rail's default time helper provides 24-hour time-- not 12 hour time. Webrat
|
48
|
-
# will convert the 2:20PM to 14:20 and then select it.
|
48
|
+
# will convert the 2:20PM to 14:20 and then select it.
|
49
49
|
When /^I select "(.*)" as the time$/ do |time|
|
50
50
|
select_time(time)
|
51
51
|
end
|
@@ -71,11 +71,11 @@ When /^I select "(.*)" as the "(.*)" date$/ do |date, date_label|
|
|
71
71
|
end
|
72
72
|
|
73
73
|
When /^I check "(.*)"$/ do |field|
|
74
|
-
check(field)
|
74
|
+
check(field)
|
75
75
|
end
|
76
76
|
|
77
77
|
When /^I uncheck "(.*)"$/ do |field|
|
78
|
-
uncheck(field)
|
78
|
+
uncheck(field)
|
79
79
|
end
|
80
80
|
|
81
81
|
When /^I choose "(.*)"$/ do |field|
|
data/features/support/paths.rb
CHANGED
@@ -4,7 +4,7 @@ module Fakettp
|
|
4
4
|
def initialize args
|
5
5
|
@args = args
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
def run
|
9
9
|
command = @args[0]
|
10
10
|
return usage unless command
|
@@ -15,9 +15,9 @@ module Fakettp
|
|
15
15
|
return usage
|
16
16
|
end
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
private
|
20
|
-
|
20
|
+
|
21
21
|
def install
|
22
22
|
@directory, @hostname = @args[1..2]
|
23
23
|
return usage unless @directory && @hostname
|
@@ -30,7 +30,7 @@ module Fakettp
|
|
30
30
|
create_database
|
31
31
|
return 0
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
def copy_files
|
35
35
|
FileUtils.mkdir_p @directory + '/tmp', :mode => 0777
|
36
36
|
FileUtils.mkdir_p @directory + '/public'
|
data/lib/fakettp/config.ru
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'sinatra'
|
3
|
-
|
3
|
+
|
4
4
|
Sinatra::Default.set :run, false
|
5
5
|
Sinatra::Default.set :environment, :production
|
6
6
|
Sinatra::Default.set :raise_errors, true
|
7
|
-
|
7
|
+
|
8
8
|
log = File.new("fakettp.log", "a")
|
9
9
|
STDOUT.reopen(log)
|
10
10
|
STDERR.reopen(log)
|
11
|
-
|
11
|
+
|
12
12
|
FAKETTP_BASE = File.expand_path(File.dirname(__FILE__))
|
13
13
|
require 'fakettp'
|
14
14
|
|
data/lib/fakettp/error.rb
CHANGED
data/lib/fakettp/expectation.rb
CHANGED
@@ -3,8 +3,9 @@ require 'fakettp/db'
|
|
3
3
|
module Fakettp
|
4
4
|
class Expectation < ActiveRecord::Base
|
5
5
|
set_table_name :expectations
|
6
|
+
# TODO Why has_many? There can be only one!
|
6
7
|
has_many :errors
|
7
|
-
|
8
|
+
|
8
9
|
class Error < StandardError
|
9
10
|
attr_reader :line_number
|
10
11
|
def initialize message, line_number = nil
|
@@ -12,27 +13,26 @@ module Fakettp
|
|
12
13
|
super(message)
|
13
14
|
end
|
14
15
|
end
|
15
|
-
|
16
|
-
def render
|
17
|
-
if executed
|
18
|
-
span_class = errors.empty? ? 'pass' : 'fail'
|
19
|
-
%(<span class="#{span_class}">#{contents}</span>)
|
20
|
-
else
|
21
|
-
contents
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
16
|
+
|
25
17
|
def execute binding
|
26
18
|
self.executed = true
|
27
19
|
save
|
28
20
|
eval contents, binding
|
29
21
|
# TODO: Include context of expectation file
|
30
22
|
end
|
31
|
-
|
23
|
+
|
24
|
+
def status
|
25
|
+
if executed
|
26
|
+
errors.empty? ? 'pass' : 'fail'
|
27
|
+
else
|
28
|
+
'pending'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
32
|
def self.all_received?
|
33
33
|
!exists? :executed => false
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
def self.next
|
37
37
|
find_by_executed(false)
|
38
38
|
end
|
@@ -3,12 +3,37 @@ body {
|
|
3
3
|
"Lucida Sans", "DejaVu Sans", "Bitstream Vera Sans",
|
4
4
|
"Liberation Sans", Verdana, sans-serif;
|
5
5
|
}
|
6
|
+
div.request {
|
7
|
+
margin-bottom: 10px;
|
8
|
+
}
|
6
9
|
div.expectation {
|
7
10
|
width: 95%;
|
8
11
|
border: 1px solid #888;
|
12
|
+
border-top: none;
|
9
13
|
background-color: #eee;
|
10
|
-
margin: 0 auto
|
14
|
+
margin: 0 auto 0 auto;
|
15
|
+
padding: 5px;
|
16
|
+
}
|
17
|
+
div.error {
|
18
|
+
width: 95%;
|
19
|
+
border: 1px solid #f00;
|
20
|
+
border-top: none;
|
21
|
+
background-color: #fdd;
|
22
|
+
margin: 0 auto 0 auto;
|
11
23
|
padding: 5px;
|
24
|
+
color: #f00;
|
25
|
+
}
|
26
|
+
.pass h1 {
|
27
|
+
background-color: #0a0;
|
28
|
+
}
|
29
|
+
.fail h1 {
|
30
|
+
background-color: #f00;
|
31
|
+
}
|
32
|
+
.pass h1, .pass div {
|
33
|
+
border-color: #0a0;
|
34
|
+
}
|
35
|
+
.fail h1, .fail div {
|
36
|
+
border-color: #f00;
|
12
37
|
}
|
13
38
|
h1 {
|
14
39
|
width: 95%;
|
@@ -19,15 +44,22 @@ h1 {
|
|
19
44
|
font-size: 110%;
|
20
45
|
color: #fff;
|
21
46
|
}
|
22
|
-
.expectation pre {
|
47
|
+
.expectation pre, .error pre {
|
23
48
|
padding: 0;
|
24
49
|
margin: 0;
|
25
50
|
font: 75% Monaco, "Bitstream Vera Sans Mono", "Lucida Console",
|
26
|
-
Terminal, monospace;
|
51
|
+
Terminal, monospace;
|
52
|
+
}
|
53
|
+
div.pass {
|
54
|
+
border-color: #0a0;
|
55
|
+
}
|
56
|
+
div.fail {
|
57
|
+
border-color: #f00;
|
27
58
|
}
|
28
|
-
.pass {
|
59
|
+
span.pass {
|
29
60
|
color: #0a0;
|
30
61
|
}
|
31
|
-
.fail {
|
62
|
+
span.fail {
|
32
63
|
color: #f00;
|
33
64
|
}
|
65
|
+
|
data/lib/fakettp/simulator.rb
CHANGED
@@ -2,21 +2,21 @@ require 'fakettp/expectation'
|
|
2
2
|
require 'fakettp/error'
|
3
3
|
|
4
4
|
module Fakettp
|
5
|
-
class Simulator
|
5
|
+
class Simulator
|
6
6
|
def self.reset
|
7
7
|
Expectation.delete_all
|
8
8
|
Error.delete_all
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
def self.verify
|
12
12
|
Error.create!(:message => 'Expected request not received') unless Expectation.all_received?
|
13
13
|
return !Error.exists?
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
def self.<< expectation
|
17
17
|
Expectation.create! :contents => expectation
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
def self.handle_request binding
|
21
21
|
expectation = Expectation.next
|
22
22
|
if expectation
|
@@ -31,9 +31,9 @@ module Fakettp
|
|
31
31
|
raise Expectation::Error.new('Received unexpected request')
|
32
32
|
end
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
def self.list_errors
|
36
36
|
Error.list
|
37
37
|
end
|
38
38
|
end
|
39
|
-
end
|
39
|
+
end
|
data/lib/fakettp/views/index.erb
CHANGED
@@ -5,9 +5,16 @@
|
|
5
5
|
</head>
|
6
6
|
<body>
|
7
7
|
<% @expectations.each_with_index do |expectation, index| %>
|
8
|
-
<
|
9
|
-
|
10
|
-
<
|
8
|
+
<div class="request <%= expectation.status %>">
|
9
|
+
<h1><%= index + 1 %></h1>
|
10
|
+
<div class="expectation">
|
11
|
+
<pre><%= expectation.contents %></pre>
|
12
|
+
</div>
|
13
|
+
<% unless expectation.errors.empty? %>
|
14
|
+
<div class="error">
|
15
|
+
<pre><%= expectation.errors.first.message %></pre>
|
16
|
+
</div>
|
17
|
+
<% end %>
|
11
18
|
</div>
|
12
19
|
<% end %>
|
13
20
|
</body>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
-
require '
|
2
|
+
require 'nokogiri'
|
3
3
|
|
4
4
|
describe 'Controller' do
|
5
5
|
include Rack::Test::Methods
|
@@ -7,7 +7,7 @@ describe 'Controller' do
|
|
7
7
|
def app
|
8
8
|
Sinatra::Application
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
before :all do
|
12
12
|
@host = YAML.load(File.read(FAKETTP_BASE + '/fakettp.yml'))['hostname']
|
13
13
|
end
|
@@ -15,11 +15,11 @@ describe 'Controller' do
|
|
15
15
|
before do
|
16
16
|
Fakettp::Simulator.reset
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
it 'mixes in Fakettp::ExpectationHelper' do
|
20
20
|
Sinatra::Application.included_modules.should include(Fakettp::ExpectationHelper)
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
describe 'posting to /reset' do
|
24
24
|
before do
|
25
25
|
Fakettp::Simulator.stub! :reset
|
@@ -50,7 +50,7 @@ describe 'Controller' do
|
|
50
50
|
last_response.body.should == "Reset OK\n"
|
51
51
|
end
|
52
52
|
end
|
53
|
-
|
53
|
+
|
54
54
|
describe 'on another host' do
|
55
55
|
it 'acts like any other simulated request' do
|
56
56
|
post '/reset', nil, 'HTTP_HOST' => 'foo.fake.local'
|
@@ -90,7 +90,7 @@ describe 'Controller' do
|
|
90
90
|
last_response.body.should == "Expect OK\n"
|
91
91
|
end
|
92
92
|
end
|
93
|
-
|
93
|
+
|
94
94
|
describe 'on another host' do
|
95
95
|
it 'acts like any other simulated request' do
|
96
96
|
post '/expect', @body, 'HTTP_HOST' => 'foo.fake.local'
|
@@ -195,7 +195,7 @@ describe 'Controller' do
|
|
195
195
|
end
|
196
196
|
end
|
197
197
|
end
|
198
|
-
|
198
|
+
|
199
199
|
describe 'on another host' do
|
200
200
|
it 'acts like any other simulated request' do
|
201
201
|
get '/verify', nil, 'HTTP_HOST' => 'foo.fake.local'
|
@@ -207,44 +207,70 @@ describe 'Controller' do
|
|
207
207
|
describe 'getting /' do
|
208
208
|
describe 'on the fakettp host' do
|
209
209
|
before do
|
210
|
-
|
211
|
-
|
212
|
-
|
210
|
+
error = Fakettp::Error.new :message => 'Oh noes!'
|
211
|
+
expectation_1 = stub :expectation, :id => 1, :status => 'pass', :contents => 'foo', :errors => []
|
212
|
+
expectation_2 = stub :expectation, :id => 2, :status => 'fail', :contents => 'bar', :errors => [error]
|
213
|
+
expectation_3 = stub :expectation, :id => 3, :status => 'pending', :contents => 'baz', :errors => []
|
214
|
+
Fakettp::Expectation.stub!(:all).and_return [expectation_1, expectation_2, expectation_3]
|
213
215
|
end
|
214
|
-
|
216
|
+
|
215
217
|
def do_get
|
216
218
|
get '/', nil, 'HTTP_HOST' => @host
|
217
|
-
@response_doc =
|
219
|
+
@response_doc = Nokogiri::XML(last_response.body)
|
218
220
|
end
|
219
221
|
|
220
222
|
it 'returns an html response' do
|
221
223
|
do_get
|
222
224
|
last_response.content_type.should == 'text/html'
|
223
225
|
end
|
224
|
-
|
226
|
+
|
225
227
|
it 'sets the title' do
|
226
228
|
do_get
|
227
229
|
(@response_doc/'head/title').inner_html.should == 'FakeTTP'
|
228
230
|
end
|
229
|
-
|
231
|
+
|
230
232
|
it 'renders a div for each expectation' do
|
231
233
|
do_get
|
232
|
-
@response_doc.search("//div[@class='expectation']").size.should ==
|
234
|
+
@response_doc.search("//div[@class='expectation']").size.should == 3
|
233
235
|
end
|
234
|
-
|
236
|
+
|
235
237
|
it 'numbers the expectations' do
|
236
238
|
do_get
|
237
|
-
(@response_doc/"//h1
|
238
|
-
(@response_doc/"//h1[2]").inner_html.should == '2'
|
239
|
+
(@response_doc/"//div/h1").map(&:inner_html).should == %w(1 2 3)
|
239
240
|
end
|
240
|
-
|
241
|
+
|
241
242
|
it 'displays the expectation contents' do
|
242
243
|
do_get
|
243
|
-
(@response_doc/"//div[@class='expectation']
|
244
|
-
|
244
|
+
(@response_doc/"//div[@class='expectation']/pre").map(&:inner_html).should == %w(foo bar baz)
|
245
|
+
end
|
246
|
+
|
247
|
+
describe 'for passed expectations' do
|
248
|
+
it "sets the request div class to 'request pass'" do
|
249
|
+
do_get
|
250
|
+
(@response_doc/"//body/div[1]/@class").to_s.should == 'request pass'
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
describe 'for failed expectations' do
|
255
|
+
it "sets the request div class to 'request fail'" do
|
256
|
+
do_get
|
257
|
+
(@response_doc/"//body/div[2]/@class").to_s.should == 'request fail'
|
258
|
+
end
|
259
|
+
|
260
|
+
it 'renders the error message' do
|
261
|
+
do_get
|
262
|
+
(@response_doc/"//body/div[2]/div[@class='error']/pre").inner_html.should == 'Oh noes!'
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
describe 'for pending expectations' do
|
267
|
+
it "sets the request div class to 'request pending'" do
|
268
|
+
do_get
|
269
|
+
(@response_doc/"//body/div[3]/@class").to_s.should == 'request pending'
|
270
|
+
end
|
245
271
|
end
|
246
272
|
end
|
247
|
-
|
273
|
+
|
248
274
|
describe 'on another host' do
|
249
275
|
it 'acts like any other simulated request' do
|
250
276
|
get '/', nil, 'HTTP_HOST' => 'foo.fake.local'
|
data/spec/fakettp/error_spec.rb
CHANGED
@@ -4,34 +4,34 @@ describe Fakettp::Error do
|
|
4
4
|
before do
|
5
5
|
Fakettp::Error.delete_all
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
it 'is an ActiveRecord' do
|
9
9
|
Fakettp::Error.new.should be_a_kind_of(ActiveRecord::Base)
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
it { should have_db_column(:message).of_type(:text) }
|
13
13
|
|
14
14
|
it { should have_db_column(:line_number).of_type(:integer) }
|
15
|
-
|
15
|
+
|
16
16
|
it { should belong_to(:expectation) }
|
17
|
-
|
17
|
+
|
18
18
|
describe 'listing errors' do
|
19
19
|
describe 'when errors exist' do
|
20
20
|
before do
|
21
21
|
Fakettp::Error.create! :message => 'foo'
|
22
22
|
Fakettp::Error.create! :message => 'bar'
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
it 'returns the concatenated error messages' do
|
26
26
|
Fakettp::Error.list.should == "foo\nbar\n"
|
27
27
|
end
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
describe 'when no errors exist' do
|
31
31
|
before do
|
32
32
|
Fakettp::Error.delete_all
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
it 'returns an empty string' do
|
36
36
|
Fakettp::Error.list.should == ''
|
37
37
|
end
|
@@ -5,10 +5,10 @@ describe Fakettp::ExpectationHelper do
|
|
5
5
|
class Foo
|
6
6
|
include Fakettp::ExpectationHelper
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
Foo.included_modules.should include(Spec::Matchers)
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
describe 'calling expect' do
|
13
13
|
describe 'when a matcher exception occurs' do
|
14
14
|
it 'raises an exception' do
|
@@ -20,7 +20,7 @@ describe Fakettp::ExpectationHelper do
|
|
20
20
|
/Error in foo: expected: 2,\s*got: 1/)
|
21
21
|
end
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
describe 'when the block returns a value' do
|
25
25
|
it 'returns the value' do
|
26
26
|
result = Fakettp::ExpectationHelper.expect 'foo' do
|
@@ -4,27 +4,27 @@ describe Fakettp::Expectation do
|
|
4
4
|
before do
|
5
5
|
Fakettp::Expectation.delete_all
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
it 'is an ActiveRecord' do
|
9
9
|
Fakettp::Expectation.new.should be_a_kind_of(ActiveRecord::Base)
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
it { should have_db_column(:contents).of_type(:text) }
|
13
13
|
|
14
14
|
it { should have_db_column(:executed).of_type(:boolean) }
|
15
|
-
|
15
|
+
|
16
16
|
it { should have_many(:errors) }
|
17
|
-
|
17
|
+
|
18
18
|
it 'starts out unexecuted' do
|
19
19
|
Fakettp::Expectation.create.executed.should be_false
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
describe 'checking whether all expected requests have been received' do
|
23
23
|
describe 'when there are no expectations' do
|
24
24
|
before do
|
25
25
|
Fakettp::Expectation.delete_all
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
it 'returns true' do
|
29
29
|
Fakettp::Expectation.should be_all_received
|
30
30
|
end
|
@@ -35,7 +35,7 @@ describe Fakettp::Expectation do
|
|
35
35
|
Fakettp::Expectation.create! :executed => true
|
36
36
|
Fakettp::Expectation.create! :executed => false
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
it 'returns false' do
|
40
40
|
Fakettp::Expectation.should_not be_all_received
|
41
41
|
end
|
@@ -46,13 +46,13 @@ describe Fakettp::Expectation do
|
|
46
46
|
Fakettp::Expectation.create! :executed => true
|
47
47
|
Fakettp::Expectation.create! :executed => true
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
it 'returns true' do
|
51
51
|
Fakettp::Expectation.should be_all_received
|
52
52
|
end
|
53
53
|
end
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
56
|
describe 'getting the next expectation' do
|
57
57
|
describe 'when there are expectations' do
|
58
58
|
before do
|
@@ -60,7 +60,7 @@ describe Fakettp::Expectation do
|
|
60
60
|
@expectation_2 = Fakettp::Expectation.create :executed => false
|
61
61
|
@expectation_3 = Fakettp::Expectation.create :executed => false
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
it 'returns the first unexecuted expectation' do
|
65
65
|
Fakettp::Expectation.next.should == @expectation_2
|
66
66
|
end
|
@@ -70,60 +70,62 @@ describe Fakettp::Expectation do
|
|
70
70
|
before do
|
71
71
|
Fakettp::Expectation.delete_all
|
72
72
|
end
|
73
|
-
|
73
|
+
|
74
74
|
it 'returns nil' do
|
75
75
|
Fakettp::Expectation.next.should be_nil
|
76
76
|
end
|
77
77
|
end
|
78
78
|
end
|
79
|
-
|
80
|
-
describe 'rendering itself' do
|
81
|
-
before do
|
82
|
-
@expectation = Fakettp::Expectation.new(:contents => 'foo')
|
83
|
-
end
|
84
79
|
|
85
|
-
|
86
|
-
|
87
|
-
|
80
|
+
describe 'executing' do
|
81
|
+
it 'evals the expectation code in the context of the supplied binding' do
|
82
|
+
def getBinding(n)
|
83
|
+
return binding
|
88
84
|
end
|
85
|
+
Fakettp::Expectation.new(:contents => 'n + 2').execute(getBinding(2)).should == 4
|
89
86
|
end
|
90
87
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
88
|
+
it 'marks itself as executed' do
|
89
|
+
expectation = Fakettp::Expectation.create! :contents => ''
|
90
|
+
expectation.execute binding
|
91
|
+
expectation.reload
|
92
|
+
expectation.executed.should be_true
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe 'status' do
|
97
|
+
before do
|
98
|
+
@expectation = Fakettp::Expectation.new
|
99
|
+
end
|
95
100
|
|
96
|
-
|
97
|
-
|
101
|
+
describe 'when not executed' do
|
102
|
+
it "is 'pending'" do
|
103
|
+
@expectation.status.should == 'pending'
|
98
104
|
end
|
99
105
|
end
|
100
106
|
|
101
|
-
describe 'when executed
|
107
|
+
describe 'when executed' do
|
102
108
|
before do
|
103
109
|
@expectation.executed = true
|
104
|
-
@expectation.errors = [Fakettp::Error.new]
|
105
110
|
end
|
106
111
|
|
107
|
-
|
108
|
-
|
112
|
+
describe 'without errors' do
|
113
|
+
it "is 'pass'" do
|
114
|
+
@expectation.status.should == 'pass'
|
115
|
+
end
|
109
116
|
end
|
110
|
-
end
|
111
|
-
end
|
112
117
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
118
|
+
describe 'with errors' do
|
119
|
+
before do
|
120
|
+
@expectation.errors << Fakettp::Error.new
|
121
|
+
end
|
122
|
+
|
123
|
+
it "is 'fail'" do
|
124
|
+
@expectation.status.should == 'fail'
|
125
|
+
end
|
117
126
|
end
|
118
|
-
Fakettp::Expectation.new(:contents => 'n + 2').execute(getBinding(2)).should == 4
|
119
127
|
end
|
120
128
|
|
121
|
-
it 'marks itself as executed' do
|
122
|
-
expectation = Fakettp::Expectation.create! :contents => ''
|
123
|
-
expectation.execute binding
|
124
|
-
expectation.reload
|
125
|
-
expectation.executed.should be_true
|
126
|
-
end
|
127
129
|
end
|
128
130
|
end
|
129
131
|
|
@@ -131,11 +133,11 @@ describe Fakettp::Expectation::Error do
|
|
131
133
|
it 'stores a message' do
|
132
134
|
Fakettp::Expectation::Error.new('foo', 2).message.should == 'foo'
|
133
135
|
end
|
134
|
-
|
136
|
+
|
135
137
|
it 'stores a line number' do
|
136
138
|
Fakettp::Expectation::Error.new('foo', 2).line_number.should == 2
|
137
139
|
end
|
138
|
-
|
140
|
+
|
139
141
|
it 'defaults the line number to nil' do
|
140
142
|
Fakettp::Expectation::Error.new('foo').line_number.should be_nil
|
141
143
|
end
|
@@ -5,38 +5,38 @@ describe Fakettp::Simulator do
|
|
5
5
|
Fakettp::Expectation.stub! :delete_all
|
6
6
|
Fakettp::Error.stub! :delete_all
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
describe "resetting" do
|
10
10
|
def do_reset
|
11
11
|
Fakettp::Simulator.reset
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
it 'clears expectations' do
|
15
15
|
Fakettp::Expectation.should_receive :delete_all
|
16
16
|
do_reset
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
it 'clears errors' do
|
20
20
|
Fakettp::Error.should_receive :delete_all
|
21
21
|
do_reset
|
22
22
|
end
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
describe 'adding an expectation' do
|
26
26
|
before do
|
27
27
|
@expectation = stub(:expectation)
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
def do_add
|
31
31
|
Fakettp::Simulator << @expectation
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
it 'creates a new expectation' do
|
35
35
|
Fakettp::Expectation.should_receive(:create!).with :contents => @expectation
|
36
36
|
do_add
|
37
37
|
end
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
describe 'handling a request' do
|
41
41
|
before do
|
42
42
|
@binding = stub :binding
|
@@ -44,89 +44,89 @@ describe Fakettp::Simulator do
|
|
44
44
|
@expectation = mock Fakettp::Expectation, :execute => @result
|
45
45
|
Fakettp::Expectation.stub!(:next).and_return @expectation
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
def do_handle
|
49
49
|
Fakettp::Simulator.handle_request @binding
|
50
50
|
end
|
51
|
-
|
51
|
+
|
52
52
|
it 'executes the next request' do
|
53
53
|
@expectation.should_receive(:execute).with @binding
|
54
54
|
do_handle
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
it 'returns the execution result' do
|
58
58
|
do_handle.should == @result
|
59
59
|
end
|
60
|
-
|
60
|
+
|
61
61
|
describe 'when there are no expectations left' do
|
62
62
|
before do
|
63
63
|
Fakettp::Expectation.stub!(:next).and_return nil
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
66
|
it 'adds an error' do
|
67
67
|
Fakettp::Error.should_receive(:create!).with(:message => 'Received unexpected request')
|
68
68
|
begin
|
69
69
|
do_handle
|
70
70
|
rescue Fakettp::Expectation::Error;end
|
71
71
|
end
|
72
|
-
|
72
|
+
|
73
73
|
it 'raises an exception' do
|
74
74
|
lambda {do_handle}.should raise_error(Fakettp::Expectation::Error, 'Received unexpected request')
|
75
75
|
end
|
76
76
|
end
|
77
|
-
|
77
|
+
|
78
78
|
describe 'when an error occurs while executing the expectation' do
|
79
79
|
before do
|
80
80
|
@expectation.stub!(:execute).and_raise Fakettp::Expectation::Error.new('foo', 2)
|
81
81
|
@errors = stub :errors, :null_object => true
|
82
82
|
@expectation.stub!(:errors).and_return @errors
|
83
83
|
end
|
84
|
-
|
84
|
+
|
85
85
|
it 'adds an error to the expectation' do
|
86
86
|
@errors.should_receive(:create).with(:message => 'foo', :line_number => 2)
|
87
87
|
begin
|
88
88
|
do_handle
|
89
89
|
rescue Fakettp::Expectation::Error;end
|
90
90
|
end
|
91
|
-
|
91
|
+
|
92
92
|
it 're-raises the exception' do
|
93
93
|
lambda {do_handle}.should raise_error(Fakettp::Expectation::Error, 'foo')
|
94
94
|
end
|
95
95
|
end
|
96
96
|
end
|
97
|
-
|
97
|
+
|
98
98
|
describe "verifying" do
|
99
99
|
def do_verify
|
100
100
|
Fakettp::Simulator.verify
|
101
101
|
end
|
102
|
-
|
102
|
+
|
103
103
|
describe 'when there are pending expectations' do
|
104
104
|
before do
|
105
105
|
Fakettp::Expectation.stub!(:all_received?).and_return true
|
106
106
|
end
|
107
|
-
|
107
|
+
|
108
108
|
describe 'when there are no errors' do
|
109
109
|
before do
|
110
110
|
Fakettp::Error.stub!(:exists?).with(no_args).and_return false
|
111
111
|
end
|
112
|
-
|
112
|
+
|
113
113
|
it { do_verify.should be_true }
|
114
114
|
end
|
115
|
-
|
115
|
+
|
116
116
|
describe 'when there are errors' do
|
117
117
|
before do
|
118
118
|
Fakettp::Error.stub!(:exists?).with(no_args).and_return true
|
119
119
|
end
|
120
|
-
|
120
|
+
|
121
121
|
it { do_verify.should be_false }
|
122
122
|
end
|
123
123
|
end
|
124
|
-
|
124
|
+
|
125
125
|
describe 'when there are pending expectations' do
|
126
126
|
before do
|
127
127
|
Fakettp::Expectation.stub!(:all_received?).and_return false
|
128
128
|
end
|
129
|
-
|
129
|
+
|
130
130
|
it 'adds an error' do
|
131
131
|
Fakettp::Error.should_receive(:create!).with(:message => 'Expected request not received')
|
132
132
|
do_verify
|
@@ -135,13 +135,13 @@ describe Fakettp::Simulator do
|
|
135
135
|
it { do_verify.should be_false }
|
136
136
|
end
|
137
137
|
end
|
138
|
-
|
138
|
+
|
139
139
|
describe 'listing errors' do
|
140
140
|
before do
|
141
141
|
@errors = stub :errors
|
142
142
|
Fakettp::Error.stub!(:list).and_return @errors
|
143
143
|
end
|
144
|
-
|
144
|
+
|
145
145
|
it 'returns the error list' do
|
146
146
|
Fakettp::Simulator.list_errors.should == @errors
|
147
147
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fakettp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kerry Buckley
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-11-
|
12
|
+
date: 2009-11-20 00:00:00 +00:00
|
13
13
|
default_executable: fakettp
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -92,6 +92,16 @@ dependencies:
|
|
92
92
|
- !ruby/object:Gem::Version
|
93
93
|
version: "0"
|
94
94
|
version:
|
95
|
+
- !ruby/object:Gem::Dependency
|
96
|
+
name: nokogiri
|
97
|
+
type: :development
|
98
|
+
version_requirement:
|
99
|
+
version_requirements: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: "0"
|
104
|
+
version:
|
95
105
|
description: HTTP server mocking tool
|
96
106
|
email: kerryjbuckley@gmail.com
|
97
107
|
executables:
|