gon 4.1.1 → 5.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/.gitignore CHANGED
@@ -3,3 +3,4 @@
3
3
  Gemfile.lock
4
4
  pkg/*
5
5
  .rvmrc
6
+ *.idea
@@ -5,7 +5,9 @@ rvm:
5
5
  - 2.0.0
6
6
  - jruby-18mode # JRuby in 1.8 mode
7
7
  - jruby-19mode # JRuby in 1.9 mode
8
- - rbx-18mode
9
- - rbx-19mode
8
+ - rbx
9
+ matrix:
10
+ allow_failures:
11
+ - rvm: rbx
10
12
  # uncomment this line if your project needs to run something other than `rake`:
11
13
  # script: bundle exec rspec spec
@@ -1,5 +1,15 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 5.0.0
4
+
5
+ * Gon is threadsafe now! (@razum2um)
6
+ * Camelcasing with depth (@MaxSchmeling)
7
+ * Optional CDATA and style refactoring (@torbjon)
8
+ * jBuilder supports not only String and Hash types of locals
9
+ (@steakchaser)
10
+ * Using ActionDispatch::Request#uuid instead of
11
+ ActionDispatch::Request#id (@sharshenov)
12
+
3
13
  ## 4.1.1
4
14
 
5
15
  * Fixed critical XSS vulnerability https://github.com/gazay/gon/issues/84 (@vadimr & @Hebo)
data/README.md CHANGED
@@ -27,7 +27,7 @@ you might be doing something like this:
27
27
  3. Then there can be two ways in js:
28
28
  + if you previously wrote data in data
29
29
  attributes - you should parse this attributes and write data to some
30
- js variable.
30
+ js variable.
31
31
  + if you wrote js right in view (many frontenders would shame you for
32
32
  that) - you just use data from this js - OK.
33
33
  4. You can use your data in your js
@@ -102,7 +102,7 @@ gon.your_array # > [1, 2, 123]
102
102
  gon.clear # gon.all_variables now is {}
103
103
  ```
104
104
 
105
- Access the varaibles from your JavaScript file:
105
+ Access the variables from your JavaScript file:
106
106
 
107
107
  ``` js
108
108
  alert(gon.your_int)
@@ -313,7 +313,7 @@ json.partial! 'app/views/posts/_part.json.jbuilder', :comments => @posts[0].comm
313
313
  `app/views/posts/_part.json.jbuilder`
314
314
 
315
315
  ``` jbuilder
316
- json.comments comments.map{ |it| 'comment#' + it.id }
316
+ json.comments comments.map { |it| 'comment#' + it.id }
317
317
  ```
318
318
 
319
319
  ``` js
data/Rakefile CHANGED
@@ -5,5 +5,5 @@ Bundler::GemHelper.install_tasks
5
5
 
6
6
  desc 'Run all tests by default'
7
7
  task :default do
8
- system("rspec spec")
8
+ system('rspec spec')
9
9
  end
@@ -1,28 +1,29 @@
1
1
  # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require "gon/version"
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'gon/version'
4
5
 
5
6
  Gem::Specification.new do |s|
6
- s.name = "gon"
7
+ s.name = 'gon'
7
8
  s.version = Gon::VERSION
8
9
  s.platform = Gem::Platform::RUBY
9
10
  s.authors = ['gazay']
10
11
  s.email = ['alex.gaziev@gmail.com']
11
- s.homepage = "https://github.com/gazay/gon"
12
+ s.homepage = 'https://github.com/gazay/gon'
12
13
  s.summary = %q{Get your Rails variables in your JS}
13
14
  s.description = %q{If you need to send some data to your js files and you don't want to do this with long way trough views and parsing - use this force!}
14
15
 
15
- s.rubyforge_project = "gon"
16
+ s.rubyforge_project = 'gon'
16
17
 
17
18
  s.files = `git ls-files`.split("\n")
18
19
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
- s.require_paths = ["lib"]
21
- s.add_dependency "actionpack", '>= 2.3.0'
22
- s.add_dependency "json"
23
- s.add_development_dependency "rabl"
24
- s.add_development_dependency "rabl-rails"
25
- s.add_development_dependency "rspec"
26
- s.add_development_dependency "jbuilder"
27
- s.add_development_dependency "rake"
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
21
+ s.require_paths = ['lib']
22
+ s.add_dependency 'actionpack', '>= 2.3.0'
23
+ s.add_dependency 'json'
24
+ s.add_development_dependency 'rabl'
25
+ s.add_development_dependency 'rabl-rails'
26
+ s.add_development_dependency 'rspec'
27
+ s.add_development_dependency 'jbuilder'
28
+ s.add_development_dependency 'rake'
28
29
  end
data/lib/gon.rb CHANGED
@@ -21,9 +21,9 @@ class Gon
21
21
  end
22
22
 
23
23
  def method_missing(method, *args, &block)
24
- if ( method.to_s =~ /=$/ )
25
- if public_method_name? method
26
- raise "You can't use Gon public methods for storing data"
24
+ if method.to_s =~ /=$/
25
+ if public_method_name?(method)
26
+ raise 'You can\'t use Gon public methods for storing data'
27
27
  end
28
28
 
29
29
  set_variable(method.to_s.delete('='), args[0])
@@ -33,15 +33,15 @@ class Gon
33
33
  end
34
34
 
35
35
  def get_variable(name)
36
- Request.gon[name]
36
+ current_gon.gon[name]
37
37
  end
38
38
 
39
39
  def set_variable(name, value)
40
- Request.gon[name] = value
40
+ current_gon.gon[name] = value
41
41
  end
42
42
 
43
43
  def push(data = {})
44
- raise "Object must have each_pair method" unless data.respond_to? :each_pair
44
+ raise 'Object must have each_pair method' unless data.respond_to? :each_pair
45
45
 
46
46
  data.each_pair do |name, value|
47
47
  set_variable(name.to_s, value)
@@ -49,11 +49,11 @@ class Gon
49
49
  end
50
50
 
51
51
  def all_variables
52
- Request.gon
52
+ current_gon.gon
53
53
  end
54
54
 
55
55
  def clear
56
- Request.clear
56
+ current_gon.clear
57
57
  end
58
58
 
59
59
  def rabl(*args)
@@ -73,13 +73,15 @@ class Gon
73
73
 
74
74
  private
75
75
 
76
+ def current_gon
77
+ Thread.current['gon']
78
+ end
79
+
76
80
  def store_builder_data(builder, data, options)
77
81
  if options[:as]
78
82
  set_variable(options[:as].to_s, data)
79
83
  elsif data.is_a? Hash
80
- data.each do |key, value|
81
- set_variable(key, value)
82
- end
84
+ data.each { |k, v| set_variable(k, v) }
83
85
  else
84
86
  set_variable(builder, data)
85
87
  end
@@ -3,20 +3,20 @@ class Gon
3
3
  class << self
4
4
 
5
5
  def render_data(options)
6
- namespace, tag, cameled, watch = parse_options options
7
- script = "window.#{namespace} = {};"
6
+ namespace, tag, cameled, camel_depth, watch, type, cdata = parse_options(options)
7
+ script = "window.#{namespace}={};"
8
8
 
9
- script << formatted_data(namespace, cameled, watch)
9
+ script << formatted_data(namespace, cameled, camel_depth, watch)
10
10
  script = Gon::Escaper.escape_unicode(script)
11
- script = Gon::Escaper.javascript_tag(script) if tag
11
+ script = Gon::Escaper.javascript_tag(script, type, cdata) if tag
12
12
 
13
13
  script.html_safe
14
14
  end
15
15
 
16
16
  def get_controller(options = {})
17
17
  options[:controller] ||
18
- Gon::Request.env['action_controller.instance'] ||
19
- Gon::Request.env['action_controller.rescue.response'].
18
+ current_gon.env['action_controller.instance'] ||
19
+ current_gon.env['action_controller.rescue.response'].
20
20
  instance_variable_get('@template').
21
21
  instance_variable_get('@controller')
22
22
  end
@@ -37,22 +37,29 @@ class Gon
37
37
 
38
38
  private
39
39
 
40
- def parse_options(options)
41
- namespace = options[:namespace] || 'gon'
42
- need_tag = options[:need_tag].nil? || options[:need_tag]
43
- cameled = options[:camel_case]
44
- watch = options[:watch]
45
- tag = need_tag
40
+ def current_gon
41
+ Thread.current[:gon]
42
+ end
46
43
 
47
- [namespace, tag, cameled, watch]
44
+ def parse_options(options)
45
+ namespace = options[:namespace] || 'gon'
46
+ need_tag = options[:need_tag].nil? || options[:need_tag]
47
+ cameled = options[:camel_case]
48
+ camel_depth = options[:camel_depth] || 1
49
+ watch = options[:watch]
50
+ tag = need_tag
51
+ type = options[:type].nil? || options[:type]
52
+ cdata = options[:cdata].nil? || options[:cdata]
53
+
54
+ [namespace, tag, cameled, camel_depth, watch, type, cdata]
48
55
  end
49
56
 
50
- def formatted_data(namespace, keys_cameled, watch)
57
+ def formatted_data(namespace, keys_cameled, camel_depth, watch)
51
58
  script = ''
52
59
 
53
60
  gon_variables.each do |key, val|
54
61
  js_key = keys_cameled ? key.to_s.camelize(:lower) : key.to_s
55
- script << "#{namespace}.#{js_key}=#{val.to_json};"
62
+ script << "#{namespace}.#{js_key}=#{to_json(val, camel_depth)};"
56
63
  end
57
64
 
58
65
  if watch and Gon::Watch.all_variables.present?
@@ -62,6 +69,20 @@ class Gon
62
69
  script
63
70
  end
64
71
 
72
+ def to_json(value, camel_depth)
73
+ # starts at two because 1 is the root key which is converted in the formatted_data method
74
+ convert_hash_keys(value, 2, camel_depth).to_json
75
+ end
76
+
77
+ def convert_hash_keys(value, current_depth, max_depth)
78
+ return value if current_depth > (max_depth.is_a?(Symbol) ? 1000 : max_depth)
79
+ return value unless value.is_a? Hash
80
+
81
+ Hash[value.map { |k, v|
82
+ [ k.to_s.camelize(:lower), convert_hash_keys(v, current_depth + 1, max_depth) ]
83
+ }]
84
+ end
85
+
65
86
  def gon_variables
66
87
  data = Gon.all_variables || {}
67
88
 
@@ -9,8 +9,19 @@ class Gon
9
9
  if javascript
10
10
  result = javascript.gsub(/\342\200\250/u, '&#x2028;').gsub(/(<\/)/u, '\u003C/')
11
11
  javascript.html_safe? ? result.html_safe : result
12
+ end
13
+ end
14
+
15
+ def javascript_tag(content, type, cdata)
16
+ type = { type: 'text/javascript' } if type
17
+ content_tag(:script, javascript_cdata_section(content, cdata).html_safe, type)
18
+ end
19
+
20
+ def javascript_cdata_section(content, cdata)
21
+ if cdata
22
+ "\n//#{cdata_section("\n#{content}\n//")}\n"
12
23
  else
13
- ''
24
+ "\n#{content}\n"
14
25
  end
15
26
  end
16
27
 
@@ -17,16 +17,18 @@ class Gon
17
17
  Gon.clear if Gon.all_variables.present?
18
18
  Gon::Base.render_data(options)
19
19
  else
20
- ""
20
+ ''
21
21
  end
22
22
  end
23
23
 
24
24
  private
25
25
 
26
26
  def variables_for_request_present?
27
- Gon::Request.env &&
28
- Gon::Request.id == request.object_id &&
29
- Gon.all_variables.present?
27
+ current_gon.gon.present?
28
+ end
29
+
30
+ def current_gon
31
+ Thread.current['gon']
30
32
  end
31
33
 
32
34
  end
@@ -42,8 +44,9 @@ class Gon
42
44
 
43
45
  def gon
44
46
  if wrong_gon_request?
45
- Gon::Request.id = request.object_id
46
- Gon::Request.env = request.env
47
+ gon_request = Request.new(env)
48
+ gon_request.id = request.uuid
49
+ Thread.current['gon'] = gon_request
47
50
  end
48
51
  Gon
49
52
  end
@@ -51,12 +54,14 @@ class Gon
51
54
  private
52
55
 
53
56
  def wrong_gon_request?
54
- Gon::Request.env.blank? ||
55
- Gon::Request.id != request.object_id
57
+ current_gon.blank? || current_gon.id != request.uuid
56
58
  end
57
59
 
58
- end
60
+ def current_gon
61
+ Thread.current['gon']
62
+ end
59
63
 
64
+ end
60
65
  end
61
66
  end
62
67
 
@@ -13,7 +13,7 @@ class Gon
13
13
  include_helpers
14
14
 
15
15
  data = parse_jbuilder \
16
- Gon::Base.get_template_path(options,'jbuilder'),
16
+ Gon::Base.get_template_path(options, 'jbuilder'),
17
17
  controller,
18
18
  options[:locals]
19
19
 
@@ -59,7 +59,11 @@ class Gon
59
59
  end
60
60
  locals ||= {}
61
61
  locals.each do |name, value|
62
- eval "def #{name}; return #{value}; end"
62
+ self.class.class_eval do
63
+ define_method "#{name}" do
64
+ return value
65
+ end
66
+ end
63
67
  end
64
68
  lines = find_partials File.readlines(jbuilder_path)
65
69
  source = lines.join('')
@@ -100,7 +104,7 @@ class Gon
100
104
  tmp_path = construct_path(splitted[0], splitted[1])
101
105
  return tmp_path if tmp_path
102
106
  elsif splitted.size == 1
103
- tmp_path = construct_path @_controller_name, splitted[0]
107
+ tmp_path = construct_path(@_controller_name, splitted[0])
104
108
  return tmp_path if tmp_path
105
109
  end
106
110
 
@@ -1,11 +1,11 @@
1
1
  require 'action_view'
2
2
 
3
- begin
3
+ begin
4
4
  require 'rabl' # use rabl gem if it's available
5
5
  rescue LoadError
6
6
  end
7
- begin
8
- require 'rabl-rails' # use rabl-rails gem if it's available
7
+ begin
8
+ require 'rabl-rails' # use rabl-rails gem if it's available
9
9
  rescue LoadError
10
10
  end
11
11
 
@@ -1,32 +1,29 @@
1
1
  class 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
2
+ class Request
3
+ def initialize(environment)
4
+ @request_env = environment
5
+ @gon = {}
6
+ end
13
7
 
14
- def id
15
- @request_id if defined? @request_id
16
- end
8
+ def env
9
+ @request_env if defined? @request_env
10
+ end
17
11
 
18
- def id=(request_id)
19
- @request_id = request_id
20
- end
12
+ def id
13
+ @request_id if defined? @request_id
14
+ end
21
15
 
22
- def gon
23
- env['gon'] if env
24
- end
16
+ def id=(request_id)
17
+ @request_id = request_id
18
+ end
25
19
 
26
- def clear
27
- env && (env['gon'] = {})
28
- end
20
+ def gon
21
+ @gon
22
+ end
29
23
 
24
+ def clear
25
+ @gon = {}
30
26
  end
27
+
31
28
  end
32
29
  end
@@ -1,3 +1,3 @@
1
1
  class Gon
2
- VERSION = '4.1.1'
2
+ VERSION = '5.0.0'
3
3
  end
@@ -24,7 +24,7 @@ class Gon
24
24
  else
25
25
  variable = {}
26
26
  @watch_variables ||= {}
27
- env = Gon::Request.env
27
+ env = Gon.send(:current_gon).env
28
28
  variable['url'] = env['ORIGINAL_FULLPATH'] || env['REQUEST_URI']
29
29
  variable['method'] = env['REQUEST_METHOD']
30
30
  variable['name'] = name
@@ -46,7 +46,6 @@ class Gon
46
46
 
47
47
  def return_variable(value)
48
48
  controller = Gon::Base.get_controller
49
-
50
49
  controller.render :json => value
51
50
  end
52
51
 
@@ -3,7 +3,6 @@ require 'spec_helper'
3
3
  describe Gon do
4
4
 
5
5
  before(:each) do
6
- Gon::Request.env = {}
7
6
  end
8
7
 
9
8
  describe '#all_variables' do
@@ -13,18 +12,18 @@ describe Gon do
13
12
  Gon.b = 2
14
13
  Gon.c = Gon.a + Gon.b
15
14
  Gon.c.should == 3
16
- Gon.all_variables.should == {'a' => 1, 'b' => 2, 'c' => 3}
15
+ Gon.all_variables.should == { 'a' => 1, 'b' => 2, 'c' => 3 }
17
16
  end
18
17
 
19
18
  it 'supports all data types' do
20
19
  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
20
+ Gon.int = 1
21
+ Gon.float = 1.1
22
+ Gon.string = 'string'
23
+ Gon.array = [1, 'string']
24
+ Gon.hash_var = { :a => 1, :b => '2' }
25
+ Gon.hash_w_array = { :a => [2, 3] }
26
+ Gon.klass = Hash
28
27
  end
29
28
 
30
29
  it 'can be filled with dynamic named variables' do
@@ -43,7 +42,7 @@ describe Gon do
43
42
  Gon.clear
44
43
  var_name = "variable#{rand}"
45
44
 
46
- Gon.set_variable var_name, 1
45
+ Gon.set_variable(var_name, 1)
47
46
  Gon.get_variable(var_name).should == 1
48
47
  end
49
48
 
@@ -57,8 +56,8 @@ describe Gon do
57
56
  it 'push with wrong object' do
58
57
  expect {
59
58
  Gon.clear
60
- Gon.push(String.new("string object"))
61
- }.to raise_error("Object must have each_pair method")
59
+ Gon.push(String.new('string object'))
60
+ }.to raise_error('Object must have each_pair method')
62
61
  end
63
62
 
64
63
  end
@@ -81,7 +80,7 @@ describe Gon do
81
80
  Gon.int = 1
82
81
  @base.include_gon.should == '<script type="text/javascript">' +
83
82
  "\n//<![CDATA[\n" +
84
- 'window.gon = {};' +
83
+ 'window.gon={};' +
85
84
  'gon.int=1;' +
86
85
  "\n//]]>\n" +
87
86
  '</script>'
@@ -91,7 +90,7 @@ describe Gon do
91
90
  Gon.str = %q(a'b"c)
92
91
  @base.include_gon.should == '<script type="text/javascript">' +
93
92
  "\n//<![CDATA[\n" +
94
- 'window.gon = {};' +
93
+ 'window.gon={};' +
95
94
  %q(gon.str="a'b\"c";) +
96
95
  "\n//]]>\n" +
97
96
  '</script>'
@@ -101,7 +100,7 @@ describe Gon do
101
100
  Gon.str = %q(</script><script>alert('!')</script>)
102
101
  @base.include_gon.should == '<script type="text/javascript">' +
103
102
  "\n//<![CDATA[\n" +
104
- 'window.gon = {};' +
103
+ 'window.gon={};' +
105
104
  %q(gon.str="\u003C/script><script>alert('!')\u003C/script>";) +
106
105
  "\n//]]>\n" +
107
106
  '</script>'
@@ -112,16 +111,38 @@ describe Gon do
112
111
  @base.include_gon(camel_case: true, namespace: 'camel_cased').should == \
113
112
  '<script type="text/javascript">' +
114
113
  "\n//<![CDATA[\n" +
115
- 'window.camel_cased = {};' +
114
+ 'window.camel_cased={};' +
116
115
  'camel_cased.intCased=1;' +
117
116
  "\n//]]>\n" +
118
117
  '</script>'
119
118
  end
120
119
 
120
+ it 'outputs correct js with camel_depth = :recursive' do
121
+ Gon.test_hash = { test_depth_one: { test_depth_two: 1 } }
122
+ @base.include_gon(camel_case: true, camel_depth: :recursive).should == \
123
+ '<script type="text/javascript">' +
124
+ "\n//<![CDATA[\n" +
125
+ 'window.gon={};' +
126
+ 'gon.testHash={"testDepthOne":{"testDepthTwo":1}};' +
127
+ "\n//]]>\n" +
128
+ '</script>'
129
+ end
130
+
131
+ it 'outputs correct js with camel_depth = 2' do
132
+ Gon.test_hash = { test_depth_one: { test_depth_two: 1 } }
133
+ @base.include_gon(camel_case: true, camel_depth: 2).should == \
134
+ '<script type="text/javascript">' +
135
+ "\n//<![CDATA[\n" +
136
+ 'window.gon={};' +
137
+ 'gon.testHash={"testDepthOne":{"test_depth_two":1}};' +
138
+ "\n//]]>\n" +
139
+ '</script>'
140
+ end
141
+
121
142
  it 'outputs correct js with an integer and without tag' do
122
143
  Gon.int = 1
123
144
  @base.include_gon(need_tag: false).should == \
124
- 'window.gon = {};' +
145
+ 'window.gon={};' +
125
146
  'gon.int=1;'
126
147
  end
127
148
 
@@ -130,26 +151,37 @@ describe Gon do
130
151
  instance_variable_set(:@request_id, 123)
131
152
  Gon::Request.instance_variable_set(:@request_env, { 'gon' => { :a => 1 } })
132
153
  @base.include_gon(need_tag: false, init: true).should == \
133
- 'window.gon = {};'
154
+ 'window.gon={};'
134
155
  end
135
156
 
136
157
  it 'outputs correct js without variables, without tag and gon init' do
137
158
  @base.include_gon(need_tag: false, init: true).should == \
138
- 'window.gon = {};'
159
+ 'window.gon={};'
139
160
  end
140
161
 
141
162
  it 'outputs correct js without variables, without tag, gon init and an integer' do
142
163
  Gon.int = 1
143
164
  @base.include_gon(need_tag: false, init: true).should == \
144
- 'window.gon = {};' +
165
+ 'window.gon={};' +
145
166
  'gon.int=1;'
146
167
  end
147
168
 
169
+ it 'outputs correct js without cdata, without type, gon init and an integer' do
170
+ Gon.int = 1
171
+ @base.include_gon(cdata: false, type: false).should == \
172
+ '<script>' +
173
+ "\n" +
174
+ 'window.gon={};' +
175
+ 'gon.int=1;' +
176
+ "\n" +
177
+ '</script>'
178
+ end
179
+
148
180
  it 'outputs correct js with type text/javascript' do
149
181
  @base.include_gon(need_type: true, init: true).should == \
150
182
  '<script type="text/javascript">' +
151
183
  "\n//<![CDATA[\n" +
152
- 'window.gon = {};'\
184
+ 'window.gon={};'\
153
185
  "\n//]]>\n" +
154
186
  '</script>'
155
187
  end
@@ -162,7 +194,6 @@ describe Gon do
162
194
  lambda { Gon.rabl = 123 }.should raise_error
163
195
  end
164
196
 
165
-
166
197
  describe '#check_for_rabl_and_jbuilder' do
167
198
 
168
199
  let(:controller) { ActionController::Base.new }
@@ -14,18 +14,18 @@ describe Gon::Global do
14
14
  Gon.global.b = 2
15
15
  Gon.global.c = Gon.global.a + Gon.global.b
16
16
  Gon.global.c.should == 3
17
- Gon.global.all_variables.should == {'a' => 1, 'b' => 2, 'c' => 3}
17
+ Gon.global.all_variables.should == { 'a' => 1, 'b' => 2, 'c' => 3 }
18
18
  end
19
19
 
20
20
  it 'supports all data types' do
21
21
  Gon.global.clear
22
- Gon.global.int = 1
23
- Gon.global.float = 1.1
24
- Gon.global.string = 'string'
25
- Gon.global.array = [ 1, 'string' ]
26
- Gon.global.hash_var = { :a => 1, :b => '2'}
27
- Gon.global.hash_w_array = { :a => [ 2, 3 ] }
28
- Gon.global.klass = Hash
22
+ Gon.global.int = 1
23
+ Gon.global.float = 1.1
24
+ Gon.global.string = 'string'
25
+ Gon.global.array = [1, 'string']
26
+ Gon.global.hash_var = { :a => 1, :b => '2' }
27
+ Gon.global.hash_w_array = { :a => [2, 3] }
28
+ Gon.global.klass = Hash
29
29
  end
30
30
 
31
31
  end
@@ -47,21 +47,18 @@ describe Gon::Global do
47
47
  Gon.global.int = 1
48
48
  @base.include_gon.should == "<script type=\"text/javascript\">" +
49
49
  "\n//<![CDATA[\n" +
50
- "window.gon = {};" +
50
+ "window.gon={};" +
51
51
  "gon.global={\"int\":1};" +
52
52
  "\n//]]>\n" +
53
53
  "</script>"
54
54
  end
55
55
 
56
56
  it 'outputs correct js with an integer and integer in Gon' do
57
- Gon::Request.
58
- instance_variable_set(:@request_id, request.object_id)
59
- Gon::Request.env = {}
60
57
  Gon.int = 1
61
58
  Gon.global.int = 1
62
59
  @base.include_gon.should == "<script type=\"text/javascript\">" +
63
60
  "\n//<![CDATA[\n" +
64
- "window.gon = {};" +
61
+ "window.gon={};" +
65
62
  "gon.int=1;" +
66
63
  "gon.global={\"int\":1};" +
67
64
  "\n//]]>\n" +
@@ -72,7 +69,7 @@ describe Gon::Global do
72
69
  Gon.global.str = %q(a'b"c)
73
70
  @base.include_gon.should == "<script type=\"text/javascript\">" +
74
71
  "\n//<![CDATA[\n" +
75
- "window.gon = {};" +
72
+ "window.gon={};" +
76
73
  "gon.global={\"str\":\"a'b\\\"c\"};" +
77
74
  "\n//]]>\n" +
78
75
  "</script>"
@@ -82,7 +79,7 @@ describe Gon::Global do
82
79
  Gon.global.str = %q(</script><script>alert('!')</script>)
83
80
  @base.include_gon.should == "<script type=\"text/javascript\">" +
84
81
  "\n//<![CDATA[\n" +
85
- "window.gon = {};" +
82
+ "window.gon={};" +
86
83
  "gon.global={\"str\":\"\\u003C/script><script>alert('!')\\u003C/script>\"};" +
87
84
  "\n//]]>\n" +
88
85
  "</script>"
@@ -92,7 +89,7 @@ describe Gon::Global do
92
89
  Gon.global.str = "\u2028"
93
90
  @base.include_gon.should == "<script type=\"text/javascript\">" +
94
91
  "\n//<![CDATA[\n" +
95
- "window.gon = {};" +
92
+ "window.gon={};" +
96
93
  "gon.global={\"str\":\"&#x2028;\"};" +
97
94
  "\n//]]>\n" +
98
95
  "</script>"
@@ -114,15 +111,15 @@ describe Gon::Global do
114
111
  end
115
112
 
116
113
  let(:controller) { ActionController::Base.new }
117
- let(:objects) { [1,2] }
114
+ let(:objects) { [1, 2] }
118
115
 
119
116
  it 'works fine with rabl' do
120
- Gon.global.rabl :template =>'spec/test_data/sample.rabl', :controller => controller
117
+ Gon.global.rabl :template => 'spec/test_data/sample.rabl', :controller => controller
121
118
  Gon.global.objects.length.should == 2
122
119
  end
123
120
 
124
121
  it 'works fine with jbuilder' do
125
- Gon.global.jbuilder :template =>'spec/test_data/sample.json.jbuilder', :controller => controller
122
+ Gon.global.jbuilder :template => 'spec/test_data/sample.json.jbuilder', :controller => controller
126
123
  Gon.global.objects.length.should == 2
127
124
  end
128
125
 
@@ -2,10 +2,6 @@ require 'spec_helper'
2
2
 
3
3
  describe Gon do
4
4
 
5
- before(:each) do
6
- Gon::Request.env = {}
7
- end
8
-
9
5
  describe '.jbuilder' do
10
6
  context 'render jbuilder templates' do
11
7
 
@@ -15,7 +11,7 @@ describe Gon do
15
11
  end
16
12
 
17
13
  let(:controller) { ActionController::Base.new }
18
- let(:objects) { [1,2] }
14
+ let(:objects) { [1, 2] }
19
15
 
20
16
  it 'render json from jbuilder template' do
21
17
  Gon.jbuilder 'spec/test_data/sample.json.jbuilder', :controller => controller
@@ -23,8 +19,11 @@ describe Gon do
23
19
  end
24
20
 
25
21
  it 'render json from jbuilder template with locals' do
26
- Gon.jbuilder 'spec/test_data/sample_with_locals.json.jbuilder', :controller => controller, :locals => { :some_local => 1234 }
22
+ Gon.jbuilder 'spec/test_data/sample_with_locals.json.jbuilder',
23
+ :controller => controller,
24
+ :locals => { :some_local => 1234, :some_complex_local => OpenStruct.new(:id => 1234) }
27
25
  Gon.some_local.should == 1234
26
+ Gon.some_complex_local_id.should == 1234
28
27
  end
29
28
 
30
29
  it 'render json from jbuilder template with locals' do
@@ -1,15 +1,11 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Gon do
4
-
4
+
5
5
  before(:all) do
6
6
  ensure_rabl_rails_is_loaded
7
7
  end
8
8
 
9
- before(:each) do
10
- Gon::Request.env = {}
11
- end
12
-
13
9
  describe '.rabl with rabl-rails gem' do
14
10
 
15
11
  before :each do
@@ -17,9 +13,9 @@ describe Gon do
17
13
  controller.instance_variable_set('@objects', objects)
18
14
  controller.request = ActionDispatch::TestRequest.new
19
15
  end
20
-
16
+
21
17
  let(:controller) { ActionController::Base.new }
22
- let(:objects) { [1,2] }
18
+ let(:objects) { [1, 2] }
23
19
 
24
20
  context 'render template with deprecation' do
25
21
  it 'still works' do
@@ -27,39 +23,39 @@ describe Gon do
27
23
  Gon.objects.length.should == 2
28
24
  end
29
25
  end
30
-
26
+
31
27
  context 'option locals' do
32
28
  it 'works without locals object properly' do
33
29
  Gon.rabl(
34
30
  :template =>'spec/test_data/sample_rabl_rails.rabl',
35
31
  :controller => controller
36
32
  )
37
- Gon.objects.map { |it| it['inspect'] }.should == ['1', '2']
33
+ Gon.objects.map { |it| it['inspect'] }.should == %w(1 2)
38
34
  end
39
35
 
40
36
  it 'works with different locals object' do
41
37
  Gon.rabl(
42
- :template =>'spec/test_data/sample_rabl_rails.rabl',
38
+ :template => 'spec/test_data/sample_rabl_rails.rabl',
43
39
  :controller => controller,
44
40
  :locals => { :objects => [3, 4] }
45
41
  )
46
- Gon.objects.map { |it| it['inspect'] }.should == ['3', '4']
42
+ Gon.objects.map { |it| it['inspect'] }.should == %w(3 4)
47
43
  end
48
44
  end
49
-
45
+
50
46
  it 'works if rabl-rails is included' do
51
- Gon.rabl :template =>'spec/test_data/sample_rabl_rails.rabl', :controller => controller
47
+ Gon.rabl :template => 'spec/test_data/sample_rabl_rails.rabl', :controller => controller
52
48
  Gon.objects.length.should == 2
53
49
  end
54
-
50
+
55
51
  it 'works with ActionView::Helpers' do
56
52
  Gon.rabl :template =>'spec/test_data/sample_with_helpers_rabl_rails.rabl', :controller => controller
57
53
  Gon.objects.first['time_ago'].should == 'about 6 hours'
58
54
  end
59
-
55
+
60
56
  it 'raise exception if rabl or rabl-rails is not included' do
61
57
  Object.send :remove_const, :RablRails # ensure_rabl_rails_is_loaded method already removed Rabl
62
- expect { Gon.rabl :template =>'spec/test_data/sample.rabl', :controller => controller}.to raise_error
58
+ expect { Gon.rabl :template => 'spec/test_data/sample.rabl', :controller => controller}.to raise_error
63
59
  ensure_rabl_rails_is_loaded # load up rabl-rails again, we're not done testing
64
60
  end
65
61
 
@@ -1,15 +1,11 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Gon do
4
-
4
+
5
5
  before(:all) do
6
6
  ensure_rabl_is_loaded
7
7
  end
8
8
 
9
- before(:each) do
10
- Gon::Request.env = {}
11
- end
12
-
13
9
  describe '.rabl' do
14
10
 
15
11
  before :each do
@@ -18,7 +14,7 @@ describe Gon do
18
14
  end
19
15
 
20
16
  let(:controller) { ActionController::Base.new }
21
- let(:objects) { [1,2] }
17
+ let(:objects) { [1, 2] }
22
18
 
23
19
  context 'render template with deprecation' do
24
20
  it 'still works' do
@@ -30,35 +26,35 @@ describe Gon do
30
26
  context 'option locals' do
31
27
  it 'works without locals object properly' do
32
28
  Gon.rabl(
33
- :template =>'spec/test_data/sample.rabl',
29
+ :template => 'spec/test_data/sample.rabl',
34
30
  :controller => controller
35
31
  )
36
- Gon.objects.map { |it| it['object']['inspect'] }.should == ['1', '2']
32
+ Gon.objects.map { |it| it['object']['inspect'] }.should == %w(1 2)
37
33
  end
38
34
 
39
35
  it 'works with different locals object' do
40
36
  Gon.rabl(
41
- :template =>'spec/test_data/sample.rabl',
37
+ :template => 'spec/test_data/sample.rabl',
42
38
  :controller => controller,
43
- :locals => { :objects => [3, 4] }
39
+ :locals => { :objects => [3, 4] }
44
40
  )
45
- Gon.objects.map { |it| it['object']['inspect'] }.should == ['3', '4']
41
+ Gon.objects.map { |it| it['object']['inspect'] }.should == %w(3 4)
46
42
  end
47
43
  end
48
44
 
49
45
  it 'works if rabl is included' do
50
- Gon.rabl :template =>'spec/test_data/sample.rabl', :controller => controller
46
+ Gon.rabl :template => 'spec/test_data/sample.rabl', :controller => controller
51
47
  Gon.objects.length.should == 2
52
48
  end
53
49
 
54
50
  it 'works with ActionView::Helpers' do
55
- Gon.rabl :template =>'spec/test_data/sample_with_helpers.rabl', :controller => controller
51
+ Gon.rabl :template => 'spec/test_data/sample_with_helpers.rabl', :controller => controller
56
52
  Gon.objects.first['object']['time_ago'].should == 'about 6 hours'
57
53
  end
58
54
 
59
55
  it 'raise exception if rabl is not included' do
60
56
  Gon.send :remove_const, 'Rabl'
61
- expect { Gon.rabl :template =>'spec/test_data/sample.rabl', :controller => controller}.to raise_error
57
+ expect { Gon.rabl :template => 'spec/test_data/sample.rabl', :controller => controller }.to raise_error
62
58
  load 'rabl.rb'
63
59
  load 'gon/rabl.rb'
64
60
  end
@@ -67,11 +63,11 @@ describe Gon do
67
63
  context 'template is specified' do
68
64
 
69
65
  it 'add the extension if not included in the template name' do
70
- Gon::Base.send(:get_template_path, { :template => 'spec/test_data/sample'}, 'rabl').should eql('spec/test_data/sample.rabl')
66
+ Gon::Base.send(:get_template_path, { :template => 'spec/test_data/sample' }, 'rabl').should eql('spec/test_data/sample.rabl')
71
67
  end
72
68
 
73
69
  it 'return the specified template' do
74
- Gon::Base.send(:get_template_path, { :template => 'spec/test_data/sample.rabl'}, 'rabl').should eql('spec/test_data/sample.rabl')
70
+ Gon::Base.send(:get_template_path, { :template => 'spec/test_data/sample.rabl' }, 'rabl').should eql('spec/test_data/sample.rabl')
75
71
  end
76
72
 
77
73
  end
@@ -85,11 +81,11 @@ describe Gon do
85
81
  end
86
82
 
87
83
  let(:controller) { ActionController::Base.new }
88
- let(:objects) { [1,2] }
84
+ let(:objects) { [1, 2] }
89
85
 
90
86
  context 'the action doesn as a template at a different format' do
91
87
  it 'return the same template as the action with rabl extension' do
92
- Gon::Base.send(:get_template_path, {:controller => controller}, 'rabl').should eql('app/views/action_controller/base/show.json.rabl')
88
+ Gon::Base.send(:get_template_path, { :controller => controller }, 'rabl').should eql('app/views/action_controller/base/show.json.rabl')
93
89
  end
94
90
  end
95
91
 
@@ -2,19 +2,15 @@ require 'spec_helper'
2
2
 
3
3
  describe Gon do
4
4
 
5
- before(:each) do
6
- Gon::Request.env = {}
7
- end
8
-
9
5
  describe '.get_template_path' do
10
6
  context 'template is specified' do
11
7
 
12
8
  it 'add the extension if not included in the template name' do
13
- Gon::Base.send(:get_template_path, { :template => 'spec/test_data/sample'}, 'jbuilder').should eql('spec/test_data/sample.jbuilder')
9
+ Gon::Base.send(:get_template_path, { :template => 'spec/test_data/sample' }, 'jbuilder').should eql('spec/test_data/sample.jbuilder')
14
10
  end
15
11
 
16
12
  it 'return the specified template' do
17
- Gon::Base.send(:get_template_path, { :template => 'spec/test_data/sample.jbuilder'}, 'jbuilder').should eql('spec/test_data/sample.jbuilder')
13
+ Gon::Base.send(:get_template_path, { :template => 'spec/test_data/sample.jbuilder' }, 'jbuilder').should eql('spec/test_data/sample.jbuilder')
18
14
  end
19
15
 
20
16
  end
@@ -28,11 +24,11 @@ describe Gon do
28
24
  end
29
25
 
30
26
  let(:controller) { ActionController::Base.new }
31
- let(:objects) { [1,2] }
27
+ let(:objects) { [1, 2] }
32
28
 
33
29
  context 'the action doesn as a template at a different format' do
34
30
  it 'return the same template as the action with rabl extension' do
35
- Gon::Base.send(:get_template_path, {:controller => controller}, 'jbuilder').should eql('app/views/action_controller/base/show.json.jbuilder')
31
+ Gon::Base.send(:get_template_path, { :controller => controller }, 'jbuilder').should eql('app/views/action_controller/base/show.json.jbuilder')
36
32
  end
37
33
  end
38
34
 
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'threading behaviour' do
4
+ it 'is threadsafe' do
5
+ threads = []
6
+ 10.times do
7
+ threads << Thread.new do
8
+ Gon.clear
9
+ Gon.a ||= 1
10
+ Gon.a += 1
11
+ expect(Gon.a).to eq 2
12
+ end
13
+ end
14
+ threads.each(&:join)
15
+ expect(Gon.a).to eq 2
16
+ end
17
+ end
@@ -13,8 +13,8 @@ describe Gon::Watch do
13
13
  env['REQUEST_METHOD'] = 'GET'
14
14
 
15
15
  Gon::Watch.clear
16
- Gon::Request.instance_variable_set(:@request_env, env)
17
- Gon::Request.env['action_controller.instance'] = controller
16
+ Gon.send(:current_gon).instance_variable_set(:@request_env, env)
17
+ Gon.send(:current_gon).env['action_controller.instance'] = controller
18
18
  Gon.clear
19
19
  end
20
20
 
@@ -44,15 +44,15 @@ describe Gon::Watch do
44
44
  end
45
45
 
46
46
  it 'should return value of variable if called right request' do
47
- env = Gon::Request.instance_variable_get :@request_env
48
- env["HTTP_X_REQUESTED_WITH"] = "XMLHttpRequest"
47
+ env = Gon.send(:current_gon).instance_variable_get(:@request_env)
48
+ env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
49
49
  request = ActionDispatch::Request.new env
50
50
  controller.request = request
51
51
  params = {}
52
52
  params[:gon_return_variable] = true
53
53
  params[:gon_watched_variable] = 'a'
54
54
  controller.params = params
55
- Gon::Request.env['action_controller.instance'] = controller
55
+ Gon.send(:current_gon).env['action_controller.instance'] = controller
56
56
 
57
57
  controller.should_receive('render').with(:json => 1)
58
58
 
@@ -37,3 +37,10 @@ def ensure_rabl_rails_is_loaded
37
37
  load 'rabl-rails.rb'
38
38
  end
39
39
  end
40
+
41
+ RSpec.configure do |config|
42
+ config.before(:each) do
43
+ @request = Thread.current['gon'] = Gon::Request.new({})
44
+ Gon.stub(:current_gon).and_return(@request)
45
+ end
46
+ end
@@ -1 +1,2 @@
1
1
  json.some_local some_local
2
+ json.some_complex_local_id some_complex_local.id
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gon
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.1
4
+ version: 5.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-06-04 00:00:00.000000000 Z
12
+ date: 2013-12-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: actionpack
@@ -159,6 +159,7 @@ files:
159
159
  - spec/gon/rabl_with_rabl_rails_spec.rb
160
160
  - spec/gon/rabl_with_rabl_spec.rb
161
161
  - spec/gon/templates_spec.rb
162
+ - spec/gon/thread_spec.rb
162
163
  - spec/gon/watch_spec.rb
163
164
  - spec/spec_helper.rb
164
165
  - spec/test_data/_sample_partial.json.jbuilder
@@ -202,6 +203,7 @@ test_files:
202
203
  - spec/gon/rabl_with_rabl_rails_spec.rb
203
204
  - spec/gon/rabl_with_rabl_spec.rb
204
205
  - spec/gon/templates_spec.rb
206
+ - spec/gon/thread_spec.rb
205
207
  - spec/gon/watch_spec.rb
206
208
  - spec/spec_helper.rb
207
209
  - spec/test_data/_sample_partial.json.jbuilder