rabl-rails 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +69 -0
- data/MIT-LICENSE +20 -0
- data/README.md +248 -0
- data/Rakefile +35 -0
- data/lib/rabl-rails.rb +41 -0
- data/lib/rabl-rails/compiler.rb +146 -0
- data/lib/rabl-rails/handler.rb +15 -0
- data/lib/rabl-rails/library.rb +37 -0
- data/lib/rabl-rails/railtie.rb +9 -0
- data/lib/rabl-rails/renderer.rb +2 -0
- data/lib/rabl-rails/renderers/base.rb +116 -0
- data/lib/rabl-rails/renderers/json.rb +10 -0
- data/lib/rabl-rails/template.rb +11 -0
- data/lib/rabl-rails/version.rb +3 -0
- data/lib/tasks/rabl-rails.rake +4 -0
- data/rabl-rails.gemspec +23 -0
- data/test/cache_templates_test.rb +34 -0
- data/test/compiler_test.rb +163 -0
- data/test/deep_nesting_test.rb +58 -0
- data/test/non_restful_response_test.rb +35 -0
- data/test/renderers/json_renderer_test.rb +131 -0
- data/test/test_helper.rb +45 -0
- metadata +139 -0
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class DeepNestingTest < ActiveSupport::TestCase
|
4
|
+
|
5
|
+
class Post
|
6
|
+
attr_accessor :id, :title
|
7
|
+
|
8
|
+
def initialize(id, title)
|
9
|
+
@id, @title = id, title
|
10
|
+
end
|
11
|
+
|
12
|
+
def comments
|
13
|
+
[Struct.new(:id, :content).new(1, 'first'), Struct.new(:id, :content).new(2, 'second')]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
setup do
|
18
|
+
RablRails::Library.reset_instance
|
19
|
+
@post = Post.new(42, 'I rock !')
|
20
|
+
@user = User.new(1, 'foobar', 'male')
|
21
|
+
@user.stub(:posts).and_return([@post])
|
22
|
+
@user.stub(:respond_to?).with(:each).and_return(false)
|
23
|
+
|
24
|
+
@context = Context.new
|
25
|
+
@context.stub(:instance_variable_get).with(:@user).and_return(@user)
|
26
|
+
@context.stub(:instance_variable_get).with(:@virtual_path).and_return('users/show')
|
27
|
+
@context.stub(:instance_variable_get).with(:@_assigns).and_return({})
|
28
|
+
@context.stub(:lookup_context).and_return(mock(:find_template => mock(:source => %{ object :@comment\n attribute :content })))
|
29
|
+
end
|
30
|
+
|
31
|
+
test "compile and render deep nesting template" do
|
32
|
+
source = %{
|
33
|
+
object :@user
|
34
|
+
attributes :id, :name
|
35
|
+
child :posts do
|
36
|
+
attribute :title
|
37
|
+
child :comments do
|
38
|
+
extends 'comments/show'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
}
|
42
|
+
|
43
|
+
assert_equal(MultiJson.encode(:user => {
|
44
|
+
:id => 1,
|
45
|
+
:name => 'foobar',
|
46
|
+
:posts => [{
|
47
|
+
:title => 'I rock !',
|
48
|
+
:comments => [
|
49
|
+
{ :content => 'first' },
|
50
|
+
{ :content => 'second' }
|
51
|
+
]
|
52
|
+
}]
|
53
|
+
}), RablRails::Library.instance.get_rendered_template(source, @context))
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class NonRestfulResponseTest < ActiveSupport::TestCase
|
4
|
+
setup do
|
5
|
+
RablRails::Library.reset_instance
|
6
|
+
|
7
|
+
@user = User.new(1, 'foo', 'male')
|
8
|
+
@user.stub_chain(:posts, :count).and_return(10)
|
9
|
+
@user.stub(:respond_to?).with(:each).and_return(false)
|
10
|
+
|
11
|
+
@context = Context.new
|
12
|
+
@context.stub(:instance_variable_get).with(:@user).and_return(@user)
|
13
|
+
@context.stub(:instance_variable_get).with(:@virtual_path).and_return('user/show')
|
14
|
+
@context.stub(:instance_variable_get).with(:@_assigns).and_return({'user' => @user})
|
15
|
+
@context.stub(:lookup_context)
|
16
|
+
end
|
17
|
+
|
18
|
+
test "compile and render non restful resource" do
|
19
|
+
source = %{
|
20
|
+
object false
|
21
|
+
node(:post_count) { @user.posts.count }
|
22
|
+
child(:@user => :user) do
|
23
|
+
attributes :id, :name
|
24
|
+
end
|
25
|
+
}
|
26
|
+
|
27
|
+
assert_equal(MultiJson.encode({
|
28
|
+
:post_count => 10,
|
29
|
+
:user => {
|
30
|
+
:id => 1,
|
31
|
+
:name => 'foo'
|
32
|
+
}
|
33
|
+
}), RablRails::Library.instance.get_rendered_template(source, @context))
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TestJsonRenderer < ActiveSupport::TestCase
|
4
|
+
|
5
|
+
setup do
|
6
|
+
@data = User.new(1, 'foobar', 'male')
|
7
|
+
@data.stub(:respond_to?).with(:each).and_return(false)
|
8
|
+
|
9
|
+
@context = Context.new
|
10
|
+
@context.stub(:instance_variable_get).with(:@data).and_return(@data)
|
11
|
+
@context.stub(:instance_variable_get).with(:@_assigns).and_return({})
|
12
|
+
|
13
|
+
@template = RablRails::CompiledTemplate.new
|
14
|
+
@template.data = :@data
|
15
|
+
end
|
16
|
+
|
17
|
+
def render_json_output
|
18
|
+
RablRails::Renderers::JSON.new(@context).render(@template).to_s
|
19
|
+
end
|
20
|
+
|
21
|
+
test "render object wth empty template" do
|
22
|
+
@template.source = {}
|
23
|
+
assert_equal %q({}), render_json_output
|
24
|
+
end
|
25
|
+
|
26
|
+
test "render collection with empty template" do
|
27
|
+
@context.stub(:instance_variable_get).with(:@data).and_return([@data])
|
28
|
+
@template.source = {}
|
29
|
+
assert_equal %q([{}]), render_json_output
|
30
|
+
end
|
31
|
+
|
32
|
+
test "render single object attributes" do
|
33
|
+
@template.source = { :id => :id, :name => :name }
|
34
|
+
assert_equal %q({"id":1,"name":"foobar"}), render_json_output
|
35
|
+
end
|
36
|
+
|
37
|
+
test "render child with object association" do
|
38
|
+
@data.stub(:address).and_return(mock(:city => 'Paris'))
|
39
|
+
@template.source = { :address => { :_data => :address, :city => :city } }
|
40
|
+
assert_equal %q({"address":{"city":"Paris"}}), render_json_output
|
41
|
+
end
|
42
|
+
|
43
|
+
test "render child with arbitrary data source" do
|
44
|
+
@template.source = { :author => { :_data => :@data, :name => :name } }
|
45
|
+
assert_equal %q({"author":{"name":"foobar"}}), render_json_output
|
46
|
+
end
|
47
|
+
|
48
|
+
test "render glued attributes from single object" do
|
49
|
+
@template.source = { :_glue0 => { :_data => :@data, :name => :name } }
|
50
|
+
assert_equal %q({"name":"foobar"}), render_json_output
|
51
|
+
end
|
52
|
+
|
53
|
+
test "render collection with attributes" do
|
54
|
+
@data = [User.new(1, 'foo', 'male'), User.new(2, 'bar', 'female')]
|
55
|
+
@context.stub(:instance_variable_get).with(:@data).and_return(@data)
|
56
|
+
@template.source = { :uid => :id, :name => :name, :gender => :sex }
|
57
|
+
assert_equal %q([{"uid":1,"name":"foo","gender":"male"},{"uid":2,"name":"bar","gender":"female"}]), render_json_output
|
58
|
+
end
|
59
|
+
|
60
|
+
test "render node property" do
|
61
|
+
proc = lambda { |object| object.name }
|
62
|
+
@template.source = { :name => proc }
|
63
|
+
assert_equal %q({"name":"foobar"}), render_json_output
|
64
|
+
end
|
65
|
+
|
66
|
+
test "render node property with true condition" do
|
67
|
+
condition = lambda { |u| true }
|
68
|
+
proc = lambda { |object| object.name }
|
69
|
+
@template.source = { :name => [condition, proc] }
|
70
|
+
assert_equal %q({"name":"foobar"}), render_json_output
|
71
|
+
end
|
72
|
+
|
73
|
+
test "render node property with false condition" do
|
74
|
+
condition = lambda { |u| false }
|
75
|
+
proc = lambda { |object| object.name }
|
76
|
+
@template.source = { :name => [condition, proc] }
|
77
|
+
assert_equal %q({}), render_json_output
|
78
|
+
end
|
79
|
+
|
80
|
+
test "node with context method call" do
|
81
|
+
@context.stub(:respond_to?).with(:context_method).and_return(true)
|
82
|
+
@context.stub(:context_method).and_return('marty')
|
83
|
+
proc = lambda { |object| context_method }
|
84
|
+
@template.source = { :name => proc }
|
85
|
+
assert_equal %q({"name":"marty"}), render_json_output
|
86
|
+
end
|
87
|
+
|
88
|
+
test "partial should be evaluated at rendering time" do
|
89
|
+
# Set assigns
|
90
|
+
@context.stub(:instance_variable_get).with(:@_assigns).and_return({'user' => @data})
|
91
|
+
@data.stub(:respond_to?).with(:empty?).and_return(false)
|
92
|
+
|
93
|
+
# Stub Library#get
|
94
|
+
t = RablRails::CompiledTemplate.new
|
95
|
+
t.source = { :name => :name }
|
96
|
+
RablRails::Library.reset_instance
|
97
|
+
RablRails::Library.instance.should_receive(:compile_template_from_path).with('users/base').and_return(t)
|
98
|
+
|
99
|
+
@template.data = false
|
100
|
+
@template.source = { :user => ->(s) { partial('users/base', :object => @user) } }
|
101
|
+
|
102
|
+
assert_equal %q({"user":{"name":"foobar"}}), render_json_output
|
103
|
+
end
|
104
|
+
|
105
|
+
test "partial with no values should raise an error" do
|
106
|
+
@template.data = false
|
107
|
+
@template.source = { :user => ->(s) { partial('users/base') } }
|
108
|
+
|
109
|
+
assert_raises(RablRails::Renderers::PartialError) { render_json_output }
|
110
|
+
end
|
111
|
+
|
112
|
+
test "partial with empty values should not raise an error" do
|
113
|
+
@template.data = false
|
114
|
+
@template.source = { :users => ->(s) { partial('users/base', :object => []) } }
|
115
|
+
|
116
|
+
assert_equal %q({"users":[]}), render_json_output
|
117
|
+
end
|
118
|
+
|
119
|
+
test "render object with root node" do
|
120
|
+
@template.root_name = :author
|
121
|
+
@template.source = { :id => :id, :name => :name }
|
122
|
+
assert_equal %q({"author":{"id":1,"name":"foobar"}}), render_json_output
|
123
|
+
end
|
124
|
+
|
125
|
+
test "render object with root options set to false" do
|
126
|
+
RablRails.include_json_root = false
|
127
|
+
@template.root_name = :author
|
128
|
+
@template.source = { :id => :id, :name => :name }
|
129
|
+
assert_equal %q({"id":1,"name":"foobar"}), render_json_output
|
130
|
+
end
|
131
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
ENV["RAILS_ENV"] = "test"
|
2
|
+
$:.unshift File.expand_path('../../lib', __FILE__)
|
3
|
+
|
4
|
+
require 'rspec/mocks'
|
5
|
+
require 'minitest/autorun'
|
6
|
+
require 'active_support/test_case'
|
7
|
+
|
8
|
+
require 'action_controller'
|
9
|
+
|
10
|
+
require 'singleton'
|
11
|
+
class <<Singleton
|
12
|
+
def included_with_reset(klass)
|
13
|
+
included_without_reset(klass)
|
14
|
+
class <<klass
|
15
|
+
def reset_instance
|
16
|
+
Singleton.send :__init__, self
|
17
|
+
self
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
alias_method_chain :included, :reset
|
22
|
+
end
|
23
|
+
|
24
|
+
require 'rabl-rails'
|
25
|
+
|
26
|
+
module ActiveSupport
|
27
|
+
class TestCase
|
28
|
+
RSpec::Mocks::setup(self)
|
29
|
+
include RSpec::Mocks::ExampleMethods
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Context
|
34
|
+
attr_accessor :virtual_path
|
35
|
+
|
36
|
+
def initialize
|
37
|
+
@_assigns = {}
|
38
|
+
end
|
39
|
+
|
40
|
+
def params
|
41
|
+
{}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
User = Struct.new(:id, :name, :sex)
|
metadata
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rabl-rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Christopher Cocchi-Perrier
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-24 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '3.0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3.0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: railties
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '3.0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '3.0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: sqlite3
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: actionpack
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '3.0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '3.0'
|
78
|
+
description: Fast Rails 3+ templating system with JSON and XML support
|
79
|
+
email:
|
80
|
+
- cocchi.c@gmail.com
|
81
|
+
executables: []
|
82
|
+
extensions: []
|
83
|
+
extra_rdoc_files: []
|
84
|
+
files:
|
85
|
+
- .gitignore
|
86
|
+
- Gemfile
|
87
|
+
- Gemfile.lock
|
88
|
+
- MIT-LICENSE
|
89
|
+
- README.md
|
90
|
+
- Rakefile
|
91
|
+
- lib/rabl-rails.rb
|
92
|
+
- lib/rabl-rails/compiler.rb
|
93
|
+
- lib/rabl-rails/handler.rb
|
94
|
+
- lib/rabl-rails/library.rb
|
95
|
+
- lib/rabl-rails/railtie.rb
|
96
|
+
- lib/rabl-rails/renderer.rb
|
97
|
+
- lib/rabl-rails/renderers/base.rb
|
98
|
+
- lib/rabl-rails/renderers/json.rb
|
99
|
+
- lib/rabl-rails/template.rb
|
100
|
+
- lib/rabl-rails/version.rb
|
101
|
+
- lib/tasks/rabl-rails.rake
|
102
|
+
- rabl-rails.gemspec
|
103
|
+
- test/cache_templates_test.rb
|
104
|
+
- test/compiler_test.rb
|
105
|
+
- test/deep_nesting_test.rb
|
106
|
+
- test/non_restful_response_test.rb
|
107
|
+
- test/renderers/json_renderer_test.rb
|
108
|
+
- test/test_helper.rb
|
109
|
+
homepage: https://github.com/ccocchi/rabl-rails
|
110
|
+
licenses: []
|
111
|
+
post_install_message:
|
112
|
+
rdoc_options: []
|
113
|
+
require_paths:
|
114
|
+
- lib
|
115
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
116
|
+
none: false
|
117
|
+
requirements:
|
118
|
+
- - ! '>='
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0'
|
121
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
122
|
+
none: false
|
123
|
+
requirements:
|
124
|
+
- - ! '>='
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
127
|
+
requirements: []
|
128
|
+
rubyforge_project:
|
129
|
+
rubygems_version: 1.8.21
|
130
|
+
signing_key:
|
131
|
+
specification_version: 3
|
132
|
+
summary: Fast Rails 3+ templating system with JSON and XML support
|
133
|
+
test_files:
|
134
|
+
- test/cache_templates_test.rb
|
135
|
+
- test/compiler_test.rb
|
136
|
+
- test/deep_nesting_test.rb
|
137
|
+
- test/non_restful_response_test.rb
|
138
|
+
- test/renderers/json_renderer_test.rb
|
139
|
+
- test/test_helper.rb
|