<repo_name>akirahrkw/sinatra-jbuilder<file_sep>/lib/sinatra/jbuilder.rb
require 'sinatra/base'
require 'multi_json'
require 'jbuilder'

module Sinatra
  module Jbuilder
    VERSION   = "1.0"

    def jbuilder(object, status:200, type: :json)
      content_type type
      response.status = status

      ::Jbuilder.encode do |json|
        json.set! :meta do
          json.status status
        end
        json.set! :data do
          if object.class == Array
            json.array! object do |o|
              o.to_json(json)
            end
          else
            object.to_json(json)
          end
        end
      end
    end  
  end

  Base.set :json_encoder do
    ::MultiJson
  end

  Base.helpers Jbuilder
end<file_sep>/spec/jbuilder_spec.rb
require_relative 'spec_helper'

describe Sinatra::Jbuilder do

  class Human
    def initialize(first_name:'akira', last_name:'hirakawa')
      @last_name = last_name
      @first_name = first_name
    end

    def to_json(json)
      json.last_name @last_name
      json.first_name @first_name
    end
  end

  it 'changes http status' do
    mock_app {
      get('/') {
        o = Human.new
        jbuilder o, status:400
      }
    }
    o = get('/')
    expect(o.status).to eq 400
    json = JSON.parse(o.body)['meta']
    expect(json['status']).to eq 400
  end

  it 'changes content-type' do
    mock_app {
      get('/') {
        o = Human.new
        jbuilder o, type: :js
      }
    }
    o = get('/')
    expect(o['Content-Type']).to eq 'application/javascript;charset=utf-8'
  end

  it 'gets object' do
    mock_app {
      get('/') {
        o = Human.new
        jbuilder o
      }
    }
    o = get('/')
    expect(o['Content-Type']).to eq 'application/json'
    json = JSON.parse(o.body)['data']
   
    expect(json['last_name']).to eq 'hirakawa'
    expect(json['first_name']).to eq 'akira'
  end

  it 'gets array' do
    mock_app {
      get('/') {
        array = []
        array << Human.new
        array << Human.new
        array << Human.new
        array << Human.new
        array << Human.new
        jbuilder array
      }
    }

    o = get('/')
    expect(o['Content-Type']).to eq 'application/json' 
    json = JSON.parse(o.body)['data']

    expect(json.class).to eq Array
    expect(json.size).to eq 5
  end
end
<file_sep>/Gemfile
source "http://rubygems.org"
gemspec

gem 'sinatra', :github => 'sinatra/sinatra'

group :development, :test do
  gem 'sinatra-contrib'
  gem 'jbuilder'
  gem 'multi_json'
end<file_sep>/sinatra-jbuilder.gemspec
# -*- encoding: utf-8 -*-

Gem::Specification.new do |gem|
  gem.authors       = ["<NAME>"]
  gem.email         = ["<EMAIL>"]
  gem.summary       = %q{jbuilder for sinatra}
  gem.description   = %q{jbuilder for sinatra}
  gem.homepage      = "http://akirahrkw.com"
  gem.files         = `git ls-files`.split($\)
  gem.test_files    = gem.files.grep(%r{^(test|spec|features)/})
  gem.name          = "sinatra-jbuilder"
  gem.require_paths = ["lib"]
  gem.version       = "1.0"
  gem.license       = "MIT"

  gem.add_dependency "sinatra", '~> 1.4', '>= 1.4.0'
  gem.add_dependency "multi_json"

  gem.add_development_dependency "rspec", "~> 2.3"
end<file_sep>/README.md
Intro
=========
a plugin to use jbuilder in sinatra
jbuilder: https://github.com/rails/jbuilder

Concept
=========
model class takes responsibility for rendering json

Usage
=========
require 'sinatra/jbuilder'

ex: 
```
class Human
  ...
  ...
  # model class has to implement to_json method
  def to_json(json)
   json.id id
   json.name name
  end
end

get '/object' do
  o = Human.new
  jbuilder o
end

get '/array' do
  array = Human.all
  jbuilder array
end
```

```
{
  meta: {
    status: 200
  },
  data: {
    id: 1,
    name: 'akira'
  }
}
```

Copyright
=========
Copyright (c) 2014 <NAME>. See LICENSE for details.
<file_sep>/spec/spec_helper.rb
require 'jbuilder'
require 'sinatra/contrib'
require 'sinatra/jbuilder'

RSpec.configure do |config|
  config.expect_with :rspec
  config.include Sinatra::TestHelpers
end