reactrb 0.8.3 → 0.8.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,15 +1,15 @@
1
1
  require 'action_controller'
2
2
 
3
- module ReactiveRuby
4
- module Rails
5
- class ActionController::Base
6
- def render_component(*args)
7
- @component_name = ((args[0].is_a? Hash) || args.empty?) ? params[:action].camelize : args.shift
8
- @render_params = args.shift || {}
9
- options = args[0] || {}
10
- layout = options.key?(:layout) ? options[:layout].to_s : :default
11
- render inline: "<%= react_component @component_name, @render_params, { prerender: !params[:no_prerender] } %>", layout: layout
12
- end
3
+ module ActionController
4
+ # adds render_component helper to ActionControllers
5
+ class Base
6
+ def render_component(*args)
7
+ @component_name = (args[0].is_a? Hash) || args.empty? ? params[:action].camelize : args.shift
8
+ @render_params = args.shift || {}
9
+ options = args[0] || {}
10
+ render inline: '<%= react_component @component_name, @render_params, '\
11
+ '{ prerender: !params[:no_prerender] } %>',
12
+ layout: options.key?(:layout) ? options[:layout].to_s : :default
13
13
  end
14
14
  end
15
15
  end
@@ -1,3 +1,3 @@
1
1
  module React
2
- VERSION = '0.8.3'
2
+ VERSION = '0.8.4'
3
3
  end
@@ -2,26 +2,25 @@
2
2
 
3
3
  if RUBY_ENGINE == 'opal'
4
4
  if `window.React === undefined || window.React.version === undefined`
5
- raise [
6
- "No React.js Available",
7
- "",
8
- "React.js must be defined before requiring 'reactrb'",
9
- "'reactrb' has been tested with react v13, v14, and v15.",
10
- "",
11
- "IF USING 'react-rails':",
12
- " add 'require \"react\"' immediately before the 'require \"reactive-ruby\" directive in 'views/components.rb'.",
13
- "IF USING WEBPACK:",
14
- " add 'react' to your webpack manifest.",
15
- "OTHERWISE TO GET THE LATEST TESTED VERSION",
16
- " add 'require \"react-latest\"' immediately before the require of 'reactrb',",
17
- "OR TO USE A SPECIFIC VERSION",
18
- " add 'require \"react-v1x\"' immediately before the require of 'reactrb'."
19
- ].join("\n")
5
+ raise "No React.js Available\n\n"\
6
+ "React.js must be defined before requiring 'reactrb'\n"\
7
+ "'reactrb' has been tested with react v13, v14, and v15.\n\n"\
8
+ "IF USING 'react-rails':\n"\
9
+ " add 'require \"react\"' immediately before the 'require \"reactive-ruby\" "\
10
+ "directive in 'views/components.rb'.\n"\
11
+ "IF USING WEBPACK:\n"\
12
+ " add 'react' to your webpack manifest.\n"\
13
+ "OTHERWISE TO GET THE LATEST TESTED VERSION\n"\
14
+ " add 'require \"react-latest\"' immediately before the require of 'reactrb',\n"\
15
+ "OR TO USE A SPECIFIC VERSION\n"\
16
+ " add 'require \"react-v1x\"' immediately before the require of 'reactrb'."
20
17
  end
21
18
  require 'react/hash'
22
19
  require 'react/top_level'
23
20
  require 'react/observable'
24
21
  require 'react/component'
22
+ require 'react/component/dsl_instance_methods'
23
+ require 'react/component/tags'
25
24
  require 'react/component/base'
26
25
  require 'react/element'
27
26
  require 'react/event'
@@ -36,10 +35,12 @@ if RUBY_ENGINE == 'opal'
36
35
  else
37
36
  require 'opal'
38
37
  require 'opal-browser'
38
+ # rubocop:disable Lint/HandleExceptions
39
39
  begin
40
40
  require 'opal-jquery'
41
41
  rescue LoadError
42
42
  end
