gon 5.2.3 → 6.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.

@@ -3,10 +3,7 @@ class Gon
3
3
  def include_gon(options = {})
4
4
  if variables_for_request_present?
5
5
  Gon::Base.render_data(options)
6
- elsif Gon.global.all_variables.present?
7
- Gon.clear
8
- Gon::Base.render_data(options)
9
- elsif options[:init].present?
6
+ elsif Gon.global.all_variables.present? || options[:init].present?
10
7
  Gon.clear
11
8
  Gon::Base.render_data(options)
12
9
  else
@@ -15,7 +12,7 @@ class Gon
15
12
  end
16
13
 
17
14
  def include_gon_amd(options={})
18
- Gon::Base.render_data_amd(options)
15
+ Gon::Base.render_data(options.merge({amd: true}))
19
16
  end
20
17
 
21
18
  private
@@ -4,27 +4,27 @@ class Gon
4
4
 
5
5
  def handler(args, global = false)
6
6
  options = parse_options_from args
7
- if global && !options[:template]
8
- raise 'You should provide :template when use rabl with global variables'
9
- end
10
- controller = Gon::Base.get_controller(options)
11
- @_controller_name = global ? '' : controller.controller_path
7
+ valid_options? options, global
12
8
 
13
- include_helpers
9
+ controller = Gon::EnvFinder.controller_env(options)
10
+ controller_name = global ? '' : controller.controller_path
14
11
 
15
- data = parse_jbuilder \
16
- Gon::Base.get_template_path(options, 'jbuilder'),
17
- controller,
18
- options[:locals]
12
+ parser = Gon::Jbuilder::Parser.new(
13
+ template_path: Gon::EnvFinder.template_path(options, 'jbuilder'),
14
+ controller: controller,
15
+ controller_name: controller_name,
16
+ locals: options[:locals]
17
+ )
18
+ data = parser.parse!
19
19
 
20
20
  [data, options]
21
21
  end
22
22
 
23
23
  private
24
24
 
25
- def include_helpers
26
- unless self.class.include? ::ActionView::Helpers
27
- self.class.send(:include, ::ActionView::Helpers)
25
+ def valid_options?(options, global)
26
+ if global && !options[:template]
27
+ raise 'You should provide :template when use rabl with global variables'
28
28
  end
29
29
  end
30
30
 
@@ -32,7 +32,7 @@ class Gon
32
32
  if old_api? args
33
33
  text = "[DEPRECATION] view_path argument is now optional. "
34
34
  text << "If you need to specify it, "
35
- text << "please use gon.rabl(:template => 'path')"
35
+ text << "please use gon.jbuilder(:template => 'path')"
36
36
  warn text
37
37
 
38
38
  args.extract_options!.merge(:template => args[0])
@@ -51,92 +51,6 @@ class Gon
51
51
  args.first.is_a? Hash
52
52
  end
53
53
 
