rspec-performance 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. data/Rakefile +6 -0
  2. data/lib/rspec-performance.rb +2 -1
  3. data/lib/spec/client/http/driver/curl_driver.rb +71 -0
  4. data/lib/spec/client/http/matcher/transaction_matchers.rb +74 -0
  5. data/lib/spec/client/http/request.rb +28 -0
  6. data/lib/spec/client/http/response.rb +32 -0
  7. data/lib/spec/client/http/session.rb +41 -0
  8. data/lib/spec/client/http/transaction.rb +29 -0
  9. data/lib/spec/client/http_client.rb +32 -0
  10. data/lib/spec/performance/configuration.rb +1 -1
  11. data/lib/spec/performance/example/performance_example_group_methods.rb +0 -1
  12. data/lib/spec/performance/example/performance_execution_builder.rb +1 -0
  13. data/lib/spec/performance/version.rb +2 -2
  14. data/spec/helpers/integration_server.rb +50 -30
  15. data/spec/helpers/integration_server_spec.rb +0 -16
  16. data/spec/lib/spec/client/http/driver/curl_driver_spec.rb +46 -0
  17. data/spec/lib/spec/client/http/matcher/transaction_matchers_spec.rb +130 -0
  18. data/spec/lib/spec/client/http/request_spec.rb +26 -0
  19. data/spec/lib/spec/client/http/response_spec.rb +25 -0
  20. data/spec/lib/spec/client/http/session_spec.rb +64 -0
  21. data/spec/lib/spec/client/http/transaction_spec.rb +76 -0
  22. data/spec/lib/spec/client/http_client_spec.rb +21 -0
  23. data/spec/lib/spec/performance/example/performance_example_group_methods_spec.rb +1 -1
  24. data/spec/lib/spec/performance/example/performance_example_group_spec.rb +2 -2
  25. data/spec/spec_helper.rb +1 -1
  26. metadata +48 -11
  27. data/lib/spec/performance/client.rb +0 -1
  28. data/lib/spec/performance/client/http_client.rb +0 -94
  29. data/lib/spec/performance/client/response.rb +0 -25
  30. data/spec/lib/spec/performance/client/http_client_spec.rb +0 -112
data/Rakefile CHANGED
@@ -24,4 +24,10 @@ task :publish do
24
24
  system "gem push rspec-performance-#{Spec::Performance::VERSION::STRING}.gem"
25
25
  end
26
26
 
27
+ desc "Runs the integration test server"
28
+ task "integration:run" do
29
+ require "spec/helpers/integration_server"
30
+ IntegrationServer.new(8888).run
31
+ end
32
+
27
33
  # Gem packaging tasks
@@ -1,4 +1,5 @@
1
1
  require "spec/performance/version"
2
- require "spec/performance/client"
2
+ require "spec/client/http_client"
3
+ require "spec/client/http/matcher/transaction_matchers"
3
4
  require "spec/performance/configuration"
4
5
  require "spec/performance/example/performance_example_group"
