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.
@@ -0,0 +1,8 @@
1
+ 0.0.3 ( GET Parameter Support )
2
+ - added support for GET parameters in URLs
3
+
4
+ 0.0.2 ( Bug fixes )
5
+ - fixed intermittently hanging Thin server
6
+
7
+ 0.0.1 ( First gem release )
8
+ - added gemspec, namespacing, etc
@@ -0,0 +1,12 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README
4
+ lib/replicant
5
+ lib/replicant/matchers.rb
6
+ lib/replicant/response.rb
7
+ lib/replicant/server.rb
8
+ lib/replicant/site.rb
9
+ lib/replicant/version.rb
10
+ lib/replicant.rb
11
+ spec
12
+ spec/replicant_spec.rb
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
@@ -0,0 +1,14 @@
1
+ require 'rack'
2
+
3
+ require 'replicant/site'
4
+ require 'replicant/server'
5
+ require 'replicant/response'
6
+ require 'replicant/matchers'
7
+
8
+ module Replicant
9
+ class << self
10
+ def new
11
+ Replicant::Site.new
12
+ end
13
+ end
14
+ end
@@ -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,9 @@
1
+ module Replicant
2
+ module VERSION
3
+ MAJOR = 0
4
+ MINOR = 0
5
+ TINY = 3
6
+
7
+ STRING = [ MAJOR, MINOR, TINY ].join( '.' )
8
+ end
9
+ end
@@ -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
+