43
+ # rubocop:enable Lint/HandleExceptions
43
44
  require 'opal-activesupport'
44
45
  require 'reactive-ruby/version'
45
46
  require 'reactive-ruby/rails' if defined?(Rails)
@@ -0,0 +1,32 @@
1
+ # rubocop:disable Style/FileName
2
+ # require 'reactrb/auto-import' to automatically
3
+ # import JS libraries and components when they are detected
4
+ if RUBY_ENGINE == 'opal'
5
+ # modifies const and method_missing so that they will attempt
6
+ # to auto import native libraries and components using React::NativeLibrary
7
+ class Object
8
+ class << self
9
+ alias _reactrb_original_const_missing const_missing
10
+ alias _reactrb_original_method_missing method_missing
11
+
12
+ def const_missing(const_name)
13
+ # Opal uses const_missing to initially define things,
14
+ # so we always call the original, and respond to the exception
15
+ _reactrb_original_const_missing(const_name)
16
+ rescue StandardError => e
17
+ React::NativeLibrary.import_const_from_native(Object, const_name, true) || raise(e)
18
+ end
19
+
20
+ def method_missing(method_name, *args, &block)
21
+ method = method_name.gsub(/_as_node/, '') # remove once _as_node is deprecated.
22
+ component_class = React::NativeLibrary.import_const_from_native(self, method, false)
23
+ _reactrb_original_method_missing(method, *args, &block) unless component_class
24
+ if method == method_name
25
+ React::RenderingContext.render(component_class, *args, &block)
26
+ else # remove once _as_node is deprecated.
27
+ React::RenderingContext.build_only(component_class, *args, &block)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -20816,3 +20816,87 @@ module.exports = warning;
20816
20816
  })(function(React) {
20817
20817
  return React.__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
20818
20818
  });
20819
+ /**
20820
+ * ReactDOM v0.14.8
20821
+ *
20822
+ * Copyright 2013-2015, Facebook, Inc.
20823
+ * All rights reserved.
20824
+ *
20825
+ * This source code is licensed under the BSD-style license found in the
20826
+ * LICENSE file in the root directory of this source tree. An additional grant
20827
+ * of patent rights can be found in the PATENTS file in the same directory.
20828
+ *
20829
+ */
20830
+ // Based off https://github.com/ForbesLindesay/umd/blob/master/template.js
20831
+ ;(function(f) {
20832
+ // CommonJS
20833
+ if (typeof exports === "object" && typeof module !== "undefined") {
20834
+ module.exports = f(require('react'));
20835
+
20836
+ // RequireJS
20837
+ } else if (typeof define === "function" && define.amd) {
20838
+ define(['react'], f);
20839
+
20840
+ // <script>
20841
+ } else {
20842
+ var g;
20843
+ if (typeof window !== "undefined") {
20844
+ g = window;
20845
+ } else if (typeof global !== "undefined") {
20846
+ g = global;
20847
+ } else if (typeof self !== "undefined") {
20848
+ g = self;
20849
+ } else {
20850
+ // works providing we're not in "use strict";
20851
+ // needed for Java 8 Nashorn
20852
+ // see https://github.com/facebook/react/issues/3037
20853
+ g = this;
20854
+ }
20855
+ g.ReactDOM = f(g.React);
20856
+ }
20857
+
20858
+ })(function(React) {
20859
+ return React.__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
20860
+ });
20861
+ /**
20862
+ * ReactDOMServer v0.14.8
20863
+ *
20864
+ * Copyright 2013-2015, Facebook, Inc.
20865
+ * All rights reserved.
20866
+ *
20867
+ * This source code is licensed under the BSD-style license found in the
20868
+ * LICENSE file in the root directory of this source tree. An additional grant
20869
+ * of patent rights can be found in the PATENTS file in the same directory.
20870
+ *
20871
+ */
20872
+ // Based off https://github.com/ForbesLindesay/umd/blob/master/template.js
20873
+ ;(function(f) {
20874
+ // CommonJS
20875
+ if (typeof exports === "object" && typeof module !== "undefined") {
20876
+ module.exports = f(require('react'));
20877
+
20878
+ // RequireJS
20879
+ } else if (typeof define === "function" && define.amd) {
20880
+ define(['react'], f);
20881
+
20882
+ // <script>
20883
+ } else {
20884
+ var g;
20885
+ if (typeof window !== "undefined") {
20886
+ g = window;
20887
+ } else if (typeof global !== "undefined") {
20888
+ g = global;
20889
+ } else if (typeof self !== "undefined") {
20890
+ g = self;
20891
+ } else {
20892
+ // works providing we're not in "use strict";
20893
+ // needed for Java 8 Nashorn
20894
+ // see https://github.com/facebook/react/issues/3037
20895
+ g = this;
20896
+ }
20897
+ g.ReactDOMServer = f(g.React);
20898
+ }
20899
+
20900
+ })(function(React) {
20901
+ return React.__SECRET_DOM_SERVER_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
20902
+ });
@@ -616,47 +616,6 @@ describe React::Component do
616
616
  expect(React.render_to_static_markup(element)).to eq('<div></div>')