@@ -0,0 +1,71 @@
1
+ require 'rubygems'
2
+ require 'curb'
3
+ require 'uri'
4
+ require 'cgi'
5
+
6
+ # TODO: make an abstract parent driver class, and a spec for it
7
+
8
+ module Spec
9
+ module Client
10
+ module Http
11
+ module Driver
12
+ class CurlDriver
13
+ def url_encode_params(params)
14
+ return nil if params.empty?
15
+
16
+ params.inject([]) do |query, (name, value)|
17
+ # TODO: come up with a better way to deal with true and false parameters
18
+ query << [name,value].collect {|s| s.nil? ? "" : s==false ? "0" : s==true ? "1" : CGI.escape(s.to_s)}.join('=')
19
+ end.join("&")
20
+ end
21
+
22
+ def initialize()
23
+ end
24
+
25
+ def execute(url, method, headers, params)
26
+ # Workaround for potential bug in curl
27
+ request_url = url
28
+ encoded_params = url_encode_params(params)
29
+
30
+ if method == "GET"
31
+ request_url += "?#{encoded_params}"
32
+ end
33
+
34
+ response_headers = {}
35
+ response_body = ""
36
+
37
+ curl = Curl::Easy.new(request_url)
38
+ curl.headers = headers
39
+
40
+ curl.on_header do |header|
41
+ size = header.size; header.chomp!
42
+ name, value = header.split(/\: /)
43
+ response_headers[name] ||= []
44
+ response_headers[name] << value
45
+ size
46
+ end
47
+
48
+ body_content = ""
49
+ curl.on_body do |body|
50
+ body_content += body
51
+ body.size
52
+ end
53
+
54
+ case method.upcase
55
+ when "GET"
56
+ curl.http_get
57
+ when "POST"
58
+ curl.http_post(encoded_params)
59
+ end
60
+
61
+ response = Response.new(url)
62
+ response.code = curl.response_code
63
+ response.headers = response_headers
64
+ response.body = body_content
65
+ response
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,74 @@
1
+ module Spec
2
+ module Client
3
+ module Http
4
+ module Matcher
5
+ module TransactionMatchers
6
+ class VerboseHttpMatcher
7
+ attr_accessor :transaction
8
+
9
+ def matches?(transaction)
10
+ @transaction = transaction
11
+ return transaction.is_a?(Spec::Client::Http::Transaction)
12
+ end
13
+
14
+ def transaction_info
15
+ "Request: #{transaction.request.url} using #{transaction.request.request_method}" + "\n" +
16
+ " sent headers: #{transaction.request.headers}" + "\n" +
17
+ " sent params: #{transaction.request.url_encoded_params}" + "\n" +
18
+ "Response code: #{transaction.response.code}" + "\n" +
19
+ " with cookies: #{transaction.response.cookies}" + "\n" +
20
+ " with html body: #{transaction.response.body}"
21
+ end
22
+
23
+ def failure_message
24
+ transaction_info
25
+ end
26
+
27
+ def negative_failure_message
28
+ transaction_info
29
+ end
30
+ end
31
+
32
+ class BeRedirect < VerboseHttpMatcher
33
+ def matches?(transaction)
34
+ super(transaction) && transaction.redirect?
35
+ #(300..399).include? transaction.response.code
36
+ end
37
+
38
+ def failure_message
39
+ "expected redirect? to return true, got false" + "\n" + super
40
+ end
41
+
42
+ def negative_failure_message
43
+ "expected redirect? to return false, got true" + "\n" + super
44
+ end
45
+ end
46
+
47
+ def be_redirect
48
+ BeRedirect.new()
49
+ end
50
+
51
+ class BeSuccess < VerboseHttpMatcher
52
+ def matches?(transaction)
53
+ super(transaction) && transaction.success?
54
+ #(200..299).include? transaction.response.code
55
+ end
56
+
57
+ def failure_message
58
+ "expected success? to return true, got false" + "\n" + super
59
+ end
60
+
61
+ def negative_failure_message
62
+ "expected success? to return false, got true" + "\n" + super
63
+ end
64
+ end
65
+
66
+ def be_success
67
+ BeSuccess.new()
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+
@@ -0,0 +1,28 @@
1
+ require "spec/client/http/request"
2
+ require "spec/client/http/driver/curl_driver"
3
+
4
+ module Spec
5
+ module Client
6
+ module Http
7
+ class Request
8
+ attr_accessor :url, :request_method, :params, :headers
9
+
10
+ def initialize(url, request_method, params, headers, driver=Driver::CurlDriver.new)
11
+ @url, @request_method, @params, @headers, @driver = url, request_method, params, headers, driver
12
+ end
13
+
14
+ def url_encoded_params
15
+ @driver.url_encode_params(params)
16
+ end
17
+
18
+ def execute
19
+ driver_execute(url,request_method,headers,params)
20
+ end
21
+
22
+ def driver_execute(url,request_method,headers,params)
23
+ @driver.execute(url,request_method,headers,params)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,32 @@
1
+ require "spec/client/http/request"
2
+ require "mechanize"
3
+ require "uri"
4
+
5
+ module Spec
6
+ module Client
7
+ module Http
8
+ class Response
9
+ attr_accessor :code, :headers, :body
10
+
11
+ def initialize(url)
12
+ @code = 0
13
+ @headers = {}
14
+ @body = ""
15
+ @url = url
16
+ end
17
+
18
+ def cookies
19
+ # TODO: can probably use ruby tricks to bind these together rather than using a temporary array...
20
+ tmp_cookies = []
21
+ (headers["Set-Cookie"]||[]).map do |raw_cookie|
22
+ uri = URI::parse(@url)
23
+ Mechanize::Cookie::parse(uri,raw_cookie) do |c|
24
+ tmp_cookies.push(c)
25
+ end
26
+ end
27
+ tmp_cookies
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,41 @@
1
+ require "spec/client/http/request"
2
+ require "spec/client/http/response"
3
+ require "spec/client/http/transaction"
4
+ require "mechanize"
5
+ require "uri"
6
+
7
+ module Spec
8
+ module Client
9
+ module Http
10
+ class Session
11
+ attr_reader :client, :cookie_jar
12
+
13
+ def initialize(client, options = {})
14
+ @client = client
15
+ @cookie_jar = Mechanize::CookieJar.new
16
+ end
17
+
18
+ def get(url, params = {})
19
+ execute(Request.new(url, "GET", params, request_headers(url)))
20
+ end
21
+
22
+ def post(url, params = {})
23
+ execute(Request.new(url, "POST", params, request_headers(url)))
24
+ end
25
+
26
+ def request_headers(url)
27
+ { "Cookie" => @cookie_jar.cookies(URI::parse(url)) }
28
+ end
29
+
30
+ def execute(request)
31
+ transaction = Transaction.new(request)
32
+ transaction.execute
33
+ transaction.response.cookies.each do |cookie|
34
+ cookie_jar.add(URI::parse(transaction.request.url),cookie)
35
+ end
36
+ transaction
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,29 @@
1
+ require "spec/client/http/matcher/transaction_matchers"
2
+
3
+ module Spec
4
+ module Client
5
+ module Http
6
+ class Transaction
7
+ attr_reader :request, :response
8
+
9
+ def initialize(request)
10
+ @request = request
11
+ @response = nil
12
+ end
13
+
14
+ def execute
15
+ @response = request.execute
16
+ self
17
+ end
18
+
19
+ def success?
20
+ (200..299).include? @response.code
21
+ end
22
+
23
+ def redirect?
24
+ (300..399).include? @response.code
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,32 @@
1
+ require "uri"
2
+ require "spec/client/http/session"
3
+
4
+ module Spec
5
+ module Client
6
+ class HttpClient
7
+ attr_reader :session, :base_uri
8
+
9
+ def initialize(base_uri)
10
+ @base_uri = base_uri
11
+ @session = Http::Session.new(self)
12
+ end
13
+
14
+ def new_session()
15
+ @session = Http::Session.new(self)
16
+ end
17
+
18
+ def get(path, params = {})
19
+ session.get(full_url(path), params)
20
+ end
21
+
22
+ def post(path, params = {})
23
+ session.post(full_url(path), params)
24
+ end
25
+
26
+ def full_url(path)
27
+ URI.join(base_uri, path).to_s
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -50,7 +50,7 @@ module Spec
50
50
  :iterations => 20,
