Merge branch 'master' into fragment-cache
This commit is contained in:
commit
4cf10fb8f6
2
Gemfile
2
Gemfile
@ -1,6 +1,6 @@
|
|||||||
source "http://rubygems.org"
|
source "http://rubygems.org"
|
||||||
|
|
||||||
# Declare your gem's dependencies in rabl-fast-json.gemspec.
|
# Declare your gem's dependencies in rabl-rails.gemspec.
|
||||||
# Bundler will treat runtime dependencies like base dependencies, and
|
# Bundler will treat runtime dependencies like base dependencies, and
|
||||||
# development dependencies will be added by default to the :development group.
|
# development dependencies will be added by default to the :development group.
|
||||||
gemspec
|
gemspec
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
PATH
|
PATH
|
||||||
remote: .
|
remote: .
|
||||||
specs:
|
specs:
|
||||||
rabl-fast-json (0.1.0)
|
rabl-rails (0.1.0)
|
||||||
activesupport (~> 3.2.1)
|
activesupport (~> 3.2.1)
|
||||||
|
|
||||||
GEM
|
GEM
|
||||||
@ -61,7 +61,7 @@ PLATFORMS
|
|||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
actionpack (~> 3.2.1)
|
actionpack (~> 3.2.1)
|
||||||
rabl-fast-json!
|
rabl-rails!
|
||||||
railties (~> 3.2.1)
|
railties (~> 3.2.1)
|
||||||
rspec-mocks
|
rspec-mocks
|
||||||
sqlite3
|
sqlite3
|
||||||
|
85
README.md
85
README.md
@ -1,3 +1,84 @@
|
|||||||
= RablFastJson
|
# RABL for Rails #
|
||||||
|
|
||||||
This project rocks and uses MIT-LICENSE.
|
RABL (Ruby API Builder Language) is a ruby templating system for rendering resources in different format (JSON, XML, BSON, ...). You can find documentation [here](http://github.com/nesquena/rabl).
|
||||||
|
|
||||||
|
RABL-rails only target Rails 3+ application because Rails 2 applications are becoming less and less present and will be obsolete with Rails 4. So let's look to the future !
|
||||||
|
|
||||||
|
So now you ask why used `rabl-rails` if `rabl` already exists and supports Rails. Rabl-rails is *faster* and uses * less memory* than standard rabl gem while letting you access same features. Of course, there are some slight changes to do on your templates to get this gem to work but it should't take you more than 5 minutes.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Install as a gem :
|
||||||
|
|
||||||
|
```
|
||||||
|
gem install rabl-rails
|
||||||
|
```
|
||||||
|
|
||||||
|
or add directly to your `Gemfile`
|
||||||
|
|
||||||
|
```
|
||||||
|
gem 'rabl'
|
||||||
|
```
|
||||||
|
|
||||||
|
And that's it !
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Once you have installed RABL, you can directly used RABL templates to render your resources without changing anything to you controller. As example,
|
||||||
|
assuming you have a `Post` model filled with blog posts, and a `PostController` that look like this :
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
class PostController < ApplicationController
|
||||||
|
respond_to :html, :json, :xml
|
||||||
|
|
||||||
|
def index
|
||||||
|
@posts = Post.order('created_at DESC')
|
||||||
|
respond_with(@posts)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
You can create the following RABL-rails template to express the API output of `@posts`
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
# app/views/post/index.rabl
|
||||||
|
collection :@posts
|
||||||
|
attributes :id, :title, :subject
|
||||||
|
child(:user) { attributes :full_name }
|
||||||
|
node(:read) { |post| post.read_by?(@user) }
|
||||||
|
```
|
||||||
|
|
||||||
|
This would output the following JSON when visiting `http://localhost:3000/posts.json`
|
||||||
|
|
||||||
|
```js
|
||||||
|
[{
|
||||||
|
"id" : 5, title: "...", subject: "...",
|
||||||
|
"user" : { full_name : "..." },
|
||||||
|
"read" : true
|
||||||
|
}]
|
||||||
|
```
|
||||||
|
|
||||||
|
That's a basic overview but there is a lot more to see such as partials, inheritance or fragment caching.
|
||||||
|
|
||||||
|
## How it works
|
||||||
|
|
||||||
|
As opposed to standard RABL gem, this gem separate compiling (a.k.a transforming a RABL-rails template into a Ruby hash) and the actual rendering of the object or collection. This allow to only compile the template once and only Ruby hashes.
|
||||||
|
|
||||||
|
The fact of compiling the template outside of any rendering context prevent us to use any instances variables (with the exception of node) in the template because they are rendering objects. So instead, you'll have to use symbols of these variables. For example, to render the collection `@posts` inside your `PostController`, you need to use `:@posts` inside of the template.
|
||||||
|
|
||||||
|
The only places where you can actually used instance variables are into Proc (or lambda) or into custom node (because they are treated as Proc).
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
# We reference the @posts varibles that will be used at rendering time
|
||||||
|
collection :@posts
|
||||||
|
|
||||||
|
# Here you can use directly the instance variable because it
|
||||||
|
# will be evaluated when rendering the object
|
||||||
|
node(:read) { |post| post.read_by?(@user) }
|
||||||
|
```
|
||||||
|
|
||||||
|
The same rule applies for view helpers such as `current_user`
|
||||||
|
|
||||||
|
After the template is compiled into a hash, Rabl-rails will use a renderer to do the actual output. Actually, only JSON and XML formats are supported.
|
||||||
|
|
||||||
|
## Usage
|
2
Rakefile
Normal file → Executable file
2
Rakefile
Normal file → Executable file
@ -14,7 +14,7 @@
|
|||||||
#
|
#
|
||||||
# RDoc::Task.new(:rdoc) do |rdoc|
|
# RDoc::Task.new(:rdoc) do |rdoc|
|
||||||
# rdoc.rdoc_dir = 'rdoc'
|
# rdoc.rdoc_dir = 'rdoc'
|
||||||
# rdoc.title = 'RablFastJson'
|
# rdoc.title = 'RablRails'
|
||||||
# rdoc.options << '--line-numbers'
|
# rdoc.options << '--line-numbers'
|
||||||
# rdoc.rdoc_files.include('README.rdoc')
|
# rdoc.rdoc_files.include('README.rdoc')
|
||||||
# rdoc.rdoc_files.include('lib/**/*.rb')
|
# rdoc.rdoc_files.include('lib/**/*.rb')
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
module RablFastJson
|
|
||||||
module Helpers
|
|
||||||
def root_given?(options) #:nodoc:
|
|
||||||
options[:root].present?
|
|
||||||
end
|
|
||||||
|
|
||||||
def partial_given?(options) #:nodoc:
|
|
||||||
options[:partial].present?
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,86 +0,0 @@
|
|||||||
module RablFastJson
|
|
||||||
class CompiledTemplate
|
|
||||||
attr_accessor :source, :data, :root_name, :context
|
|
||||||
|
|
||||||
delegate :[], :[]=, :merge!, :to => :source
|
|
||||||
|
|
||||||
def initialize
|
|
||||||
@source = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
def has_root_name?
|
|
||||||
!@root_name.nil?
|
|
||||||
end
|
|
||||||
|
|
||||||
def render
|
|
||||||
get_object_from_context
|
|
||||||
get_assigns_from_context
|
|
||||||
@object.respond_to?(:each) ? render_collection : render_resource
|
|
||||||
end
|
|
||||||
|
|
||||||
def render_resource(data = nil, source = nil)
|
|
||||||
data ||= @object
|
|
||||||
source ||= @source
|
|
||||||
|
|
||||||
source.inject({}) { |output, current|
|
|
||||||
key, value = current
|
|
||||||
|
|
||||||
out = case value
|
|
||||||
when Symbol
|
|
||||||
data.send(value) # attributes
|
|
||||||
when Proc
|
|
||||||
instance_exec data, &value # node
|
|
||||||
when Array # node with condition
|
|
||||||
next output if !instance_exec data, &(value.first) #value.first.call(data)
|
|
||||||
instance_exec data, &(value.last)
|
|
||||||
when Hash
|
|
||||||
current_value = value.dup
|
|
||||||
data_symbol = current_value.delete(:_data)
|
|
||||||
object = data_symbol.nil? ? data : data_symbol.to_s.start_with?('@') ? @context.instance_variable_get(data_symbol) : data.send(data_symbol)
|
|
||||||
|
|
||||||
if key.to_s.start_with?('_') # glue
|
|
||||||
current_value.each_pair { |k, v|
|
|
||||||
output[k] = object.send(v)
|
|
||||||
}
|
|
||||||
next output
|
|
||||||
else # child
|
|
||||||
object.respond_to?(:each) ? render_collection(object, current_value) : render_resource(object, current_value)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
output[key] = out
|
|
||||||
output
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def render_collection(collection = nil, source = nil)
|
|
||||||
collection ||= @object
|
|
||||||
collection.inject([]) { |output, o| output << render_resource(o, source) }
|
|
||||||
end
|
|
||||||
|
|
||||||
def method_missing(name, *args, &block)
|
|
||||||
@context.respond_to?(name) ? @context.send(name, *args, &block) : super
|
|
||||||
end
|
|
||||||
|
|
||||||
def partial(template_path, options = {})
|
|
||||||
raise "No object was given to partial" if options[:object].nil?
|
|
||||||
object = options[:object]
|
|
||||||
|
|
||||||
return [] if object.respond_to?(:empty?) && object.empty?
|
|
||||||
|
|
||||||
template = Library.instance.get(template_path)
|
|
||||||
object.respond_to?(:each) ? template.render_collection(object) : template.render_resource(object)
|
|
||||||
end
|
|
||||||
|
|
||||||
protected
|
|
||||||
|
|
||||||
def get_object_from_context
|
|
||||||
@object = @context.instance_variable_get(@data) if @data
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_assigns_from_context
|
|
||||||
@context.instance_variable_get(:@_assigns).each_pair { |k, v|
|
|
||||||
instance_variable_set("@#{k}", v) unless k.start_with?('_') || k == @data
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
@ -4,15 +4,19 @@ require 'active_support'
|
|||||||
require 'active_support/json'
|
require 'active_support/json'
|
||||||
require 'active_support/core_ext/class/attribute_accessors'
|
require 'active_support/core_ext/class/attribute_accessors'
|
||||||
|
|
||||||
require 'rabl-fast-json/version'
|
require 'rabl-rails/version'
|
||||||
require 'rabl-fast-json/helpers'
|
require 'rabl-rails/template'
|
||||||
require 'rabl-fast-json/template'
|
require 'rabl-rails/compiler'
|
||||||
require 'rabl-fast-json/compiler'
|
|
||||||
require 'rabl-fast-json/library'
|
|
||||||
require 'rabl-fast-json/handler'
|
|
||||||
require 'rabl-fast-json/railtie'
|
|
||||||
|
|
||||||
module RablFastJson
|
require 'rabl-rails/renderer'
|
||||||
|
|
||||||
|
require 'rabl-rails/library'
|
||||||
|
require 'rabl-rails/handler'
|
||||||
|
require 'rabl-rails/railtie'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
module RablRails
|
||||||
extend self
|
extend self
|
||||||
|
|
||||||
mattr_accessor :cache_templates
|
mattr_accessor :cache_templates
|
@ -1,11 +1,9 @@
|
|||||||
module RablFastJson
|
module RablRails
|
||||||
#
|
#
|
||||||
# Class that will compile RABL source code into a hash
|
# Class that will compile RABL source code into a hash
|
||||||
# representing data structure
|
# representing data structure
|
||||||
#
|
#
|
||||||
class Compiler
|
class Compiler
|
||||||
include Helpers
|
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@glue_count = 0
|
@glue_count = 0
|
||||||
end
|
end
|
||||||
@ -20,15 +18,6 @@ module RablFastJson
|
|||||||
@template
|
@template
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
|
||||||
# Same as compile_source but from a block
|
|
||||||
#
|
|
||||||
def compile_block(&block)
|
|
||||||
@template = {}
|
|
||||||
instance_eval(&block)
|
|
||||||
@template
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Sets the object to be used as the data for the template
|
# Sets the object to be used as the data for the template
|
||||||
# Example:
|
# Example:
|
||||||
@ -49,7 +38,7 @@ module RablFastJson
|
|||||||
#
|
#
|
||||||
def collection(data, options = {})
|
def collection(data, options = {})
|
||||||
object(data)
|
object(data)
|
||||||
@template.root_name = options[:root] if root_given?(options)
|
@template.root_name = options[:root] if options[:root]
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -80,14 +69,14 @@ module RablFastJson
|
|||||||
# child(:@posts, :root => :posts) { attribute :id }
|
# child(:@posts, :root => :posts) { attribute :id }
|
||||||
# child(:posts, :partial => 'posts/base')
|
# child(:posts, :partial => 'posts/base')
|
||||||
#
|
#
|
||||||
def child(name_or_data, options = {}, &block)
|
def child(name_or_data, options = {})
|
||||||
data, name = extract_data_and_name(name_or_data)
|
data, name = extract_data_and_name(name_or_data)
|
||||||
name = options[:root] if root_given?(options)
|
name = options[:root] if options[:root]
|
||||||
if partial_given?(options)
|
if options[:partial]
|
||||||
template = Library.instance.get(options[:partial])
|
template = Library.instance.get(options[:partial])
|
||||||
@template[name] = template.merge!(:_data => data)
|
@template[name] = template.merge!(:_data => data)
|
||||||
else
|
elsif block_given?
|
||||||
_compile_sub_template(name, data, &block)
|
@template[name] = sub_compile(data) { yield }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -96,11 +85,11 @@ module RablFastJson
|
|||||||
# Example:
|
# Example:
|
||||||
# glue(:@user) { attribute :name }
|
# glue(:@user) { attribute :name }
|
||||||
#
|
#
|
||||||
def glue(data, &block)
|
def glue(data)
|
||||||
return unless block_given?
|
return unless block_given?
|
||||||
name = :"_glue#{@glue_count}"
|
name = :"_glue#{@glue_count}"
|
||||||
@glue_count += 1
|
@glue_count += 1
|
||||||
_compile_sub_template(name, data, &block)
|
@template[name] = sub_compile(data) { yield }
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -159,10 +148,13 @@ module RablFastJson
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def _compile_sub_template(name, data, &block) #:nodoc:
|
def sub_compile(data)
|
||||||
compiler = Compiler.new
|
return {} unless block_given?
|
||||||
template = compiler.compile_block(&block)
|
old_template, @template = @template, {}
|
||||||
@template[name] = template.merge!(:_data => data)
|
yield
|
||||||
|
@template.merge!(:_data => data)
|
||||||
|
ensure
|
||||||
|
@template = old_template
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -1,4 +1,4 @@
|
|||||||
module RablFastJson
|
module RablRails
|
||||||
module Handlers
|
module Handlers
|
||||||
class Rabl
|
class Rabl
|
||||||
cattr_accessor :default_format
|
cattr_accessor :default_format
|
||||||
@ -6,7 +6,7 @@ module RablFastJson
|
|||||||
|
|
||||||
def self.call(template)
|
def self.call(template)
|
||||||
%{
|
%{
|
||||||
RablFastJson::Library.instance.
|
RablRails::Library.instance.
|
||||||
get_rendered_template(#{template.source.inspect}, self)
|
get_rendered_template(#{template.source.inspect}, self)
|
||||||
}
|
}
|
||||||
end
|
end
|
@ -1,27 +1,25 @@
|
|||||||
require 'singleton'
|
require 'singleton'
|
||||||
|
|
||||||
module RablFastJson
|
module RablRails
|
||||||
class Library
|
class Library
|
||||||
include Singleton
|
include Singleton
|
||||||
|
|
||||||
attr_accessor :view_renderer
|
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@cached_templates = {}
|
@cached_templates = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_rendered_template(source, context)
|
def get_rendered_template(source, context)
|
||||||
path = context.instance_variable_get(:@virtual_path)
|
path = context.instance_variable_get(:@virtual_path)
|
||||||
@view_renderer = context.instance_variable_get(:@view_renderer)
|
@lookup_context = context.lookup_context
|
||||||
|
|
||||||
compiled_template = get_compiled_template(path, source)
|
compiled_template = get_compiled_template(path, source)
|
||||||
compiled_template.context = context
|
|
||||||
body = compiled_template.render
|
format = context.params[:format] || 'json'
|
||||||
ActiveSupport::JSON.encode(compiled_template.root_name ? { compiled_template.root_name => body } : body)
|
Renderers.const_get(format.upcase!).new(context).render(compiled_template)
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_compiled_template(path, source)
|
def get_compiled_template(path, source)
|
||||||
if path && RablFastJson.cache_templates?
|
if path && RablRails.cache_templates?
|
||||||
@cached_templates[path] ||= Compiler.new.compile_source(source)
|
@cached_templates[path] ||= Compiler.new.compile_source(source)
|
||||||
@cached_templates[path].dup
|
@cached_templates[path].dup
|
||||||
else
|
else
|
||||||
@ -31,8 +29,8 @@ module RablFastJson
|
|||||||
|
|
||||||
def get(path)
|
def get(path)
|
||||||
template = @cached_templates[path]
|
template = @cached_templates[path]
|
||||||
return template unless template.nil?
|
return template if template
|
||||||
t = @view_renderer.lookup_context.find_template(path, [], false)
|
t = @lookup_context.find_template(path, [], false)
|
||||||
get_compiled_template(path, t.source)
|
get_compiled_template(path, t.source)
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -1,8 +1,8 @@
|
|||||||
module RablFastJson
|
module RablRails
|
||||||
class Railtie < Rails::Railtie
|
class Railtie < Rails::Railtie
|
||||||
initializer "rabl.initialize" do |app|
|
initializer "rabl.initialize" do |app|
|
||||||
ActiveSupport.on_load(:action_view) do
|
ActiveSupport.on_load(:action_view) do
|
||||||
ActionView::Template.register_template_handler :rabl, RablFastJson::Handlers::Rabl
|
ActionView::Template.register_template_handler :rabl, RablRails::Handlers::Rabl
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
2
lib/rabl-rails/renderer.rb
Normal file
2
lib/rabl-rails/renderer.rb
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
require 'rabl-rails/renderers/base'
|
||||||
|
require 'rabl-rails/renderers/json'
|
114
lib/rabl-rails/renderers/base.rb
Normal file
114
lib/rabl-rails/renderers/base.rb
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
module RablRails
|
||||||
|
module Renderers
|
||||||
|
class PartialError < StandardError; end
|
||||||
|
|
||||||
|
class Base
|
||||||
|
|
||||||
|
def initialize(context) # :nodoc:
|
||||||
|
@_context = context
|
||||||
|
setup_render_context
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Render a template.
|
||||||
|
# Uses the compiled template source to get a hash with the actual
|
||||||
|
# data and then format the result according to the `format_result`
|
||||||
|
# method defined by the renderer.
|
||||||
|
#
|
||||||
|
def render(template)
|
||||||
|
collection_or_resource = @_context.instance_variable_get(template.data) if template.data
|
||||||
|
output_hash = collection_or_resource.respond_to?(:each) ? render_collection(collection_or_resource, template.source) :
|
||||||
|
render_resource(collection_or_resource, template.source)
|
||||||
|
output_hash = { template.root_name => output_hash } if template.root_name
|
||||||
|
format_output(output_hash)
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Format a hash into the desired output.
|
||||||
|
# Renderer subclasses must implement this method
|
||||||
|
#
|
||||||
|
def format_output(hash)
|
||||||
|
raise "Muse be implemented by renderer"
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
#
|
||||||
|
# Render a single resource as a hash, according to the compiled
|
||||||
|
# template source passed.
|
||||||
|
#
|
||||||
|
def render_resource(data, source)
|
||||||
|
source.inject({}) { |output, current|
|
||||||
|
key, value = current
|
||||||
|
|
||||||
|
out = case value
|
||||||
|
when Symbol
|
||||||
|
data.send(value) # attributes
|
||||||
|
when Proc
|
||||||
|
instance_exec data, &value # node
|
||||||
|
when Array # node with condition
|
||||||
|
next output if !instance_exec data, &(value.first)
|
||||||
|
instance_exec data, &(value.last)
|
||||||
|
when Hash
|
||||||
|
current_value = value.dup
|
||||||
|
data_symbol = current_value.delete(:_data)
|
||||||
|
object = data_symbol.nil? ? data : data_symbol.to_s.start_with?('@') ? @_context.instance_variable_get(data_symbol) : data.send(data_symbol)
|
||||||
|
|
||||||
|
if key.to_s.start_with?('_') # glue
|
||||||
|
current_value.each_pair { |k, v|
|
||||||
|
output[k] = object.send(v)
|
||||||
|
}
|
||||||
|
next output
|
||||||
|
else # child
|
||||||
|
object.respond_to?(:each) ? render_collection(object, current_value) : render_resource(object, current_value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
output[key] = out
|
||||||
|
output
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Call the render_resource mtehod on each object of the collection
|
||||||
|
# and return an array of the returned values.
|
||||||
|
#
|
||||||
|
def render_collection(collection, source)
|
||||||
|
collection.map { |o| render_resource(o, source) }
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Allow to use partial inside of node blocks (they are evaluated at)
|
||||||
|
# rendering time.
|
||||||
|
#
|
||||||
|
def partial(template_path, options = {})
|
||||||
|
raise PartialError.new("No object was given to partial #{template_path}") unless options[:object]
|
||||||
|
object = options[:object]
|
||||||
|
|
||||||
|
return [] if object.respond_to?(:empty?) && object.empty?
|
||||||
|
|
||||||
|
template = Library.instance.get(template_path)
|
||||||
|
object.respond_to?(:each) ? render_collection(object, template.source) : render_resource(object, template.source)
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# If a method is called inside a 'node' property or a 'if' lambda
|
||||||
|
# it will be passed to context if it exists or treated as a standard
|
||||||
|
# missing method.
|
||||||
|
#
|
||||||
|
def method_missing(name, *args, &block)
|
||||||
|
@_context.respond_to?(name) ? @_context.send(name, *args, &block) : super
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copy assigns from controller's context into this
|
||||||
|
# renderer context to include instances variables when
|
||||||
|
# evaluating 'node' properties.
|
||||||
|
#
|
||||||
|
def setup_render_context
|
||||||
|
@_context.instance_variable_get(:@_assigns).each_pair { |k, v|
|
||||||
|
instance_variable_set("@#{k}", v) unless k.start_with?('_') || k == @data
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
9
lib/rabl-rails/renderers/json.rb
Normal file
9
lib/rabl-rails/renderers/json.rb
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
module RablRails
|
||||||
|
module Renderers
|
||||||
|
class JSON < Base
|
||||||
|
def format_output(hash)
|
||||||
|
ActiveSupport::JSON.encode(hash)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
11
lib/rabl-rails/template.rb
Normal file
11
lib/rabl-rails/template.rb
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
module RablRails
|
||||||
|
class CompiledTemplate
|
||||||
|
attr_accessor :source, :data, :root_name
|
||||||
|
|
||||||
|
delegate :[], :[]=, :merge!, :to => :source
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
@source = {}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -1,3 +1,3 @@
|
|||||||
module RablFastJson
|
module RablRails
|
||||||
VERSION = '0.1.0'
|
VERSION = '0.1.0'
|
||||||
end
|
end
|
@ -1,4 +1,4 @@
|
|||||||
# desc "Explaining what the task does"
|
# desc "Explaining what the task does"
|
||||||
# task :rabl-fast-json do
|
# task :rabl-rails do
|
||||||
# # Task goes here
|
# # Task goes here
|
||||||
# end
|
# end
|
@ -1,17 +1,17 @@
|
|||||||
$:.push File.expand_path("../lib", __FILE__)
|
$:.push File.expand_path("../lib", __FILE__)
|
||||||
|
|
||||||
# Maintain your gem's version:
|
# Maintain your gem's version:
|
||||||
require "rabl-fast-json/version"
|
require "rabl-rails/version"
|
||||||
|
|
||||||
# Describe your gem and declare its dependencies:
|
# Describe your gem and declare its dependencies:
|
||||||
Gem::Specification.new do |s|
|
Gem::Specification.new do |s|
|
||||||
s.name = "rabl-fast-json"
|
s.name = "rabl-rails"
|
||||||
s.version = RablFastJson::VERSION
|
s.version = RablRails::VERSION
|
||||||
s.authors = ["TODO: Your name"]
|
s.authors = ["TODO: Your name"]
|
||||||
s.email = ["TODO: Your email"]
|
s.email = ["TODO: Your email"]
|
||||||
s.homepage = "TODO"
|
s.homepage = "TODO"
|
||||||
s.summary = "TODO: Summary of RablFastJson."
|
s.summary = "TODO: Summary of RablRails."
|
||||||
s.description = "TODO: Description of RablFastJson."
|
s.description = "TODO: Description of RablRails."
|
||||||
|
|
||||||
s.files = Dir["{app,config,db,lib}/**/*"] + ["MIT-LICENSE", "Rakefile", "README.md"]
|
s.files = Dir["{app,config,db,lib}/**/*"] + ["MIT-LICENSE", "Rakefile", "README.md"]
|
||||||
s.test_files = Dir["test/**/*"]
|
s.test_files = Dir["test/**/*"]
|
@ -3,12 +3,12 @@ require 'test_helper'
|
|||||||
class CacheTemplatesTest < ActiveSupport::TestCase
|
class CacheTemplatesTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
setup do
|
setup do
|
||||||
RablFastJson::Library.reset_instance
|
RablRails::Library.reset_instance
|
||||||
@library = RablFastJson::Library.instance
|
@library = RablRails::Library.instance
|
||||||
|
RablRails.cache_templates = true
|
||||||
end
|
end
|
||||||
|
|
||||||
test "cache templates if perform_caching is active and cache_templates is enabled" do
|
test "cache templates if perform_caching is active and cache_templates is enabled" do
|
||||||
RablFastJson.cache_templates = true
|
|
||||||
ActionController::Base.stub(:perform_caching).and_return(true)
|
ActionController::Base.stub(:perform_caching).and_return(true)
|
||||||
@library.get_compiled_template('some/path', "")
|
@library.get_compiled_template('some/path', "")
|
||||||
t = @library.get_compiled_template('some/path', "attribute :id")
|
t = @library.get_compiled_template('some/path', "attribute :id")
|
||||||
@ -17,18 +17,18 @@ class CacheTemplatesTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
test "cached templates should not be modifiable in place" do
|
test "cached templates should not be modifiable in place" do
|
||||||
RablFastJson.cache_templates = true
|
|
||||||
ActionController::Base.stub(:perform_caching).and_return(true)
|
ActionController::Base.stub(:perform_caching).and_return(true)
|
||||||
t = @library.get_compiled_template('some/path', "")
|
@library.get_compiled_template('some/path', "")
|
||||||
assert_nil t.context
|
t = @library.get_compiled_template('some/path', "attribute :id")
|
||||||
t.context = "foobar"
|
|
||||||
assert_nil @library.get_compiled_template('some/path', "").context
|
assert_equal({}, t.source)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "don't cache templates cache_templates is enabled but perform_caching is not active" do
|
test "don't cache templates cache_templates is enabled but perform_caching is not active" do
|
||||||
RablFastJson.cache_templates = true
|
|
||||||
ActionController::Base.stub(:perform_caching).and_return(false)
|
ActionController::Base.stub(:perform_caching).and_return(false)
|
||||||
|
@library.get_compiled_template('some/path', "")
|
||||||
|
t = @library.get_compiled_template('some/path', "attribute :id")
|
||||||
|
|
||||||
refute_equal @library.get_compiled_template('some/path', ""), @library.get_compiled_template('some/path', "")
|
assert_equal({ :id => :id }, t.source)
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -4,13 +4,47 @@ class CompilerTest < ActiveSupport::TestCase
|
|||||||
|
|
||||||
setup do
|
setup do
|
||||||
@user = User.new
|
@user = User.new
|
||||||
@compiler = RablFastJson::Compiler.new
|
@compiler = RablRails::Compiler.new
|
||||||
end
|
end
|
||||||
|
|
||||||
test "compiler return a compiled template" do
|
test "compiler return a compiled template" do
|
||||||
assert_instance_of RablFastJson::CompiledTemplate, @compiler.compile_source("")
|
assert_instance_of RablRails::CompiledTemplate, @compiler.compile_source("")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "object set data for the template" do
|
||||||
|
t = @compiler.compile_source(%{ object :@user })
|
||||||
|
assert_equal :@user, t.data
|
||||||
|
assert_equal({}, t.source)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "object property can define root name" do
|
||||||
|
t = @compiler.compile_source(%{ object :@user => :author })
|
||||||
|
assert_equal :@user, t.data
|
||||||
|
assert_equal :author, t.root_name
|
||||||
|
assert_equal({}, t.source)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "collection set the data for the template" do
|
||||||
|
t = @compiler.compile_source(%{ collection :@user })
|
||||||
|
assert_equal :@user, t.data
|
||||||
|
assert_equal({}, t.source)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "collection property can define root name" do
|
||||||
|
t = @compiler.compile_source(%{ collection :@user => :users })
|
||||||
|
assert_equal :@user, t.data
|
||||||
|
assert_equal :users, t.root_name
|
||||||
|
assert_equal({}, t.source)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "collection property can define root name via options" do
|
||||||
|
t = @compiler.compile_source(%{ collection :@user, :root => :users })
|
||||||
|
assert_equal :@user, t.data
|
||||||
|
assert_equal :users, t.root_name
|
||||||
|
end
|
||||||
|
|
||||||
|
# Compilation
|
||||||
|
|
||||||
test "simple attributes are compiled to hash" do
|
test "simple attributes are compiled to hash" do
|
||||||
t = @compiler.compile_source(%{ attributes :id, :name })
|
t = @compiler.compile_source(%{ attributes :id, :name })
|
||||||
assert_equal({ :id => :id, :name => :name}, t.source)
|
assert_equal({ :id => :id, :name => :name}, t.source)
|
||||||
@ -57,11 +91,10 @@ class CompilerTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
test "child with succint partial notation" do
|
test "child with succint partial notation" do
|
||||||
@view_renderer = mock()
|
mock_template = RablRails::CompiledTemplate.new
|
||||||
@view_renderer.stub_chain(:lookup_context, :find_template).with('users/base', [], false).and_return(
|
mock_template.source = { :id => :id }
|
||||||
mock(:source => %{ attribute :id }))
|
RablRails::Library.reset_instance
|
||||||
RablFastJson::Library.reset_instance
|
RablRails::Library.instance.stub(:get).with('users/base').and_return(mock_template)
|
||||||
RablFastJson::Library.instance.view_renderer = @view_renderer
|
|
||||||
|
|
||||||
t = @compiler.compile_source(%{child(:user, :partial => 'users/base') })
|
t = @compiler.compile_source(%{child(:user, :partial => 'users/base') })
|
||||||
assert_equal( {:user => { :_data => :user, :id => :id } }, t.source)
|
assert_equal( {:user => { :_data => :user, :id => :id } }, t.source)
|
||||||
@ -84,42 +117,10 @@ class CompilerTest < ActiveSupport::TestCase
|
|||||||
}, t.source)
|
}, t.source)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "object set data for the template" do
|
|
||||||
t = @compiler.compile_source(%{ object :@user })
|
|
||||||
assert_equal :@user, t.data
|
|
||||||
assert_equal({}, t.source)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "object property can define root name" do
|
|
||||||
t = @compiler.compile_source(%{ object :@user => :author })
|
|
||||||
assert_equal :@user, t.data
|
|
||||||
assert_equal :author, t.root_name
|
|
||||||
assert_equal({}, t.source)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "collection set the data for the template" do
|
|
||||||
t = @compiler.compile_source(%{ collection :@user })
|
|
||||||
assert_equal :@user, t.data
|
|
||||||
assert_equal({}, t.source)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "collection property can define root name" do
|
|
||||||
t = @compiler.compile_source(%{ collection :@user => :users })
|
|
||||||
assert_equal :@user, t.data
|
|
||||||
assert_equal :users, t.root_name
|
|
||||||
assert_equal({}, t.source)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "collection property can define root name via options" do
|
|
||||||
t = @compiler.compile_source(%{ collection :@user, :root => :users })
|
|
||||||
assert_equal :@user, t.data
|
|
||||||
assert_equal :users, t.root_name
|
|
||||||
end
|
|
||||||
|
|
||||||
test "extends use other template source as itself" do
|
test "extends use other template source as itself" do
|
||||||
template = mock('template', :source => { :id => :id })
|
template = mock('template', :source => { :id => :id })
|
||||||
RablFastJson::Library.reset_instance
|
RablRails::Library.reset_instance
|
||||||
RablFastJson::Library.instance.stub(:get).with('users/base').and_return(template)
|
RablRails::Library.instance.stub(:get).with('users/base').and_return(template)
|
||||||
t = @compiler.compile_source(%{ extends 'users/base' })
|
t = @compiler.compile_source(%{ extends 'users/base' })
|
||||||
assert_equal({ :id => :id }, t.source)
|
assert_equal({ :id => :id }, t.source)
|
||||||
end
|
end
|
||||||
|
@ -15,21 +15,17 @@ class DeepNestingTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
setup do
|
setup do
|
||||||
RablFastJson::Library.reset_instance
|
RablRails::Library.reset_instance
|
||||||
@post = Post.new(42, 'I rock !')
|
@post = Post.new(42, 'I rock !')
|
||||||
@user = User.new(1, 'foobar', 'male')
|
@user = User.new(1, 'foobar', 'male')
|
||||||
@user.stub(:posts).and_return([@post])
|
@user.stub(:posts).and_return([@post])
|
||||||
@user.stub(:respond_to?).with(:each).and_return(false)
|
@user.stub(:respond_to?).with(:each).and_return(false)
|
||||||
|
|
||||||
@view_renderer = mock()
|
|
||||||
@view_renderer.stub_chain(:lookup_context, :find_template).with('comments/show', [], false).and_return(
|
|
||||||
mock(:source => %{ object :@comment\n attribute :content }))
|
|
||||||
|
|
||||||
@context = Context.new
|
@context = Context.new
|
||||||
@context.stub(:instance_variable_get).with(:@user).and_return(@user)
|
@context.stub(:instance_variable_get).with(:@user).and_return(@user)
|
||||||
@context.stub(:instance_variable_get).with(:@view_renderer).and_return(@view_renderer)
|
|
||||||
@context.stub(:instance_variable_get).with(:@virtual_path).and_return('users/show')
|
@context.stub(:instance_variable_get).with(:@virtual_path).and_return('users/show')
|
||||||
@context.stub(:instance_variable_get).with(:@_assigns).and_return({})
|
@context.stub(:instance_variable_get).with(:@_assigns).and_return({})
|
||||||
|
@context.stub(:lookup_context).and_return(mock(:find_template => mock(:source => %{ object :@comment\n attribute :content })))
|
||||||
end
|
end
|
||||||
|
|
||||||
test "compile and render deep nesting template" do
|
test "compile and render deep nesting template" do
|
||||||
@ -54,7 +50,7 @@ class DeepNestingTest < ActiveSupport::TestCase
|
|||||||
{ :content => 'second' }
|
{ :content => 'second' }
|
||||||
]
|
]
|
||||||
}]
|
}]
|
||||||
}), RablFastJson::Library.instance.get_rendered_template(source, @context))
|
}), RablRails::Library.instance.get_rendered_template(source, @context))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ require 'test_helper'
|
|||||||
|
|
||||||
class NonRestfulResponseTest < ActiveSupport::TestCase
|
class NonRestfulResponseTest < ActiveSupport::TestCase
|
||||||
setup do
|
setup do
|
||||||
RablFastJson::Library.reset_instance
|
RablRails::Library.reset_instance
|
||||||
|
|
||||||
@user = User.new(1, 'foo', 'male')
|
@user = User.new(1, 'foo', 'male')
|
||||||
@user.stub_chain(:posts, :count).and_return(10)
|
@user.stub_chain(:posts, :count).and_return(10)
|
||||||
@ -10,9 +10,9 @@ class NonRestfulResponseTest < ActiveSupport::TestCase
|
|||||||
|
|
||||||
@context = Context.new
|
@context = Context.new
|
||||||
@context.stub(:instance_variable_get).with(:@user).and_return(@user)
|
@context.stub(:instance_variable_get).with(:@user).and_return(@user)
|
||||||
@context.stub(:instance_variable_get).with(:@view_renderer).and_return(mock())
|
|
||||||
@context.stub(:instance_variable_get).with(:@virtual_path).and_return('user/show')
|
@context.stub(:instance_variable_get).with(:@virtual_path).and_return('user/show')
|
||||||
@context.stub(:instance_variable_get).with(:@_assigns).and_return({'user' => @user})
|
@context.stub(:instance_variable_get).with(:@_assigns).and_return({'user' => @user})
|
||||||
|
@context.stub(:lookup_context)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "compile and render non restful resource" do
|
test "compile and render non restful resource" do
|
||||||
@ -30,6 +30,6 @@ class NonRestfulResponseTest < ActiveSupport::TestCase
|
|||||||
:id => 1,
|
:id => 1,
|
||||||
:name => 'foo'
|
:name => 'foo'
|
||||||
}
|
}
|
||||||
}), RablFastJson::Library.instance.get_rendered_template(source, @context))
|
}), RablRails::Library.instance.get_rendered_template(source, @context))
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -1,72 +1,88 @@
|
|||||||
require 'test_helper'
|
require 'test_helper'
|
||||||
|
|
||||||
class TestCompiledTemplate < ActiveSupport::TestCase
|
class TestJsonRenderer < ActiveSupport::TestCase
|
||||||
|
|
||||||
setup do
|
setup do
|
||||||
@context = Context.new
|
|
||||||
@data = User.new(1, 'foobar', 'male')
|
@data = User.new(1, 'foobar', 'male')
|
||||||
@data.stub(:respond_to?).with(:each).and_return(false)
|
@data.stub(:respond_to?).with(:each).and_return(false)
|
||||||
|
|
||||||
|
@context = Context.new
|
||||||
@context.stub(:instance_variable_get).with(:@data).and_return(@data)
|
@context.stub(:instance_variable_get).with(:@data).and_return(@data)
|
||||||
@context.stub(:instance_variable_get).with(:@_assigns).and_return({})
|
@context.stub(:instance_variable_get).with(:@_assigns).and_return({})
|
||||||
@template = RablFastJson::CompiledTemplate.new
|
|
||||||
@template.context = @context
|
@template = RablRails::CompiledTemplate.new
|
||||||
@template.data = :@data
|
@template.data = :@data
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def render_json_output
|
||||||
|
RablRails::Renderers::JSON.new(@context).render(@template).to_s
|
||||||
|
end
|
||||||
|
|
||||||
test "render object wth empty template" do
|
test "render object wth empty template" do
|
||||||
@template.source = {}
|
@template.source = {}
|
||||||
assert_equal({}, @template.render)
|
assert_equal %q({}), render_json_output
|
||||||
end
|
end
|
||||||
|
|
||||||
test "render collection with empty template" do
|
test "render collection with empty template" do
|
||||||
@context.stub(:instance_variable_get).with(:@data).and_return([@data])
|
@context.stub(:instance_variable_get).with(:@data).and_return([@data])
|
||||||
@template.source = {}
|
@template.source = {}
|
||||||
assert_equal([{}], @template.render)
|
assert_equal %q([{}]), render_json_output
|
||||||
end
|
end
|
||||||
|
|
||||||
test "render single object attributes" do
|
test "render single object attributes" do
|
||||||
@template.source = { :id => :id, :name => :name }
|
@template.source = { :id => :id, :name => :name }
|
||||||
assert_equal({ :id => 1, :name => 'foobar'}, @template.render)
|
assert_equal %q({"id":1,"name":"foobar"}), render_json_output
|
||||||
end
|
end
|
||||||
|
|
||||||
test "render object as a child" do
|
test "render child with object association" do
|
||||||
|
@data.stub(:address).and_return(mock(:city => 'Paris'))
|
||||||
|
@template.source = { :address => { :_data => :address, :city => :city } }
|
||||||
|
assert_equal %q({"address":{"city":"Paris"}}), render_json_output
|
||||||
|
end
|
||||||
|
|
||||||
|
test "render child with arbitrary data source" do
|
||||||
@template.source = { :author => { :_data => :@data, :name => :name } }
|
@template.source = { :author => { :_data => :@data, :name => :name } }
|
||||||
assert_equal({ :author => { :name => 'foobar' } }, @template.render)
|
assert_equal %q({"author":{"name":"foobar"}}), render_json_output
|
||||||
end
|
end
|
||||||
|
|
||||||
test "render glued attributes from single object" do
|
test "render glued attributes from single object" do
|
||||||
@template.source = { :_glue0 => { :_data => :@data, :name => :name } }
|
@template.source = { :_glue0 => { :_data => :@data, :name => :name } }
|
||||||
assert_equal({ :name => 'foobar' }, @template.render)
|
assert_equal %q({"name":"foobar"}), render_json_output
|
||||||
end
|
end
|
||||||
|
|
||||||
test "render collection with attributes" do
|
test "render collection with attributes" do
|
||||||
@data = [User.new(1, 'foo', 'male'), User.new(2, 'bar', 'female')]
|
@data = [User.new(1, 'foo', 'male'), User.new(2, 'bar', 'female')]
|
||||||
@context.stub(:instance_variable_get).with(:@data).and_return(@data)
|
@context.stub(:instance_variable_get).with(:@data).and_return(@data)
|
||||||
@template.source = { :uid => :id, :name => :name, :gender => :sex }
|
@template.source = { :uid => :id, :name => :name, :gender => :sex }
|
||||||
assert_equal([
|
assert_equal %q([{"uid":1,"name":"foo","gender":"male"},{"uid":2,"name":"bar","gender":"female"}]), render_json_output
|
||||||
{ :uid => 1, :name => 'foo', :gender => 'male'},
|
|
||||||
{ :uid => 2, :name => 'bar', :gender => 'female'}
|
|
||||||
], @template.render)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test "render node property" do
|
test "render node property" do
|
||||||
proc = lambda { |object| object.sex }
|
proc = lambda { |object| object.name }
|
||||||
@template.source = { :sex => proc }
|
@template.source = { :name => proc }
|
||||||
assert_equal({ :sex => 'male' }, @template.render)
|
assert_equal %q({"name":"foobar"}), render_json_output
|
||||||
end
|
end
|
||||||
|
|
||||||
test "render node property with true condition" do
|
test "render node property with true condition" do
|
||||||
condition = lambda { |u| true }
|
condition = lambda { |u| true }
|
||||||
proc = lambda { |object| object.name }
|
proc = lambda { |object| object.name }
|
||||||
@template.source = { :name => [condition, proc] }
|
@template.source = { :name => [condition, proc] }
|
||||||
assert_equal({ :name => 'foobar' }, @template.render)
|
assert_equal %q({"name":"foobar"}), render_json_output
|
||||||
end
|
end
|
||||||
|
|
||||||
test "render node property with false condition" do
|
test "render node property with false condition" do
|
||||||
condition = lambda { |u| false }
|
condition = lambda { |u| false }
|
||||||
proc = lambda { |object| object.name }
|
proc = lambda { |object| object.name }
|
||||||
@template.source = { :name => [condition, proc] }
|
@template.source = { :name => [condition, proc] }
|
||||||
assert_equal({}, @template.render)
|
assert_equal %q({}), render_json_output
|
||||||
|
end
|
||||||
|
|
||||||
|
test "node with context method call" do
|
||||||
|
@context.stub(:respond_to?).with(:context_method).and_return(true)
|
||||||
|
@context.stub(:context_method).and_return('marty')
|
||||||
|
proc = lambda { |object| context_method }
|
||||||
|
@template.source = { :name => proc }
|
||||||
|
assert_equal %q({"name":"marty"}), render_json_output
|
||||||
end
|
end
|
||||||
|
|
||||||
test "partial should be evaluated at rendering time" do
|
test "partial should be evaluated at rendering time" do
|
||||||
@ -75,28 +91,28 @@ class TestCompiledTemplate < ActiveSupport::TestCase
|
|||||||
@data.stub(:respond_to?).with(:empty?).and_return(false)
|
@data.stub(:respond_to?).with(:empty?).and_return(false)
|
||||||
|
|
||||||
# Stub Library#get
|
# Stub Library#get
|
||||||
t = RablFastJson::CompiledTemplate.new
|
t = RablRails::CompiledTemplate.new
|
||||||
t.source, t.context = { :name => :name }, @context
|
t.source = { :name => :name }
|
||||||
RablFastJson::Library.reset_instance
|
RablRails::Library.reset_instance
|
||||||
RablFastJson::Library.instance.should_receive(:get).with('users/base').and_return(t)
|
RablRails::Library.instance.should_receive(:get).with('users/base').and_return(t)
|
||||||
|
|
||||||
@template.data = false
|
@template.data = false
|
||||||
@template.source = { :user => ->(s) { partial('users/base', :object => @user) } }
|
@template.source = { :user => ->(s) { partial('users/base', :object => @user) } }
|
||||||
|
|
||||||
assert_equal({ :user => { :name => 'foobar' } }, @template.render)
|
assert_equal %q({"user":{"name":"foobar"}}), render_json_output
|
||||||
end
|
end
|
||||||
|
|
||||||
test "partial with nil values should raise an error" do
|
test "partial with no values should raise an error" do
|
||||||
@template.data = false
|
@template.data = false
|
||||||
@template.source = { :user => ->(s) { partial('users/base') } }
|
@template.source = { :user => ->(s) { partial('users/base') } }
|
||||||
|
|
||||||
assert_raises(RuntimeError) { @template.render }
|
assert_raises(RablRails::Renderers::PartialError) { render_json_output }
|
||||||
end
|
end
|
||||||
|
|
||||||
test "partial with empty values should not raise an error" do
|
test "partial with empty values should not raise an error" do
|
||||||
@template.data = false
|
@template.data = false
|
||||||
@template.source = { :users => ->(s) { partial('users/base', :object => []) } }
|
@template.source = { :users => ->(s) { partial('users/base', :object => []) } }
|
||||||
|
|
||||||
assert_equal({ :users => [] }, @template.render)
|
assert_equal %q({"users":[]}), render_json_output
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -21,7 +21,7 @@ class <<Singleton
|
|||||||
alias_method_chain :included, :reset
|
alias_method_chain :included, :reset
|
||||||
end
|
end
|
||||||
|
|
||||||
require 'rabl-fast-json'
|
require 'rabl-rails'
|
||||||
|
|
||||||
module ActiveSupport
|
module ActiveSupport
|
||||||
class TestCase
|
class TestCase
|
||||||
@ -35,15 +35,10 @@ class Context
|
|||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@_assigns = {}
|
@_assigns = {}
|
||||||
@virtual_path = '/users'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_assign(key, value)
|
def params
|
||||||
@_assigns[key] = value
|
{}
|
||||||
end
|
|
||||||
|
|
||||||
def get_assign(key)
|
|
||||||
@_assigns[key]
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user