rspec-performance 0.0.3 → 0.1.0

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.
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