51
51
  :iterations_per_second => nil,
52
52
  :maximum_iteration_time => nil,
53
- :performance_driver_class => Spec::Performance::Client::HttpClient,
53
+ :performance_driver_class => Spec::Client::HttpClient,
54
54
  :performance_driver_base_uri => "http://localhost/"
55
55
  }
56
56
  end
@@ -5,7 +5,6 @@ module Spec
5
5
  module Example
6
6
 
7
7
  module PerformanceExampleGroupMethods
8
-
9
8
  def perform(description, options = {}, backtrace = nil, &implementation)
10
9
  options = Spec::Performance::Configuration.configured_options.merge(options)
11
10
 
@@ -41,6 +41,7 @@ module Spec
41
41
  maximum_iteration_time = _calculate_average(current_iteration - 1, maximum_iteration_time, iteration_run_time)
42
42
  end
43
43
  end
44
+
44
45
  [example_run_time, maximum_iteration_time]
45
46
  end
46
47
 
@@ -2,8 +2,8 @@ module Spec
2
2
  module Performance
3
3
  module VERSION
4
4
  MAJOR = 0
5
- MINOR = 0
6
- TINY = 3
5
+ MINOR = 1
6
+ TINY = 0
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY].join(".")
9
9
  end
@@ -1,5 +1,6 @@
1
1
  require "rubygems"
2
2
  require "thin"
3
+ require "cgi"
3
4
 
4
5
  Thread.abort_on_exception = true
5
6
 
@@ -10,26 +11,44 @@ class IntegrationServer
10
11
  @running = false
11
12
  end
12
13
 
13
- def self.base_url
14
- "http://localhost:#{@@port}/"
15
- end
14
+ class << self
15
+ def base_url
16
+ "http://127.0.0.1:#{@@port}/"
17
+ end
16
18
 
17
- def self.instance
18
- @@instance ||= new(@@port)
19
- end
19
+ def instance
20
+ @@instance ||= new(@@port)
21
+ end
20
22
 
21
- def self.start
22
- instance.start
23
- end
23
+ def start
24
+ instance.start
25
+ end
24
26
 
25
- def self.kill
26
- @@instance.kill
27
- end
27
+ def kill
28
+ @@instance.kill
29
+ end
28
30
 
29
- def self.port=(value)
30
- @@port = value
31
+ def port=(value)
32
+ @@port = value
33
+ end
31
34
  end
32
35
 
36
+ def run
37
+ Thin::Server.start('0.0.0.0', @port) do
38
+ map "/hello" do
39
+ run HelloAdapter.new
40
+ end
41
+
42
+ map "/cookie_echo" do
43
+ run CookieEchoAdapter.new
44
+ end
45
+
46
+ map "/host_echo" do
47
+ run HostEchoAdapter.new
48
+ end
49
+ end
50
+ end
51
+
33
52
  def running?
34
53
  @running
35
54
  end
@@ -39,19 +58,7 @@ class IntegrationServer
39
58
 
40
59
  Thin::Logging.silent = true
41
60
  @server_thread = Thread.new do
42
- @server = Thin::Server.start('0.0.0.0', @port) do
43
- map "/hello" do
44
- run HelloAdapter.new
45
- end
46
-
47
- map "/cookie_echo" do
48
- run CookieEchoAdapter.new
49
- end
50
-
51
- map "/host_echo" do
52
- run HostEchoAdapter.new
53
- end
54
- end
61
+ @server = run
55
62
  end
56
63
  sleep 0.010 unless @server && @server.running?
57
64
  @running = true
@@ -73,13 +80,26 @@ class IntegrationServer
73
80
 
74
81
  class CookieEchoAdapter
75
82
  def call(env)
76
- cookies = env["rack.input"].read.split(/&/).inject([]) do |acc, pair|
77
- name, value = pair.split(/=/).map {|p| CGI::unescape(p) }
83
+ params = {}
84
+ params.merge!(parse_raw_params(env["rack.input"].read))
85
+ params.merge!(parse_raw_params(env["QUERY_STRING"]))
86
+
87
+ cookies = params.inject([]) do |acc, (name, value)|
78
88
  acc << CGI::Cookie.new(name, value).to_s
79
89
  acc
80
90
  end
81
91
  cookie_string = cookies.join("\n")
82
- [200, { "Set-Cookie" => cookie_string }, ["echo"]]
92
+ [200, { "Set-Cookie" => cookie_string }, ["echo: " + cookie_string]]
93
+ end
94
+
95
+ def parse_raw_params(input)
96
+ return {} if input.empty?
97
+
98
+ input.split(/&/).inject({}) do |parsed, pair|
99
+ name, value = pair.split(/\=/).map {|p| CGI::unescape(p) }
100
+ parsed[name] = value
101
+ parsed
102
+ end
83
103
  end
84
104
  end
85
105
 
@@ -1,20 +1,4 @@
1
1
  require "#{File.dirname(__FILE__)}/../spec_helper"
2
2
 
3
3
  describe IntegrationServer do
