hyper-react 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +26 -4
  3. data/Appraisals +3 -2
  4. data/CHANGELOG.md +19 -0
  5. data/README.md +3 -3
  6. data/config.ru +2 -1
  7. data/gemfiles/opal_0.10_react_13.gemfile +13 -0
  8. data/gemfiles/opal_0.10_react_14.gemfile +13 -0
  9. data/gemfiles/opal_0.10_react_15.gemfile +13 -0
  10. data/gemfiles/opal_0.8_react_15.gemfile +1 -1
  11. data/gemfiles/opal_0.9_react_15.gemfile +1 -1
  12. data/hyper-react.gemspec +1 -1
  13. data/lib/generators/reactive_ruby/test_app/templates/assets/javascripts/components.rb +0 -1
  14. data/lib/hyper-react.rb +2 -1
  15. data/lib/react/api.rb +3 -2
  16. data/lib/react/component/class_methods.rb +2 -2
  17. data/lib/react/component/props_wrapper.rb +2 -2
  18. data/lib/react/element.rb +1 -1
  19. data/lib/react/ext/opal-jquery/element.rb +26 -0
  20. data/lib/react/state.rb +6 -5
  21. data/lib/react/test/matchers/render_html_matcher.rb +5 -0
  22. data/lib/react/test/session.rb +14 -23
  23. data/lib/react/test/utils.rb +25 -0
  24. data/lib/react/top_level.rb +12 -28
  25. data/lib/react/top_level_render.rb +29 -0
  26. data/lib/reactive-ruby/isomorphic_helpers.rb +2 -2
  27. data/lib/reactive-ruby/version.rb +1 -1
  28. data/spec/index.html.erb +1 -0
  29. data/spec/react/children_spec.rb +1 -1
  30. data/spec/react/component/base_spec.rb +2 -2
  31. data/spec/react/component_spec.rb +74 -73
  32. data/spec/react/dsl_spec.rb +24 -21
  33. data/spec/react/element_spec.rb +7 -7
  34. data/spec/react/event_spec.rb +2 -2
  35. data/spec/react/native_library_spec.rb +20 -24
  36. data/spec/react/observable_spec.rb +36 -1
  37. data/spec/react/opal_jquery_extensions_spec.rb +48 -46
  38. data/spec/react/param_declaration_spec.rb +8 -8
  39. data/spec/react/react_spec.rb +41 -28
  40. data/spec/react/test/rspec_spec.rb +1 -1
  41. data/spec/react/test/session_spec.rb +8 -20
  42. data/spec/react/test/utils_spec.rb +11 -28
  43. data/spec/react/top_level_component_spec.rb +7 -2
  44. data/spec/react/tutorial/tutorial_spec.rb +2 -2
  45. data/spec/reactive-ruby/component_loader_spec.rb +10 -4
  46. data/spec/reactive-ruby/isomorphic_helpers_spec.rb +6 -1
  47. data/spec/spec_helper.rb +2 -0
  48. data/spec/support/react/spec_helpers.rb +1 -21
  49. metadata +12 -6
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  if opal?
4
- describe 'the React DSL' do
4
+ describe 'the React DSL', type: :component do
5
5
 
6
6
  context "render macro" do
7
7
 
@@ -14,7 +14,7 @@ describe 'the React DSL' do
14
14
  end
15
15
  end
16
16
 
17
- expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<div class="foo">hello</div>')
17
+ expect(Foo).to render_static_html('<div class="foo">hello</div>')
18
18
  end
19
19
 
20
20
  it "can define the render method with the render macro without a container" do
@@ -26,7 +26,7 @@ describe 'the React DSL' do
26
26
  end
27
27
  end
28
28
 
29
- expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<span>hello</span>')
29
+ expect(Foo).to render_static_html('<span>hello</span>')
30
30
  end
31
31
 
32
32
  it "can define the render method with the render macro with a application defined container" do
@@ -40,7 +40,7 @@ describe 'the React DSL' do
40
40
  render Bar, p1: "fred"
41
41
  end
42
42
 
