alice 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -9,17 +9,17 @@ question is, Who in the world am I?
9
9
 
10
10
  == Usage
11
11
 
12
- conn = Alice::Connection.new(:url => 'http://sushi.com') do
13
- use Alice::Request::Yajl # convert body to json with Yajl lib
14
- use Alice::Adapter::Logger # log the request somewhere?
15
- use Alice::Adapter::Typhoeus # make http request with typhoeus
16
- use Alice::Response::Yajl # # parse body with yajl
12
+ conn = Alice::Connection.new(:url => 'http://sushi.com') do |builder|
13
+ builder.use Alice::Request::Yajl # convert body to json with Yajl lib
14
+ builder.use Alice::Adapter::Logger # log the request somewhere?
15
+ builder.use Alice::Adapter::Typhoeus # make http request with typhoeus
16
+ builder.use Alice::Response::Yajl # # parse body with yajl
17
17
 
18
18
  # or use shortcuts
19
- request :yajl # Alice::Request::Yajl
20
- adapter :logger # Alice::Adapter::Logger
21
- adapter :typhoeus # Alice::Adapter::Typhoeus
22
- response :yajl # Alice::Response::Yajl
19
+ builder.request :yajl # Alice::Request::Yajl
20
+ builder.adapter :logger # Alice::Adapter::Logger
21
+ builder.adapter :typhoeus # Alice::Adapter::Typhoeus
22
+ builder.response :yajl # Alice::Response::Yajl
23
23
  end
24
24
 
25
25
  resp1 = conn.get '/nigiri/sake.json'
@@ -31,16 +31,30 @@ question is, Who in the world am I?
31
31
 
32
32
  == Testing
33
33
 
