Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Write helpers to deteremine desired format

First try the format part of the query string like a conventional rails
app. Then fall back to the mime type in the accept header and if
anything goes default to json.
  • Loading branch information...
commit e4681b58328fd3a48981a9ef410b03f5c24339fd 1 parent fb2e87b
@vanstee authored
Showing with 124 additions and 0 deletions.
  1. +38 −0 lib/hovercraft/helpers.rb
  2. +86 −0 spec/hovercraft/helpers_spec.rb
View
38 lib/hovercraft/helpers.rb
@@ -0,0 +1,38 @@
+module Hovercraft
+ module Helpers
+ def self.registered(application)
+ application.helpers(Hovercraft::Helpers)
+ end
+
+ def respond_with(content)
+ if content.respond_to?(format_method_name)
+ content.send(format_method_name)
+ else
+ fail "Serialization method not supported: #{format_method_name}"
+ end
+ end
+
+ def format_method_name
+ "to_#{format}"
+ end
+
+ def format
+ params[:format] ||
+ preferred_type ||
+ default_format
+ end
+
+ def preferred_type
+ case request.preferred_type
+ when /.*\/json/ then :json
+ when /.*\/xml/ then :xml
+ when /.*\/\*/ then default_format
+ else fail "Unknown media type: %p" % request.preferred_type
+ end
+ end
+
+ def default_format
+ :json
+ end
+ end
+end
View
86 spec/hovercraft/helpers_spec.rb
@@ -0,0 +1,86 @@
+require 'hovercraft/helpers'
+
+describe Hovercraft::Helpers do
+ subject { Class.new { extend Hovercraft::Helpers } }
+ let(:model_to_json) { stub }
+ let(:model) { stub(to_json: model_to_json) }
+
+ describe '.registered' do
+ let(:application) { stub }
+
+ it 'includes the helpers in the application' do
+ application.should_receive(:helpers).with(described_class)
+
+ Hovercraft::Helpers.registered(application)
+ end
+ end
+
+ describe '#respond_with' do
+ it 'serializes the content to the preferred format' do
+ subject.stub(format: :json)
+
+ subject.respond_with(model).should == model_to_json
+ end
+
+ it 'fails if the preferred format is not supported' do
+ subject.stub(format: :xml)
+
+ lambda { subject.respond_with(model) }.should raise_error
+ end
+ end
+
+ describe '#format' do
+ let(:format_param) { stub }
+ let(:preferred_type) { stub }
+ let(:default_format) { stub }
+
+ before do
+ subject.stub(
+ params: { format: nil },
+ preferred_type: nil,
+ default_format: nil
+ )
+ end
+
+ it 'defaults to the format param' do
+ subject.stub(params: { format: format_param })
+ subject.format.should == format_param
+ end
+
+ it 'falls back on the preferred_type' do
+ subject.stub(preferred_type: preferred_type)
+ subject.format.should == preferred_type
+ end
+
+ it 'uses the default format as a worst case' do
+ subject.stub(default_format: default_format)
+ subject.format.should == default_format
+ end
+ end
+
+ describe '#preferred_type' do
+ let(:default_format) { stub }
+
+ before { subject.stub(default_format: default_format) }
+
+ it 'checks for json' do
+ subject.stub_chain(:request, :preferred_type) { 'application/json' }
+ subject.preferred_type.should == :json
+ end
+
+ it 'checks for xml' do
+ subject.stub_chain(:request, :preferred_type) { 'application/xml' }
+ subject.preferred_type.should == :xml
+ end
+
+ it 'defaults to json if any format is allowed' do
+ subject.stub_chain(:request, :preferred_type) { '*/*' }
+ subject.preferred_type.should == default_format
+ end
+
+ it 'fails if the acceptable type is unknown' do
+ subject.stub_chain(:request, :preferred_type) { 'unknown/type' }
+ lambda { subject.preferred_type.should }.should raise_error
+ end
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.