diff --git a/.travis.yml b/.travis.yml
index 1172c1e..335a18d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,8 +1,8 @@
language: ruby
rvm:
- - 1.9.3
- 2.0.0
- 2.1.0
- 2.2.2
+ - 2.3.0
bundler_args: --without development
before_install: gem install bundler
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8bd7f9d..c1b42f2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,16 @@
+## 1.0.0.pre
+ * Changes:
+ * Dropped support for Ruby 1.9.3.
+ * Dropped `rest-client` dependency.
+ * Request headers now use string keys instead of symbols.
+ ```ruby
+ # Old
+ { accept_language: 'en_us' }
+
+ # New
+ { 'Accept-Language' => 'en_us' }
+ ```
+
## 0.5.0
* Changes:
* OpenComponents::PrerenderedComponent is now OpenComponents::UnrenderedComponent
diff --git a/Gemfile.lock b/Gemfile.lock
index c39b3aa..326ae56 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,8 +1,7 @@
PATH
remote: .
specs:
- opencomponents (0.5.0)
- rest-client (~> 1.8)
+ opencomponents (1.0.0.pre)
GEM
remote: https://rubygems.org/
@@ -128,4 +127,4 @@ DEPENDENCIES
webmock (~> 1.21)
BUNDLED WITH
- 1.10.3
+ 1.11.2
diff --git a/README.md b/README.md
index dc77d2e..f5e0a67 100644
--- a/README.md
+++ b/README.md
@@ -15,10 +15,6 @@
[6]:https://github.com/opentable/oc
-## Important
-This gem is still under heavy development and the API is likely to change at any
-time.
-
## Getting Started
Add the gem to your Gemfile and run `bundle install`:
```ruby
@@ -48,7 +44,7 @@ component = OpenComponents::RenderedComponent.new(
'my-awesome-component',
params: {name: 'Kate'},
version: '1.0.2',
- headers: {accept_language: 'emoji'}
+ headers: {'Accept-Language' => 'emoji'}
)
```
diff --git a/lib/opencomponents.rb b/lib/opencomponents.rb
index c98fe99..550ebb0 100644
--- a/lib/opencomponents.rb
+++ b/lib/opencomponents.rb
@@ -1,4 +1,5 @@
-require 'rest-client'
+require 'json'
+require 'net/http'
require 'opencomponents/component'
require 'opencomponents/rendered_component'
@@ -14,7 +15,7 @@ module OpenComponents
DEFAULT_TIMEOUT = 5
# Internal: Custom exception class to raise in the event a component cannot be
- # found in the registry.
+ # found in the registry.
ComponentNotFound = Class.new(RuntimeError)
# Internal: Custom exception class to raise for response timeouts.
diff --git a/lib/opencomponents/component.rb b/lib/opencomponents/component.rb
index b7c9d51..fcffc53 100644
--- a/lib/opencomponents/component.rb
+++ b/lib/opencomponents/component.rb
@@ -1,6 +1,9 @@
module OpenComponents
# Wrapper object for a component fetched from an OC registry.
class Component
+ REGISTRY_TIMEOUT_MESSAGE = 'The registry took too long to respond.'.freeze #:nodoc:
+ BLANK = ''.freeze #:nodoc:
+
# Public: Gets/sets the String name of the component.
attr_accessor :name
@@ -13,43 +16,40 @@ class Component
# Public: Gets/sets a Hash of headers to send in the component request.
attr_accessor :headers
- # Public: Returns the String URL of the requested component.
+ # Public: Gets the String URL of the requested component.
attr_reader :href
- # Public: Returns the String version of the component as served by the
- # registry.
+ # Public: Gets the String version of the component as served by the
+ # registry.
attr_reader :registry_version
- # Public: Returns the String type of the component as served by the
- # registry.
+ # Public: Gets the String type of the component as served by the
+ # registry.
attr_reader :type
- # Public: Returns the String render mode of the component as served by the
- # registry. Generally either `rendered` or `unrendered`.
+ # Public: Gets the String render mode of the component as served by the
+ # registry. Generally either `rendered` or `unrendered`.
attr_reader :render_mode
# Public: Initializes a new Component subclass.
#
# name - The String name of the component to request.
- # opts - A Hash of options to use when requesting the component
- # (default: {}).
- # :params - A Hash of parameters to send in the component request
- # (optional, default: {}).
- # :version - The String version of the component to request
- # (optional, default: '').
- # :headers - A Hash of HTTP request headers to include in the
- # component request (optional, default: {}).
- def initialize(name, opts = {})
+ #
+ # Options
+ # params - A Hash of parameters to send in the component request (default: {}).
+ # version - The String version of the component to request (default: '').
+ # headers - A Hash of HTTP request headers to include in the request (default: {}).
+ def initialize(name, params: {}, version: nil, headers: {})
@name = name
- @params = opts[:params] || {}
- @version = opts[:version] || ''
- @headers = opts[:headers] || {}
+ @params = params
+ @version = version || BLANK
+ @headers = headers
end
# Public: Returns the String value of `requestVersion` from a component
- # response, `nil` if not present.
+ # response, `nil` if not present.
def request_version
- @request_version == '' ? nil : @request_version
+ @request_version == BLANK ? nil : @request_version
end
# Public: Resets all component attributes from a registry response to `nil`.
@@ -69,7 +69,7 @@ def flush!
end
# Public: Resets all component attributes and reloads them from a registry
- # response.
+ # response.
#
# Examples
#
@@ -82,11 +82,11 @@ def reload!
load
end
- protected
+ private
# Internal: Executes a component request and sets attributes common to all
- # component render modes. Public-facing `#load` methods exist on Component
- # subclasses.
+ # component render modes. Public-facing `#load` methods exist on Component
+ # subclasses.
#
# Returns the Component.
def load
@@ -102,43 +102,60 @@ def load
# Internal: Builds the URL to send a component request to.
#
# Returns the String URL to request a component from.
- def url
- File.join(OpenComponents.config.registry, name, version)
+ def uri
+ URI(File.join(OpenComponents.config.registry, name, version)).tap do |u|
+ u.query = URI.encode_www_form(params)
+ end
end
# Internal: Executes a component request against the configured registry.
#
# Returns a response body String.
# Raises OpenComponents::ComponentNotFound if the registry responds with a
- # 404.
+ # 404.
# Raises OpenComponents::RegistryTimeout if the request times out.
def response
- request_headers = headers.merge(params: params)
-
- RestClient::Request.execute(
- method: :get,
- url: url,
- timeout: OpenComponents.config.timeout,
- headers: request_headers
- )
- rescue RestClient::ResourceNotFound => e
- fail ComponentNotFound, e.message
- rescue RestClient::RequestTimeout => e
- fail RegistryTimeout, e.message
+ _response = Net::HTTP.start(
+ uri.host,
+ uri.port,
+ read_timeout: OpenComponents.config.timeout,
+ open_timeout: OpenComponents.config.timeout
+ ) { |http| http.request request }
+
+ case _response
+ when Net::HTTPNotFound
+ fail ComponentNotFound, "Component #{name} not found."
+ when Net::HTTPRequestTimeOut
+ fail_with_timeout
+ end
+
+ _response
+ rescue Timeout::Error
+ fail_with_timeout
+ end
+
+ # Internal: Helper method for building the component request. Includes
+ # all params and headers.
+ def request
+ Net::HTTP::Get.new(uri).tap do |r|
+ headers.each { |k, v| r[k] = v }
+ end
end
# Internal: Helper method for converting and memoizing registry response
- # data.
+ # data.
#
# Returns a Hash of registry response data.
def response_data
- @_response_data ||= JSON.parse(response)
+ @_response_data ||= JSON.parse(response.body)
end
- private
+ def fail_with_timeout
+ fail RegistryTimeout, REGISTRY_TIMEOUT_MESSAGE
+ end
# Internal: Whitelists instance variable names allowed to be reset when
- # calling `#flush!`.
+ # calling `#flush!`.
#
# Returns an Array of instance variable Symbols allowed to be reset.
def flush_variables_whitelist
diff --git a/lib/opencomponents/rendered_component.rb b/lib/opencomponents/rendered_component.rb
index f0b0ad3..23c66b2 100644
--- a/lib/opencomponents/rendered_component.rb
+++ b/lib/opencomponents/rendered_component.rb
@@ -5,7 +5,7 @@ class RenderedComponent < Component
attr_reader :html
# Public: Executes a request for the Component against the configured
- # registry and sets the component attributes.
+ # registry and sets the component attributes.
#
# Examples
#
diff --git a/lib/opencomponents/renderer.rb b/lib/opencomponents/renderer.rb
index 8cc6bee..aeef5f4 100644
--- a/lib/opencomponents/renderer.rb
+++ b/lib/opencomponents/renderer.rb
@@ -2,21 +2,21 @@ module OpenComponents
# Provides rendering helper methods for components.
module Renderer
# Public: Builds a new RenderedComponent, executes a request for it against
- # the configured registry, and returns the rendered component HTML.
+ # the configured registry, and returns the rendered component HTML.
#
# component - The String name of the component to render.
- # opts - A Hash of options to use when requesting the component
- # (default: {}).
- # :params - A Hash of parameters to send in the component request
- # (optional, default: {}).
- # :version - The String version of the component to request
- # (optional, default: nil).
- # :headers - A Hash of HTTP request headers to include in the
- # component request (optional, default: {}).
- def render_component(component, opts = {})
- OpenComponents::RenderedComponent.new(component, opts)
- .load
- .html
+ #
+ # Options
+ # params - A Hash of parameters to send in the component request (default: {}).
+ # version - The String version of the component to request (default: nil).
+ # headers - A Hash of HTTP request headers to include in the request (default: {}).
+ def render_component(component, params: {}, version: nil, headers: {})
+ OpenComponents::RenderedComponent.new(
+ component,
+ params: params,
+ version: version,
+ headers: headers
+ ).load.html
end
end
end
diff --git a/lib/opencomponents/unrendered_component.rb b/lib/opencomponents/unrendered_component.rb
index 4b2600f..4e20466 100644
--- a/lib/opencomponents/unrendered_component.rb
+++ b/lib/opencomponents/unrendered_component.rb
@@ -2,7 +2,7 @@ module OpenComponents
# Wrapper object for components using the `unrendered` rendering mode.
class UnrenderedComponent < Component
# Internal: Default HTTP headers to send when requesting a component.
- DEFAULT_HEADERS = {accept: 'application/vnd.oc.unrendered+json'}
+ DEFAULT_HEADERS = {'Accept' => 'application/vnd.oc.unrendered+json'}
# Public: Returns a Hash of data to use when rendering the component.
attr_reader :data
@@ -13,22 +13,19 @@ class UnrenderedComponent < Component
# Public: Initializes a new UnrenderedComponent.
#
# name - The String name of the component to request.
- # opts - A Hash of options to use when requesting the component
- # (default: {}).
- # :params - A Hash of parameters to send in the component request
- # (optional, default: {}).
- # :version - The String version of the component to request
- # (optional, default: nil).
- # :headers - A Hash of HTTP request headers to include in the
- # component request (optional, default: DEFAULT_HEADERS).
- def initialize(name, opts = {})
- super(name, opts)
+ #
+ # Options
+ # params - A Hash of parameters to send in the component request (default: {}).
+ # version - The String version of the component to request (default: nil).
+ # headers - A Hash of HTTP request headers to include in the request (default: DEFAULT_HEADERS).
+ def initialize(name, params: {}, version: nil, headers: {})
+ super
@headers.merge!(DEFAULT_HEADERS)
end
# Public: Executes a request for the Component against the configured
- # registry and sets the component attributes.
+ # registry and sets the component attributes.
#
# Examples
#
diff --git a/lib/opencomponents/version.rb b/lib/opencomponents/version.rb
index 5cb5591..76bf50b 100644
--- a/lib/opencomponents/version.rb
+++ b/lib/opencomponents/version.rb
@@ -1,3 +1,3 @@
module OpenComponents
- VERSION = '0.5.0' # :nodoc:
+ VERSION = '1.0.0.pre'.freeze # :nodoc:
end
diff --git a/opencomponents.gemspec b/opencomponents.gemspec
index 3808170..b2acac1 100644
--- a/opencomponents.gemspec
+++ b/opencomponents.gemspec
@@ -4,9 +4,8 @@ $:.unshift File.expand_path('../lib', __FILE__)
require 'opencomponents/version'
Gem::Specification.new do |spec|
- spec.required_ruby_version = '>= 1.9.3'
+ spec.required_ruby_version = '>= 2.0.0'
- spec.add_dependency 'rest-client', '~> 1.8'
spec.add_development_dependency 'bundler', '~> 1.10'
spec.authors = ['Todd Bealmear']
diff --git a/spec/lib/opencomponents/rendered_component_spec.rb b/spec/lib/opencomponents/rendered_component_spec.rb
index 17d41bb..9fcd6d8 100644
--- a/spec/lib/opencomponents/rendered_component_spec.rb
+++ b/spec/lib/opencomponents/rendered_component_spec.rb
@@ -7,7 +7,6 @@
before do
stub_request(:get, "http://localhost:3030/foobar/").
with(
- headers: {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate', 'User-Agent'=>'Ruby'},
query: {name: 'foobar'}
).
to_return(status: 200, body: '{"href":"http://localhost:3030/foobar?name=foobar","type":"oc-component-local","version":"1.0.0","requestVersion":"","html":"ohai, my name is foobar
ohai, my name is Todd
ohai, my name is foobar
ohai, my name is Todd
ohai, my name is Todd