4
- describe "HostEchoAdapter" do
5
- describe "when HTTP_HOST is set by the client" do
6
- it "echos the client specified value back" do
7
- uri = URI.parse("http://localhost:8888/host_echo")
8
- http = Net::HTTP.start(uri.host, uri.port)
9
- response = http.get(uri.request_uri, { "Host" => "x.y.z.com" })
10
- http.finish
11
-
12
- response.body.should include("x.y.z.com")
13
- end
14
- end
15
-
16
- describe "when HTTP_HOST is not set" do
17
- it "defaults to the machine name"
18
- end
19
- end
20
4
  end
@@ -0,0 +1,46 @@
1
+ require "#{File.dirname(__FILE__)}/../../../../../spec_helper"
2
+
3
+ describe Spec::Client::Http::Driver::CurlDriver do
4
+ attr_reader :url, :params, :headers, :driver
5
+ before do
6
+ @url = "http://www.example.com"
7
+ @params = { "some[param]" => "encode me", "ok" => "done" }
8
+ @headers = { "Cookie", "hey=now" }
9
+ @driver = Spec::Client::Http::Driver::CurlDriver.new()
10
+ end
11
+
12
+ describe "#url_encode_params" do
13
+ describe "when there are params" do
14
+ it "creates a url encoded query string" do
15
+ @driver.url_encode_params(params).should include("some%5Bparam%5D=encode+me")
16
+ @driver.url_encode_params(params).should include("ok=done")
17
+ @driver.url_encode_params(params).should include("&")
18
+ end
19
+ end
20
+
21
+ describe "when there are no params" do
22
+ it "returns nil" do
23
+ @driver.url_encode_params({}).should be_nil
24
+ end
25
+ end
26
+ end
27
+
28
+ describe "#execute" do
29
+ describe "when the request is a GET" do
30
+ it "makes a get request" do
31
+ curler = mock(Curl::Easy.new(@url))
32
+ stub(Curl::Easy).new {curler}
33
+ curler.http_get
34
+ driver.execute(url, "GET", headers, params)
35
+ end
36
+ end
37
+ describe "when the request is a POST" do
38
+ it "makes a post request" do
39
+ curler = mock(Curl::Easy.new(@url))
40
+ stub(Curl::Easy).new {curler}
41
+ curler.http_post(anything)
42
+ driver.execute(url, "POST", headers, params)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,130 @@
1
+ require "#{File.dirname(__FILE__)}/../../../../../spec_helper"
2
+
3
+ describe Spec::Client::Http::Matcher::TransactionMatchers do
4
+ attr_reader :transaction, :matcher
5
+
6
+ describe "DerivedVerboseHttpMatcher" do
7
+ before do
8
+ class DerivedVerboseHttpMatcher < Spec::Client::Http::Matcher::TransactionMatchers::VerboseHttpMatcher
9
+ def matches?(transaction)
10
+ super(transaction) && true
11
+ end
12
+ end
13
+ # make a transaction for testing
14
+ url = "http://www.example.com"
15
+ params = { "some[param]" => "encode me", "ok" => "done" }
16
+ headers = { "Cookie", "hey=now" }
17
+ driver = Spec::Client::Http::Driver::CurlDriver.new()
18
+ request = Spec::Client::Http::Request.new(url, "GET", params, {})
19
+ @transaction = Spec::Client::Http::Transaction.new(request)
20
+ transaction.execute
21
+ @matcher = DerivedVerboseHttpMatcher.new
22
+ matcher.matches?(transaction)
23
+ end
24
+
25
+ describe "#transaction_info" do
26
+ it "returns a string with information about the http transaction" do
27
+ matcher.transaction_info.include?("Request: #{transaction.request.url} using #{transaction.request.request_method}").should be_true
28
+ matcher.transaction_info.include?(" sent headers: #{transaction.request.headers}").should be_true
29
+ matcher.transaction_info.include?("Response code: #{transaction.response.code}").should be_true
30
+ matcher.transaction_info.include?(" with cookies: #{transaction.response.cookies}").should be_true
31
+ end
32
+ end
33
+
34
+ describe "#failure_message" do
35
+ it "contains the transaction info" do
36
+ matcher.failure_message.include?(matcher.transaction_info).should be_true
37
+ end
38
+ end
39
+
40
+ describe "#negative_failure_message" do
41
+ it "contains the transaction info" do
42
+ matcher.negative_failure_message.include?(matcher.transaction_info).should be_true
43
+ end
44
+ end
45
+ end
46
+
47
+ describe "BeRedirect" do
48
+ before do
49
+ # make a transaction for testing
50
+ url = "http://www.example.com"
51
+ params = { "some[param]" => "encode me", "ok" => "done" }
52
+ headers = { "Cookie", "hey=now" }
53
+ driver = Spec::Client::Http::Driver::CurlDriver.new()
54
+ request = Spec::Client::Http::Request.new(url, "GET", params, {})
55
+ @transaction = Spec::Client::Http::Transaction.new(request)
56
+ transaction.execute
57
+ @matcher = Spec::Client::Http::Matcher::TransactionMatchers::BeRedirect.new
58
+ matcher.matches?(transaction)
59
+ end
60
+
61
+ describe "#matches?" do
62
+ describe "transaction is a redirect" do
63
+ it "returns true" do
64
+ stub(transaction).redirect? {true}
65
+ matcher.matches?(transaction).should be_true
66
+ end
67
+ end
68
+ describe "transaction is not a redirect" do
69
+ it "returns false" do
70
+ stub(transaction).redirect? {false}
71
+ matcher.matches?(transaction).should be_false
72
+ end
73
+ end
74
+ end
75
+
76
+ describe "#failure_message" do
77
+ it "contains the transaction info" do
78
+ matcher.failure_message.include?(matcher.transaction_info).should be_true
79
+ end
80
+ end
81
+
82
+ describe "#negative_failure_message" do
83
+ it "contains the transaction info" do
84
+ matcher.negative_failure_message.include?(matcher.transaction_info).should be_true
85
+ end
86
+ end
87
+ end
88
+
89
+ describe "BeSuccess" do
90
+ before do
91
+ # make a transaction for testing
92
+ url = "http://www.example.com"
93
+ params = { "some[param]" => "encode me", "ok" => "done" }
94
+ headers = { "Cookie", "hey=now" }
95
+ driver = Spec::Client::Http::Driver::CurlDriver.new()
96
+ request = Spec::Client::Http::Request.new(url, "GET", params, {})
97
+ @transaction = Spec::Client::Http::Transaction.new(request)
98
+ transaction.execute
99
+ @matcher = Spec::Client::Http::Matcher::TransactionMatchers::BeSuccess.new
100
+ matcher.matches?(transaction)
101
+ end
102
+
103
+ describe "#matches?" do
104
+ describe "transaction is successful" do
105
+ it "returns true" do
106
+ stub(transaction).success? {true}
107
+ matcher.matches?(transaction).should be_true
108
+ end
109
+ end
110
+ describe "transaction is not successful" do
111
+ it "returns false" do
112
+ stub(transaction).success? {false}
113
+ matcher.matches?(transaction).should be_false
114
+ end
115
+ end
116
+ end
117
+
118
+ describe "#failure_message" do
119
+ it "contains the transaction info" do
120
+ matcher.failure_message.include?(matcher.transaction_info).should be_true
121
+ end
122
+ end
123
+
124
+ describe "#negative_failure_message" do
125
+ it "contains the transaction info" do
126
+ matcher.negative_failure_message.include?(matcher.transaction_info).should be_true
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,26 @@
1
+ require "#{File.dirname(__FILE__)}/../../../../spec_helper"
2
+
3
+ describe Spec::Client::Http::Request do
4
+ attr_reader :url, :params, :headers, :request
5
+ before do
6
+ @url = "http://www.example.com"
7
+ @params = { "some[param]" => "encode me", "ok" => "done" }
8
+ @headers = { "Cookie", "hey=now" }
9
+ @request = Spec::Client::Http::Request.new(url, "GET", params, headers)
10
+ end
11
+
12
+ describe "#initialize" do
13
+ it "populates the readers" do
14
+ request.url == url
15
+ request.params == params
16
+ request.headers == headers
17
+ end
18
+ end
19
+
20
+ describe "#execute" do
21
+ it "makes an http request via the driver" do
22
+ mock(request).driver_execute(url, "GET", headers, params)
23
+ response = request.execute
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,25 @@
1
+ require "#{File.dirname(__FILE__)}/../../../../spec_helper"
2
+
3
+ describe Spec::Client::Http::Response do
4
+ describe "#cookies" do
5
+ attr_reader :response
6
+ before do
7
+ @response = Spec::Client::Http::Response.new("http://www.example.com")
8
+ response.headers = { "Set-Cookie" => ["foo=bar", "baz=bang; domain=.example.com"] }
9
+ end
10
+
11
+ def assert_cookies_equal(actual, expected)
12
+ actual.name.should == expected.name
13
+ actual.value.should == expected.value
14
+ actual.domain.should == expected.domain
15
+ actual.path.should == expected.path
16
+ actual.expires.should == expected.expires
17
+ end
18
+
19
+ it "returns an array of cookies" do
20
+ response.cookies.size.should == 2
21
+ assert_cookies_equal(response.cookies.first, Mechanize::Cookie::parse(URI::parse("http://www.example.com"), "foo=bar") {|c| c}.first)
22
+ assert_cookies_equal(response.cookies.last, Mechanize::Cookie::parse(URI::parse("http://www.example.com"), "baz=bang; domain=.example.com"){|c| c}.first)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,64 @@
1
+ require "#{File.dirname(__FILE__)}/../../../../spec_helper"
2
+
3
+ describe Spec::Client::Http::Session do
4
+ class TestClient
5
+ def intialize
6
+ end
7
+
8
+ def get(url, params = {})
9
+ end
10
+
11
+ def post(url, params = {})
12
+ end
13
+ end
14
+
15
+ class TestRequest < Spec::Client::Http::Request
16
+ def driver_execute(url,method,headers,params)
17
+ Spec::Client::Http::Response.new(url)
18
+ end
19
+ end
20
+
21
+ attr_reader :client
22
+ before do
23
+ @client = TestClient.new
24
+ end
25
+
26
+ describe "#intialize" do
27
+ it "creates a new cookie jar" do
28
+ session = Spec::Client::Http::Session.new(client)
29
+ session.client.should == client
30
+ session.cookie_jar.should be_a(Mechanize::CookieJar)
31
+ end
32
+ end
33
+
34
+ describe "#get" do
35
+ it "calls execute with a new get request" do
36
+ session = Spec::Client::Http::Session.new(client)
37
+ mock(session).execute(anything) do |request|
38
+ request.should be_a(Spec::Client::Http::Request)
39
+ request.request_method.should == "GET"
40
+ end
41
+
42
+ session.get("http://127.0.0.1", {})
43
+ end
44
+ end
45
+
46
+ describe "#post" do
47
+ it "calls execute with a new post request" do
48
+ session = Spec::Client::Http::Session.new(client)
49
+ mock(session).execute(anything) do |request|
50
+ request.should be_a(Spec::Client::Http::Request)
51
+ request.request_method.should == "POST"
52
+ end
53
+ session.post("http://127.0.0.1", {})
54
+ end
55
+ end
56
+
57
+ describe "#execute" do
58
+ it "makes a request and returns the Transaction" do
59
+ # mock.instance_of(Spec::Client::Http::Transaction).execute
60
+ session = Spec::Client::Http::Session.new(client)
61
+ transaction = session.execute(TestRequest.new("http://127.0.0.1/", "GET", {}, {}))
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,76 @@
1
+ require "#{File.dirname(__FILE__)}/../../../../spec_helper"
2
+
3
+ describe Spec::Client::Http::Transaction do
4
+ attr_reader :request, :response
5
+ before do
6
+ @request = Spec::Client::Http::Request.new("http://example.com", "GET", {}, {})
7
+ @response = Spec::Client::Http::Response.new(@request.url)
8
+ end
9
+
10
+ describe "#execute" do
11
+ it "executes the request and sets the response" do
12
+ mock(request).execute { "foo" }
13
+
14
+ transaction = Spec::Client::Http::Transaction.new(request)
15
+ transaction.execute.should == transaction
16
+ transaction.response.should == "foo"
17
+ end
18
+ end
19
+
20
+ describe "#success?" do
21
+ describe "when the response code is an http success code" do
22
+ before do
23
+ response.code = 201
24
+ mock(request).execute { response }
25
+ end
26
+
27
+ it "returns true" do
28
+ transaction = Spec::Client::Http::Transaction.new(request)
29
+ transaction.execute
30
+ transaction.should be_success
31
+ end
32
+ end
33
+
34
+ describe "when the response code is NOT an http success code" do
35
+ before do
36
+ response.code = 300
37
+ mock(request).execute { response }
38
+ end
39
+
40
+ it "returns false" do
41
+ transaction = Spec::Client::Http::Transaction.new(request)
42
+ transaction.execute
43
+ transaction.should_not be_success
44
+ end
45
+ end
46
+ end
47
+
48
+ describe "#redirect?" do
49
+ describe "when the response code is an http redirect code" do
50
+ before do
51
+ response.code = 302
52
+ mock(request).execute { response }
53
+ end
54
+
55
+ it "returns true" do
56
+ transaction = Spec::Client::Http::Transaction.new(request)
57
+ transaction.execute
58
+ transaction.should be_redirect
59
+ end
60
+ end
61
+
62
+ describe "when the response code is NOT an http redirect code" do
63
+ before do
64
+ response.code = 400
65
+ mock(request).execute { response }
66
+ end
67
+
68
+ it "returns false" do
69
+ transaction = Spec::Client::Http::Transaction.new(request)
70
+ transaction.execute
71
+ transaction.should_not be_redirect
72
+ end
73
+ end
74
+
75
+ end
76
+ end
@@ -0,0 +1,21 @@
1
+ require "#{File.dirname(__FILE__)}/../../../spec_helper"
2
+
3
+ describe Spec::Client::HttpClient do
4
+
5
+ describe "#full_url" do
6
+ it "creates a full url from base_uri and a path" do
7
+ full_url = Spec::Client::HttpClient.new("http://example.com").full_url("foo")
8
+ full_url.should == "http://example.com/foo"
9
+ end
10
+ end
11
+
12
+ describe "#new_session" do
13
+ it "empties cookies" do
14
+ client = Spec::Client::HttpClient.new("http://example.com")
15
+ client.session.cookie_jar.add(URI::parse("http://example.com"),Mechanize::Cookie::parse(URI::parse("http://example.com"), "foo=bar") {|c| c}.first)
16
+ client.session.cookie_jar.cookies(URI::parse("http://example.com")).should_not be_empty
17
+ client.new_session()
18
+ client.session.cookie_jar.cookies(URI::parse("http://example.com")).should be_empty
19
+ end
20
+ end
21
+ end
@@ -84,7 +84,7 @@ describe Spec::Performance::Example::PerformanceExampleGroupMethods do
84
84
  it "reports the success" do
