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
@@ -12,7 +12,7 @@ describe 'the param macro', type: :component do
12
12
  end
13
13
  end
14
14
 
15
- expect(Foo).to render('<div>biz</div>').with_params(bar: 'biz')
15
+ expect(Foo).to render_static_html('<div>biz</div>').with_params(bar: 'biz')
16
16
  end
17
17
 
18
18
  it "can create and access a required param" do
@@ -25,7 +25,7 @@ describe 'the param macro', type: :component do
25
25
  end
26
26
  end
27
27
 
28
- expect(Foo).to render('<div>bar</div>').with_params(foo: :bar)
28
+ expect(Foo).to render_static_html('<div>bar</div>').with_params(foo: :bar)
29
29
  end
30
30
 
31
31
  it "can create and access an optional params" do
@@ -42,7 +42,7 @@ describe 'the param macro', type: :component do
42
42
  end
43
43
  end
44
44
 
45
- expect(Foo).to render('<div>bar1-no_bar2-bar3-no_bar4</div>').with_params(foo1: :bar1, foo3: :bar3)
45
+ expect(Foo).to render_static_html('<div>bar1-no_bar2-bar3-no_bar4</div>').with_params(foo1: :bar1, foo3: :bar3)
46
46
  end
47
47
 
48
48
  it 'can specify validation rules with the type option' do
@@ -66,7 +66,7 @@ describe 'the param macro', type: :component do
66
66
  end
67
67
  end
68
68
 
69
- expect(Foo).to render('<div>12-string</div>').with_params(foo1: 12, foo2: "string")
69
+ expect(Foo).to render_static_html('<div>12-string</div>').with_params(foo1: 12, foo2: "string")
70
70
  end
71
71
 
72
72
  it 'logs error in warning if validation failed' do
@@ -167,7 +167,7 @@ describe 'the param macro', type: :component do
167
167
  end
168
168
 
169
169
  params = { foo: "", bar: { bazwoggle: 1 }, baz: [{ bazwoggle: 2 }] }
170
- expect(Foo).to render('<span>1, 2</span>').with_params(params)
170
+ expect(Foo).to render_static_html('<span>1, 2</span>').with_params(params)
171
171
  expect(`window.dummy_log[0]`).to match(/Warning: Failed prop( type|Type): In component `Foo`\nProvided prop `foo` could not be converted to BazWoggle/)
172
172
  end
173
173
 
@@ -190,7 +190,7 @@ describe 'the param macro', type: :component do
190
190
  "#{params.foo.kind}"
191
191
  end
192
192
  end
193
- expect(React.render_to_static_markup(React.create_element(Foo, foo: {bazwoggle: 1}))).to eq('<span>2</span>')
193
+ expect(Foo).to render_static_html('<span>2</span>').with_params(foo: {bazwoggle: 1})
194
194
  end
195
195
 
196
196
  it "even if contains an embedded native object" do
@@ -235,7 +235,7 @@ describe 'the param macro', type: :component do
235
235
  params.foo
236
236
  end
237
237
  end
238
- expect(Foo).to render('<span>works!</span>').with_params(foo: lambda { 'works!' })
238
+ expect(Foo).to render_static_html('<span>works!</span>').with_params(foo: lambda { 'works!' })
239
239
  end
240
240
 
241
241
  it "will create a 'bang' (i.e. update) method if the type is React::Observable" do
@@ -250,7 +250,7 @@ describe 'the param macro', type: :component do
250
250
  end
251
251
  current_state = ""
252
252
  observer = React::Observable.new(current_state) { |new_state| current_state = new_state }
253
- expect(Foo).to render('<span>ha!</span>').with_params(foo: observer)
253
+ expect(Foo).to render_static_html('<span>ha!</span>').with_params(foo: observer)
254
254
  expect(current_state).to eq("ha!")
255
255
  end
256
256
  end
@@ -6,28 +6,28 @@ RSpec.describe React, type: :component do
6
6
  React::API.clear_component_class_cache
7
7
  end
8
8
 
9
- describe "is_valid_element" do
9
+ describe "is_valid_element?" do
10
10
  it "should return true if passed a valid element" do
11
11
  element = React::Element.new(`React.createElement('div')`)
12
- expect(React.is_valid_element(element)).to eq(true)
12
+ expect(React.is_valid_element?(element)).to eq(true)
13
13
  end
14
14
 
15
15
  it "should return false is passed a non React element" do
16
16
  element = React::Element.new(`{}`)
17
- expect(React.is_valid_element(element)).to eq(false)
17
+ expect(React.is_valid_element?(element)).to eq(false)
18
18
  end
19
19
  end
20
20
 
21
21
  describe "create_element" do
22
22
  it "should create a valid element with only tag" do
