Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/react-rails.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
require 'react'
require 'react/jsx'
require 'react/rails'
require 'react/server_rendering'

19 changes: 19 additions & 0 deletions lib/react.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module React
# Recursively camelize `props`, returning a new Hash
# @param props [Object] If it's a Hash or Array, it will be recursed. Otherwise it will be returned.
# @return [Hash] a new hash whose keys are camelized strings
def self.camelize_props(props)
case props
when Hash
props.each_with_object({}) do |(key, value), new_props|
new_key = key.to_s.camelize(:lower)
new_value = camelize_props(value)
new_props[new_key] = new_value
end
when Array
props.map { |item| camelize_props(item) }
else
props
end
end
end
21 changes: 3 additions & 18 deletions lib/react/rails/component_mount.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ def teardown(env)
# on the client.
def react_component(name, props = {}, options = {}, &block)
options = {:tag => options} if options.is_a?(Symbol)
props = camelize_props_key(props) if camelize_props_switch
if camelize_props_switch
props = React.camelize_props(props)
end

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

content_tag(html_tag, '', html_options, &block)
end

private

def camelize_props_key(props)
return props unless props.is_a?(Hash)
props.inject({}) do |h, (k,v)|
h[k.to_s.camelize(:lower)] = case v
when Hash
camelize_props_key(v)
when Array
v.map {|i| camelize_props_key(i) }
else
v
end
h
end
end
end
end
end
47 changes: 47 additions & 0 deletions test/react_asset_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
require 'test_helper'

class ReactAssetTest < ActionDispatch::IntegrationTest
setup do
clear_sprockets_cache
end

teardown do
clear_sprockets_cache
end

test 'asset pipeline should deliver drop-in react file replacement' do
app_react_file_path = File.expand_path("../dummy/vendor/assets/javascripts/react.js", __FILE__)
react_file_token = "'test_confirmation_token_react_content_non_production';\n"
File.write(app_react_file_path, react_file_token)
manually_expire_asset("react.js")
react_asset = Rails.application.assets['react.js']

get '/assets/react.js'

File.unlink(app_react_file_path)

assert_response :success
assert_equal react_file_token.length, react_asset.to_s.length, "The asset pipeline serves the drop-in file"
assert_equal react_file_token.length, @response.body.length, "The asset route serves the drop-in file"
end

test 'precompiling assets works' do
begin
precompile_assets
ensure
clear_precompiled_assets
end
end

test "the development version with addons is loaded" do
asset = Rails.application.assets.find_asset('react')
assert asset.pathname.to_s.end_with?('development-with-addons/react.js')
end

test "the production build is optimized for production" do
production_path = File.expand_path("../../lib/assets/react-source/production/react.js", __FILE__)
production_js = File.read(production_path)
env_checks = production_js.scan("NODE_ENV")
assert_equal(0, env_checks.length, "Dead code is removed for production")
end
end
73 changes: 29 additions & 44 deletions test/react_test.rb
Original file line number Diff line number Diff line change
@@ -1,46 +1,31 @@
require 'test_helper'
class ReactTest < ActionDispatch::IntegrationTest
setup do
clear_sprockets_cache
end

teardown do
clear_sprockets_cache
end

test 'asset pipeline should deliver drop-in react file replacement' do
app_react_file_path = File.expand_path("../dummy/vendor/assets/javascripts/react.js", __FILE__)
react_file_token = "'test_confirmation_token_react_content_non_production';\n"
File.write(app_react_file_path, react_file_token)
manually_expire_asset("react.js")
react_asset = Rails.application.assets['react.js']

get '/assets/react.js'

File.unlink(app_react_file_path)

assert_response :success
assert_equal react_file_token.length, react_asset.to_s.length, "The asset pipeline serves the drop-in file"
assert_equal react_file_token.length, @response.body.length, "The asset route serves the drop-in file"
end

test 'precompiling assets works' do
begin
precompile_assets
ensure
clear_precompiled_assets
end
end

test "the development version with addons is loaded" do
asset = Rails.application.assets.find_asset('react')
assert asset.pathname.to_s.end_with?('development-with-addons/react.js')
end

test "the production build is optimized for production" do
production_path = File.expand_path("../../lib/assets/react-source/production/react.js", __FILE__)
production_js = File.read(production_path)
env_checks = production_js.scan("NODE_ENV")
assert_equal(0, env_checks.length, "Dead code is removed for production")
require "test_helper"

class ReactTest < ActiveSupport::TestCase
def test_it_camelizes_props
raw_props = {
multi_word_sym: {
nested_key: [
{double_nested: true},
1,
"string item",
[ { nested_array: {} }],
]
},
"alreadyCamelized" => :ok,
}

expected_props = {
"multiWordSym" => {
"nestedKey" => [
{ "doubleNested" => true },
1,
"string item",
[ { "nestedArray" => {} }],
]
},
"alreadyCamelized" => :ok
}

assert_equal expected_props, React.camelize_props(raw_props)
end
end