85
85
  example_group.perform("reports the success", spec_options) { 1.should == 1 }
86
86
  example_group.run(fake_run_options)
87
-
87
+
88
88
  fake_run_options.reporter.example_failures.should be_empty
89
89
  example = fake_run_options.reporter.example_successes.first
90
90
  example.description.should == "reports the success"
@@ -33,10 +33,10 @@ describe Spec::Performance::Example::PerformanceExampleGroup do
33
33
  example_group.run(fake_run_options)
34
34
  fake_run_options.reporter.example_failures.should be_empty
35
35
 
36
- driver_instance_in_first_perform_block.should be_a(Spec::Performance::Client::HttpClient)
36
+ driver_instance_in_first_perform_block.should be_a(Spec::Client::HttpClient)
37
37
  driver_instance_in_before_block.base_uri.should == "http://localhost/"
38
38
 
39
- driver_instance_in_second_perform_block.should be_a(Spec::Performance::Client::HttpClient)
39
+ driver_instance_in_second_perform_block.should be_a(Spec::Client::HttpClient)
40
40
  driver_instance_in_second_perform_block.base_uri.should == "http://localhost/"
41
41
 
42
42
  driver_instance_in_first_perform_block.eql?(driver_instance_in_second_perform_block).should be_false
@@ -2,7 +2,7 @@ begin
2
2
  require "spec"