23
23
  element = React.create_element('div')
24
- expect(React.is_valid_element(element)).to eq(true)
24
+ expect(React.is_valid_element?(element)).to eq(true)
25
25
  end
26
26
 
27
27
  context "with block" do
28
28
  it "should create a valid element with text as only child when block yield String" do
29
29
  element = React.create_element('div') { "lorem ipsum" }
30
- expect(React.is_valid_element(element)).to eq(true)
30
+ expect(React.is_valid_element?(element)).to eq(true)
31
31
  expect(element.props.children).to eq("lorem ipsum")
32
32
  end
33
33
 
@@ -35,7 +35,7 @@ RSpec.describe React, type: :component do
35
35
  element = React.create_element('div') do
36
36
  [React.create_element('span'), React.create_element('span'), React.create_element('span')]
37
37
  end
38
- expect(React.is_valid_element(element)).to eq(true)
38
+ expect(React.is_valid_element?(element)).to eq(true)
39
39
  expect(element.props.children.length).to eq(3)
40
40
  end
41
41
 
@@ -43,8 +43,9 @@ RSpec.describe React, type: :component do
43
43
  element = React.create_element('div') do
44
44
  [React.create_element('span'), React.create_element('span'), React.create_element('span')]
45
45
  end
46
- instance = renderElementToDocument(element)
47
- expect(Element[instance].children.length).to eq(3)
46
+ dom_node = React::Test::Utils.render_into_document(element)
47
+
48
+ expect(`#{dom_node}.children.length`).to eq(3)
48
49
  end
49
50
  end
50
51
 
@@ -52,29 +53,37 @@ RSpec.describe React, type: :component do
52
53
  before do
53
54
  stub_const 'Foo', Class.new
54
55
  Foo.class_eval do
56
+ def initialize(native)
57
+ @native = native
58
+ end
59
+
55
60
  def render
56
61
  React.create_element("div") { "lorem" }
57
62
  end
63
+
64
+ def props
65
+ Hash.new(`#@native.props`)
66
+ end
58
67
  end
59
68
  end
60
69
 
61
70
  it "should render element with only one children correctly" do
62
71
  element = React.create_element(Foo) { React.create_element('span') }
63
- instance = renderElementToDocument(element)
64
- expect(instance.props.children).not_to be_a(Array)
65
- expect(instance.props.children.type).to eq("span")
72
+ instance = React::Test::Utils.render_into_document(element)
73
+ expect(instance.props[:children]).not_to be_a(Array)
74
+ expect(instance.props[:children][:type]).to eq("span")
66
75
  end
67
76
 
68
77
  it "should render element with more than one children correctly" do
69
78
  element = React.create_element(Foo) { [React.create_element('span'), React.create_element('span')] }
70
- instance = renderElementToDocument(element)
71
- expect(instance.props.children).to be_a(Array)
72
- expect(instance.props.children.length).to eq(2)
79
+ instance = React::Test::Utils.render_into_document(element)
80
+ expect(instance.props[:children]).to be_a(Array)
81
+ expect(instance.props[:children].length).to eq(2)
73
82
  end
74
83
 
75
84
  it "should create a valid element provided class defined `render`" do
76
85
  element = React.create_element(Foo)
77
- expect(React.is_valid_element(element)).to eq(true)
86
+ expect(React.is_valid_element?(element)).to eq(true)
78
87
  end
79
88
 
80
89
  it "should allow creating with properties" do
@@ -102,14 +111,14 @@ RSpec.describe React, type: :component do
102
111
  end
103
112
  end
104
113
 
105
- expect(Foo).to render("<div>20</div>")
114
+ expect(Foo).to render_static_html("<div>20</div>")
106
115
  end
107
116
 
108
117
  it "should match the instance cycle to ReactComponent life cycle" do
109
118
  `var count = 0;`
110
119
 
111
120
  Foo.class_eval do
112
- def initialize
121
+ def initialize(native)
113
122
  `count = count + 1;`
114
123
  end
115
124
  def render
@@ -117,8 +126,8 @@ RSpec.describe React, type: :component do
117
126
  end
118
127
  end
119
128
 
120
- renderToDocument(Foo)
121
- renderToDocument(Foo)
129
+ React::Test::Utils.render_into_document(React.create_element(Foo))
130
+ React::Test::Utils.render_into_document(React.create_element(Foo))
122
131
 
123
132
  expect(`count`).to eq(2)
124
133
  end
@@ -172,19 +181,23 @@ RSpec.describe React, type: :component do
172
181
  React.render(React.create_element('span') { "lorem" }, div)
173
182
  end
174
183
 
