sk-hoth 0.0.1 → 0.3.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 (47) hide show
  1. data/README.rdoc +69 -39
  2. data/THANKS.md +9 -0
  3. data/TODO +2 -0
  4. data/lib/hoth/encoding/json.rb +28 -0
  5. data/lib/hoth/encoding/no_op.rb +19 -0
  6. data/lib/hoth/endpoint.rb +28 -0
  7. data/lib/hoth/exceptions.rb +14 -0
  8. data/lib/hoth/extension/core/exception.rb +15 -0
  9. data/lib/hoth/modules.rb +27 -0
  10. data/lib/hoth/providers/bertrpc_provider.rb +35 -0
  11. data/lib/hoth/providers/rack_provider.rb +45 -0
  12. data/lib/hoth/service.rb +50 -0
  13. data/lib/hoth/service_definition.rb +18 -0
  14. data/lib/hoth/service_module.rb +49 -0
  15. data/lib/hoth/service_registry.rb +34 -0
  16. data/lib/hoth/services.rb +51 -0
  17. data/lib/hoth/transport/base.rb +19 -0
  18. data/lib/hoth/transport/bert.rb +87 -0
  19. data/lib/hoth/transport/http.rb +41 -0
  20. data/lib/hoth/transport/http_hmac.rb +37 -0
  21. data/lib/hoth/transport/workling.rb +23 -0
  22. data/lib/hoth/transport.rb +48 -0
  23. data/lib/hoth/util/logger.rb +46 -0
  24. data/lib/hoth.rb +56 -0
  25. data/spec/spec_helper.rb +7 -26
  26. data/spec/unit/encoding/json_spec.rb +25 -0
  27. data/spec/unit/endpoint_spec.rb +34 -0
  28. data/spec/unit/extension/core/exception_spec.rb +34 -0
  29. data/spec/unit/hoth_spec.rb +30 -0
  30. data/spec/unit/providers/rack_provider_spec.rb +49 -0
  31. data/spec/unit/service_definition_spec.rb +21 -0
  32. data/spec/unit/service_module_spec.rb +59 -0
  33. data/spec/unit/service_spec.rb +77 -0
  34. data/spec/unit/transport/base_spec.rb +43 -0
  35. data/spec/unit/transport/http_hmac_spec.rb +44 -0
  36. data/spec/unit/transport/http_spec.rb +73 -0
  37. data/spec/unit/transport/workling_spec.rb +42 -0
  38. data/spec/unit/transport_spec.rb +29 -0
  39. metadata +86 -23
  40. data/lib/king_soa/rack/middleware.rb +0 -47
  41. data/lib/king_soa/registry.rb +0 -55
  42. data/lib/king_soa/service.rb +0 -88
  43. data/lib/king_soa.rb +0 -56
  44. data/spec/king_soa/rack/middleware_spec.rb +0 -36
  45. data/spec/king_soa/registry_spec.rb +0 -28
  46. data/spec/king_soa/service_spec.rb +0 -46
  47. data/spec/server/app.rb +0 -26