3
3
  rescue LoadError
4
4
  require "rubygems" unless ENV["NO_RUBYGEMS"]
5
- gem "rspec"
5
+ gem "spec"
6
6
  require "spec"
7
7
  end
8
8
 
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-performance
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
5
11
  platform: ruby
6
12
  authors:
7
13
  - Bob Remeika
@@ -9,10 +15,25 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2010-02-02 00:00:00 -08:00
18
+ date: 2010-05-21 00:00:00 -07:00
13
19
  default_executable:
14
- dependencies: []
15
-
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: mechanize
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 23
30
+ segments:
31
+ - 1
32
+ - 0
33
+ - 0
34
+ version: 1.0.0
35
+ type: :runtime
36
+ version_requirements: *id001
16
37
  description: rspec-performance adds a couple of utility methods for unit testing performance
17
38
  email: bob@grockit.com
18
39
  executables: []
@@ -23,9 +44,13 @@ extra_rdoc_files: []
23
44
 
24
45
  files:
25
46
  - lib/rspec-performance.rb
26
- - lib/spec/performance/client/http_client.rb
27
- - lib/spec/performance/client/response.rb
28
- - lib/spec/performance/client.rb
47
+ - lib/spec/client/http/driver/curl_driver.rb
48
+ - lib/spec/client/http/matcher/transaction_matchers.rb
49
+ - lib/spec/client/http/request.rb
50
+ - lib/spec/client/http/response.rb
51
+ - lib/spec/client/http/session.rb
52
+ - lib/spec/client/http/transaction.rb
53
+ - lib/spec/client/http_client.rb
29
54
  - lib/spec/performance/configuration.rb