175
- it "should return a React::Component::API compatible object" do
176
- div = `document.createElement("div")`
177
- component = React.render(React.create_element('span') { "lorem" }, div)
178
- React::Component::API.public_instance_methods(true).each do |method_name|
179
- expect(component).to respond_to(method_name)
184
+ it "returns the actual ruby instance" do
185
+ stub_const 'Foo', Class.new
186
+ Foo.class_eval do
187
+ def render
188
+ React.create_element("div") { "lorem" }
189
+ end
180
190
  end
191
+
192
+ div = `document.createElement("div")`
193
+ instance = React.render(React.create_element(Foo), div)
194
+ expect(instance).to be_a(Foo)
181
195
  end
182
196
 
183
- pending "should return nil to prevent abstraction leakage" do
197
+ it "returns the actual DOM node" do
184
198
  div = `document.createElement("div")`
185
- expect {
186
- React.render(React.create_element('span') { "lorem" }, div)
187
- }.to be_nil
199
+ node = React.render(React.create_element('span') { "lorem" }, div)
200
+ expect(`#{node}.nodeType`).to eq(1)
188
201
  end
189
202
  end
190
203
 
@@ -23,7 +23,7 @@ if opal?
23
23
  end
24
24
 
25
25
  it 'includes rspec matchers' do