43
- expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<span>hello fred</span>')
43
+ expect(Foo).to render_static_html('<span>hello fred</span>')
44
44
  end
45
45
  end
46
46
 
@@ -53,7 +53,7 @@ describe 'the React DSL' do
53
53
  end
54
54
  end
55
55
 
56
- expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<div>hello</div>')
56
+ expect(Foo).to render_static_html('<div>hello</div>')
57
57
  end
58
58
 
59
59
  it "will pass converted props through event handlers" do
@@ -77,7 +77,7 @@ describe 'the React DSL' do
77
77
  end
78
78
  end
79
79
 
80
- expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<div>hello</div>')
80
+ expect(Foo).to render_static_html('<div>hello</div>')
81
81
  end
82
82
 
83
83
  it "has a .span short hand String method" do
@@ -89,7 +89,7 @@ describe 'the React DSL' do
89
89
  end
90
90
  end
91
91
 
92
- expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<div><span>hello</span><span>goodby</span></div>')
92
+ expect(Foo).to render_static_html('<div><span>hello</span><span>goodby</span></div>')
93
93
  end
94
94
 
95
95
  it "has a .br short hand String method" do
@@ -113,7 +113,7 @@ describe 'the React DSL' do
113
113
  end
114
114
  end
115
115
 
116
- expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<table><tr><td>hello</td></tr></table>')
116
+ expect(Foo).to render_static_html('<table><tr><td>hello</td></tr></table>')
117
117
  end
118
118
 
119
119
  it "has a .para short hand String method" do
@@ -125,7 +125,7 @@ describe 'the React DSL' do
125
125
  end
126
126
  end
127
127
 
128
- expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<div><p>hello</p></div>')
128
+ expect(Foo).to render_static_html('<div><p>hello</p></div>')
129
129
  end
130
130
 
131
131
  it 'can do a method call on a class name that is not a direct sibling' do
@@ -141,8 +141,8 @@ describe 'the React DSL' do
141
141
  Comp()
142
142
  end
143
143
  end
144
- expect(React.render_to_static_markup(React.create_element(Mod::NestedMod::NestedComp)))
145
- .to eq('<span>Mod::Comp</span>')
144
+ expect(Mod::NestedMod::NestedComp)
145
+ .to render_static_html('<span>Mod::Comp</span>')
146
146
  end
147
147
 
148
148
  it 'raises a meaningful error if a Constant Name is not actually a component' do
@@ -187,7 +187,7 @@ describe 'the React DSL' do
187
187
  end
188
188
  end
189
189
 
190
- expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<span>a man walks into a bar</span>')
190
+ expect(Foo).to render_static_html('<span>a man walks into a bar</span>')
191
191
  end
192
192
 
193
193
  it "can add class names by the haml .class notation" do
@@ -206,7 +206,7 @@ describe 'the React DSL' do
206
206
  end
207
207
  end
208
208
 
209
- expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<span class="other-class the-class">a man walks into a bar</span>')
209
+ expect(Foo).to render_static_html('<span class="other-class the-class">a man walks into a bar</span>')
210
210
  end
211
211
 
212
212
  it "can use the 'class' keyword for classes" do
@@ -218,7 +218,7 @@ describe 'the React DSL' do
218
218
  end
219
219
  end
220
220
 
221
- expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<span class="the-class">hello</span>')
221
+ expect(Foo).to render_static_html('<span class="the-class">hello</span>')
222
222
  end
223
223
 
224
224
  it "can generate a unrendered node using the .as_node method" do # div { "hello" }.as_node
@@ -230,7 +230,8 @@ describe 'the React DSL' do
230
230
  end
231
231
  end
232
232
 
233
- expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<span data-size="12">React::Element</span>')
233
+ expect(Foo)
234
+ .to render_static_html('<span data-size="12">React::Element</span>')
234
235
  end
235
236
 
236
237
  it "can use the dangerously_set_inner_HTML param" do
@@ -242,7 +243,7 @@ describe 'the React DSL' do
242
243
  end
243
244
  end
