sham_rack 1.1.2 → 1.2.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.
@@ -1,3 +1,7 @@
1
+ ## 27-Nov-2009 [mdub@dogbiscuit.org]
2
+
3
+ * Change of approach: extend rather than reimplement Net:HTTP. This should improve coverage of all the weird and wonderful ways of using the Net:HTTP API.
4
+
1
5
  ## 5-Jun-2009 [mdub@dogbiscuit.org]
2
6
 
3
7
  * Add support for Net::HTTP.get_response.
@@ -6,14 +6,16 @@ ShamRack plumbs Net:HTTP into [Rack][rack].
6
6
  What's it for, again?
7
7
  ---------------------
8
8
 
9
- Well, you can _test your HTTP client code_, using ShamRack to stub out an external web-service. Think of it as [FakeWeb][fakeweb] on steriods.
9
+ Well, it makes it easy to _stub out external (HTTP) services_, which is handy in development and testing environments, or when you want to _test your HTTP client code_.
10
10
 
11
- Or, you can _test your Rack application_ (or Sinatra, or Rails, or Merb) using arbitrary HTTP client libraries, to check interoperability. For instance, you could hit a local app using:
11
+ You can also use it to _test your Rack application_ (or Sinatra, or Rails, or Merb) using arbitrary HTTP client libraries, to check interoperability. For instance, you could test your app using:
12
12
 
13
13
  * [`rest-client`][rest-client]
14
14
  * [`httparty`][httparty]
15
15
  * [`oauth`][oauth]
16
16
 
17
+ all without having to boot it in a server.
18
+
17
19
  Installing it
18
20
  -------------
19
21
 
data/Rakefile CHANGED
@@ -1,6 +1,8 @@
1
1
  require "rubygems"
2
2
  require "rake"
3
3
 
4
+ require File.dirname(__FILE__) + "/lib/sham_rack/version.rb"
5
+
4
6
  require "spec/rake/spectask"
5
7
 
6
8
  task "default" => "spec"
@@ -10,21 +12,8 @@ Spec::Rake::SpecTask.new do |t|
10
12
  t.spec_files = FileList['spec/**/*_spec.rb']
11
13
  end
12
14
 
13
- require "jeweler"
14
-
15
- Jeweler::Tasks.new do |g|
16
- g.name = "sham_rack"
17
- g.summary = "Net::HTTP-to-Rack plumbing"
18
- g.email = "mdub@dogbiscuit.org"
19
- g.homepage = "http://github.com/mdub/sham_rack"
20
- g.description = "ShamRack plumbs Net::HTTP directly into Rack, for quick and easy HTTP testing."
21
- g.authors = ["Mike Williams"]
22
- g.rubyforge_project = "shamrack"
23
- end
24
-
25
- Jeweler::RubyforgeTasks.new
26
-
27
15
  require 'rake/rdoctask'
16
+
28
17
  Rake::RDocTask.new do |rdoc|
29
18
  if File.exist?('VERSION.yml')
30
19
  config = YAML.load(File.read('VERSION.yml'))
@@ -34,7 +23,36 @@ Rake::RDocTask.new do |rdoc|
34
23
  end
35
24
 
36
25
  rdoc.rdoc_dir = 'rdoc'
37
- rdoc.title = "ShamRack #{version}"
26
+ rdoc.title = "ShamRack #{ShamRack::VERSION}"
38
27
  rdoc.main = "ShamRack"
39
28
  rdoc.rdoc_files.include('lib/**/*.rb')
40
29
  end