34
- test = Alice::Connection.new do
35
- adapter :test do |stub|
36
- stub.get '/nigiri/sake.json' do
37
- [200, {}, 'hi world']
38
- end
34
+ # It's possible to define stubbed request outside a test adapter block.
35
+ stubs = Alice::Test::Stubs.new do |stub|
36
+ stub.get('/tamago') { [200, 'egg', {} }
37
+ end
38
+
39
+ # You can pass stubbed request to the test adapter or define them in a block
40
+ # or a combination of the two.
41
+ test = Alice::Connection.new do |builder|
42
+ builder.adapter :test, stubs do |stub|
43
+ stub.get('/ebi') {[ 200, 'shrimp', {} ]}
39
44
  end
40
45
  end
41
46
 
42
- resp = test.get '/nigiri/sake.json'
43
- resp.body # => 'hi world'
47
+ # It's also possible to stub additional requests after the connection has
48
+ # been initialized. This is useful for testing.
49
+ stubs.get('/uni') {[ 200, 'urchin', {} ]}
50
+
51
+ resp = test.get '/tamago'
52
+ resp.body # => 'egg'
53
+ resp = test.get '/ebi'
54
+ resp.body # => 'shrimp'
55
+ resp = test.get '/uni'
56
+ resp.body # => 'urchin'
57
+ resp = test.get '/else' #=> raises "no such stub" error
44
58
 
45
59
  == Note on Patches/Pull Requests
46
60
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.1.1
@@ -0,0 +1,87 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{alice}
8
+ s.version = "0.1.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["rick"]
12
+ s.date = %q{2010-01-07}
13
+ s.description = %q{HTTP/REST API client library using Rack-like middleware}
14
+ s.email = %q{technoweenie@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "alice.gemspec",
27
+ "lib/alice.rb",
28
+ "lib/alice/adapter/net_http.rb",
29
+ "lib/alice/adapter/patron.rb",
30
+ "lib/alice/adapter/test.rb",
31
+ "lib/alice/adapter/typhoeus.rb",
32
+ "lib/alice/builder.rb",
33
+ "lib/alice/connection.rb",
34
+ "lib/alice/error.rb",
35
+ "lib/alice/middleware.rb",
36
+ "lib/alice/request.rb",
37
+ "lib/alice/request/active_support_json.rb",
38
+ "lib/alice/request/yajl.rb",
39
+ "lib/alice/response.rb",
40
+ "lib/alice/response/active_support_json.rb",
41
+ "lib/alice/response/yajl.rb",
42
+ "test/adapters/live_test.rb",
43
+ "test/adapters/test_middleware_test.rb",
44
+ "test/adapters/typhoeus_test.rb",
45
+ "test/connection_app_test.rb",
46
+ "test/connection_test.rb",
47
+ "test/env_test.rb",
48
+ "test/helper.rb",
49
+ "test/live_server.rb",
50
+ "test/request_middleware_test.rb",
51
+ "test/response_middleware_test.rb"
52
+ ]
53
+ s.homepage = %q{http://github.com/technoweenie/alice}
54
+ s.rdoc_options = ["--charset=UTF-8"]
55
+ s.require_paths = ["lib"]
56
+ s.rubygems_version = %q{1.3.5}
57
+ s.summary = %q{HTTP/REST API client library using Rack-like middleware}
58
+ s.test_files = [
59
+ "test/adapters/live_test.rb",
60
+ "test/adapters/test_middleware_test.rb",
61
+ "test/adapters/typhoeus_test.rb",
62
+ "test/connection_app_test.rb",
63
+ "test/connection_test.rb",
64
+ "test/env_test.rb",
65
+ "test/helper.rb",
66
+ "test/live_server.rb",
67
+ "test/request_middleware_test.rb",
68
+ "test/response_middleware_test.rb"
69
+ ]
70
+
71
+ if s.respond_to? :specification_version then
72
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
73
+ s.specification_version = 3
74
+
75
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
76
+ s.add_runtime_dependency(%q<rack>, [">= 0"])
77
+ s.add_runtime_dependency(%q<addressable>, [">= 0"])
78
+ else
79
+ s.add_dependency(%q<rack>, [">= 0"])
80
+ s.add_dependency(%q<addressable>, [">= 0"])
81
+ end
82
+ else
83
+ s.add_dependency(%q<rack>, [">= 0"])
84
+ s.add_dependency(%q<addressable>, [">= 0"])
85
+ end
86
+ end
87
+
@@ -12,6 +12,8 @@ module Alice
12
12
  # resp.body # => 'hi world'
13
13
  #
14
14
  class Test < Middleware
15
+ attr_accessor :stubs
16
+
15
17
  def self.loaded?() false end
16
18
 
17
19
  class Stubs
@@ -25,44 +27,46 @@ module Alice
25
27
  @stack.empty?
26
28
  end
27
29
 
28
- def match(request_method, path)
30
+ def match(request_method, path, body)
29
31
  return false if !@stack.key?(request_method)
30
- @stack[request_method].detect { |stub| stub.matches?(path) }
32
+ stub = @stack[request_method].detect { |stub| stub.matches?(path, body) }
33
+ @stack[request_method].delete stub
31
34
  end
32
35
 
33
36
  def get(path, &block)
34
- new_stub(:get, path, block)
37
+ new_stub(:get, path, &block)
35
38
  end
36
39
 
37
40
  def head(path, &block)
38
- new_stub(:head, path, block)
41
+ new_stub(:head, path, &block)
39
42
  end
40
43
 
41
- def post(path, &block)
42
- new_stub(:post, path, block)
44
+ def post(path, body, &block)
45
+ new_stub(:post, path, body, &block)
43
46
  end
44
47
 
45
- def put(path, &block)
46
- new_stub(:put, path, block)
48
+ def put(path, body, &block)
49
+ new_stub(:put, path, body, &block)
47
50
  end
48
51
 
49
52
  def delete(path, &block)
50
- new_stub(:delete, path, block)
53
+ new_stub(:delete, path, &block)
51
54
  end
52
55
 
53
- def new_stub(request_method, path, block)
54
- (@stack[request_method] ||= []) << Stub.new(path, block)
56
+ def new_stub(request_method, path, body=nil, &block)
57
+ (@stack[request_method] ||= []) << Stub.new(path, body, block)
55
58
  end
56
59
  end
57
60
 
58
- class Stub < Struct.new(:path, :block)
59
- def matches?(request_path)
60
- request_path == path
61
+ class Stub < Struct.new(:path, :body, :block)
62
+ def matches?(request_path, request_body)
63
+ request_path == path && request_body == body
61
64
  end
62
65
  end
63
66
 
64
- def initialize app, &block
67
+ def initialize app, stubs=nil, &block
65
68
  super(app)
69
+ @stubs = stubs || Stubs.new
66
70
  configure(&block) if block
67
71
  end
68
72
 
@@ -70,25 +74,18 @@ module Alice
70
74
  yield stubs
71
75
  end
72
76
 
73
- def stubs
74
- @stubs ||= Stubs.new
75
- end
76
-
77
77
  def call(env)
78
- if stub = stubs.match(env[:method], env[:url].path)
78
+ if stub = stubs.match(env[:method], env[:url].path, env[:body])
79
79
  status, headers, body = stub.block.call(env)
80
80
  env.update \
81
81
  :status => status,
82
82
  :response_headers => headers,
83
83
  :body => body
84
84
  else
85
- env.update \
86
- :status => 404,
87
- :response_headers => {},
88
- :body => 'no stubbed requests'
85
+ raise "no stubbed request for #{env[:method]} #{env[:url].path} with #{env[:body]}"
89
86
  end
90
87
  @app.call(env)
91
88
  end
92
89
  end
93
90
  end
94
- end
91
+ end
@@ -1,5 +1,3 @@
1
- require 'rack/builder'
2
-
3
1
  module Alice
4
2
  # Possibly going to extend this a bit.
5
3
  #
@@ -8,7 +6,9 @@ module Alice
8
6
  # adapter :logger # Alice::Adapter::Logger
9
7
  # response :yajl # Alice::Response::Yajl
10
8
  # end
11
- class Builder < Rack::Builder
9
+ class Builder
10
+ attr_accessor :handlers
11
+
12
12
  def self.create_with_inner_app(&block)
13
13
  inner = lambda do |env|
14
14
  if !env[:parallel_manager]
@@ -20,6 +20,24 @@ module Alice
20
20
  Builder.new(&block).tap { |builder| builder.run(inner) }
21
21
  end
22
22
 
23
+ def initialize
24
+ @handlers = []
25
+ yield self
26
+ end
27
+
28
+ def run app
29
+ @handlers.unshift app
30
+ end
31
+
32
+ def to_app
33
+ inner_app = @handlers.first
34
+ @handlers[1..-1].inject(inner_app) { |app, middleware| middleware.call(app) }
35
+ end
36
+
37
+ def use klass, *args, &block
38
+ @handlers.unshift(lambda { |app| klass.new(app, *args, &block) })
39
+ end
40
+
23
41
  def request(key, *args, &block)
24
42
  use_symbol Alice::Request, key, *args, &block
25
43
  end
@@ -36,4 +54,4 @@ module Alice
36
54
  use mod.lookup_module(key), *args, &block
37
55
  end
38
56
  end
39
- end
57
+ end
@@ -19,6 +19,7 @@ module Alice
19
19
  end
20
20
 
21
21
  extend AutoloadHelper
22
+
22
23
  autoload_all 'alice/response',
23
24
  :Yajl => 'yajl',
24
25
  :ActiveSupportJson => 'active_support_json'
@@ -4,11 +4,11 @@ module Adapters
4
4
  class TestMiddleware < Alice::TestCase
5
5
  describe "Test Middleware with simple path" do
6
6
  before :all do
7
- @conn = Alice::Connection.new do
8
- adapter :test do |stub|
9
- stub.get('/hello') { [200, {'Content-Type' => 'text/html'}, 'hello'] }
10
- end
7
+ @stubs = Alice::Adapter::Test::Stubs.new
8
+ @conn = Alice::Connection.new do |builder|
9
+ builder.adapter :test, @stubs
11
10
  end
11
+ @stubs.get('/hello') { [200, {'Content-Type' => 'text/html'}, 'hello'] }
12
12
  @resp = @conn.get('/hello')
13
13
  end
14
14
 
@@ -25,4 +25,4 @@ module Adapters
25
25
  end
26
26
  end
27
27
  end
28
- end
28
+ end
@@ -23,24 +23,21 @@ class TestConnectionApps < Alice::TestCase
23
23
  end
24
24
 
25
25
  before do
26
- @conn = Alice::Connection.new do
27
- use TestMiddleWare
28
- use TestAdapter
29
- end
30
- class << @conn.builder
31
- attr_reader :ins
26
+ @conn = Alice::Connection.new do |b|
27
+ b.use TestMiddleWare
28
+ b.use TestAdapter
32
29
  end
33
30
  end
34
31
 
35
32
  describe "#builder" do
36
33
  it "is built from Alice::Connection constructor" do
37
- assert_kind_of Rack::Builder, @conn.builder
38
- assert_equal 3, @conn.builder.ins.size
34
+ assert_kind_of Alice::Builder, @conn.builder
35
+ assert_equal 3, @conn.builder.handlers.size
39
36
  end
40
37
 
41
38
  it "adds middleware to the Builder stack" do
42
- assert_kind_of TestMiddleWare, @conn.builder.ins[0].call(nil)
43
- assert_kind_of TestAdapter, @conn.builder.ins[1].call(nil)
39
+ assert_kind_of TestMiddleWare, @conn.builder.handlers[2].call(nil)
40
+ assert_kind_of TestAdapter, @conn.builder.handlers[1].call(nil)
44
41
  end
45
42
  end
46
43
 
@@ -6,9 +6,9 @@ class RequestMiddlewareTest < Alice::TestCase
6
6
  encoder = Alice::Request.lookup_module(key)
7
7
  next if !encoder.loaded?
8
8
  it "uses #{encoder}" do
9
- @connection = Alice::Connection.new do
10
- use encoder
11
- adapter :test do |stub|
9
+ @connection = Alice::Connection.new do |b|
10
+ b.use encoder
11
+ b.adapter :test do |stub|
12
12
  stub.post('echo_body') { |env| [200, {'Content-Type' => 'text/html'}, env[:body]] }
13
13
  end
14
14
  end
@@ -16,4 +16,4 @@ class RequestMiddlewareTest < Alice::TestCase
16
16
  end
17
17
  end
18
18
  end
19
- end
19
+ end
@@ -6,14 +6,14 @@ class ResponseMiddlewareTest < Alice::TestCase
6
6
  parser = Alice::Response.lookup_module(key)
7
7
  next if !parser.loaded?
8
8
  it "uses #{parser}" do
9
- @connection = Alice::Connection.new do
10
- adapter :test do |stub|
9
+ @connection = Alice::Connection.new do |b|
10
+ b.adapter :test do |stub|
11
11
  stub.get('json') { [200, {'Content-Type' => 'text/html'}, "[1,2,3]"] }
12
12
  end
13
- use parser
13
+ b.use parser
14
14
  end
15
15
  assert_equal [1,2,3], @connection.get('json').body
16
16
  end
17
17
  end
18
18
  end
19
- end
19
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alice
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - rick
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-01-03 00:00:00 -08:00
12
+ date: 2010-01-07 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -48,6 +48,7 @@ files:
48
48
  - README.rdoc
49
49
  - Rakefile
50
50
  - VERSION
51
+ - alice.gemspec
51
52
  - lib/alice.rb
52
53
  - lib/alice/adapter/net_http.rb
53
54
  - lib/alice/adapter/patron.rb