617
617
  end
618
618
 
619
- it 'redefines `p` to make method missing work' do
620
- stub_const 'Foo', Class.new
621
- Foo.class_eval do
622
- include React::Component
623
-
624
- def render
625
- p(class_name: 'foo') do
626
- p
627
- div { 'lorem ipsum' }
628
- p(id: '10')
629
- end
630
- end
631
- end
632
-
633
- element = React.create_element(Foo)
634
- markup = '<p class="foo"><p></p><div>lorem ipsum</div><p id="10"></p></p>'
635
- expect(React.render_to_static_markup(element)).to eq(markup)
636
- end
637
-
638
- it 'only overrides `p` in render context' do
639
- stub_const 'Foo', Class.new
640
- Foo.class_eval do
641
- include React::Component
642
-
643
- before_mount do
644
- p 'first'
645
- end
646
-
647
- after_mount do
648
- p 'second'
649
- end
650
-
651
- def render
652
- div
653
- end
654
- end
655
-
656
- expect(Kernel).to receive(:p).with('first')
657
- expect(Kernel).to receive(:p).with('second')
658
- renderToDocument(Foo)
659
- end
660
619
  end
661
620
 
662
621
  describe 'isMounted()' do
@@ -2,13 +2,66 @@ require 'spec_helper'
2
2
 
3
3
  if opal?
4
4
 
5
- module TestMod123
6
- class Bar < React::Component::Base
5
+ module TestMod123
6
+ class Bar < React::Component::Base
7
+ end
7
8
  end
8
- end
9
9
 
10
10
  describe 'the React DSL' do
11
11
 
12
+ context "render macro" do
13
+
14
+ it "can define the render method with the render macro with a html tag container" do
15
+ stub_const 'Foo', Class.new
16
+ Foo.class_eval do
17
+ include React::Component
18
+ render(:div, class: :foo) do
19
+ "hello"
20
+ end
21
+ end
22
+
23
+ expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<div class="foo">hello</div>')
24
+ end
25
+
26
+ it "can define the render method with the render macro without a container" do
27
+ stub_const 'Foo', Class.new
28
+ Foo.class_eval do
29
+ include React::Component
30
+ render do
31
+ "hello"
32
+ end
33
+ end
34
+
35
+ expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<span>hello</span>')
36
+ end
37
+
38
+ it "can define the render method with the render macro with a application defined container" do
39
+ stub_const 'Bar', Class.new(React::Component::Base)
40
+ Bar.class_eval do
41
+ param :p1
42
+ render { "hello #{params.p1}" }
43
+ end
44
+ stub_const 'Foo', Class.new(React::Component::Base)
45
+ Foo.class_eval do
46
+ render Bar, p1: "fred"
47
+ end
48
+
49
+ expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<span>hello fred</span>')
50
+ end
51
+ end
52
+
53
+ it "can use the upcase version of builtin tags" do
54
+ stub_const 'Foo', Class.new
55
+ Foo.class_eval do
56
+ include React::Component
57
+ def render
58
+ DIV { "hello" }
59
+ end
60
+ end
61
+
62
+ expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<div>hello</div>')
63
+ end
64
+
12
65
  it "will turn the last string in a block into a element" do