244
245
 
245
- expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<div>Hello&nbsp;&nbsp;Goodby</div>')
246
+ expect(Foo).to render_static_html('<div>Hello&nbsp;&nbsp;Goodby</div>')
246
247
  end
247
248
 
248
249
  it 'should convert a hash param to hyphenated html attributes if in React::HASH_ATTRIBUTES' do
@@ -254,8 +255,8 @@ describe 'the React DSL' do
254
255
  end
255
256
  end
256
257
 
257
- expect(React.render_to_static_markup(React.create_element(Foo)))
258
- .to eq('<div data-foo="bar" aria-foo-bar="foo"></div>')
258
+ expect(Foo)
259
+ .to render_static_html('<div data-foo="bar" aria-foo-bar="foo"></div>')
259
260
  end
260
261
 
261
262
  it 'should not convert a hash param to hyphenated html attributes if not in React::HASH_ATTRIBUTES' do
@@ -267,8 +268,10 @@ describe 'the React DSL' do
267
268
  end
268
269
  end
269
270
 
270
- expect(React.render_to_static_markup(React.create_element(Foo)))
271
- .to eq('<div title="{&quot;bar&quot;=&gt;&quot;foo&quot;}"></div>')
271
+ expect(Foo)
272
+ .to render_static_html(
273
+ '<div title="{&quot;bar&quot;=&gt;&quot;foo&quot;}"></div>'
274
+ )
272
275
  end
273
276
 
274
277
  it "will remove all elements passed as params from the rendering buffer" do
@@ -290,7 +293,7 @@ describe 'the React DSL' do
290
293
  end
291
294
  end
292
295
 
293
- expect(React.render_to_static_markup(React.create_element(Test))).to eq('<div><b>hello</b><b>hello</b></div>')
296
+ expect(Test).to render_static_html('<div><b>hello</b><b>hello</b></div>')
294
297
  end
295
298
  end
296
299
  end
@@ -3,7 +3,7 @@ require "spec_helper"
3
3
  if opal?
4
4
  # require 'reactrb/new-event-name-convention' # this require will get rid of any error messages but
5
5
  # the on method will no longer attach to the param prefixed with _on
6
- describe React::Element do
6
+ describe React::Element, type: :component do
7
7
  it 'bridges `type` of native React.Element attributes' do
8
8
  element = React.create_element('div')
9
9
  expect(element.element_type).to eq("div")
@@ -110,20 +110,20 @@ describe React::Element do
110
110
  it 'is subscribable through `on(:event_name)` method' do
111
111
  expect { |b|
112
112
  element = React.create_element("div").on(:click, &b)
113
- instance = renderElementToDocument(element)
114
- simulateEvent(:click, instance)
113
+ dom_node = React::Test::Utils.render_into_document(element)
114
+ React::Test::Utils.simulate(:click, dom_node)
115
115
  }.to yield_with_args(React::Event)
116
116
 
117
117
  expect { |b|
118
118
  element = React.create_element("div").on(:key_down, &b)
119
- instance = renderElementToDocument(element)
120
- simulateEvent(:keyDown, instance, {key: "Enter"})
119
+ dom_node = React::Test::Utils.render_into_document(element)
120
+ React::Test::Utils.simulate(:keyDown, dom_node, {key: "Enter"})
121
121
  }.to yield_control
122
122
 
123
123
  expect { |b|
124
124
  element = React.create_element("form").on(:submit, &b)
125
- instance = renderElementToDocument(element)
126
- simulateEvent(:submit, instance, {})
125
+ dom_node = React::Test::Utils.render_into_document(element)
126
+ React::Test::Utils.simulate(:submit, dom_node)
127
127
  }.to yield_control
128
128
  end
129
129
 
@@ -17,8 +17,8 @@ describe React::Event do
17
17
  expect(event).to respond_to(:prevent_default)
18
18
  expect(event).to respond_to(:stop_propagation)
19
19
  end
20
- instance = renderElementToDocument(element)
21
- simulateEvent(:click, instance)
20
+ dom_node = React::Test::Utils.render_into_document(element)
21
+ React::Test::Utils.simulate(:click, dom_node)
22
22
  end