30
55
  - lib/spec/performance/example/performance_example_group.rb
31
56
  - lib/spec/performance/example/performance_example_group_methods.rb
@@ -33,7 +58,13 @@ files:
33
58
  - lib/spec/performance/version.rb
34
59
  - spec/helpers/integration_server.rb
35
60
  - spec/helpers/integration_server_spec.rb
36
- - spec/lib/spec/performance/client/http_client_spec.rb
61
+ - spec/lib/spec/client/http/driver/curl_driver_spec.rb
62
+ - spec/lib/spec/client/http/matcher/transaction_matchers_spec.rb
63
+ - spec/lib/spec/client/http/request_spec.rb
64
+ - spec/lib/spec/client/http/response_spec.rb
65
+ - spec/lib/spec/client/http/session_spec.rb
66
+ - spec/lib/spec/client/http/transaction_spec.rb
67
+ - spec/lib/spec/client/http_client_spec.rb
37
68
  - spec/lib/spec/performance/configuration_spec.rb
38
69
  - spec/lib/spec/performance/example/performance_example_group_methods_spec.rb
39
70
  - spec/lib/spec/performance/example/performance_example_group_spec.rb
@@ -51,21 +82,27 @@ rdoc_options: []
51
82
  require_paths:
52
83
  - lib
53
84
  required_ruby_version: !ruby/object:Gem::Requirement
85
+ none: false
54
86
  requirements:
55
87
  - - ">="
56
88
  - !ruby/object:Gem::Version
89
+ hash: 3
90
+ segments:
91
+ - 0
57
92
  version: "0"
58
- version:
59
93
  required_rubygems_version: !ruby/object:Gem::Requirement
94
+ none: false
60
95
  requirements:
61
96
  - - ">="
62
97
  - !ruby/object:Gem::Version
98
+ hash: 3
99
+ segments:
100
+ - 0
63
101
  version: "0"
64
- version:
65
102
  requirements:
66
103
  - rspec-1.2.6
67
104
  rubyforge_project: rspec-performance
68
- rubygems_version: 1.3.5
105
+ rubygems_version: 1.3.7
69
106
  signing_key:
70
107
  specification_version: 3
71
108
  summary: Ruby based make-like utility.