30
+
31
+ def after_requiring(lib, options = {})
32
+ begin
33
+ require(lib)
34
+ rescue LoadError
35
+ gem_name = options[:gem] || lib
36
+ $stderr.puts "WARNING: can't load #{lib}. Install it with: sudo gem install #{gem_name}"
37
+ return false
38
+ end
39
+ yield
40
+ end
41
+
42
+ after_requiring "jeweler" do
43
+
44
+ Jeweler::Tasks.new do |g|
45
+ g.name = "sham_rack"
46
+ g.version = ShamRack::VERSION
47
+ g.summary = "Net::HTTP-to-Rack plumbing"
48
+ g.email = "mdub@dogbiscuit.org"
49
+ g.homepage = "http://github.com/mdub/sham_rack"
50
+ g.description = "ShamRack plumbs Net::HTTP directly into Rack, for quick and easy HTTP testing."
51
+ g.authors = ["Mike Williams"]
52
+ g.rubyforge_project = "shamrack"
53
+ end
54
+
55
+ Jeweler::GemcutterTasks.new
56
+ # Jeweler::RubyforgeTasks.new
57
+
58
+ end
@@ -0,0 +1,49 @@
1
+ require "rubygems"
2
+
3
+ require "pathname"
4
+ dir = Pathname(__FILE__).parent
5
+ $LOAD_PATH.unshift(dir.parent + "lib")
6
+
7
+ require dir + "hello_app"
8
+ require "sham_rack"
9
+ require "restclient"
10
+
11
+ # mount an instance of the app using ShamRack
12
+ ShamRack.mount(HelloApp.new, "hello.sham")
13
+
14
+ # run another instance in a separate process
15
+ server_pid = fork do
16
+ puts "Starting HTTP server on port 3333"
17
+ $stdout = File.new('/dev/null', 'w')
18
+ HelloApp.run!(:port => 3333)
19
+ end
20
+
21
+ at_exit do
22
+ puts "Killing HTTP server"
23
+ Process.kill("TERM", server_pid)
24
+ Process.wait(server_pid)
25
+ end
26
+
27
+ puts "Waiting for server to come up"
28
+ begin
29
+ puts RestClient.get("http://localhost:3333/hello/stranger")
30
+ rescue SystemCallError => e
31
+ retry
32
+ end
33
+
34
+ iterations = (ARGV.shift || 1000).to_i
35
+
36
+ %w(hello.sham localhost:3333).each do |site|
37
+
38
+ start = Time.now
39
+
40
+ iterations.times do
41
+ x = RestClient.get("http://#{site}/hello/stranger").to_s
42
+ end
43
+
44
+ elapsed_time = (Time.now - start)
45
+ requests_per_second = iterations / elapsed_time.to_f
46
+
47
+ printf "%-20s #{iterations} requests in %f; %f per second\n", site, elapsed_time, requests_per_second
48
+
49
+ end
@@ -0,0 +1,10 @@
1
+ require "rubygems"
2
+ require "sinatra/base"
3
+
4
+ class HelloApp < Sinatra::Base
5
+
6
+ get "/hello/:subject" do
7
+ "Hello, #{params[:subject]}"
8
+ end
9
+
10
+ end
@@ -5,3 +5,4 @@
5
5
  module ShamRack; end
6
6
 
7
7
  require "sham_rack/core_ext/net/http"
8
+ require "sham_rack/version"
@@ -2,16 +2,19 @@ require "net/http"
2
2
  require "sham_rack/registry"
3
3
  require "sham_rack/http"
4
4
 
5
- module Net
5
+ class << Net::HTTP
6
6
 
7
- def HTTP.new(address, port = nil, *proxy_args)
8
- port ||= HTTP.default_port
7
+ alias :new_without_sham_rack :new
8
+
9
+ def new(address, port = nil, *proxy_args)
10
+ port ||= Net::HTTP.default_port
9
11
  rack_app = ShamRack.application_for(address, port)
12
+ http_object = new_without_sham_rack(address, port, *proxy_args)
10
13
  if rack_app
11
- ShamRack::HTTP.new(address, port, rack_app)
12
- else
13
- super(address, port, *proxy_args)
14
+ http_object.extend(ShamRack::HTTP::Extensions)
15
+ http_object.rack_app = rack_app
14
16
  end
17
+ http_object
15
18
  end
16
19
 
17
- end
20
+ end
@@ -1,120 +1,101 @@
1
1
  module ShamRack
2
-
3
- # a sham version of Net::HTTP
4
- class HTTP
5
-
6
- def initialize(address, port, rack_app)
7
- @address = address
8
- @port = port
9
- @rack_app = rack_app
10
- end
11
2
 
12
- attr_reader :address, :port, :rack_app
13
-
14
- attr_accessor :read_timeout, :open_timeout
15
- attr_accessor :use_ssl,:key, :cert, :ca_file, :ca_path, :verify_mode, :verify_callback, :verify_depth, :cert_store
3
+ module HTTP
16
4
 
17
- def start
18
- yield self
19
- end
5
+ module Extensions
20
6
 
21
- def request(req, body = nil)
22
- env = default_env
23
- env.merge!(path_env(req.path))
24
- env.merge!(method_env(req))
25
- env.merge!(header_env(req))
26
- env.merge!(io_env(req, body))
27
- response = build_response(@rack_app.call(env))
28
- yield response if block_given?
29
- return response
30
- end
31
-
32
- def request_get(path, initheader = nil, &block)
33
- request Net::HTTP::Get.new(path, initheader), &block
34
- end
7
+ attr_accessor :rack_app
35
8
 
36
- def request_head(path, initheader = nil, &block)
37
- request Net::HTTP::Head.new(path, initheader), &block
38
- end
9
+ attr_accessor :read_timeout, :open_timeout
10
+ attr_accessor :use_ssl,:key, :cert, :ca_file, :ca_path, :verify_mode, :verify_callback, :verify_depth, :cert_store
39
11
 
40
- def request_post(path, data, initheader = nil, &block)
41
- request Net::HTTP::Post.new(path, initheader), data, &block
42
- end
12
+ def start
13
+ yield self
14
+ end
43
15
 
