replicant 0.0.3
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/History.txt +8 -0
- data/Manifest.txt +12 -0
- data/README +42 -0
- data/lib/replicant.rb +14 -0
- data/lib/replicant/matchers.rb +15 -0
- data/lib/replicant/response.rb +39 -0
- data/lib/replicant/server.rb +20 -0
- data/lib/replicant/site.rb +78 -0
- data/lib/replicant/version.rb +9 -0
- data/spec/replicant_spec.rb +42 -0
- metadata +92 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
data/README
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
Replicant is a Rack-based http-endpoint Gem I use in tests along with
|
2
|
+
automation frameworks such as Watir, Selenium, or any framework which
|
3
|
+
does not rely on Net:HTTP, and therefore cannot be mock'd using normal
|
4
|
+
methods. It acts as a real http endpoint that can assert specific
|
5
|
+
requests occurred with the expected post data. It's not close to being
|
6
|
+
"done", but go ahead and take a look anyway.
|
7
|
+
|
8
|
+
|
9
|
+
Sample Usage:
|
10
|
+
|
11
|
+
require 'replicant'
|
12
|
+
|
13
|
+
before do
|
14
|
+
@mock_website = Replicant.new
|
15
|
+
@mock_website.response( :login_page, "/login",
|
16
|
+
%q{ <form name='login' action='/session' method='post'>
|
17
|
+
<input type='text' name='username'/>
|
18
|
+
<input type='password' name='password'/>
|
19
|
+
<input type='submit' value='Login' /></form> } )
|
20
|
+
|
21
|
+
@mock_website.response( :session_page, "/session", "" )
|
22
|
+
|
23
|
+
@mock_website.start
|
24
|
+
end
|
25
|
+
|
26
|
+
after do
|
27
|
+
@mock_website.stop
|
28
|
+
end
|
29
|
+
|
30
|
+
context "when logging in" do
|
31
|
+
before do
|
32
|
+
# Your code which runs Watir/Selenium/or anything else that doesn't use Net::HTTP here
|
33
|
+
end
|
34
|
+
|
35
|
+
it "accesses the login page" do
|
36
|
+
@mock_website.should receive_request_for( :login_page )
|
37
|
+
end
|
38
|
+
|
39
|
+
it "posts to the session page" do
|
40
|
+
@mock_website.should receive_post_for( :session_page ).with_data( "user" => "sample_user", "password" => "password" )
|
41
|
+
end
|
42
|
+
end
|
data/lib/replicant.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
Spec::Matchers.define :receive_request_for do |page|
|
2
|
+
match do |mock|
|
3
|
+
mock.requested?( page ) == true
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
Spec::Matchers.define :receive_post_for do |page|
|
8
|
+
chain :with_data do |post_data|
|
9
|
+
@post_data = post_data
|
10
|
+
end
|
11
|
+
|
12
|
+
match do |mock|
|
13
|
+
mock.requested_via_post?( page, @post_data ) == true
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Replicant
|
2
|
+
class Response
|
3
|
+
attr_reader :name, :method, :path
|
4
|
+
|
5
|
+
def initialize( name, method, path, content )
|
6
|
+
@name = name
|
7
|
+
@method = method
|
8
|
+
@path = path
|
9
|
+
@content = content
|
10
|
+
|
11
|
+
@requests = [ ]
|
12
|
+
end
|
13
|
+
|
14
|
+
def content( post = { } )
|
15
|
+
mark_as_requested( post )
|
16
|
+
@content
|
17
|
+
end
|
18
|
+
|
19
|
+
def requested?( times = 1 )
|
20
|
+
@requests.length == times
|
21
|
+
end
|
22
|
+
|
23
|
+
def requested_via_post?( post_data = { }, times = 1 )
|
24
|
+
@requests.all? { |request| request[ :post ] == post_data } && requested?( times )
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_s
|
28
|
+
"#{@name} ( #{@path} )\n" +
|
29
|
+
"\tAccessed: #{@requests.length} times\n" +
|
30
|
+
@requests.collect { |request| "\t\t#{request[ :timestamp ]}\n\t\t#{request[ :post ]}\n\n" }.join( "\n" )
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def mark_as_requested( post )
|
36
|
+
@requests << { :timestamp => Time.now, :post => post }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Replicant
|
2
|
+
class Server
|
3
|
+
def self.start( mock, port = 9000 )
|
4
|
+
@server, @port = nil, port
|
5
|
+
|
6
|
+
@thread = Thread.new do
|
7
|
+
Rack::Handler::Thin.run( mock, :Port => @port ) do |server|
|
8
|
+
@server = server
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
Thread.pass until @server && @server.running?
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.stop
|
16
|
+
@server.stop!
|
17
|
+
@thread.terminate
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Replicant
|
2
|
+
class Site
|
3
|
+
def initialize
|
4
|
+
@responses = [ ]
|
5
|
+
end
|
6
|
+
|
7
|
+
def start
|
8
|
+
Replicant::Server.start self, 9000
|
9
|
+
end
|
10
|
+
|
11
|
+
def stop
|
12
|
+
Replicant::Server.stop
|
13
|
+
end
|
14
|
+
|
15
|
+
def response( name, path, content = "<html><body></body></html" )
|
16
|
+
remove_response_by_name( name ) if find_response_by_name( name )
|
17
|
+
@responses << Replicant::Response.new( name, :get, path, content )
|
18
|
+
end
|
19
|
+
|
20
|
+
def requested?( name, times = 1 )
|
21
|
+
find_response_by_name( name ).requested?( times )
|
22
|
+
end
|
23
|
+
|
24
|
+
def requested_via_post?( name, post_data = { }, times = 1 )
|
25
|
+
find_response_by_name( name ).requested_via_post?( post_data, times )
|
26
|
+
end
|
27
|
+
|
28
|
+
def call( env )
|
29
|
+
request = Rack::Request.new( env )
|
30
|
+
|
31
|
+
status_code, content =
|
32
|
+
if response = find_response_by_path( request.env[ 'REQUEST_URI' ] )
|
33
|
+
[ 200, response.content( request.POST ) ]
|
34
|
+
else
|
35
|
+
[ 404, "Not Found" ]
|
36
|
+
end
|
37
|
+
|
38
|
+
[ status_code, { 'Content-Type' => 'text/html' }, [ content ] ]
|
39
|
+
end
|
40
|
+
|
41
|
+
def print_responses
|
42
|
+
@responses.each { |r| puts r }
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def find_position( &block )
|
48
|
+
@responses.index &block
|
49
|
+
end
|
50
|
+
|
51
|
+
def find_position_by_name( name )
|
52
|
+
find_position { |response| response.name == name }
|
53
|
+
end
|
54
|
+
|
55
|
+
def find_position_by_path( path )
|
56
|
+
find_position { |response| path == response.path }
|
57
|
+
end
|
58
|
+
|
59
|
+
def find_response_by_path( path )
|
60
|
+
if position = find_position_by_path( path )
|
61
|
+
@responses[ position ]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def find_response_by_name( name )
|
66
|
+
if position = find_position_by_name( name )
|
67
|
+
@responses[ position ]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def remove_response_by_name( name )
|
72
|
+
if position = find_position_by_name( name )
|
73
|
+
@responses.delete_at position
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'replicant'
|
2
|
+
require 'spec'
|
3
|
+
|
4
|
+
describe Replicant do
|
5
|
+
before do
|
6
|
+
@mock_website = Replicant.new
|
7
|
+
end
|
8
|
+
|
9
|
+
context "#response" do
|
10
|
+
before do
|
11
|
+
@mock_website.response :name, '/path', "<response>text</response>"
|
12
|
+
end
|
13
|
+
|
14
|
+
context "when no responses matching the given name exist" do
|
15
|
+
it "registers the response given" do
|
16
|
+
@mock_website.instance_variable_get( :@responses ).should have( 1 ).response
|
17
|
+
|
18
|
+
response = @mock_website.instance_variable_get( :@responses ).first
|
19
|
+
|
20
|
+
response.name.should == :name
|
21
|
+
response.path.should == '/path'
|
22
|
+
response.content.should == "<response>text</response>"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "when responses matching the given name already exist" do
|
27
|
+
before do
|
28
|
+
@mock_website.response :name, '/new-path', "<response>new text</response>"
|
29
|
+
end
|
30
|
+
|
31
|
+
it "registers the response given" do
|
32
|
+
@mock_website.instance_variable_get( :@responses ).should have( 1 ).response
|
33
|
+
|
34
|
+
response = @mock_website.instance_variable_get( :@responses ).first
|
35
|
+
|
36
|
+
response.name.should == :name
|
37
|
+
response.path.should == '/new-path'
|
38
|
+
response.content.should == "<response>new text</response>"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
metadata
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: replicant
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 25
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 3
|
10
|
+
version: 0.0.3
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- James Bobowski
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-10-02 00:00:00 -07:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rack
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 21
|
30
|
+
segments:
|
31
|
+
- 1
|
32
|
+
- 0
|
33
|
+
- 1
|
34
|
+
version: 1.0.1
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
description: Replicant is a Rack-based http-endpoint gem used to mock/assert real http calls.
|
38
|
+
email:
|
39
|
+
- james.bobowski@gmail.com
|
40
|
+
executables: []
|
41
|
+
|
42
|
+
extensions: []
|
43
|
+
|
44
|
+
extra_rdoc_files:
|
45
|
+
- README
|
46
|
+
files:
|
47
|
+
- History.txt
|
48
|
+
- Manifest.txt
|
49
|
+
- README
|
50
|
+
- lib/replicant.rb
|
51
|
+
- lib/replicant/matchers.rb
|
52
|
+
- lib/replicant/response.rb
|
53
|
+
- lib/replicant/server.rb
|
54
|
+
- lib/replicant/site.rb
|
55
|
+
- lib/replicant/version.rb
|
56
|
+
- spec/replicant_spec.rb
|
57
|
+
has_rdoc: true
|
58
|
+
homepage: http://github.com/jamesbobowski/replicant
|
59
|
+
licenses: []
|
60
|
+
|
61
|
+
post_install_message:
|
62
|
+
rdoc_options: []
|
63
|
+
|
64
|
+
require_paths:
|
65
|
+
- lib
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
hash: 3
|
72
|
+
segments:
|
73
|
+
- 0
|
74
|
+
version: "0"
|
75
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
hash: 3
|
81
|
+
segments:
|
82
|
+
- 0
|
83
|
+
version: "0"
|
84
|
+
requirements: []
|
85
|
+
|
86
|
+
rubyforge_project: replicant
|
87
|
+
rubygems_version: 1.5.3
|
88
|
+
signing_key:
|
89
|
+
specification_version: 3
|
90
|
+
summary: Replicant is a Rack-based http-endpoint gem used to mock/assert real http calls.
|
91
|
+
test_files: []
|
92
|
+
|