@@ -1 +0,0 @@
1
- require "spec/performance/client/http_client"
@@ -1,94 +0,0 @@
1
- require "net/http"
2
- require "cgi"
3
- require "spec/performance/client/response"
4
-
5
- module Spec
6
- module Performance
7
- module Client
8
- class HttpClient
9
- attr_writer :recording, :cookies
10
- attr_reader :base_uri, :cookies
11
-
12
- def initialize(base_uri)
13
- @base_uri = base_uri
14
- @headers = {}
15
- @cookies = {}
16
- @recording = true
17
- end
18
-
19
- def post(uri, params = {})
20
- request = Net::HTTP::Post.new(uri.path, headers)
21
- request.form_data = params
22
- request.basic_auth uri.user, uri.password if uri.user
23
- response = Net::HTTP.new(uri.host, uri.port).start do |http|
24
- http.request(request)
25
- end
26
- capture(response) if recording?
27
- create_http_client_response(response)
28
- end
29
-
30
- def get(uri, params = {})
31
- if params && params.size > 0
32
- query = params2query(params)
33
- uri = URI.parse("#{uri}?#{query}")
34
- end
35
-
36
- http = Net::HTTP.start(uri.host, uri.port)
37
- response = http.get(uri.request_uri, headers)
38
- http.finish
39
-
40
- create_http_client_response(response)
41
- end
42
-
43
- def add_header(key, value)
44
- @headers[key] = value
45
- end
46
-
47
- def remove_header(key)
48
- @headers.delete(key)
49
- end
50
-
51
- def recording?
52
- @recording
53
- end
54
-
55
- private
56
-
57
- def params2query(hash)
58
- q = hash.inject([]) do |acc, (k, v)|
59
- acc << CGI::escape(k.to_s) + "=" + CGI::escape(v.to_s)
60
- end.join("&")
61
- end
62
-
63
- def capture(response)
64
- if raw_cookies = response.get_fields("Set-Cookie")
65
- cookie_jar = raw_cookies.inject({}) do |parsed_cookies, raw_cookie_string|
66
- CGI::Cookie.parse(raw_cookie_string).each do |name, cookie|
67
- parsed_cookies[name.to_sym] = cookie
68
- end
69
- parsed_cookies
70
- end
71
- @cookies.merge!(cookie_jar)
72
- end
73
- end
74
-
75
- def headers
76
- @headers.merge("Cookie" => browser_cookies)
77
- end
78
-
79
- def browser_cookies
80
- cookies_to_send = @cookies.values.reject {|cookie| cookie.name == "path" || cookie.name == "domain" }
81
- cookies_to_send.map do |cookie|
82
- CGI::escape(cookie.name) + "=" + CGI::escape(cookie.value.first)
83
- end.join("; ")
84
- end
85
-
86
- def create_http_client_response(net_http_response)
87
- attributes = { :code => net_http_response.code,
88
- :body => net_http_response.body }
89
- Response.new(attributes)
90
- end
91
- end
92
- end
93
- end
94
- end
@@ -1,25 +0,0 @@
1
-
2
- module Spec
3
- module Performance
4
- module Client
5
-
6
- class Response
7
- attr_reader :code, :body, :cookies
8
-
9
- def initialize(attributes = {})
10
- @code = attributes[:code].to_i
11
- @body = attributes[:body]
12
- end
13
-
14
- def success?
15
- @code == 200
16
- end
17
-
18
- def redirect?
19
- @code == 301 || @code == 302
20
- end
21
- end
22
-
23
- end
24
- end
25
- end
@@ -1,112 +0,0 @@
1
- require "#{File.dirname(__FILE__)}/../../../../spec_helper"
2
-
3
- describe Spec::Performance::Client::HttpClient do
4
- attr_reader :client
5
-
6
- before do
7
- @client = Spec::Performance::Client::HttpClient.new("http://localhost")
8
- end
9
-
10
- describe "#initialize" do
11
- it "initializes the cookie jar" do
12
- client.cookies.should be_a(Hash)
13
- end
14
- end
15
-
16
- describe "#post" do
17
- attr_reader :uri, :params
18
- before do
19
- @uri = URI.join(IntegrationServer.base_url, "hello")
20
- @params = { :foo => "bar", :baz => "quux" }
21
- end
22
-
23
- it "makes an HTTP post" do
24
- mock.instance_of(Net::HTTP).request(anything) do |request|
25
- request.should be_a(Net::HTTP::Post)
26
- stub(Net::HTTPResponse.new(1.1, 200, nil)).body { "stubbed response body" }
27
- end
28
- client.post(uri, params).should be_success
29
- end
30
-
31
- it "returns a response object" do
32
- client.post(uri, params).should be_a(Spec::Performance::Client::Response)
33
- end
34
-
35
- describe "when the client is recording" do
36
- before do
37
- @uri = URI.join(IntegrationServer.base_url, "cookie_echo")
38
- client.should be_recording
39
- end
40
-
41
- it "captures the cookie from the response" do
42
- client.post(uri, params).should be_success
43
- client.cookies[:foo].value.first.should == "bar"
44
- client.cookies[:baz].value.first.should == "quux"
45
- end
46
- end
47
-
48
- describe "when the client is not recording" do
49
- before do
50
- @uri = URI.join(IntegrationServer.base_url, "cookie_echo")
51
- client.recording = false
52
- client.should_not be_recording
53
- end
54
-
55
- it "does not capture cookies" do
56
- client.post(uri, params).should be_success
57
- client.cookies.should_not have_key(:foo)
58
- client.cookies.should_not have_key(:baz)
59
- end
60
- end
61
- end
62
-
63
- describe "#get" do
64
- attr_reader :uri, :params
65
- before do
66
- @params = { :monster_truck => "Truckasaurus", :us_president => "Grover Cleveland" }
67
- @uri = URI.join(IntegrationServer.base_url, "hello")
68
- end
69
-
70
- it "sends an HTTP get request, sending the current cookies" do
71
- expected_cookie = CGI::Cookie.new("cookie-name", "cookie-value")
72
- expected_headers = { "Cookie" => "cookie-name=cookie-value" }
73
- client.cookies = { "cookie-name".to_sym => expected_cookie }
74
-
75
- mock_http = Object.new
76
- mock(Net::HTTP).start("localhost", 8888) { mock_http }
77
- mock(mock_http).get(anything, expected_headers) do |request_uri, headers|
78
- request_uri.index("/hello?").should == 0
79
- request_uri.should include("monster_truck=Truckasaurus")
80
- request_uri.should include("us_president=Grover+Cleveland")
81
- request_uri.should include("&")
82
-
83
- stub(Net::HTTPResponse.new(1.1, 200, nil)).body { "stubbed response body" }
84
- end
85
- mock(mock_http).finish
86
-
87
- response = client.get(uri, params)
88
- end
89
-
90
- it "returns a response object" do
91
- response = client.get(uri, params)
92
- response.should be_a(Spec::Performance::Client::Response)
93
- response.should be_success
94
- end
95
-
96
- describe "when the client is recording" do
97
- it "captures the cookie from the response" do
98
- end
99
- end
100
-
101
- describe "when the client is not recording" do
102
- it "does not capture" do
103
- end
104
- end
105
- end
106
-
107
- describe "#restore" do
108
- it "resets after each run" do
109
- end
110
- end
111
-
112
- end