rabl-rails 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|