23
23
  end
24
24
  end
@@ -17,7 +17,7 @@ module NativeLibraryTestModule
17
17
  end
18
18
  end
19
19
 
20
- describe "React::NativeLibrary" do
20
+ describe "React::NativeLibrary", type: :component do
21
21
 
22
22
  after(:each) do
23
23
  %x{
@@ -52,8 +52,7 @@ describe "React::NativeLibrary" do
52
52
  Foo.class_eval do
53
53
  imports "NativeLibrary.FunctionalComponent"
54
54
  end
55
- expect(React.render_to_static_markup(
56
- React.create_element(Foo, name: "There"))).to eq('<div>Hello There</div>')
55
+ expect(Foo).to render_static_html('<div>Hello There</div>').with_params(name: "There")
57
56
  end
58
57
  end
59
58
 
@@ -69,7 +68,7 @@ describe "React::NativeLibrary" do
69
68
  expect(React::API.native_react_component?(`window.NativeComponent`)).to be_truthy
70
69
  expect(React::API.native_react_component?(`{render: function render() {}}`)).to be_falsy
71
70
  expect(React::API.native_react_component?(`window.DoesntExist`)).to be_falsy
72
- expect(React::API.native_react_component?(``)).to be_falsy
71
+ expect(React::API.native_react_component?()).to be_falsy
73
72
  end
74
73
 
75
74
  it "will import a React.js library into the Ruby name space" do
@@ -87,8 +86,8 @@ describe "React::NativeLibrary" do
87
86
  Foo.class_eval do
88
87
  imports "NativeLibrary"
89
88
  end
90
- expect(React.render_to_static_markup(
91
- React.create_element(Foo::NativeComponent, name: "There"))).to eq('<div>Hello There</div>')
89
+ expect(Foo::NativeComponent)
90
+ .to render_static_html('<div>Hello There</div>').with_params(name: "There")
92
91
  end
93
92
 
94
93
  it "will import a nested React.js library into the Ruby name space" do
@@ -107,8 +106,8 @@ describe "React::NativeLibrary" do
107
106
  Foo.class_eval do
108
107
  imports "NativeLibrary"
109
108
  end
110
- expect(React.render_to_static_markup(
111
- React.create_element(Foo::NestedLibrary::NativeComponent, name: "There"))).to eq('<div>Hello There</div>')
109
+ expect(Foo::NestedLibrary::NativeComponent)
110
+ .to render_static_html('<div>Hello There</div>').with_params(name: "There")
112
111
  end
113
112
 
114
113
  it "will rename an imported a React.js component" do
@@ -127,8 +126,8 @@ describe "React::NativeLibrary" do
127
126
  imports "NativeLibrary"
128
127
  rename "NativeComponent" => "Bar"
129
128
  end
130
- expect(React.render_to_static_markup(
131
- React.create_element(Foo::Bar, name: "There"))).to eq('<div>Hello There</div>')
129
+ expect(Foo::Bar)
130
+ .to render_static_html('<div>Hello There</div>').with_params(name: "There")
132
131
  end
133
132
 
134
133
  it "will give a reasonable error when failing to import a renamed component" do
@@ -164,8 +163,8 @@ describe "React::NativeLibrary" do
164
163
  Foo.class_eval do
165
164
  imports "NativeComponent"
166
165
  end
167
- expect(React.render_to_static_markup(
168
- React.create_element(Foo, name: "There"))).to eq('<div>Hello There</div>')
166
+ expect(Foo)
167
+ .to render_static_html('<div>Hello There</div>').with_params(name: "There")
169
168
 
170
169
  end
171
170
 
@@ -184,8 +183,8 @@ describe "React::NativeLibrary" do
184
183
  Foo.class_eval do
185
184
  imports "NativeLibrary.NativeComponent"
186
185
  end
187
- expect(React.render_to_static_markup(
188
- React.create_element(Foo, name: "There"))).to eq('<div>Hello There</div>')
186
+ expect(Foo)
187
+ .to render_static_html('<div>Hello There</div>').with_params(name: "There")
189
188
 
190
189
  end
191
190
 
@@ -234,8 +233,7 @@ describe "React::NativeLibrary" do
234
233
  }