13
66
  stub_const 'Foo', Class.new
14
67
  Foo.class_eval do
@@ -17,7 +70,6 @@ describe 'the React DSL' do
17
70
  div { "hello" }
18
71
  end
19
72
  end
20
-
21
73
  expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<div>hello</div>')
22
74
  end
23
75
 
@@ -69,6 +121,38 @@ describe 'the React DSL' do
69
121
  expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<div><p>hello</p></div>')
70
122
  end
71
123
 
124
+ it 'can do a method call on a class name that is not a direct sibling' do
125
+ stub_const 'Mod', Module.new
126
+ stub_const 'Mod::NestedMod', Module.new
127
+ stub_const 'Mod::Comp', Class.new(React::Component::Base)
128
+ Mod::Comp.class_eval do
129
+ render { 'Mod::Comp' }
130
+ end
131
+ stub_const 'Mod::NestedMod::NestedComp', Class.new(React::Component::Base)
132
+ Mod::NestedMod::NestedComp.class_eval do
133
+ render do
134
+ Comp()
135
+ end
136
+ end
137
+ expect(React.render_to_static_markup(React.create_element(Mod::NestedMod::NestedComp)))
138
+ .to eq('<span>Mod::Comp</span>')
139
+ end
140
+
141
+ it 'raises a meaningful error if a Constant Name is not actually a component' do
142
+ stub_const 'Mod', Module.new
143
+ stub_const 'Mod::NestedMod', Module.new
144
+ stub_const 'Mod::Comp', Class.new
145
+ stub_const 'Mod::NestedMod::NestedComp', Class.new(React::Component::Base)
146
+ Mod::NestedMod::NestedComp.class_eval do
147
+ backtrace :none
148
+ render do
149
+ Comp()
150
+ end
151
+ end
152
+ expect { React.render_to_static_markup(React.create_element(Mod::NestedMod::NestedComp)) }
153
+ .to raise_error('Comp does not appear to be a react component.')
154
+ end
155
+
72
156
  it "will treat the component class name as a first class component name" do
73
157
  stub_const 'Mod::Bar', Class.new
74
158
  Mod::Bar.class_eval do
@@ -141,6 +225,32 @@ describe 'the React DSL' do
141
225
  expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<div>Hello&nbsp;&nbsp;Goodby</div>')
142
226
  end
143
227
 
228
+ it 'should convert a hash param to hyphenated html attributes if in React::HASH_ATTRIBUTES' do
229
+ stub_const 'Foo', Class.new
230
+ Foo.class_eval do
231
+ include React::Component
232
+ def render
233
+ div(data: { foo: :bar }, aria: { foo_bar: :foo })
234
+ end
235
+ end
236
+
237
+ expect(React.render_to_static_markup(React.create_element(Foo)))
238
+ .to eq('<div data-foo="bar" aria-foo-bar="foo"></div>')
239
+ end
240
+
241
+ it 'should not convert a hash param to hyphenated html attributes if not in React::HASH_ATTRIBUTES' do
242
+ stub_const 'Foo', Class.new
243
+ Foo.class_eval do
244
+ include React::Component
245
+ def render
246
+ div(title: { bar: :foo })
247
+ end
248
+ end
249
+
250
+ expect(React.render_to_static_markup(React.create_element(Foo)))
251
+ .to eq('<div title="{&quot;bar&quot;=&gt;&quot;foo&quot;}"></div>')
252
+ end
253
+
144
254
  it "will remove all elements passed as params from the rendering buffer" do