@@ -0,0 +1,41 @@
1
+ require 'net/http'
2
+
3
+ module Hoth
4
+ module Transport
5
+ class Http < Base
6
+ def call_remote_with(*params)
7
+ begin
8
+ handle_response post_payload(params)
9
+ rescue Exception => e
10
+ raise TransportError.wrap(e)
11
+ end
12
+ end
13
+
14
+ def handle_response(response)
15
+ case response
16
+ when Net::HTTPSuccess
17
+ Hoth::Logger.debug "response.body: #{response.body}"
18
+ encoder.decode(response.body)["result"]
19
+ when Net::HTTPServerError
20
+ begin
21
+ Hoth::Logger.debug "response.body: #{response.body}"
22
+ raise encoder.decode(response.body)["error"]
23
+ rescue JSON::ParserError => jpe
24
+ raise TransportError.wrap(jpe)
25
+ end
26
+ when Net::HTTPRedirection, Net::HTTPClientError, Net::HTTPInformation, Net::HTTPUnknownResponse
27
+ raise NotImplementedError, "code: #{response.code}, message: #{response.body}"
28
+ end
29
+ end
30
+
31
+ def post_payload(payload)
32
+ uri = URI.parse(self.endpoint.to_url)
33
+ return Net::HTTP.post_form(uri,
34
+ 'name' => self.name.to_s,
35
+ 'params' => encoder.encode(payload)
36
+ )
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,37 @@
1
+ require 'king_hmac'
2
+ require 'net/http'
3
+ module Hoth
4
+ module Transport
5
+ class HttpHmac < Http
6
+ attr_accessor :hmac_access_id, :hmac_secret
7
+ # just for testing request
8
+ attr_accessor :req
9
+ # Manually construct the HTTP request because it needs to be signed with
10
+ # hmac before.
11
+ # This function is more or less a copy of HTTP.post_form
12
+ # == Prerequisites
13
+ # you must set both instance variables: hmac_access_id, hmac_secret before
14
+ # the call can be made
15
+ # === Returns
16
+ # <Object>:. Net::HTTPResponse
17
+ def post_payload(payload)
18
+ raise TransportError, 'no hmac credentials set for hmac transport' unless hmac_access_id && hmac_secret
19
+ uri = URI.parse(self.endpoint.to_url)
20
+ # construct request object
21
+ self.req = Net::HTTP::Post.new(uri.path)
22
+ # add its form data
23
+ self.req.form_data = {'name' => self.name.to_s,
24
+ 'params' => encoder.encode(payload) }
25
+ # ensure a date header is set, needed for hmac
26
+ self.req['Date'] = Time.now.httpdate if self.req['Date'].nil?
27
+ # sign request object => set Authorisation header
28
+ KingHmac::Auth.sign!(self.req, hmac_access_id, hmac_secret)
29
+ # go for it
30
+ return Net::HTTP.new(uri.host, uri.port).start {|http|
31
+ http.request(self.req)
32
+ }
33
+ end
34
+
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,23 @@
1
+ begin
2
+ require 'simple_publisher'
3
+ rescue LoadError
4
+ STDERR.puts "You need the simple_publisher gem if you want to use Workling/Starling transport."
5
+ end
6
+
7
+ module Hoth
8
+ module Transport
9
+
10
+ class Workling < Base
11
+
12
+ def call_remote_with(*args)
13
+ topic = SimplePublisher::Topic.new(:name => "#{self.module.name.to_s.underscore}_subscribers__#{name.to_s.underscore}")
14
+ connection = SimplePublisher::StarlingConnection.new(:host => endpoint.host, :port => endpoint.port)
15
+
16
+ publisher = SimplePublisher::Publisher.new(:topic => topic, :connection => connection)
17
+ publisher.publish(encoder.encode(args))
18
+ end
19
+
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,48 @@
1
+ require 'hoth/transport/base'
2
+ require 'hoth/transport/http'
3
+ require 'hoth/transport/http_hmac'
4
+ require 'hoth/transport/bert'
5
+ require 'hoth/transport/workling'
6
+
7
+ require 'hoth/encoding/json'
8
+ require 'hoth/encoding/no_op'
9
+
10
+ module Hoth
11
+ module Transport
12
+
13
+ POSSIBLE_TRANSPORTS = {
14
+ :json_via_http => {
15
+ :transport_class => Transport::Http,
16
+ :encoder => Encoding::Json
17
+ },
18
+ :http => :json_via_http,
19
+ :json_via_http_hmac => {
20
+ :transport_class => Transport::HttpHmac,
21
+ :encoder => Encoding::Json
22
+ },
23
+ :http_hmac => :json_via_http_hmac,
24
+ :workling => {
25
+ :transport_class => Transport::Workling
26
+ }
27
+ }
28
+
29
+ class <<self
30
+ def create(transport_name, service)
31
+ new_transport_with_encoding(transport_name, service)
32
+ end
33
+
34
+ def new_transport_with_encoding(transport_name, service)
35
+ if POSSIBLE_TRANSPORTS[transport_name.to_sym]
36
+ if POSSIBLE_TRANSPORTS[transport_name.to_sym].kind_of?(Hash)
37
+ POSSIBLE_TRANSPORTS[transport_name.to_sym][:transport_class].new(service, :encoder => POSSIBLE_TRANSPORTS[transport_name.to_sym][:encoder])
38
+ else
39
+ new_transport_with_encoding(POSSIBLE_TRANSPORTS[transport_name.to_sym], service)
40
+ end
41
+ else
42
+ raise TransportException.new("specified transport '#{transport_name}' does not exist, use one of these: #{POSSIBLE_TRANSPORTS.keys.join(", ")}")
43
+ end
44
+ end
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,46 @@
1
+ module Hoth
2
+ class Logger
3
+ class <<self
4
+
5
+ def log_provider=(log_provider)
6
+ @log_provider = log_provider
7
+ end
8
+
9
+ def init_logging!
10
+ Hoth::Logger.log_provider = if Object.const_defined?("Rails")
11
+ Rails.logger
12
+ else
13
+ require 'logger'
14
+ ::Logger.new("/tmp/hoth.log")
15
+ end
16
+ end
17
+
18
+ def debug(msg)
19
+ log_provider.debug msg
20
+ end
21
+
22
+ def info(msg)
23
+ log_provider.info msg
24
+ end
25
+
26
+ def warn(msg)
27
+ log_provider.warn msg
28
+ end
29
+
30
+ def error(msg)
31
+ log_provider.error msg
32
+ end
33
+
34
+ def fatal(msg)
35
+ log_provider.fatal msg
36
+ end
37
+
38
+ private
39
+
40
+ def log_provider
41
+ @log_provider || init_logging!
42
+ end
43
+ end
44
+
45
+ end
46
+ end
data/lib/hoth.rb ADDED
@@ -0,0 +1,56 @@
1
+ require 'singleton'
2
+
3
+ require 'active_support/inflector'
4
+
5
+ # must be loaded after alls transports and all encodings
6
+ require 'hoth/transport'
7
+
8
+ require 'hoth/service_definition'
9
+ require 'hoth/service_module'
10
+ require 'hoth/endpoint'
11
+ require 'hoth/service'
12
+ require 'hoth/modules'
13
+ require 'hoth/service_registry'
14
+ require 'hoth/services'
15
+
16
+ require 'hoth/util/logger'
17
+
18
+ require 'hoth/extension/core/exception'
19
+ require 'hoth/exceptions'
20
+
21
+ module Hoth
22
+
23
+ class <<self
24
+ def init!
25
+ load_service_definition
26
+ load_module_definition
27
+ Logger.init_logging!
28
+ end
29
+
30
+ def config_path
31
+ @config_path || "config/"
32
+ end
33
+
34
+ def config_path=(config_path)
35
+ @config_path = config_path
36
+ end
37
+
38
+ def load_service_definition
39
+ require File.join(config_path, "service_definition")
40
+ end
41
+
42
+ def load_module_definition
43
+ require File.join(config_path, "module_definition")
44
+ end
45
+
46
+ def env
47
+ @env || ENV["HOTH_ENV"] || (Object.const_defined?("Rails") ? Rails.env.to_sym : :development)
48
+ end
49
+
50
+ def env=(env)
51
+ @env = env.to_sym
52
+ end
53
+
54
+ end
55
+
56
+ end
data/spec/spec_helper.rb CHANGED
@@ -2,36 +2,17 @@ require 'rubygems'
2
2
 
