Skip to content

Commit ce6ff38

Browse files
committed
feat(React) expose camelize_props function
1 parent 53d9ad7 commit ce6ff38

File tree

5 files changed

+99
-63
lines changed

5 files changed

+99
-63
lines changed

lib/react-rails.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1+
require 'react'
12
require 'react/jsx'
23
require 'react/rails'
34
require 'react/server_rendering'
4-

lib/react.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
module React
2+
# Recursively camelize `props`, returning a new Hash
3+
# @param props [Object] If it's a Hash or Array, it will be recursed. Otherwise it will be returned.
4+
# @return [Hash] a new hash whose keys are camelized strings
5+
def self.camelize_props(props)
6+
case props
7+
when Hash
8+
props.each_with_object({}) do |(key, value), new_props|
9+
new_key = key.to_s.camelize(:lower)
10+
new_value = camelize_props(value)
11+
new_props[new_key] = new_value
12+
end
13+
when Array
14+
props.map { |item| camelize_props(item) }
15+
else
16+
props
17+
end
18+
end
19+
end

lib/react/rails/component_mount.rb

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ def teardown(env)
2424
# on the client.
2525
def react_component(name, props = {}, options = {}, &block)
2626
options = {:tag => options} if options.is_a?(Symbol)
27-
props = camelize_props_key(props) if camelize_props_switch
27+
if camelize_props_switch
28+
props = React.camelize_props(props)
29+
end
2830

2931
prerender_options = options[:prerender]
3032
if prerender_options
@@ -45,23 +47,6 @@ def react_component(name, props = {}, options = {}, &block)
4547

4648
content_tag(html_tag, '', html_options, &block)
4749
end
48-
49-
private
50-
51-
def camelize_props_key(props)
52-
return props unless props.is_a?(Hash)
53-
props.inject({}) do |h, (k,v)|
54-
h[k.to_s.camelize(:lower)] = case v
55-
when Hash
56-
camelize_props_key(v)
57-
when Array
58-
v.map {|i| camelize_props_key(i) }
59-
else
60-
v
61-
end
62-
h
63-
end
64-
end
6550
end
6651
end
6752
end

test/react_asset_test.rb

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
require 'test_helper'
2+
3+
class ReactAssetTest < ActionDispatch::IntegrationTest
4+
setup do
5+
clear_sprockets_cache
6+
end
7+
8+
teardown do
9+
clear_sprockets_cache
10+
end
11+
12+
test 'asset pipeline should deliver drop-in react file replacement' do
13+
app_react_file_path = File.expand_path("../dummy/vendor/assets/javascripts/react.js", __FILE__)
14+
react_file_token = "'test_confirmation_token_react_content_non_production';\n"
15+
File.write(app_react_file_path, react_file_token)
16+
manually_expire_asset("react.js")
17+
react_asset = Rails.application.assets['react.js']
18+
19+
get '/assets/react.js'
20+
21+
File.unlink(app_react_file_path)
22+
23+
assert_response :success
24+
assert_equal react_file_token.length, react_asset.to_s.length, "The asset pipeline serves the drop-in file"
25+
assert_equal react_file_token.length, @response.body.length, "The asset route serves the drop-in file"
26+
end
27+
28+
test 'precompiling assets works' do
29+
begin
30+
precompile_assets
31+
ensure
32+
clear_precompiled_assets
33+
end
34+
end
35+
36+
test "the development version with addons is loaded" do
37+
asset = Rails.application.assets.find_asset('react')
38+
assert asset.pathname.to_s.end_with?('development-with-addons/react.js')
39+
end
40+
41+
test "the production build is optimized for production" do
42+
production_path = File.expand_path("../../lib/assets/react-source/production/react.js", __FILE__)
43+
production_js = File.read(production_path)
44+
env_checks = production_js.scan("NODE_ENV")
45+
assert_equal(0, env_checks.length, "Dead code is removed for production")
46+
end
47+
end

test/react_test.rb

Lines changed: 29 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,31 @@
1-
require 'test_helper'
2-
class ReactTest < ActionDispatch::IntegrationTest
3-
setup do
4-
clear_sprockets_cache
5-
end
6-
7-
teardown do
8-
clear_sprockets_cache
9-
end
10-
11-
test 'asset pipeline should deliver drop-in react file replacement' do
12-
app_react_file_path = File.expand_path("../dummy/vendor/assets/javascripts/react.js", __FILE__)
13-
react_file_token = "'test_confirmation_token_react_content_non_production';\n"
14-
File.write(app_react_file_path, react_file_token)
15-
manually_expire_asset("react.js")
16-
react_asset = Rails.application.assets['react.js']
17-
18-
get '/assets/react.js'
19-
20-
File.unlink(app_react_file_path)
21-
22-
assert_response :success
23-
assert_equal react_file_token.length, react_asset.to_s.length, "The asset pipeline serves the drop-in file"
24-
assert_equal react_file_token.length, @response.body.length, "The asset route serves the drop-in file"
25-
end
26-
27-
test 'precompiling assets works' do
28-
begin
29-
precompile_assets
30-
ensure
31-
clear_precompiled_assets
32-
end
33-
end
34-
35-
test "the development version with addons is loaded" do
36-
asset = Rails.application.assets.find_asset('react')
37-
assert asset.pathname.to_s.end_with?('development-with-addons/react.js')
38-
end
39-
40-
test "the production build is optimized for production" do
41-
production_path = File.expand_path("../../lib/assets/react-source/production/react.js", __FILE__)
42-
production_js = File.read(production_path)
43-
env_checks = production_js.scan("NODE_ENV")
44-
assert_equal(0, env_checks.length, "Dead code is removed for production")
1+
require "test_helper"
2+
3+
class ReactTest < ActiveSupport::TestCase
4+
def test_it_camelizes_props
5+
raw_props = {
6+
multi_word_sym: {
7+
nested_key: [
8+
{double_nested: true},
9+
1,
10+
"string item",
11+
[ { nested_array: {} }],
12+
]
13+
},
14+
"alreadyCamelized" => :ok,
15+
}
16+
17+
expected_props = {
18+
"multiWordSym" => {
19+
"nestedKey" => [
20+
{ "doubleNested" => true },
21+
1,
22+
"string item",
23+
[ { "nestedArray" => {} }],
24+
]
25+
},
26+
"alreadyCamelized" => :ok
27+
}
28+
29+
assert_equal expected_props, React.camelize_props(raw_props)
4530
end
4631
end

0 commit comments

Comments
 (0)