235
234
  })
236
235
  }
237
- expect(React.render_to_static_markup(
238
- React.create_element(Foo))).to eq('<div>Hello There</div>')
236
+ expect(Foo).to render_static_html('<div>Hello There</div>')
239
237
  end
240
238
 
241
239
  it 'will automatically import a React.js component when referenced in another component with the _as_node suffix' do
@@ -254,8 +252,7 @@ describe "React::NativeLibrary" do
254
252
  }
255
253
  })
256
254
  }
257
- expect(React.render_to_static_markup(
258
- React.create_element(Foo))).to eq('<div><div>Hello There</div><div>Hello There</div></div>')
255
+ expect(Foo).to render_static_html('<div><div>Hello There</div><div>Hello There</div></div>')
259
256
  end
260
257
 
261
258
  it "will automatically import a React.js component in a library when referenced in another component with the _as_node suffix" do
@@ -276,8 +273,7 @@ describe "React::NativeLibrary" do
276
273
  })
277
274
  }
278
275
  }
279
- expect(React.render_to_static_markup(
280
- React.create_element(Foo))).to eq('<div><div>Hello There</div><div>Hello There</div></div>')
276
+ expect(Foo).to render_static_html('<div><div>Hello There</div><div>Hello There</div></div>')
281
277
  end
282
278
 
283
279
  it "will automatically import a React.js component when referenced as a constant" do
@@ -289,8 +285,8 @@ describe "React::NativeLibrary" do
289
285
  }
290
286
  })
291
287
  }
292
- expect(React.render_to_static_markup(
293
- React.create_element(NativeComponent, name: "There"))).to eq('<div>Hello There</div>')
288
+ expect(NativeComponent)
289
+ .to render_static_html('<div>Hello There</div>').with_params(name: "There")
294
290
  end
295
291
 
296
292
  it "will automatically import a native library containing a React.js component" do
@@ -322,8 +318,8 @@ describe "React::NativeLibrary" do
322
318
  })
323
319
  }
324
320
  }
325
- expect(React.render_to_static_markup(
326
- React.create_element(NativeLibrary::NativeComponent, name: "There"))).to eq('<div>Hello There</div>')
321
+ expect(NativeLibrary::NativeComponent)
322
+ .to render_static_html('<div>Hello There</div>').with_params(name: "There")
327
323
  end
328
324
 
329
325
  it "will produce a sensible error if the component is not in the library" do
@@ -1,7 +1,42 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  if opal?
4
+
4
5
  describe 'React::Observable' do
5
- # tbd
6
+ it "allows to set value on Observable" do
7
+ stub_const 'Zoo', Class.new {
8
+ include React::Component
9
+ param :foo, type: React::Observable
10
+ before_mount do
11
+ params.foo! 4
12
+ end
13
+
14
+ def render
15
+ nil
16
+ end
17
+ }
18
+
19
+ stub_const 'Foo', Class.new
20
+ Foo.class_eval do
21
+ include React::Component
22
+
23
+ def render
24
+ div do
25
+ Zoo(foo: state.foo! )
26
+ span { state.foo.to_s }
27
+ end
28
+ end
29
+ end
30
+
31
+ instance = React::Test::Utils.render_into_document(React.create_element(Foo))
32
+ html = `#{instance.dom_node}.innerHTML`
33
+ # data-reactid appear in earlier versions of reactjs
34
+ %x{
35
+ var REGEX_REMOVE_IDS = /\s?data-reactid="[^"]+"/g;
36
+ html = html.replace(REGEX_REMOVE_IDS, '');
37
+ }
38
+ expect(html).to eq('<span></span><span>4</span>')
39
+ end
6
40
  end
41
+
7
42
  end