145
255
  stub_const 'X2', Class.new
146
256
  X2.class_eval do
@@ -1,10 +1,298 @@
1
1
  require 'spec_helper'
2
+ require 'reactrb/auto-import'
2
3
 
3
4
  if opal?
4
- describe React::NativeLibrary do
5
- it "will import a React.js library into the Ruby name space" # class BS < NativeLibrary; imports 'ReactBootstrap'; end
6
- it "exclude specific components from a library" # exclude "Modal" # can't access BS.Modal
7
- it "rename specific components from a library" # rename "Modal" => "FooBar" # BS.FooBar connects to ReactBootstrap.Modal
8
- it "can importan multiple libraries into one class"
5
+
6
+ module NativeLibraryTestModule
7
+ class Component < React::Component::Base
8
+ param :time_stamp
9
+ backtrace :none
10
+ render { NativeComponent(name: "There - #{params.time_stamp}") }
11
+ end
12
+
13
+ class NestedComponent < React::Component::Base
14
+ param :time_stamp
15
+ backtrace :none
16
+ render { NativeLibrary::NativeNestedLibrary::NativeComponent(name: "There - #{params.time_stamp}") }
17
+ end
18
+ end
19
+
20
+ describe "React::NativeLibrary" do
21
+
22
+ after(:each) do
23
+ %x{
24
+ delete window.NativeLibrary;
25
+ delete window.NativeComponent;
26
+ delete window.nativeLibrary;
27
+ delete window.nativeComponent;
28
+ delete window.NativeObject;
29
+ }
30
+ Object.send :remove_const, :NativeLibrary
31
+ Object.send :remove_const, :NativeComponent
32
+ end
33
+
34
+ it "can use native_react_component? to detect a native React.js component" do
35
+ %x{
36
+ window.NativeComponent = React.createClass({
37
+ displayName: "HelloMessage",
38
+ render: function render() {
39
+ return React.createElement("div", null, "Hello ", this.props.name);
40
+ }
41
+ })
42
+ }
43
+ expect(React::API.native_react_component?(`window.NativeComponent`)).to be_truthy
44
+ expect(React::API.native_react_component?(`{render: function render() {}}`)).to be_falsy
45
+ expect(React::API.native_react_component?(`window.DoesntExist`)).to be_falsy
46
+ expect(React::API.native_react_component?(``)).to be_falsy
47
+ end
48
+
49
+ it "will import a React.js library into the Ruby name space" do
50
+ %x{
51
+ window.NativeLibrary = {
52
+ NativeComponent: React.createClass({
53
+ displayName: "HelloMessage",
54
+ render: function render() {
55
+ return React.createElement("div", null, "Hello ", this.props.name);
56
+ }
57
+ })
58
+ }
59
+ }
60
+ stub_const 'Foo', Class.new(React::NativeLibrary)
61
+ Foo.class_eval do
62
+ imports "NativeLibrary"
63
+ end
64
+ expect(React.render_to_static_markup(
65
+ React.create_element(Foo::NativeComponent, name: "There"))).to eq('<div>Hello There</div>')
66
+ end
67
+
68
+ it "will rename an imported a React.js component" do
69
+ %x{
70
+ window.NativeLibrary = {
71
+ NativeComponent: React.createClass({
72
+ displayName: "HelloMessage",
73
+ render: function render() {
74
+ return React.createElement("div", null, "Hello ", this.props.name);
75
+ }
76
+ })
77
+ }
78
+ }
79
+ stub_const 'Foo', Class.new(React::NativeLibrary)
80
+ Foo.class_eval do
81
+ imports "NativeLibrary"
82
+ rename "NativeComponent" => "Bar"
83
+ end
84
+ expect(React.render_to_static_markup(
85
+ React.create_element(Foo::Bar, name: "There"))).to eq('<div>Hello There</div>')
86
+ end
87
+
88
+ it "will give a reasonable error when failing to import a renamed component" do
89
+ %x{
90
+ window.NativeLibrary = {
91
+ NativeComponent: React.createClass({
92
+ displayName: "HelloMessage",
93
+ render: function render() {
94
+ return React.createElement("div", null, "Hello ", this.props.name);
95
+ }
96
+ })
97
+ }
98
+ }
99
+ stub_const 'Foo', Class.new(React::NativeLibrary)
100
+ expect do
101
+ Foo.class_eval do
102
+ imports "NativeLibrary"
103
+ rename "MispelledComponent" => "Bar"
104
+ end
105
+ end.to raise_error(/could not import MispelledComponent/)
106
+ end
107
+
108
+ it "will import a single React.js component into the ruby name space" do
109
+ %x{
110
+ window.NativeComponent = React.createClass({
111
+ displayName: "HelloMessage",
112
+ render: function render() {
113
+ return React.createElement("div", null, "Hello ", this.props.name);
114
+ }
115
+ })
116
+ }
117
+ stub_const 'Foo', Class.new(React::Component::Base)
118
+ Foo.class_eval do
119
+ imports "NativeComponent"
120
+ end
121
+ expect(React.render_to_static_markup(
122
+ React.create_element(Foo, name: "There"))).to eq('<div>Hello There</div>')
123
+
124
+ end
125
+
126
+ it "will import a name scoped React.js component into the ruby name space" do
127
+ %x{
128
+ window.NativeLibrary = {
129
+ NativeComponent: React.createClass({
130
+ displayName: "HelloMessage",
131
+ render: function render() {
132
+ return React.createElement("div", null, "Hello ", this.props.name);
133
+ }
134
+ })
135
+ }
136
+ }
137
+ stub_const 'Foo', Class.new(React::Component::Base)
138
+ Foo.class_eval do
139
+ imports "NativeLibrary.NativeComponent"
140
+ end
141
+ expect(React.render_to_static_markup(
142
+ React.create_element(Foo, name: "There"))).to eq('<div>Hello There</div>')
143
+
144
+ end
145
+
146
+ it "will give a meaningful error if the React.js component is invalid" do
147
+ %x{
148
+ window.NativeObject = {}
149
+ }
150
+ stub_const 'Foo', Class.new(React::Component::Base)
151
+ expect do
152
+ Foo.class_eval do
153
+ imports "NativeObject"
154
+ end
155
+ end.to raise_error("Foo cannot import 'NativeObject': does not appear to be a native react component.")
156
+ expect do
157
+ Foo.class_eval do
158
+ imports "window.Baz"
159
+ end
160
+ end.to raise_error(/^Foo cannot import \'window\.Baz\'\: (?!does not appear to be a native react component)..*$/)
161
+ end
162
+
163
+ context "automatic importing" do
164
+
165
+ it "will automatically import a React.js component when referenced in another component" do
166
+ %x{
167
+ window.NativeComponent = React.createClass({
168
+ displayName: "HelloMessage",
169
+ render: function render() {
170
+ return React.createElement("div", null, "Hello ", this.props.name);
171
+ }
172
+ })
173
+ }
174
+ expect(React.render_to_static_markup(
175
+ React.create_element(NativeLibraryTestModule::Component, time_stamp: Time.now))).to match(/<div>Hello There.*<\/div>/)
176
+ end
177
+
178
+ it "will automatically import a React.js component when referenced in another component" do
179
+ stub_const 'Foo', Class.new(React::Component::Base)
180
+ Foo.class_eval do
181
+ render { NativeComponent(name: "There") }
182
+ end
183
+ %x{
184
+ window.NativeComponent = React.createClass({
185
+ displayName: "HelloMessage",
186
+ render: function render() {
187
+ return React.createElement("div", null, "Hello ", this.props.name);
188
+ }
189
+ })
190
+ }
191
+ expect(React.render_to_static_markup(
192
+ React.create_element(Foo))).to eq('<div>Hello There</div>')
193
+ end
194
+
195
+ it 'will automatically import a React.js component when referenced in another component with the _as_node suffix' do
196
+ stub_const 'Foo', Class.new(React::Component::Base)
197
+ Foo.class_eval do
198
+ render(:div) do
199
+ e = React::Element.new(NativeComponent_as_node(name: 'There'))
200
+ 2.times { e.render }
201
+ end
202
+ end
203
+ %x{
204
+ window.NativeComponent = React.createClass({
205
+ displayName: "HelloMessage",
206
+ render: function render() {
207
+ return React.createElement("div", null, "Hello ", this.props.name);
208
+ }
209
+ })
210
+ }
211
+ expect(React.render_to_static_markup(
212
+ React.create_element(Foo))).to eq('<div><div>Hello There</div><div>Hello There</div></div>')
213
+ end
214
+
215
+ it "will automatically import a React.js component in a library when referenced in another component with the _as_node suffix" do
216
+ stub_const 'Foo', Class.new(React::Component::Base)
217
+ Foo.class_eval do
218
+ render(:div) do
219
+ e = React::Element.new(NativeLibrary::NativeComponent_as_node(name: 'There'))
220
+ 2.times { e.render }
221
+ end
222
+ end
223
+ %x{
224
+ window.NativeLibrary = {
225
+ NativeComponent: React.createClass({
226
+ displayName: "HelloMessage",
227
+ render: function render() {
228
+ return React.createElement("div", null, "Hello ", this.props.name);
229
+ }
230
+ })
231
+ }
232
+ }
233
+ expect(React.render_to_static_markup(
234
+ React.create_element(Foo))).to eq('<div><div>Hello There</div><div>Hello There</div></div>')
235
+ end
236
+
237
+ it "will automatically import a React.js component when referenced as a constant" do
238
+ %x{
239
+ window.NativeComponent = React.createClass({
240
+ displayName: "HelloMessage",
241
+ render: function render() {
242
+ return React.createElement("div", null, "Hello ", this.props.name);
243
+ }
244
+ })
245
+ }
246
+ expect(React.render_to_static_markup(
247
+ React.create_element(NativeComponent, name: "There"))).to eq('<div>Hello There</div>')
248
+ end
249
+
250
+ it "will automatically import a native library containing a React.js component" do
251
+ %x{
252
+ window.NativeLibrary = {
253
+ NativeNestedLibrary: {
254
+ NativeComponent: React.createClass({
255
+ displayName: "HelloMessage",
256
+ render: function render() {
257
+ return React.createElement("div", null, "Hello ", this.props.name);
258
+ }
259
+ })
260
+ }
261
+ }
262
+ }
263
+
264
+ expect(React.render_to_static_markup(
265
+ React.create_element(NativeLibraryTestModule::NestedComponent, time_stamp: Time.now))).to match(/<div>Hello There.*<\/div>/)
266
+ end
267
+
268
+ it "the library and components can begin with lower case letters" do
269
+ %x{
270
+ window.nativeLibrary = {
271
+ nativeComponent: React.createClass({
272
+ displayName: "HelloMessage",
273
+ render: function render() {
274
+ return React.createElement("div", null, "Hello ", this.props.name);
275
+ }
276
+ })
277
+ }
278
+ }
279
+ expect(React.render_to_static_markup(
280
+ React.create_element(NativeLibrary::NativeComponent, name: "There"))).to eq('<div>Hello There</div>')
281
+ end
282
+
283
+ it "will produce a sensible error if the component is not in the library" do
284
+ %x{
285
+ window.NativeLibrary = {
286
+ NativeNestedLibrary: {
287
+ }
288
+ }
289
+ }
290
+ expect do
291
+ React.render_to_static_markup(React.create_element(NativeLibraryTestModule::NestedComponent, time_stamp: Time.now))
292
+ end.to raise_error("could not import a react component named: NativeLibrary.NativeNestedLibrary.NativeComponent")
293
+
294
+ end
295
+
296
+ end
9
297
  end
10
298
  end