gon 2.3.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of gon might be problematic. Click here for more details.
- data/CHANGELOG.md +11 -0
- data/README.md +29 -5
- data/lib/gon.rb +46 -73
- data/lib/gon/base.rb +58 -0
- data/lib/gon/global.rb +68 -0
- data/lib/gon/helpers.rb +23 -19
- data/lib/gon/jbuilder.rb +48 -8
- data/lib/gon/rabl.rb +49 -0
- data/lib/gon/request.rb +32 -0
- data/lib/gon/version.rb +1 -1
- data/spec/gon/basic_spec.rb +79 -0
- data/spec/gon/global_spec.rb +120 -0
- data/spec/gon/jbuilder_spec.rb +52 -0
- data/spec/gon/rabl_spec.rb +86 -0
- data/spec/gon/templates_spec.rb +52 -0
- data/spec/test_data/sample_with_helpers.rabl +3 -0
- metadata +86 -109
- data/spec/gon/gon_spec.rb +0 -215
data/lib/gon/rabl.rb
CHANGED
@@ -1,9 +1,27 @@
|
|
1
|
+
require 'action_view'
|
1
2
|
require 'rabl'
|
2
3
|
|
3
4
|
module Gon
|
4
5
|
module Rabl
|
5
6
|
class << self
|
6
7
|
|
8
|
+
def handler(args, global = false)
|
9
|
+
options = parse_options_from args, global
|
10
|
+
if global && !options[:template]
|
11
|
+
raise 'You should provide :template when use rabl with global variables'
|
12
|
+
end
|
13
|
+
|
14
|
+
include_helpers
|
15
|
+
|
16
|
+
data = parse_rabl \
|
17
|
+
Gon::Base.get_template_path(options, 'rabl'),
|
18
|
+
Gon::Base.get_controller(options)
|
19
|
+
|
20
|
+
[data, options]
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
7
25
|
def parse_rabl(rabl_path, controller)
|
8
26
|
source = File.read(rabl_path)
|
9
27
|
rabl_engine = ::Rabl::Engine.new(source, :format => 'json')
|
@@ -11,6 +29,37 @@ module Gon
|
|
11
29
|
JSON.parse(output)
|
12
30
|
end
|
13
31
|
|
32
|
+
def parse_options_from(args, global)
|
33
|
+
if old_api? args
|
34
|
+
unless global
|
35
|
+
text = "[DEPRECATION] view_path argument is now optional. "
|
36
|
+
text << "If you need to specify it, "
|
37
|
+
text << "please use gon.rabl(:template => 'path')"
|
38
|
+
warn text
|
39
|
+
end
|
40
|
+
|
41
|
+
args.extract_options!.merge(:template => args[0])
|
42
|
+
elsif new_api? args
|
43
|
+
args.first
|
44
|
+
else
|
45
|
+
{}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def include_helpers
|
50
|
+
unless ::Rabl::Engine.include? ::ActionView::Helpers
|
51
|
+
::Rabl::Engine.send(:include, ::ActionView::Helpers)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def old_api?(args)
|
56
|
+
args.first.is_a? String
|
57
|
+
end
|
58
|
+
|
59
|
+
def new_api?(args)
|
60
|
+
args.first.is_a? Hash
|
61
|
+
end
|
62
|
+
|
14
63
|
end
|
15
64
|
end
|
16
65
|
end
|
data/lib/gon/request.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
module Gon
|
2
|
+
module Request
|
3
|
+
class << self
|
4
|
+
|
5
|
+
def env
|
6
|
+
@request_env if defined? @request_env
|
7
|
+
end
|
8
|
+
|
9
|
+
def env=(environment)
|
10
|
+
@request_env = environment
|
11
|
+
@request_env['gon'] ||= {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def id
|
15
|
+
@request_id if defined? @request_id
|
16
|
+
end
|
17
|
+
|
18
|
+
def id=(request_id)
|
19
|
+
@request_id = request_id
|
20
|
+
end
|
21
|
+
|
22
|
+
def gon
|
23
|
+
env['gon'] if env
|
24
|
+
end
|
25
|
+
|
26
|
+
def clear
|
27
|
+
@request_env['gon'] = {}
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/gon/version.rb
CHANGED
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'gon'
|
2
|
+
|
3
|
+
describe Gon do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
Gon::Request.env = {}
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '#all_variables' do
|
10
|
+
|
11
|
+
it 'returns all variables in hash' do
|
12
|
+
Gon.a = 1
|
13
|
+
Gon.b = 2
|
14
|
+
Gon.c = Gon.a + Gon.b
|
15
|
+
Gon.c.should == 3
|
16
|
+
Gon.all_variables.should == {'a' => 1, 'b' => 2, 'c' => 3}
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'supports all data types' do
|
20
|
+
Gon.clear
|
21
|
+
Gon.int = 1
|
22
|
+
Gon.float = 1.1
|
23
|
+
Gon.string = 'string'
|
24
|
+
Gon.array = [ 1, 'string' ]
|
25
|
+
Gon.hash_var = { :a => 1, :b => '2'}
|
26
|
+
Gon.hash_w_array = { :a => [ 2, 3 ] }
|
27
|
+
Gon.klass = Hash
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#include_gon' do
|
33
|
+
|
34
|
+
before(:each) do
|
35
|
+
Gon.clear
|
36
|
+
Gon::Request.
|
37
|
+
instance_variable_set(:@request_id, request.object_id)
|
38
|
+
ActionView::Base.
|
39
|
+
instance_methods.
|
40
|
+
map(&:to_s).
|
41
|
+
include?('include_gon').should == true
|
42
|
+
@base = ActionView::Base.new
|
43
|
+
@base.request = request
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'outputs correct js with an integer' do
|
47
|
+
Gon.int = 1
|
48
|
+
@base.include_gon.should == '<script>window.gon = {};' +
|
49
|
+
'gon.int=1;' +
|
50
|
+
'</script>'
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'outputs correct js with a string' do
|
54
|
+
Gon.str = %q(a'b"c)
|
55
|
+
@base.include_gon.should == '<script>window.gon = {};' +
|
56
|
+
%q(gon.str="a'b\"c";) +
|
57
|
+
'</script>'
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'outputs correct js with a script string' do
|
61
|
+
Gon.str = %q(</script><script>alert('!')</script>)
|
62
|
+
@base.include_gon.should == '<script>window.gon = {};' +
|
63
|
+
%q(gon.str="<\\/script><script>alert('!')<\\/script>";) +
|
64
|
+
'</script>'
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'returns exception if try to set public method as variable' do
|
70
|
+
Gon.clear
|
71
|
+
lambda { Gon.all_variables = 123 }.should raise_error
|
72
|
+
lambda { Gon.rabl = 123 }.should raise_error
|
73
|
+
end
|
74
|
+
|
75
|
+
def request
|
76
|
+
@request ||= double 'request', :env => {}
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'gon'
|
2
|
+
|
3
|
+
describe Gon::Global do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
Gon::Global.clear
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '#all_variables' do
|
10
|
+
|
11
|
+
it 'returns all variables in hash' do
|
12
|
+
Gon.global.a = 1
|
13
|
+
Gon.global.b = 2
|
14
|
+
Gon.global.c = Gon.global.a + Gon.global.b
|
15
|
+
Gon.global.c.should == 3
|
16
|
+
Gon.global.all_variables.should == {'a' => 1, 'b' => 2, 'c' => 3}
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'supports all data types' do
|
20
|
+
Gon.global.clear
|
21
|
+
Gon.global.int = 1
|
22
|
+
Gon.global.float = 1.1
|
23
|
+
Gon.global.string = 'string'
|
24
|
+
Gon.global.array = [ 1, 'string' ]
|
25
|
+
Gon.global.hash_var = { :a => 1, :b => '2'}
|
26
|
+
Gon.global.hash_w_array = { :a => [ 2, 3 ] }
|
27
|
+
Gon.global.klass = Hash
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#include_gon' do
|
33
|
+
|
34
|
+
before(:each) do
|
35
|
+
Gon.clear
|
36
|
+
Gon.global.clear
|
37
|
+
ActionView::Base.
|
38
|
+
instance_methods.
|
39
|
+
map(&:to_s).
|
40
|
+
include?('include_gon').should == true
|
41
|
+
@base = ActionView::Base.new
|
42
|
+
@base.request = request
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'outputs correct js with an integer' do
|
46
|
+
Gon.global.int = 1
|
47
|
+
@base.include_gon.should == "<script>window.gon = {};" +
|
48
|
+
"gon.global={\"int\":1};" +
|
49
|
+
"</script>"
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'outputs correct js with an integer and integer in Gon' do
|
53
|
+
Gon::Request.
|
54
|
+
instance_variable_set(:@request_id, request.object_id)
|
55
|
+
Gon.int = 1
|
56
|
+
Gon.global.int = 1
|
57
|
+
@base.include_gon.should == "<script>window.gon = {};" +
|
58
|
+
"gon.int=1;" +
|
59
|
+
"gon.global={\"int\":1};" +
|
60
|
+
"</script>"
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'outputs correct js with a string' do
|
64
|
+
Gon.global.str = %q(a'b"c)
|
65
|
+
@base.include_gon.should == "<script>window.gon = {};" +
|
66
|
+
"gon.global={\"str\":\"a'b\\\"c\"};" +
|
67
|
+
"</script>"
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'outputs correct js with a script string' do
|
71
|
+
Gon.global.str = %q(</script><script>alert('!')</script>)
|
72
|
+
@base.include_gon.should == "<script>window.gon = {};" +
|
73
|
+
"gon.global={\"str\":\"<\\/script><script>alert('!')<\\/script>\"};" +
|
74
|
+
"</script>"
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'returns exception if try to set public method as variable' do
|
80
|
+
Gon.global.clear
|
81
|
+
lambda { Gon.global.all_variables = 123 }.should raise_error
|
82
|
+
lambda { Gon.global.rabl = 123 }.should raise_error
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'with jbuilder and rabl' do
|
86
|
+
|
87
|
+
before :each do
|
88
|
+
Gon.global.clear
|
89
|
+
controller.instance_variable_set('@objects', objects)
|
90
|
+
end
|
91
|
+
|
92
|
+
let(:controller) { ActionController::Base.new }
|
93
|
+
let(:objects) { [1,2] }
|
94
|
+
|
95
|
+
it 'works fine with rabl' do
|
96
|
+
Gon.global.rabl :template =>'spec/test_data/sample.rabl', :controller => controller
|
97
|
+
Gon.global.objects.length.should == 2
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'works fine with jbuilder' do
|
101
|
+
Gon.global.jbuilder :template =>'spec/test_data/sample.json.jbuilder', :controller => controller
|
102
|
+
Gon.global.objects.length.should == 2
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should throw exception, if use rabl or jbuilder without :template' do
|
106
|
+
lambda { Gon.global.rabl }.should raise_error
|
107
|
+
lambda { Gon.global.jbuilder }.should raise_error
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
after(:all) do
|
113
|
+
Gon.global.clear
|
114
|
+
end
|
115
|
+
|
116
|
+
def request
|
117
|
+
@request ||= double 'request', :env => {}
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# rabl_spec_rb
|
2
|
+
require 'gon'
|
3
|
+
|
4
|
+
describe Gon do
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
Gon::Request.env = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'jbuilder'
|
11
|
+
require 'gon/jbuilder'
|
12
|
+
|
13
|
+
describe '.jbuilder' do
|
14
|
+
context 'render jbuilder templates' do
|
15
|
+
|
16
|
+
before do
|
17
|
+
Gon.clear
|
18
|
+
controller.instance_variable_set('@objects', objects)
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:controller) { ActionController::Base.new }
|
22
|
+
let(:objects) { [1,2] }
|
23
|
+
|
24
|
+
it 'render json from jbuilder template' do
|
25
|
+
Gon.jbuilder 'spec/test_data/sample.json.jbuilder', :controller => controller
|
26
|
+
Gon.objects.length.should == 2
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'render json from jbuilder template with a partial' do
|
30
|
+
controller.view_paths << 'spec/test_data'
|
31
|
+
Gon.jbuilder 'spec/test_data/sample_with_partial.json.jbuilder', :controller => controller
|
32
|
+
Gon.objects.length.should == 2
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should raise error if you use gon.jbuilder without requiring jbuilder gem' do
|
38
|
+
Gon.send(:remove_const, :Jbuilder)
|
39
|
+
|
40
|
+
expect { Gon.jbuilder 'some_path' }.to raise_error(NameError)
|
41
|
+
load 'jbuilder.rb'
|
42
|
+
load 'gon/jbuilder.rb'
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
def request
|
49
|
+
@request ||= double 'request', :env => {}
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# rabl_spec_rb
|
2
|
+
require 'gon'
|
3
|
+
|
4
|
+
describe Gon do
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
Gon::Request.env = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '.rabl' do
|
11
|
+
|
12
|
+
require 'rabl'
|
13
|
+
require 'gon/rabl'
|
14
|
+
|
15
|
+
before :each do
|
16
|
+
Gon.clear
|
17
|
+
controller.instance_variable_set('@objects', objects)
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:controller) { ActionController::Base.new }
|
21
|
+
let(:objects) { [1,2] }
|
22
|
+
|
23
|
+
context 'render template with deprecation' do
|
24
|
+
it 'still works' do
|
25
|
+
Gon.rabl 'spec/test_data/sample.rabl', :controller => controller
|
26
|
+
Gon.objects.length.should == 2
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'works if rabl is included' do
|
31
|
+
Gon.rabl :template =>'spec/test_data/sample.rabl', :controller => controller
|
32
|
+
Gon.objects.length.should == 2
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'works with ActionView::Helpers' do
|
36
|
+
Gon.rabl :template =>'spec/test_data/sample_with_helpers.rabl', :controller => controller
|
37
|
+
Gon.objects.first['object']['time_ago'].should == 'about 6 hours'
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'raise exception if rabl is not included' do
|
41
|
+
Gon.send :remove_const, 'Rabl'
|
42
|
+
expect { Gon.rabl :template =>'spec/test_data/sample.rabl', :controller => controller}.to raise_error
|
43
|
+
load 'rabl.rb'
|
44
|
+
load 'gon/rabl.rb'
|
45
|
+
end
|
46
|
+
|
47
|
+
context '.get_template_path' do
|
48
|
+
context 'template is specified' do
|
49
|
+
|
50
|
+
it 'add the extension if not included in the template name' do
|
51
|
+
Gon::Base.send(:get_template_path, { :template => 'spec/test_data/sample'}, 'rabl').should eql('spec/test_data/sample.rabl')
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'return the specified template' do
|
55
|
+
Gon::Base.send(:get_template_path, { :template => 'spec/test_data/sample.rabl'}, 'rabl').should eql('spec/test_data/sample.rabl')
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'template is not specified' do
|
61
|
+
|
62
|
+
before do
|
63
|
+
Gon.clear
|
64
|
+
controller.instance_variable_set('@objects', objects)
|
65
|
+
controller.action_name = 'show'
|
66
|
+
end
|
67
|
+
|
68
|
+
let(:controller) { ActionController::Base.new }
|
69
|
+
let(:objects) { [1,2] }
|
70
|
+
|
71
|
+
context 'the action doesn as a template at a different format' do
|
72
|
+
it 'return the same template as the action with rabl extension' do
|
73
|
+
Gon::Base.send(:get_template_path, {:controller => controller}, 'rabl').should eql('app/views/action_controller/base/show.json.rabl')
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
def request
|
83
|
+
@request ||= double 'request', :env => {}
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# rabl_spec_rb
|
2
|
+
require 'gon'
|
3
|
+
|
4
|
+
describe Gon do
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
Gon::Request.env = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'jbuilder'
|
11
|
+
require 'gon/jbuilder'
|
12
|
+
require 'rabl'
|
13
|
+
require 'gon/rabl'
|
14
|
+
|
15
|
+
describe '.get_template_path' do
|
16
|
+
context 'template is specified' do
|
17
|
+
|
18
|
+
it 'add the extension if not included in the template name' do
|
19
|
+
Gon::Base.send(:get_template_path, { :template => 'spec/test_data/sample'}, 'jbuilder').should eql('spec/test_data/sample.jbuilder')
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'return the specified template' do
|
23
|
+
Gon::Base.send(:get_template_path, { :template => 'spec/test_data/sample.jbuilder'}, 'jbuilder').should eql('spec/test_data/sample.jbuilder')
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'template is not specified' do
|
29
|
+
|
30
|
+
before do
|
31
|
+
Gon.clear
|
32
|
+
controller.instance_variable_set('@objects', objects)
|
33
|
+
controller.action_name = 'show'
|
34
|
+
end
|
35
|
+
|
36
|
+
let(:controller) { ActionController::Base.new }
|
37
|
+
let(:objects) { [1,2] }
|
38
|
+
|
39
|
+
context 'the action doesn as a template at a different format' do
|
40
|
+
it 'return the same template as the action with rabl extension' do
|
41
|
+
Gon::Base.send(:get_template_path, {:controller => controller}, 'jbuilder').should eql('app/views/action_controller/base/show.json.jbuilder')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def request
|
49
|
+
@request ||= double 'request', :env => {}
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|