@@ -1,66 +1,68 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  if opal?
4
- describe 'Element' do
5
- after(:each) do
6
- React::API.clear_component_class_cache
7
- end
4
+ describe 'opal-jquery extensions' do
5
+ describe 'Element' do
6
+ after(:each) do
7
+ React::API.clear_component_class_cache
8
+ end
8
9
 
9
- it 'will reuse the wrapper componet class for the same Element' do
10
- stub_const 'Foo', Class.new(React::Component::Base)
11
- Foo.class_eval do
12
- param :name
13
- def render
14
- "hello #{params.name}"
15
- end
10
+ it 'will reuse the wrapper componet class for the same Element' do
11
+ stub_const 'Foo', Class.new(React::Component::Base)
12
+ Foo.class_eval do
13
+ param :name
14
+ def render
15
+ "hello #{params.name}"
16
+ end
16
17
 
17
- def component_will_unmount
18
+ def component_will_unmount
18
19
 
20
+ end
19
21
  end
20
- end
21
22
 
22
- expect_any_instance_of(Foo).to_not receive(:component_will_unmount)
23
+ expect_any_instance_of(Foo).to_not receive(:component_will_unmount)
23
24
 
24
- test_div = Element.new(:div)
25
- test_div.render { Foo(name: 'fred') }
26
- test_div.render { Foo(name: 'freddy') }
27
- expect(Element[test_div].find('span').html).to eq('hello freddy')
28
- end
25
+ test_div = Element.new(:div)
26
+ test_div.render { Foo(name: 'fred') }
27
+ test_div.render { Foo(name: 'freddy') }
28
+ expect(Element[test_div].find('span').html).to eq('hello freddy')
29
+ end
29
30
 
30
- it 'renders a top level component using render with a block' do
31
- stub_const 'Foo', Class.new(React::Component::Base)
32
- Foo.class_eval do
33
- param :name
34
- def render
35
- "hello #{params.name}"
31
+ it 'renders a top level component using render with a block' do
32
+ stub_const 'Foo', Class.new(React::Component::Base)
33
+ Foo.class_eval do
34
+ param :name
35
+ def render
36
+ "hello #{params.name}"
37
+ end
36
38
  end
39
+ test_div = Element.new(:div)
40
+ test_div.render { Foo(name: 'fred') }
41
+ expect(Element[test_div].find('span').html).to eq('hello fred')
37
42
  end
38
- test_div = Element.new(:div)
39
- test_div.render { Foo(name: 'fred') }
40
- expect(Element[test_div].find('span').html).to eq('hello fred')
41
- end
42
43
 
43
- it 'renders a top level component using render with a container and params ' do
44
- test_div = Element.new(:div)
45
- test_div.render(:span, id: :render_test_span) { 'hello' }
46
- expect(Element[test_div].find('#render_test_span').html).to eq('hello')
47
- end
44
+ it 'renders a top level component using render with a container and params ' do
45
+ test_div = Element.new(:div)
46
+ test_div.render(:span, id: :render_test_span) { 'hello' }
47
+ expect(Element[test_div].find('#render_test_span').html).to eq('hello')
48
+ end
48
49
 
49
- it 'will find the DOM node given a react element' do
50
- stub_const 'Foo', Class.new(React::Component::Base)
51
- Foo.class_eval do
52
- def render
53
- div { 'hello' }
50
+ it 'will find the DOM node given a react element' do
51
+ stub_const 'Foo', Class.new(React::Component::Base)
52
+ Foo.class_eval do
53
+ def render
54
+ div { 'hello' }
55
+ end
54
56
  end
55
- end
56
57
 
57
- expect(Element[renderToDocument(Foo)].html).to eq('hello')
58
- end
58
+ expect(Element[renderToDocument(Foo)].html).to eq('hello')
59
+ end
59
60
 
60
- it "accepts plain js object as selector" do
61
- expect {
62
- Element[`window`]
63
- }.not_to raise_error
61
+ it "accepts plain js object as selector" do
62
+ expect {
63
+ Element[`window`]
64
+ }.not_to raise_error
65
+ end
64
66
  end
65
67
  end
66
68
  end