26
- expect(Greeter).to render(
26
+ expect(Greeter).to render_static_html(
27
27
  '<span>Hello world</span>'
28
28
  ).with_params(message: 'world')
29
29
  end
@@ -41,31 +41,19 @@ if opal?
41
41
  end
42
42
  end
43
43
 
44
- describe '#element' do
45
- it 'returns the React::Element for the mounted component' do
46
- subject.mount(Greeter)
47
- expect(subject.element).to be_a(React::Element)
48
- end
49
- end
50
-
51
- describe '#native' do
52
- it 'returns the React native instance of the component' do
53
- instance = subject.mount(Greeter)
54
- native = instance.instance_variable_get('@native')
55
- expect(subject.native).to eq(native)
56
- end
57
- end
58
-
59
44
  describe '#html' do
60
45
  it 'returns the component rendered to static html' do
61
46
  subject.mount(Greeter, message: 'world')
62
47
  expect(subject.html).to eq('<span>Hello world</span>')
63
48
  end
64
49
 
65
- it 'returns the updated static html' do
50
+ async 'returns the updated static html' do
66
51
  subject.mount(Greeter)
67
- subject.update_params(message: 'moon')
68
- expect(subject.html).to eq('<span>Hello moon</span>')
52
+ subject.update_params(message: 'moon') do
53
+ run_async {
54
+ expect(subject.html).to eq('<span>Hello moon</span>')
55
+ }
56
+ end
69
57
  end
70
58
  end
71
59
 
@@ -89,11 +77,11 @@ if opal?
89
77
  end
90
78
  end
91
79
 
92
- describe '#force_update' do
80
+ describe 'instance#force_update!' do
93
81
  it 'causes the component to render' do
94
82
  instance = subject.mount(Greeter)
95
83
  expect(instance).to receive(:render)
96
- subject.force_update!
84
+ subject.instance.force_update!
97
85
  end
98
86
  end
99
87
  end
@@ -1,45 +1,28 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  if opal?
4
- module React
5
- module Test
6
- class Utils
7
- def self.simulate(event, element)
8
- Simulate.new.click(element)
9
- end
10
-
11
- class Simulate
12
- include Native
13
- def initialize
14
- super(`React.addons.TestUtils.Simulate`)
15
- end
16
-
17
- def click(component_instance)
18
- `#{@native}['click']`.call(component_instance.dom_node, {})
19
- end
20
- end
21
- end
22
- end
23
- end
24
4
  RSpec.describe React::Test::Utils do
25
5
  it 'simulates' do
26
6
  stub_const 'Foo', Class.new
27
7
  Foo.class_eval do
28
8
  include React::Component
29
9
 
30
- def hello
31
- @hello
32
- end
33
-
34
10
  def render
35
- @hello = 'hello'
36
11
  div { 'Click Me' }.on(:click) { |e| click(e) }
37
12
  end
38
13
  end
39
14
 
40
- instance = renderToDocument(Foo)
41
- expect_any_instance_of(Foo).to receive(:click)
42
- described_class.simulate(:click, instance)
15
+ instance = React::Test::Utils.render_into_document(React.create_element(Foo))
16
+ expect(instance).to receive(:click)
17
+ described_class.simulate(:click, instance.dom_node)
18
+ end
19
+
20
+ describe "render_into_document" do
21
+ it "works with native element" do
22
+ expect {
23
+ described_class.render_into_document(React.create_element('div'))
24
+ }.to_not raise_error
25
+ end
43
26
  end
44
27
  end
45
28
  end
@@ -39,8 +39,13 @@ class Component1
39
39
  end
40
40
 
41
41
  def render_top_level(controller, component_name)
42
- render_to_html(React::TopLevelRailsComponent, controller: controller,
43
- component_name: component_name, render_params: {})
42
+ params = {
43
+ controller: controller,
44
+ component_name: component_name,
45
+ render_params: {}
46
+ }
47
+ element = React.create_element(React::TopLevelRailsComponent, params)
48
+ React.render_to_static_markup(element)
44
49
  end
45
50
 
46
51
  describe React::TopLevelRailsComponent do
@@ -10,7 +10,7 @@ end
10
10
 
11
11
  describe 'An Example from the react.rb doc', type: :component do
12
12
  it 'produces the correct result' do
13
- expect(HelloMessage).to render('<div>Hello World!</div>')
13
+ expect(HelloMessage).to render_static_html('<div>Hello World!</div>')
14
14
  end
15
15
  end
16
16
 
@@ -24,7 +24,7 @@ end
24
24
 
25
25
  describe 'Adding state to a component (second tutorial example)', type: :component do
26
26
  it "produces the correct result" do
27
- expect(HelloMessage2).to render('<div>Hello @catmando</div>')
27
+ expect(HelloMessage2).to render_static_html('<div>Hello @catmando</div>')
28
28
  end
29
29
 
30
30
  it 'renders to the document' do
@@ -3,15 +3,21 @@ require 'spec_helper'
3
3
  if ruby?
4
4
  RSpec.describe ReactiveRuby::ComponentLoader do
5
5
  GLOBAL_WRAPPER = <<-JS
6
- var global = global || this;
7
- var self = self || this;
8
- var window = window || this;
6
+ #{React::ServerRendering::ExecJSRenderer::GLOBAL_WRAPPER}
9
7
  var console = {
10
8
  warn: function(s) { }
11
9
  };
12
10
  JS
13
11
 
14
- let(:js) { ::Rails.application.assets['components'].to_s }
12
+ let(:js) do
13
+ if ::Rails.application.assets['react-server.js'] &&
14
+ !::Rails.application.assets['react-server.js'].to_s.start_with?("// A placeholder file")
15
+ react_source = ::Rails.application.assets['react-server.js']
16
+ else
17
+ react_source = ::Rails.application.assets['react.js']
18
+ end
19
+ ::Rails.application.assets['components'].to_s + react_source.to_s
20
+ end
15
21
  let(:context) { ExecJS.compile(GLOBAL_WRAPPER + js) }
16
22
  let(:v8_context) { ReactiveRuby::ServerRendering.context_instance_for(context) }
17
23
 
@@ -77,7 +77,12 @@ if ruby?
77
77
  end
78
78
 
79
79
  def react_context
80
- test_context('components')
80
+ if ::Rails.application.assets['react-server.js'] &&
81
+ !::Rails.application.assets['react-server.js'].to_s.start_with?("// A placeholder file")
82
+ test_context(['components', 'react-server.js'])
83
+ else
84
+ test_context(['components', 'react.js'])
85
+ end
81
86
  end
82
87
 
83
88
  let(:v8_context) { TestV8Context.new }
@@ -18,6 +18,8 @@ if RUBY_ENGINE == 'opal'
18
18
  require 'react/react-source'
19
19
  require 'hyper-react'
20
20
  require 'react/test/rspec'
21
+ require 'react/test/utils'
22
+ require 'react/top_level_render'
21
23
 
22
24
  require File.expand_path('../support/react/spec_helpers', __FILE__)
23
25
 
@@ -3,29 +3,9 @@ module React
3
3
  module SpecHelpers
4
4
  `var ReactTestUtils = React.addons.TestUtils`
5
5
 
6
- def render_to_html(type, options = {})
7
- element = React.create_element(type, options)
8
- React.render_to_static_markup(element)
9
- end
10
-
11
6
  def renderToDocument(type, options = {})
12
7
  element = React.create_element(type, options)
13
- renderElementToDocument(element)
14
- end
15
-
16
- def renderElementToDocument(element)
17
- instance = Native(`ReactTestUtils.renderIntoDocument(#{element.to_n})`)
18
- instance.class.include(React::Component::API)
19
- instance
20
- end
21
-
22
- def simulateEvent(event, element, params = {})
23
- simulator = Native(`ReactTestUtils.Simulate`)
24
- simulator[event.to_s].call(element.dom_node, params)
25
- end
26
-
27
- def isElementOfType(element, type)
28
- `React.addons.TestUtils.isElementOfType(#{element.to_n}, #{type.cached_component_class})`
8
+ React::Test::Utils.render_into_document(element)
29
9
  end
30
10
 
31
11
  def build_element(type, options)