3
3
  $LOAD_PATH.unshift(File.dirname(__FILE__))
4
4
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
5
- require 'king_soa'
5
+ require 'hoth'
6
6
  require 'spec'
7
7
  require 'spec/autorun'
8
8
  # for mocking web requests
9
9
  require 'webmock/rspec'
10
- require 'rack/test'
11
10
  include WebMock
12
11
 
12
+ Hoth.env = "test"
13
13
 
14
-
15
- def local_service
16
- # Rack::Builder.app do
17
- # use KingSoa::Rack::Middleware
18
- # run super
19
- # end
20
-
21
- # Rack::Builder.new do
22
- # use KingSoa::Rack::Middleware
23
- # app = proc do |env|
24
- # [ 200, {'Content-Type' => 'text/plain'}, "b" ]
25
- # end
26
- # run app
27
- # end.to_app
28
- # def app
29
- # Rack::Builder.new {
30
- # # URLs starting with /account (logged in users) go to Rails
31
- # map "/soa" do
32
- # run KingSoa::Rack::Middleware.new
33
- # end
34
- # }.to_app
35
- # end
36
- # app.run
37
- end
14
+ Spec::Matchers.define :string_matching do |regex|
15
+ match do |string|
16
+ string =~ regex
17
+ end
18
+ end
@@ -0,0 +1,25 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../../', 'spec_helper'))
2
+
3
+ module Hoth
4
+ module Encoding
5
+
6
+ describe Json do
7
+
8
+ it "should decode a JSON string" do
9
+ decoded_json = Json.decode '{"test":23}'
10
+ decoded_json.should ==({"test" => 23})
11
+ end
12
+
13
+ it "should encode a JSON string" do
14
+ encoded_json = Json.encode({"test" => 23})
15
+ '{"test":23}'.should == encoded_json
16
+ end
17
+
18
+ it "should know its ContentType" do
19
+ Json.content_type.should == "application/json"
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,34 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ module Hoth
4
+
5
+ describe Endpoint do
6
+
7
+ it "should have a port" do
8
+ endpoint = Endpoint.new { port 3000 }
9
+ endpoint.port.should == 3000
10
+ end
11
+
12
+ it "should have a host name" do
13
+ endpoint = Endpoint.new { host "example.com" }
14
+ endpoint.host.should == "example.com"
15
+ end
16
+
17
+ it "should have a transport name" do
18
+ endpoint = Endpoint.new { transport :json_via_http }
19
+ endpoint.transport.should == :json_via_http
20
+ end
21
+
22
+ it "should should cast itself to URL string" do
23
+ endpoint = Endpoint.new { port 3000; host "example.com" }
24
+ endpoint.to_url.should == "http://example.com:3000/execute"
25
+ end
26
+
27
+ it "should should know the deployment module this endpoint is associated to" do
28
+ endpoint = Endpoint.new { module_name "TestModule" }
29
+ endpoint.module_name.should == "TestModule"
30
+ end
31
+
32
+ end
33
+
34
+ end
@@ -0,0 +1,34 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../../../', 'spec_helper'))
2
+
3
+ describe Exception do
4
+
5
+ it "should be able to create json with empty backtrace" do
6
+ e = Exception.new "message"
7
+ e.to_json.should == "{\"json_class\":\"Exception\",\"message\":\"message\",\"backtrace\":null}"
8
+ end
9
+
10
+ it "should be able to create json with backtrace" do
11
+ e = Exception.new "message"
12
+ e.set_backtrace ["back", "trace"]
13
+ e.to_json.should == "{\"json_class\":\"Exception\",\"message\":\"message\",\"backtrace\":[\"back\",\"trace\"]}"
14
+ end
15
+
16
+ it "should be able to deserialize exception from json" do
17
+ e = Exception.new "message"
18
+ e.set_backtrace ["back", "trace"]
19
+ deserialized = JSON(e.to_json)
20
+ deserialized.message.should == "message"
21
+ deserialized.backtrace.should == ["back", "trace"]
22
+ end
23
+
24
+ it "should be able to serialize and deserialize descendants of the Exception class" do
25
+ class ExceptionSpec < Exception; end
26
+ e = ExceptionSpec.new "message"
27
+ e.set_backtrace ["back", "trace"]
28
+ deserialized = JSON(e.to_json)
29
+ deserialized.message.should == "message"
30
+ deserialized.backtrace.should == ["back", "trace"]
31
+ deserialized.should be_a ExceptionSpec
32
+ end
33
+
34
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hoth do
4
+
5
+ before(:each) do
6
+ @old_hoth_env = Hoth.env
7
+ Hoth.instance_variable_set "@env", nil
8
+ end
9
+
10
+ after(:each) do
11
+ Hoth.env = @old_hoth_env
12
+ end
13
+
14
+ it "should set the environment explicitly" do
15
+ Hoth.env = :test
16
+ Hoth.env.should == :test
17
+ end
18
+
19
+ it "should default to :development if no environment is set" do
20
+ Hoth.env.should equal(:development)
21
+ end
22
+
23
+ it "should return the Rails env if Rails is available" do
24
+ module Rails; end
25
+ Rails.should_receive(:env).and_return(:production)
26
+ Hoth.env.should equal(:production)
27
+ Object.send :remove_const, :Rails
28
+ end
29
+
30
+ end
@@ -0,0 +1,49 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../../', 'spec_helper'))
2
+
3
+ require File.expand_path(File.join(File.dirname(__FILE__), '../../../', 'lib', 'hoth', 'providers', 'rack_provider'))
4
+
5
+ require 'rack/mock'
6
+
7
+ module Hoth
8
+ module Providers
9
+
10
+ describe RackProvider do
11
+
12
+ it "should get transport and encoder based on called service" do
13
+ app = stub("ApplicationStub").as_null_object
14
+ middleware = Hoth::Providers::RackProvider.new(app)
15
+
16
+ encoder = mock("EncoderMock")
17
+ encoder.should_receive(:decode).with("some_parameter").and_return(decoded_params = "some_parameter_decoded")
18
+ encoder.should_receive(:content_type).and_return("application/json")
19
+
20
+ transport = mock("TransportMock")
21
+ transport.should_receive(:encoder).exactly(3).times.and_return(encoder)
22
+
23
+ service = mock("ServiceMock")
24
+ service.should_receive(:transport).exactly(3).times.and_return(transport)
25
+ ServiceRegistry.should_receive(:locate_service).with("service_name").and_return(service)
26
+
27
+ Hoth::Services.should_receive(:send).with("service_name", *decoded_params).and_return(service_result = "result")
28
+ encoder.should_receive(:encode).with({"result" => service_result}).and_return("result_encoded")
29
+
30
+ mock_request = Rack::MockRequest.new(middleware)
31
+ mock_request.post("http://localhost/execute?name=service_name&params=some_parameter")
32
+ end
33
+
34
+ it "should be able to handle exceptions" do
35
+ app = stub("ApplicationStub").as_null_object
36
+ middleware = Hoth::Providers::RackProvider.new app
37
+ env = {"PATH_INFO" => "/execute/some_method", "other_params" => nil}
38
+ Rack::Request.should_receive(:new).and_raise(RuntimeError)
39
+
40
+ rack_response = middleware.call env
41
+ rack_response.first.should == 500 #status code
42
+ rack_response.last.should be_a_kind_of(Array)
43
+ rack_response.last.first.should == "An error occuered! (RuntimeError)"
44
+ end
45
+
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,21 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ module Hoth
4
+ describe ServiceDefinition do
5
+
6
+ it "should create a Service and add it to the registry instance" do
7
+ service_name = :my_service
8
+
9
+ definition = ServiceDefinition.new
10
+ definition.service service_name do |some_params|
11
+ returns :nothing
12
+ end
13
+
14
+ service = ServiceRegistry.locate_service(service_name)
15
+ service.should_not be(nil)
16
+ service.params_arity.should be(1)
17
+ service.return_nothing?.should be(true)
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,59 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ module Hoth
4
+
5
+ describe ServiceModule do
6
+
7
+ it "should have a name" do
8
+ service_module = ServiceModule.new :name => :my_service_module
9
+ service_module.name.should equal(:my_service_module)
10
+ end
11
+
12
+ it "should have an environment" do
13
+ service_module = ServiceModule.new(:name => "service_module_name")
14
+ block = Proc.new {}
15
+ service_module.env :test, &block
16
+ service_module[:test].should be_a(ServiceModule::Environment)
17
+ end
18
+
19
+ it "should have multiple environments" do
20
+ service_module = ServiceModule.new(:name => "service_module_name")
21
+ block = Proc.new {}
22
+ service_module.env :test, :development, &block
23
+ service_module[:test].should be_a(ServiceModule::Environment)
24
+ service_module[:development].should be_a(ServiceModule::Environment)
25
+ end
26
+
27
+ it "should be able to add services" do
28
+ service_module = ServiceModule.new(:name => "service_module_name")
29
+ block = Proc.new {}
30
+
31
+ service_module.env :test, &block
32
+
33
+ ServiceRegistry.should_receive(:locate_service).with(:service_name).and_return(service = mock("ServiceMock"))
34
+ service.should_receive(:module=).with(service_module)
35
+ service.should_receive(:via_endpoint).with(:special_endpoint)
36
+
37
+ service_module.add_service("service_name", :via => :special_endpoint)
38
+ end
39
+
40
+ describe ServiceModule::Environment do
41
+
42
+ it "should have an endpoint" do
43
+ endpoint_mock = mock("Endpoint", :null_object => true)
44
+
45
+ endpoint_block = Proc.new do
46
+ endpoint :development do
47
+ host 'localhost'
48
+ end
49
+ end
50
+
51
+ env = ServiceModule::Environment.new(&endpoint_block)
52
+ env[:development].should_not be(nil)
53
+ end
54
+
55
+ end
56
+
57
+ end
58
+
59
+ end
@@ -0,0 +1,77 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ class TestServiceImpl
4
+ def self.execute(param1, param2)
5
+ end
6
+ end
7
+
8
+ module Hoth
9
+
10
+ describe Service do
11
+
12
+ it "should define parameters and return values" do
13
+ service_block = Proc.new { |param_1, param_2, param_3| returns :some_data }
14
+
15
+ service = Service.new("TestService", &service_block)
16
+
17
+ service.params_arity.should be(3)
18
+ service.return_nothing?.should be(false)
19
+ end
20
+
21
+ it "should know its service-impl class" do
22
+ service = Service.new("TestService") {}
23
+ service.impl_class
24
+ end
25
+
26
+ it "should know that its service-impl class is not available" do
27
+ service = Service.new("TestServiceWithoutImplClass") {}
28
+ service.impl_class.should be(false)
29
+ end
30
+
31
+ it "should know if it is local or not based on Impl-Class availability" do
32
+ service = Service.new("TestServiceWithoutImplClass") {}
33
+ service.is_local?.should be(false)
34
+
35
+ service = Service.new("test_service") {}
36
+ service.is_local?.should be(true)
37
+ end
38
+
39
+ it "should execute the service stub locally if its impl-class was found" do
40
+ service = Service.new("test_service") { |p1, p2| returns :nothing }
41
+
42
+ service.should_receive(:is_local?).and_return(true)
43
+ service.impl_class.should_receive(:execute).with(:arg1, :arg2)
44
+
45
+ service.execute(:arg1, :arg2).should be(nil)
46
+ end
47
+
48
+ it "should execute the service stub locally if its impl-class was found and return a value" do
49
+ service = Service.new("test_service") { |p1, p2| returns :value }
50
+
51
+ service.should_receive(:is_local?).and_return(true)
52
+ service.impl_class.should_receive(:execute).with(:arg1, :arg2).and_return(result = mock("ResultMock"))
53
+
54
+ service.execute(:arg1, :arg2).should be(result)
55
+ end
56
+
57
+ it "should call the remote service if impl-class does not exist" do
58
+ service = Service.new("test_service_without_impl") { |p1, p2| returns :nothing }
59
+
60
+ service.should_receive(:is_local?).and_return(false)
61
+ service.should_receive(:transport).and_return(transport = mock("TransportMock"))
62
+ transport.should_receive(:call_remote_with).with(:arg1, :arg2)
63
+
64
+ service.execute(:arg1, :arg2)
65
+ end
66
+
67
+ it "should create transport instance based on endpoint" do
68
+ service = Service.new("test_service") { |p1, p2| returns :nothing }
69
+ service.should_receive(:endpoint).and_return(endpoint = mock("EndpointMock"))
70
+ endpoint.should_receive(:transport).and_return(:http)
71
+ Hoth::Transport.should_receive(:create).with(:http, service)
72
+ service.transport
73
+ end
74
+
75
+ end
76
+
77
+ end
@@ -0,0 +1,43 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../../', 'spec_helper'))
2
+
3
+ module Hoth
4
+ module Transport
5
+
6
+ describe "Base" do
7
+
8
+ it "should initialize with service-delegate" do
9
+ service = mock("ServiceMock")
10
+ transport = Base.new(service)
11
+ end
12
+
13
+ it "should use an NoOp encoder if no encoder class was given at all" do
14
+ service = mock("ServiceMock")
15
+ transport = Base.new(service)
16
+ transport.encoder.should == Encoding::NoOp
17
+ end
18
+
19
+ it "should delegate calls to service-delegate" do
20
+ service = mock("ServiceMock")
21
+ service.should_receive(:name)
22
+ service.should_receive(:module)
23
+ service.should_receive(:endpoint)
24
+ service.should_receive(:params)
25
+ service.should_receive(:return_nothing?)
26
+ transport = Base.new(service)
27
+
28
+ [:name, :module, :endpoint, :params, :return_nothing?].each do |method|
29
+ transport.send(method)
30
+ end
31
+ end
32
+
33
+ it "should have an encoder" do
34
+ service = mock("ServiceMock")
35
+ encoder = mock("EncoderMock")
36
+ transport = Base.new(service, :encoder => encoder)
37
+ transport.encoder.should be(encoder)
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+ end