44
- def request_put(path, data, initheader = nil, &block)
45
- request Net::HTTP::Put.new(path, initheader), data, &block
46
- end
16
+ def request(req, body = nil)
17
+ env = default_env
18
+ env.merge!(path_env(req.path))
19
+ env.merge!(method_env(req))
20
+ env.merge!(header_env(req))
21
+ env.merge!(io_env(req, body))
22
+ response = build_response(@rack_app.call(env))
23
+ yield response if block_given?
24
+ return response
25
+ end
47
26
 
48
- private
49
-
50
- def default_env
51
- {
52
- "SCRIPT_NAME" => "",
53
- "SERVER_NAME" => @address,
54
- "SERVER_PORT" => @port.to_s,
55
- "rack.version" => [0,1],
56
- "rack.url_scheme" => "http",
57
- "rack.multithread" => true,
58
- "rack.multiprocess" => true,
59
- "rack.run_once" => false
60
- }
61
- end
62
-
63
- def method_env(request)
64
- {
65
- "REQUEST_METHOD" => request.method
66
- }
67
- end
68
-
69
- def io_env(request, body)
70
- raise(ArgumentError, "both request.body and body argument were provided") if (request.body && body)
71
- body ||= request.body || ""
72
- {
73
- "rack.input" => StringIO.new(body),
74
- "rack.errors" => $stderr
75
- }
76
- end
77
-
78
- def path_env(path)
79
- uri = URI.parse(path)
80
- {
81
- "PATH_INFO" => uri.path,
82
- "QUERY_STRING" => (uri.query || ""),
83
- }
84
- end
85
-
86
- def header_env(request)
87
- result = {}
88
- request.each do |header, content|
89
- result["HTTP_" + header.upcase.gsub('-', '_')] = content
27
+ private
28
+
29
+ def default_env
30
+ {
31
+ "SCRIPT_NAME" => "",
32
+ "SERVER_NAME" => @address,
33
+ "SERVER_PORT" => @port.to_s,
34
+ "rack.version" => [0,1],
35
+ "rack.url_scheme" => "http",
36
+ "rack.multithread" => true,
37
+ "rack.multiprocess" => true,
38
+ "rack.run_once" => false
39
+ }
90
40
  end
91
- %w(TYPE LENGTH).each do |x|
92
- result["CONTENT_#{x}"] = result.delete("HTTP_CONTENT_#{x}") if result.has_key?("HTTP_CONTENT_#{x}")
41
+
42
+ def method_env(request)
43
+ {
44
+ "REQUEST_METHOD" => request.method
45
+ }
93
46
  end
94
- return result
95
- end
96
-
97
- def build_response(rack_response)
98
- status, headers, body = rack_response
99
- code, message = status.to_s.split(" ", 2)
100
- response = Net::HTTPResponse.send(:response_class, code).new("Sham", code, message)
101
- response.instance_variable_set(:@body, assemble_body(body))
102
- response.instance_variable_set(:@read, true)
103
- headers.each do |k,v|
104
- response.add_field(k, v)
47
+
48
+ def io_env(request, body)
49
+ raise(ArgumentError, "both request.body and body argument were provided") if (request.body && body)
50
+ body ||= request.body || ""
51
+ {
52
+ "rack.input" => StringIO.new(body),
53
+ "rack.errors" => $stderr
54
+ }
55
+ end
56
+
57
+ def path_env(path)
58
+ uri = URI.parse(path)
59
+ {
60
+ "PATH_INFO" => uri.path,
61
+ "QUERY_STRING" => (uri.query || ""),
62
+ }
63
+ end
64
+
65
+ def header_env(request)
66
+ result = {}
67
+ request.each do |header, content|
68
+ result["HTTP_" + header.upcase.gsub('-', '_')] = content
69
+ end
70
+ %w(TYPE LENGTH).each do |x|
71
+ result["CONTENT_#{x}"] = result.delete("HTTP_CONTENT_#{x}") if result.has_key?("HTTP_CONTENT_#{x}")
72
+ end
73
+ return result
74
+ end
75
+
76
+ def build_response(rack_response)
77
+ status, headers, body = rack_response
78
+ code, message = status.to_s.split(" ", 2)
79
+ response = Net::HTTPResponse.send(:response_class, code).new("Sham", code, message)
80
+ response.instance_variable_set(:@body, assemble_body(body))
81
+ response.instance_variable_set(:@read, true)
82
+ headers.each do |k,v|
83
+ response.add_field(k, v)
84
+ end
85
+ response.extend ShamRack::ResponseExtensions
86
+ return response
87
+ end
88
+
89
+ def assemble_body(body)
90
+ content = ""
91
+ body.each { |fragment| content << fragment }
92
+ return content
105
93
  end