54
- def parse_jbuilder(jbuilder_path, controller, locals)
55
- controller.instance_variables.each do |name|
56
- self.instance_variable_set \
57
- name,
58
- controller.instance_variable_get(name)
59
- end
60
- controller._helper_methods.each do |meth|
61
- self.class.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1
62
- def #{meth}(*args, &blk) # def current_user(*args, &blk)
63
- __controller.send(%(#{meth}), *args, &blk) # controller.send(:current_user, *args, &blk)
64
- end # end
65
- ruby_eval
66
- end
67
- locals ||= {}
68
- locals['__controller'] = controller
69
- locals.each do |name, value|
70
- self.class.class_eval do
71
- define_method "#{name}" do
72
- return value
73
- end
74
- end
75
- end
76
- lines = find_partials File.readlines(jbuilder_path)
77
- source = lines.join('')
78
-
79
- output = parse_source source, controller
80
- end
81
-
82
- def parse_source(source, controller)
83
- output = ::JbuilderTemplate.encode(controller) do |json|
84
- eval source
85
- end
86
- JSON.parse(output)
87
- end
88
-
89
- def parse_partial(partial_line)
90
- path = partial_line.match(/['"]([^'"]*)['"]/)[1]
91
- path = parse_path path
92
- options_hash = partial_line.match(/,(.*)/)[1]
93
-
94
- set_options_from_hash(options_hash) if options_hash.present?
95
-
96
- find_partials File.readlines(path)
97
- end
98
-
99
- def set_options_from_hash(options_hash)
100
- options = eval "{#{options_hash}}"
101
- options.each do |name, val|
102
- self.instance_variable_set("@#{name.to_s}", val)
103
- eval "def #{name}; self.instance_variable_get('@' + '#{name.to_s}'); end"
104
- end
105
- end
106
-
107
- def parse_path(path)
108
- return path if File.exists?(path)
109
- if (splitted = path.split('/')).blank?
110
- raise 'Something wrong with partial path in your jbuilder templates'
111
- elsif splitted.size == 1
112
- splitted.shift(@_controller_name)
113
- end
114
- construct_path(splitted)
115
- end
116
-
117
- def construct_path(args)
118
- last_arg = args.pop
119
- tmp_path = 'app/views/' + args.join('/')
120
- path = path_with_ext(tmp_path + "/_#{last_arg}")
121
- path || path_with_ext(tmp_path + "/#{last_arg}")
122
- end
123
-
124
- def path_with_ext(path)
125
- return path if File.exists?(path)
126
- return "#{path}.jbuilder" if File.exists?("#{path}.jbuilder")
127
- return "#{path}.json.jbuilder" if File.exists?("#{path}.json.jbuilder")
128
- end
129
-
130
- def find_partials(lines = [])
131
- lines.map do |line|
132
- if line =~ /partial!/
133
- parse_partial line
134
- else
135
- line
136
- end
137
- end.flatten
138
- end
139
-
140
54
  end
141
55
  end
142
56
  end
@@ -0,0 +1,128 @@
1
+ class Gon
2
+ module Jbuilder
3
+ class Parser
4
+ include ::ActionView::Helpers
5
+
6
+ attr_accessor :template_path, :controller, :_controller_name, :locals
7
+
8
+ def initialize(parse_params)
9
+ @template_path = parse_params[:template_path]
10
+ @controller = parse_params[:controller]
11
+ @_controller_name = parse_params[:controller_name]
12
+ @locals = parse_params[:locals] || {}
13
+ end
14
+
15
+ def parse!
16
+ assign_controller_variables controller
17
+ eval_controller_helpers controller
18
+ eval_controller_url_helpers controller
19
+ locals['__controller'] = controller
20
+ wrap_locals_in_methods locals
21
+
22
+ partials = find_partials(File.readlines(template_path))
23
+ source = partials.join('')
24
+
25
+ parse_source source, controller
26
+ end
27
+
28
+ def assign_controller_variables(controller)
29
+ controller.instance_variables.each do |name|
30
+ self.instance_variable_set \
31
+ name,
32
+ controller.instance_variable_get(name)
33
+ end
34
+ end
35
+
36
+ def eval_controller_helpers(controller)
37
+ controller._helper_methods.each do |meth|
38
+ self.class.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1
39
+ def #{meth}(*args, &blk) # def current_user(*args, &blk)
40
+ __controller.send(%(#{meth}), *args, &blk) # controller.send(:current_user, *args, &blk)
41
+ end # end
42
+ ruby_eval
43
+ end
44
+ end
45
+
46
+ def eval_controller_url_helpers(controller)
47
+ if defined?(Rails) && Rails.respond_to?(:application)
48
+ Rails.application.routes.url_helpers.instance_methods.each do |meth|
49
+ self.class.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1
50
+ def #{meth}(*args, &blk) # def user_path(*args, &blk)
51
+ __controller.send(%(#{meth}), *args, &blk) # controller.send(:user_path, *args, &blk)
52
+ end # end
53
+ ruby_eval
54
+ end
55
+ end
56
+ end
57
+
58
+ def wrap_locals_in_methods(locals)
59
+ locals.each do |name, value|
60
+ self.class.class_eval do
61
+ define_method "#{name}" do
62
+ return value
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ def parse_source(source, controller)
69
+ output = ::JbuilderTemplate.encode(controller) do |json|
70
+ eval source
71
+ end
72
+ JSON.parse(output)
73
+ end
74
+
75
+ def parse_partial(partial_line)
76
+ path = partial_line.match(/['"]([^'"]*)['"]/)[1]
77
+ path = parse_path path
78
+ options_hash = partial_line.match(/,(.*)/)[1]
79
+
80
+ set_options_from_hash(options_hash) if options_hash.present?
81
+
82
+ find_partials File.readlines(path)
83
+ end
84
+
85
+ def set_options_from_hash(options_hash)
86
+ options = eval "{#{options_hash}}"
87
+ options.each do |name, val|
88
+ self.instance_variable_set("@#{name.to_s}", val)
89
+ eval "def #{name}; self.instance_variable_get('@' + '#{name.to_s}'); end"
90
+ end
91
+ end
92
+
93
+ def parse_path(path)
94
+ return path if File.exists?(path)
95
+ if (splitted = path.split('/')).blank?
96
+ raise 'Something wrong with partial path in your jbuilder templates'
97
+ elsif splitted.size == 1
98
+ splitted.shift(@_controller_name)
99
+ end
100
+ construct_path(splitted)
101
+ end
102
+
103
+ def construct_path(args)
104
+ last_arg = args.pop
105
+ tmp_path = 'app/views/' + args.join('/')
106
+ path = path_with_ext(tmp_path + "/_#{last_arg}")
107
+ path || path_with_ext(tmp_path + "/#{last_arg}")
108
+ end
109
+
110
+ def path_with_ext(path)
111
+ return path if File.exists?(path)
112
+ return "#{path}.jbuilder" if File.exists?("#{path}.jbuilder")
113
+ return "#{path}.json.jbuilder" if File.exists?("#{path}.json.jbuilder")
114
+ end
115
+
116
+ def find_partials(lines = [])
117
+ lines.map do |line|
118
+ if line =~ /partial!/
119
+ parse_partial line
120
+ else
121
+ line
122
+ end
123
+ end.flatten
124
+ end
125
+
126
+ end
127
+ end
128
+ end
@@ -20,8 +20,8 @@ class Gon
20
20
  end
21
21
 
22
22
  data = parse_rabl \
23
- Gon::Base.get_template_path(options, 'rabl'),
24
- Gon::Base.get_controller(options),
23
+ Gon::EnvFinder.template_path(options, 'rabl'),
24
+ Gon::EnvFinder.controller_env(options),
25
25
  options[:locals]
26
26
 
27
27
  [data, options]
@@ -53,7 +53,7 @@ class Gon
53
53
  source = File.read(rabl_path)
54
54
  original_formats = controller.formats
55
55
  controller.formats = [:json]
56
- view_context = controller.view_context
56
+ view_context = controller.send(:view_context)
57
57
  locals.each { |k, v| view_context.assigns[k.to_s] = v }
58
58
  output = RablRails::Library.instance.get_rendered_template(source, view_context)
59
59
  controller.formats = original_formats
@@ -9,7 +9,7 @@ class Gon
9
9
  # preload threadlocal & store controller instance
10
10
  if controller.is_a? ActionController::Base
11
11
  controller.gon
12
- Gon.send(:current_gon).env[Gon::Base::ENV_CONTROLLER_KEY] =
12
+ Gon.send(:current_gon).env[Gon::EnvFinder::ENV_CONTROLLER_KEY] =
13
13
  controller
14
14
  end
15
15
  super
@@ -1,3 +1,3 @@
1
1
  class Gon
2
- VERSION = '5.2.3'
2
+ VERSION = '6.0.0'
3
3
  end
@@ -39,7 +39,7 @@ class Gon
39
39
  end
40
40
 
41
41
  def return_variable?(variable)
42
- controller = Gon::Base.get_controller
42
+ controller = Gon::EnvFinder.controller_env
43
43
  params = controller.params
44
44
  variable = variable.to_s.gsub('=', '')
45
45
 
@@ -49,7 +49,7 @@ class Gon
49
49
  end
50
50
 
51
51
  def return_variable(value)
52
- controller = Gon::Base.get_controller
52
+ controller = Gon::EnvFinder.controller_env
53
53
  controller.render json: Gon::Escaper.escape_unicode(Gon::JsonDumper.dump value)
54
54
  end
55
55
 
@@ -20,6 +20,7 @@ describe Gon do
20
20
  Gon.int = 1
21
21
  Gon.float = 1.1
22
22
  Gon.string = 'string'
23
+ Gon.symbol = :symbol
23
24
  Gon.array = [1, 'string']
24
25
  Gon.hash_var = { :a => 1, :b => '2' }
25
26
  Gon.hash_w_array = { :a => [2, 3] }
@@ -89,17 +90,14 @@ describe Gon do
89
90
  before(:each) do
90
91
  Gon::Request.
91
92
  instance_variable_set(:@request_id, request.object_id)
92
- expect(ActionView::Base.
93
- instance_methods.
94
- map(&:to_s).
95
- include?('include_gon')).to eq(true)
93
+ expect(ActionView::Base.instance_methods).to include(:include_gon)
96
94
  @base = ActionView::Base.new
97
95
  @base.request = request
98
96
  end
99
97
 
100
98
  it 'outputs correct js with an integer' do
101
99
  Gon.int = 1
102
- expect(@base.include_gon).to eq('<script type="text/javascript">' +
100
+ expect(@base.include_gon).to eq('<script>' +
103
101
  "\n//<![CDATA[\n" +
104
102
  'window.gon={};' +
105
103
  'gon.int=1;' +
@@ -109,7 +107,7 @@ describe Gon do
109
107
 
110
108
  it 'outputs correct js with a string' do
111
109
  Gon.str = %q(a'b"c)
112
- expect(@base.include_gon).to eq('<script type="text/javascript">' +
110
+ expect(@base.include_gon).to eq('<script>' +
113
111
  "\n//<![CDATA[\n" +
114
112
  'window.gon={};' +
115
113
  %q(gon.str="a'b\"c";) +
@@ -120,7 +118,7 @@ describe Gon do
120
118
  it 'outputs correct js with a script string' do
121
119
  Gon.str = %q(</script><script>alert('!')</script>)
122
120
  escaped_str = "\\u003c/script\\u003e\\u003cscript\\u003ealert('!')\\u003c/script\\u003e"
123
- expect(@base.include_gon).to eq('<script type="text/javascript">' +
121
+ expect(@base.include_gon).to eq('<script>' +
124
122
  "\n//<![CDATA[\n" +
125
123
  'window.gon={};' +
126
124
  %Q(gon.str="#{escaped_str}";) +
@@ -128,10 +126,20 @@ describe Gon do
128
126
  '</script>')
129
127
  end
130
128
 
129
+ it 'outputs correct js with an integer and type' do
130
+ Gon.int = 1
131
+ expect(@base.include_gon(type: true)).to eq('<script type="text/javascript">' +
132
+ "\n//<![CDATA[\n" +
133
+ 'window.gon={};' +
134
+ 'gon.int=1;' +
135
+ "\n//]]>\n" +
136
+ '</script>')
137
+ end
138
+
131
139
  it 'outputs correct js with an integer, camel-case and namespace' do
132
140
  Gon.int_cased = 1
133
141
  expect(@base.include_gon(camel_case: true, namespace: 'camel_cased')).to eq( \
134
- '<script type="text/javascript">' +
142
+ '<script>' +
135
143
  "\n//<![CDATA[\n" +
136
144
  'window.camel_cased={};' +
137
145
  'camel_cased.intCased=1;' +
@@ -143,7 +151,7 @@ describe Gon do
143
151
  it 'outputs correct js with camel_depth = :recursive' do
144
152
  Gon.test_hash = { test_depth_one: { test_depth_two: 1 } }
145
153
  expect(@base.include_gon(camel_case: true, camel_depth: :recursive)).to eq( \
146
- '<script type="text/javascript">' +
154
+ '<script>' +
147
155
  "\n//<![CDATA[\n" +
148
156
  'window.gon={};' +
149
157
  'gon.testHash={"testDepthOne":{"testDepthTwo":1}};' +
@@ -155,7 +163,7 @@ describe Gon do
155
163
  it 'outputs correct js with camel_depth = 2' do
156
164
  Gon.test_hash = { test_depth_one: { test_depth_two: 1 } }
157
165
  expect(@base.include_gon(camel_case: true, camel_depth: 2)).to eq( \
158
- '<script type="text/javascript">' +
166
+ '<script>' +
159
167
  "\n//<![CDATA[\n" +
160
168
  'window.gon={};' +
161
169
  'gon.testHash={"testDepthOne":{"test_depth_two":1}};' +
@@ -167,7 +175,7 @@ describe Gon do
167
175
  it 'outputs correct js for an array with camel_depth = :recursive' do
168
176
  Gon.test_hash = { test_depth_one: [{ test_depth_two: 1 }, { test_depth_two: 2 }] }
169
177
  expect(@base.include_gon(camel_case: true, camel_depth: :recursive)).to eq( \
170
- '<script type="text/javascript">' +
178
+ '<script>' +
171
179
  "\n//<![CDATA[\n" +
172
180
  'window.gon={};' +
173
181
  'gon.testHash={"testDepthOne":[{"testDepthTwo":1},{"testDepthTwo":2}]};' +
@@ -221,7 +229,7 @@ describe Gon do
221
229
 
222
230
  it 'outputs correct js with type text/javascript' do
223
231
  expect(@base.include_gon(need_type: true, init: true)).to eq( \
224
- '<script type="text/javascript">' +
232
+ '<script>' +
225
233
  "\n//<![CDATA[\n" +
226
234
  'window.gon={};'\
227
235
  "\n//]]>\n" +
@@ -231,7 +239,7 @@ describe Gon do
231
239
 
232
240
  it 'outputs correct js with namespace check' do
233
241
  expect(@base.include_gon(namespace_check: true)).to eq( \
234
- '<script type="text/javascript">' +
242
+ '<script>' +
235
243
  "\n//<![CDATA[\n" +
236
244
  'window.gon=window.gon||{};'\
237
245
  "\n//]]>\n" +
@@ -241,7 +249,7 @@ describe Gon do
241
249
 
242
250
  it 'outputs correct js without namespace check' do
243
251
  expect(@base.include_gon(namespace_check: false)).to eq( \
244
- '<script type="text/javascript">' +
252
+ '<script>' +
245
253
  "\n//<![CDATA[\n" +
246
254
  'window.gon={};'\
247
255
  "\n//]]>\n" +
@@ -257,7 +265,7 @@ describe Gon do
257
265
  end
258
266
 
259
267
  it "does not raise an exception" do
260
- expect { @base.include_gon }.to_not raise_error(Exception)
268
+ expect { @base.include_gon }.to_not raise_error
261
269
  end
262
270
 
263
271
  it 'outputs correct js' do
@@ -266,7 +274,7 @@ describe Gon do
266
274
 
267
275
  it 'outputs correct js with init' do
268
276
  expect(@base.include_gon(init: true)).to eq( \
269
- '<script type="text/javascript">' +
277
+ '<script>' +
270
278
  "\n//<![CDATA[\n" +
271
279
  'window.gon={};'\
272
280
  "\n//]]>\n" +
@@ -289,10 +297,7 @@ describe Gon do
289
297
  end
290
298
 
291
299
  it 'is included in ActionView::Base as a helper' do
292
- expect(ActionView::Base.
293
- instance_methods.
294
- map(&:to_s).
295
- include?('include_gon_amd')).to eq(true)
300
+ expect(ActionView::Base.instance_methods).to include(:include_gon_amd)
296
301
  end
297
302
 
298
303
  it 'outputs correct js without variables' do
@@ -323,8 +328,8 @@ describe Gon do
323
328
  end
324
329
 
325
330
  it 'returns exception if try to set public method as variable' do
326
- expect { Gon.all_variables = 123 }.to raise_error
327
- expect { Gon.rabl = 123 }.to raise_error
331
+ expect { Gon.all_variables = 123 }.to raise_error(RuntimeError)
332
+ expect { Gon.rabl = 123 }.to raise_error(RuntimeError)
328
333
  end
329
334
 
330
335
  describe '#check_for_rabl_and_jbuilder' do
@@ -334,15 +339,15 @@ describe Gon do
334
339
  it 'should be able to handle ruby 1.8.7 style constants array (strings)' do
335
340
  constants_as_strings = Gon.constants.map(&:to_s)
336
341
  allow(Gon).to receive(:constants) { constants_as_strings }
337
- expect { Gon.rabl 'spec/test_data/sample.rabl', :controller => controller }.not_to raise_error
338
- expect { Gon.jbuilder 'spec/test_data/sample.json.jbuilder', :controller => controller }.not_to raise_error
342
+ expect { Gon.rabl :template => 'spec/test_data/sample.rabl', :controller => controller }.not_to raise_error
343
+ expect { Gon.jbuilder :template => 'spec/test_data/sample.json.jbuilder', :controller => controller }.not_to raise_error
339
344
  end
340
345
 
341
346
  it 'should be able to handle ruby 1.9+ style constants array (symbols)' do
342
347
  constants_as_symbols = Gon.constants.map(&:to_sym)
343
348
  allow(Gon).to receive(:constants) { constants_as_symbols }
344
- expect { Gon.rabl 'spec/test_data/sample.rabl', :controller => controller }.not_to raise_error
345
- expect { Gon.jbuilder 'spec/test_data/sample.json.jbuilder', :controller => controller }.not_to raise_error
349
+ expect { Gon.rabl :template => 'spec/test_data/sample.rabl', :controller => controller }.not_to raise_error
350
+ expect { Gon.jbuilder :template => 'spec/test_data/sample.json.jbuilder', :controller => controller }.not_to raise_error
346
351
  end
347
352
  end
348
353
 
@@ -350,8 +355,8 @@ describe Gon do
350
355
  @request ||= double 'request', :env => {}
351
356
  end
352
357
 
353
- def wrap_script(content, type='text/javascript', cdata=true)
354
- script = "<script type=\"#{type}\">"
358
+ def wrap_script(content, cdata=true)
359
+ script = "<script>"
355
360
  script << "\n//<![CDATA[\n" if cdata
356
361
  script << content
357
362
  script << "\n//]]>\n" if cdata