Skip to content

Commit ec5925b

Browse files
committed
feat(React::JSX) decouple transformer class
1 parent 093fe75 commit ec5925b

File tree

4 files changed

+41
-12
lines changed

4 files changed

+41
-12
lines changed

lib/react/jsx.rb

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,22 @@
55

66
module React
77
module JSX
8-
mattr_accessor :transform_options
8+
mattr_accessor :transform_options, :transformer_class
9+
10+
# You can assign `React::JSX.transformer_class = `
11+
# to provide your own transformer. It must implement:
12+
# - #initialize(options)
13+
# - #transform(code) => new code
14+
self.transformer_class = Transformer
15+
916
def self.transform(code)
1017
transformer.transform(code)
1118
end
1219

1320
def self.transformer
1421
# lazily loaded during first request and reloaded every time when in dev or test
1522
if @transformer.nil? || !::Rails.env.production?
16-
@transformer = Transformer.new(transform_options)
23+
@transformer = transformer_class.new(transform_options)
1724
end
1825
@transformer
1926
end

test/react/jsx_test.rb

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,26 @@
2020
}).call(this);
2121
eos
2222

23+
class NullTransformer
24+
def initialize(options={}); end
25+
def transform(code)
26+
"TRANSFORMED CODE!;\n"
27+
end
28+
end
29+
2330
class JSXTransformTest < ActionDispatch::IntegrationTest
24-
setup { clear_sprockets_cache }
25-
teardown { clear_sprockets_cache }
31+
setup do
32+
clear_sprockets_cache
33+
end
34+
35+
teardown do
36+
clear_sprockets_cache
37+
React::JSX.transformer_class = React::JSX::Transformer
38+
React::JSX.transform_options = {}
39+
end
2640

2741
test 'asset pipeline should transform JSX' do
2842
get '/assets/example.js'
29-
FileUtils.rm_r CACHE_PATH if CACHE_PATH.exist?
3043
assert_response :success
3144
assert_equal EXPECTED_JS, @response.body
3245
end
@@ -85,4 +98,11 @@ class JSXTransformTest < ActionDispatch::IntegrationTest
8598
assert_response :success
8699
assert_equal 'test_confirmation_token_jsx_transformed;', @response.body
87100
end
101+
102+
test 'use a custom transformer' do
103+
React::JSX.transformer_class = NullTransformer
104+
manually_expire_asset('example2.js')
105+
get '/assets/example2.js'
106+
assert_equal "TRANSFORMED CODE!;\n", @response.body
107+
end
88108
end

test/react_test.rb

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,7 @@ class ReactTest < ActionDispatch::IntegrationTest
1212
app_react_file_path = File.expand_path("../dummy/vendor/assets/javascripts/react.js", __FILE__)
1313
react_file_token = "'test_confirmation_token_react_content_non_production';\n"
1414
File.write(app_react_file_path, react_file_token)
15-
16-
react_asset = Rails.application.assets['react.js']
17-
18-
# Sprockets 2 doesn't expire this asset correctly,
19-
# so override `fresh?` to mark it as expired.
20-
def react_asset.fresh?(env); false; end
21-
15+
manually_expire_asset("react.js")
2216
react_asset = Rails.application.assets['react.js']
2317

2418
get '/assets/react.js'

test/test_helper.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ def clear_sprockets_cache
1919
end
2020
end
2121

22+
# Sprockets 2 doesn't expire this assets well in
23+
# this kind of setting,
24+
# so override `fresh?` to mark it as expired.
25+
def manually_expire_asset(asset_name)
26+
asset = Rails.application.assets[asset_name]
27+
def asset.fresh?(env); false; end
28+
end
29+
2230
# Load support files
2331
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
2432

0 commit comments

Comments
 (0)