Skip to content

Prep for 1.0.0 #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -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
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
5 changes: 2 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -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/
Expand Down Expand Up @@ -128,4 +127,4 @@ DEPENDENCIES
webmock (~> 1.21)

BUNDLED WITH
1.10.3
1.11.2
6 changes: 1 addition & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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'}
)
```

Expand Down
5 changes: 3 additions & 2 deletions lib/opencomponents.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'rest-client'
require 'json'
require 'net/http'

require 'opencomponents/component'
require 'opencomponents/rendered_component'
Expand All @@ -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.
Expand Down
105 changes: 61 additions & 44 deletions lib/opencomponents/component.rb
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -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`.
Expand All @@ -69,7 +69,7 @@ def flush!
end

# Public: Resets all component attributes and reloads them from a registry
# response.
# response.
#
# Examples
#
Expand All @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lib/opencomponents/rendered_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
#
Expand Down
26 changes: 13 additions & 13 deletions lib/opencomponents/renderer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
21 changes: 9 additions & 12 deletions lib/opencomponents/unrendered_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
#
Expand Down
2 changes: 1 addition & 1 deletion lib/opencomponents/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module OpenComponents
VERSION = '0.5.0' # :nodoc:
VERSION = '1.0.0.pre'.freeze # :nodoc:
end
3 changes: 1 addition & 2 deletions opencomponents.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -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']
Expand Down
Loading