106
- response.extend ShamRack::ResponseExtensions
107
- return response
108
- end
109
94
 
110
- def assemble_body(body)
111
- content = ""
112
- body.each { |fragment| content << fragment }
113
- return content
114
95
  end
115
-
96
+
116
97
  end
117
-
98
+
118
99
  module ResponseExtensions
119
100
 
120
101
  def read_body(dest = nil)
@@ -122,7 +103,7 @@ module ShamRack
122
103
  dest << @body if dest
123
104
  return @body
124
105
  end
125
-
106
+
126
107
  end
127
108
 
128
109
  end
@@ -0,0 +1,3 @@
1
+ module ShamRack
2
+ VERSION = "1.2.0"
3
+ end
@@ -1,12 +1,15 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
1
4
  # -*- encoding: utf-8 -*-
2
5
 
3
6
  Gem::Specification.new do |s|
4
7
  s.name = %q{sham_rack}
5
- s.version = "1.1.2"
8
+ s.version = "1.2.0"
6
9
 
7
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
11
  s.authors = ["Mike Williams"]
9
- s.date = %q{2009-06-05}
12
+ s.date = %q{2009-11-27}
10
13
  s.description = %q{ShamRack plumbs Net::HTTP directly into Rack, for quick and easy HTTP testing.}
11
14
  s.email = %q{mdub@dogbiscuit.org}
12
15
  s.extra_rdoc_files = [
@@ -17,21 +20,22 @@ Gem::Specification.new do |s|
17
20
  "CHANGES.markdown",
18
21
  "README.markdown",
19
22
  "Rakefile",
20
- "VERSION.yml",
23
+ "benchmark/benchmark.rb",
24
+ "benchmark/hello_app.rb",
21
25
  "lib/sham_rack.rb",
22
26
  "lib/sham_rack/core_ext/net/http.rb",
23
27
  "lib/sham_rack/http.rb",
24
28
  "lib/sham_rack/registry.rb",
29
+ "lib/sham_rack/version.rb",
25
30
  "sham_rack.gemspec",
26
31
  "spec/sham_rack_spec.rb",
27
32
  "spec/spec_helper.rb"
28
33
  ]
29
- s.has_rdoc = true
30
34
  s.homepage = %q{http://github.com/mdub/sham_rack}
31
35
  s.rdoc_options = ["--charset=UTF-8"]
32
36
  s.require_paths = ["lib"]
33
37
  s.rubyforge_project = %q{shamrack}
34
- s.rubygems_version = %q{1.3.2}
38
+ s.rubygems_version = %q{1.3.5}
35
39
  s.summary = %q{Net::HTTP-to-Rack plumbing}
36
40
  s.test_files = [
37
41
  "spec/sham_rack_spec.rb",
@@ -48,3 +52,4 @@ Gem::Specification.new do |s|
48
52
  else
49
53
  end
50
54
  end
55
+
@@ -238,6 +238,17 @@ describe ShamRack do
238
238
 
239
239
  end
240
240
 
241
+ it "supports POST using Net::HTTP" do
242
+
243
+ Net::HTTP.start("env.xyz") do |http|
244
+ http.post("/resource", "q=rack")
245
+ end
246
+
247
+ env["REQUEST_METHOD"].should == "POST"
248
+ env["rack.input"].read.should == "q=rack"
249
+
250
+ end
251
+
241
252
  it "supports PUT" do
242
253
 
243
254
  RestClient.put("http://env.xyz/thing1", "stuff", :content_type => "text/plain")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sham_rack
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Williams
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-06-05 00:00:00 +10:00
12
+ date: 2009-11-27 00:00:00 +11:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -26,11 +26,13 @@ files:
26
26
  - CHANGES.markdown
27
27
  - README.markdown
28
28
  - Rakefile
29
- - VERSION.yml
29
+ - benchmark/benchmark.rb
30
+ - benchmark/hello_app.rb
30
31
  - lib/sham_rack.rb
31
32
  - lib/sham_rack/core_ext/net/http.rb
32
33
  - lib/sham_rack/http.rb
33
34
  - lib/sham_rack/registry.rb
35
+ - lib/sham_rack/version.rb
34
36
  - sham_rack.gemspec
35
37
  - spec/sham_rack_spec.rb
36
38
  - spec/spec_helper.rb
@@ -58,7 +60,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
58
60
  requirements: []
59
61
 
60
62
  rubyforge_project: shamrack
61
- rubygems_version: 1.3.2
63
+ rubygems_version: 1.3.5
62
64
  signing_key:
63
65
  specification_version: 3
64
66
  summary: Net::HTTP-to-Rack plumbing
@@ -1,4 +0,0 @@
1
- ---
2
- :major: 1
3
- :minor: 1
4
- :patch: 2