reactrb 0.8.8 → 0.9.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 (170) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +24 -3
  3. data/.gitignore +3 -0
  4. data/.rubocop.yml +1154 -3
  5. data/.travis.yml +20 -0
  6. data/Appraisals +20 -0
  7. data/CHANGELOG.md +28 -3
  8. data/Gemfile +4 -5
  9. data/README.md +6 -9
  10. data/Rakefile +6 -1
  11. data/config.ru +7 -6
  12. data/gemfiles/opal_0.8_react_13.gemfile +13 -0
  13. data/gemfiles/opal_0.8_react_14.gemfile +13 -0
  14. data/gemfiles/opal_0.8_react_15.gemfile +13 -0
  15. data/gemfiles/opal_0.9_react_13.gemfile +13 -0
  16. data/gemfiles/opal_0.9_react_14.gemfile +13 -0
  17. data/gemfiles/opal_0.9_react_15.gemfile +13 -0
  18. data/lib/generators/reactive_ruby/test_app/templates/assets/javascripts/components.rb +1 -1
  19. data/lib/rails-helpers/top_level_rails_component.rb +1 -1
  20. data/lib/react-sources/react-server.js +2 -0
  21. data/lib/react/api.rb +13 -12
  22. data/lib/react/children.rb +30 -0
  23. data/lib/react/component.rb +27 -46
  24. data/lib/react/component/class_methods.rb +28 -32
  25. data/lib/react/component/dsl_instance_methods.rb +4 -34
  26. data/lib/react/component/params.rb +6 -0
  27. data/lib/react/component/props_wrapper.rb +22 -27
  28. data/lib/react/component/should_component_update.rb +98 -0
  29. data/lib/react/component/tags.rb +45 -4
  30. data/lib/react/element.rb +26 -13
  31. data/lib/react/object.rb +15 -0
  32. data/lib/react/react-source.rb +9 -0
  33. data/lib/react/rendering_context.rb +97 -93
  34. data/lib/react/state.rb +27 -21
  35. data/lib/react/test.rb +16 -0
  36. data/lib/react/test/dsl.rb +17 -0
  37. data/lib/react/test/matchers/render_html_matcher.rb +49 -0
  38. data/lib/react/test/rspec.rb +15 -0
  39. data/lib/react/test/session.rb +46 -0
  40. data/lib/react/top_level.rb +50 -14
  41. data/lib/react/validator.rb +5 -5
  42. data/lib/reactive-ruby/isomorphic_helpers.rb +0 -7
  43. data/lib/reactive-ruby/version.rb +1 -1
  44. data/lib/reactrb.rb +14 -14
  45. data/lib/reactrb/deep-compare.rb +24 -0
  46. data/lib/sources/react-latest.js +2 -0
  47. data/lib/sources/react-v13.js +4 -1
  48. data/lib/sources/react-v14.js +3 -84
  49. data/lib/sources/react-v15.js +3 -0
  50. data/logo1.png +0 -0
  51. data/logo2.png +0 -0
  52. data/logo3.png +0 -0
  53. data/path_release_steps.md +1 -1
  54. data/reactrb.gemspec +2 -3
  55. data/spec/react/children_spec.rb +76 -0
  56. data/spec/react/component/base_spec.rb +3 -7
  57. data/spec/react/component_spec.rb +181 -60
  58. data/spec/react/dsl_spec.rb +26 -19
  59. data/spec/react/element_spec.rb +16 -1
  60. data/spec/react/native_library_spec.rb +20 -0
  61. data/spec/react/opal_jquery_extensions_spec.rb +27 -0
  62. data/spec/react/param_declaration_spec.rb +47 -78
  63. data/spec/react/react_spec.rb +7 -9
  64. data/spec/react/state_spec.rb +29 -0
  65. data/spec/react/test/dsl_spec.rb +43 -0
  66. data/spec/react/test/matchers/render_html_matcher_spec.rb +83 -0
  67. data/spec/react/test/rspec_spec.rb +62 -0
  68. data/spec/react/test/session_spec.rb +100 -0
  69. data/spec/react/test/utils_spec.rb +45 -0
  70. data/spec/react/top_level_component_spec.rb +33 -5
  71. data/spec/react/tutorial/tutorial_spec.rb +5 -5
  72. data/spec/react/validator_spec.rb +10 -13
  73. data/spec/reactive-ruby/component_loader_spec.rb +3 -0
  74. data/spec/reactive-ruby/rails/asset_pipeline_spec.rb +5 -4
  75. data/spec/spec_helper.rb +6 -3
  76. data/spec/support/react/spec_helpers.rb +9 -2
  77. metadata +47 -124
  78. data/example/examples/Gemfile +0 -7
  79. data/example/examples/app/basics.js.rb +0 -42
  80. data/example/examples/app/items.rb +0 -11
  81. data/example/examples/app/jquery.js +0 -5
  82. data/example/examples/app/nodes.rb +0 -61
  83. data/example/examples/app/react-router.js +0 -6
  84. data/example/examples/app/react_api_demo.rb +0 -29
  85. data/example/examples/app/rerendering.rb +0 -72
  86. data/example/examples/app/reuse.rb +0 -59
  87. data/example/examples/app/show.rb +0 -52
  88. data/example/examples/config.ru +0 -38
  89. data/example/rails-tutorial/.gitignore +0 -17
  90. data/example/rails-tutorial/Gemfile +0 -51
  91. data/example/rails-tutorial/README.rdoc +0 -28
  92. data/example/rails-tutorial/Rakefile +0 -6
  93. data/example/rails-tutorial/app/assets/images/.keep +0 -0
  94. data/example/rails-tutorial/app/assets/javascripts/application.rb +0 -15
  95. data/example/rails-tutorial/app/assets/stylesheets/application.css +0 -15
  96. data/example/rails-tutorial/app/controllers/application_controller.rb +0 -6
  97. data/example/rails-tutorial/app/controllers/concerns/.keep +0 -0
  98. data/example/rails-tutorial/app/controllers/home_controller.rb +0 -6
  99. data/example/rails-tutorial/app/helpers/application_helper.rb +0 -2
  100. data/example/rails-tutorial/app/mailers/.keep +0 -0
  101. data/example/rails-tutorial/app/models/.keep +0 -0
  102. data/example/rails-tutorial/app/models/concerns/.keep +0 -0
  103. data/example/rails-tutorial/app/views/components.rb +0 -3
  104. data/example/rails-tutorial/app/views/components/home/show.rb +0 -47
  105. data/example/rails-tutorial/app/views/layouts/application.html.erb +0 -14
  106. data/example/rails-tutorial/bin/bundle +0 -3
  107. data/example/rails-tutorial/bin/rails +0 -8
  108. data/example/rails-tutorial/bin/rake +0 -8
  109. data/example/rails-tutorial/bin/setup +0 -29
  110. data/example/rails-tutorial/bin/spring +0 -15
  111. data/example/rails-tutorial/config.ru +0 -4
  112. data/example/rails-tutorial/config/application.rb +0 -26
  113. data/example/rails-tutorial/config/boot.rb +0 -3
  114. data/example/rails-tutorial/config/database.yml +0 -25
  115. data/example/rails-tutorial/config/environment.rb +0 -5
  116. data/example/rails-tutorial/config/environments/development.rb +0 -41
  117. data/example/rails-tutorial/config/environments/production.rb +0 -79
  118. data/example/rails-tutorial/config/environments/test.rb +0 -42
  119. data/example/rails-tutorial/config/initializers/assets.rb +0 -11
  120. data/example/rails-tutorial/config/initializers/backtrace_silencers.rb +0 -7
  121. data/example/rails-tutorial/config/initializers/cookies_serializer.rb +0 -3
  122. data/example/rails-tutorial/config/initializers/filter_parameter_logging.rb +0 -4
  123. data/example/rails-tutorial/config/initializers/inflections.rb +0 -16
  124. data/example/rails-tutorial/config/initializers/mime_types.rb +0 -4
  125. data/example/rails-tutorial/config/initializers/session_store.rb +0 -3
  126. data/example/rails-tutorial/config/initializers/wrap_parameters.rb +0 -14
  127. data/example/rails-tutorial/config/locales/en.yml +0 -23
  128. data/example/rails-tutorial/config/routes.rb +0 -59
  129. data/example/rails-tutorial/config/secrets.yml +0 -22
  130. data/example/rails-tutorial/db/seeds.rb +0 -7
  131. data/example/rails-tutorial/lib/assets/.keep +0 -0
  132. data/example/rails-tutorial/lib/tasks/.keep +0 -0
  133. data/example/rails-tutorial/log/.keep +0 -0
  134. data/example/rails-tutorial/public/404.html +0 -67
  135. data/example/rails-tutorial/public/422.html +0 -67
  136. data/example/rails-tutorial/public/500.html +0 -66
  137. data/example/rails-tutorial/public/favicon.ico +0 -0
  138. data/example/rails-tutorial/public/robots.txt +0 -5
  139. data/example/rails-tutorial/test/controllers/.keep +0 -0
  140. data/example/rails-tutorial/test/fixtures/.keep +0 -0
  141. data/example/rails-tutorial/test/helpers/.keep +0 -0
  142. data/example/rails-tutorial/test/integration/.keep +0 -0
  143. data/example/rails-tutorial/test/mailers/.keep +0 -0
  144. data/example/rails-tutorial/test/models/.keep +0 -0
  145. data/example/rails-tutorial/test/test_helper.rb +0 -10
  146. data/example/rails-tutorial/vendor/assets/javascripts/.keep +0 -0
  147. data/example/rails-tutorial/vendor/assets/stylesheets/.keep +0 -0
  148. data/example/sinatra-tutorial/.DS_Store +0 -0
  149. data/example/sinatra-tutorial/Gemfile +0 -5
  150. data/example/sinatra-tutorial/README.md +0 -8
  151. data/example/sinatra-tutorial/_comments.json +0 -42
  152. data/example/sinatra-tutorial/app/example.rb +0 -290
  153. data/example/sinatra-tutorial/app/jquery.js +0 -5
  154. data/example/sinatra-tutorial/config.ru +0 -58
  155. data/example/sinatra-tutorial/public/base.css +0 -62
  156. data/example/todos/Gemfile +0 -11
  157. data/example/todos/README.md +0 -37
  158. data/example/todos/Rakefile +0 -8
  159. data/example/todos/app/application.rb +0 -22
  160. data/example/todos/app/components/app.react.rb +0 -61
  161. data/example/todos/app/components/footer.react.rb +0 -31
  162. data/example/todos/app/components/todo_item.react.rb +0 -46
  163. data/example/todos/app/components/todo_list.react.rb +0 -25
  164. data/example/todos/app/models/todo.rb +0 -19
  165. data/example/todos/config.ru +0 -14
  166. data/example/todos/index.html.haml +0 -16
  167. data/example/todos/spec/todo_spec.rb +0 -28
  168. data/example/todos/vendor/base.css +0 -410
  169. data/example/todos/vendor/bg.png +0 -0
  170. data/example/todos/vendor/jquery.js +0 -4
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  if opal?
4
- describe React::Component::Base do
4
+ RSpec.describe React::Component::Base, type: :component do
5
5
  after(:each) do
6
6
  React::API.clear_component_class_cache
7
7
  end
@@ -25,12 +25,8 @@ describe React::Component::Base do
25
25
  @instance_data.join(" ")
26
26
  end
27
27
  end
28
- expect(rendered_component(Foo)).to eq("<span>working</span>")
29
- expect(rendered_component(Bar)).to eq("<span>working well</span>")
30
- end
31
-
32
- def rendered_component(component)
33
- React.render_to_static_markup(React.create_element(component))
28
+ expect(Foo).to render("<span>working</span>")
29
+ expect(Bar).to render("<span>working well</span>")
34
30
  end
35
31
  end
36
32
  end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  if opal?
4
- describe React::Component do
4
+ describe React::Component, type: :component do
5
5
  after(:each) do
6
6
  React::API.clear_component_class_cache
7
7
  end
@@ -120,7 +120,7 @@ describe React::Component do
120
120
  end
121
121
  end
122
122
 
123
- expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<div>bar</div>')
123
+ expect(Foo).to render('<div>bar</div>')
124
124
  end
125
125
 
126
126
  it 'allows kernal method names like "format" to be used as state variable names' do
@@ -131,7 +131,7 @@ describe React::Component do
131
131
  end
132
132
  end
133
133
 
134
- expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<div>yes</div>')
134
+ expect(Foo).to render('<div>yes</div>')
135
135
  end
136
136
 
137
137
  it 'returns an observer with the bang method and no arguments' do
@@ -141,7 +141,7 @@ describe React::Component do
141
141
  end
142
142
  end
143
143
 
144
- expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<div>React::Observable</div>')
144
+ expect(Foo).to render('<div>React::Observable</div>')
145
145
  end
146
146
 
147
147
  it 'returns the current value of a state when written' do
@@ -152,7 +152,7 @@ describe React::Component do
152
152
  end
153
153
  end
154
154
 
155
- expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<div>bar</div>')
155
+ expect(Foo).to render('<div>bar</div>')
156
156
  end
157
157
 
158
158
  it 'can access an explicitly defined state`' do
@@ -160,7 +160,7 @@ describe React::Component do
160
160
  define_state foo: :bar
161
161
  end
162
162
 
163
- expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<div>bar</div>')
163
+ expect(Foo).to render('<div>bar</div>')
164
164
  end
165
165
 
166
166
  end
@@ -304,7 +304,7 @@ describe React::Component do
304
304
  end
305
305
  end
306
306
 
307
- expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<div>bar</div>')
307
+ expect(Foo).to render('<div>bar</div>')
308
308
  end
309
309
 
310
310
  it 'transforms state getter to Ruby object' do
@@ -320,7 +320,7 @@ describe React::Component do
320
320
  end
321
321
  end
322
322
 
323
- expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<div>Hello</div>')
323
+ expect(Foo).to render('<div>Hello</div>')
324
324
  end
325
325
  end
326
326
 
@@ -356,39 +356,38 @@ describe React::Component do
356
356
  end
357
357
  end
358
358
 
359
- # deprecated as of React 14
360
- # describe 'Props Updating' do
361
- # before do
362
- # stub_const 'Foo', Class.new
363
- # Foo.class_eval do
364
- # include React::Component
365
- # end
366
- # end
367
- #
368
- # it 'supports original `setProps` as method `set_props`' do
369
- # Foo.class_eval do
370
- # def render
371
- # React.create_element('div') { params[:foo] }
372
- # end
373
- # end
374
- #
375
- # element = renderToDocument(Foo, {foo: 10})
376
- # element.set_props(foo: 20)
377
- # expect(`#{element.dom_node}.innerHTML`).to eq('20')
378
- # end
379
- #
380
- # it 'supports original `replaceProps` as method `set_props!`' do
381
- # Foo.class_eval do
382
- # def render
383
- # React.create_element('div') { params[:foo] ? 'exist' : 'null' }
384
- # end
385
- # end
386
- #
387
- # element = renderToDocument(Foo, {foo: 10})
388
- # element.set_props!(bar: 20)
389
- # expect(element.getDOMNode.innerHTML).to eq('null')
390
- # end
391
- # end
359
+ describe 'Props Updating', v13_only: true do
360
+ before do
361
+ stub_const 'Foo', Class.new
362
+ Foo.class_eval do
363
+ include React::Component
364
+ end
365
+ end
366
+
367
+ it 'supports original `setProps` as method `set_props`' do
368
+ Foo.class_eval do
369
+ def render
370
+ React.create_element('div') { params[:foo] }
371
+ end
372
+ end
373
+
374
+ element = renderToDocument(Foo, {foo: 10})
375
+ element.set_props(foo: 20)
376
+ expect(`#{element.dom_node}.innerHTML`).to eq('20')
377
+ end
378
+
379
+ it 'supports original `replaceProps` as method `set_props!`' do
380
+ Foo.class_eval do
381
+ def render
382
+ React.create_element('div') { params[:foo] ? 'exist' : 'null' }
383
+ end
384
+ end
385
+
386
+ element = renderToDocument(Foo, {foo: 10})
387
+ element.set_props!(bar: 20)
388
+ expect(element.getDOMNode.innerHTML).to eq('null')
389
+ end
390
+ end
392
391
 
393
392
  describe 'Prop validation' do
394
393
  before do
@@ -429,7 +428,7 @@ describe React::Component do
429
428
  }
430
429
  renderToDocument(Foo, bar: 10, lorem: Lorem.new)
431
430
  `window.console.warn = org_warn_console; window.console.error = org_error_console;`
432
- expect(`log`).to eq(["Warning: Failed propType: In component `Foo`\nRequired prop `foo` was not specified\nProvided prop `bar` could not be converted to String"])
431
+ expect(`log[0]`).to match(/Warning: Failed prop( type|Type): In component `Foo`\nRequired prop `foo` was not specified\nProvided prop `bar` could not be converted to String/)
433
432
  end
434
433
 
435
434
  it 'should not log anything if validation pass' do
@@ -471,8 +470,8 @@ describe React::Component do
471
470
  end
472
471
  end
473
472
 
474
- expect(React.render_to_static_markup(React.create_element(Foo, foo: 'lorem'))).to eq('<div>lorem-bar</div>')
475
- expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<div>foo-bar</div>')
473
+ expect(Foo).to render('<div>lorem-bar</div>').with_params(foo: 'lorem')
474
+ expect(Foo).to render('<div>foo-bar</div>')
476
475
  end
477
476
  end
478
477
  end
@@ -645,6 +644,22 @@ describe React::Component do
645
644
 
646
645
  expect(element.refs.field.value).to eq('some_stuff')
647
646
  end
647
+
648
+ it "allows access the actual DOM node" do
649
+ Foo.class_eval do
650
+ after_mount do
651
+ dom = refs[:my_div].dom_node
652
+ `dom.innerHTML = 'Modified'`
653
+ end
654
+
655
+ def render
656
+ React.create_element('div', ref: :my_div) { "Original Content" }
657
+ end
658
+ end
659
+
660
+ instance = renderToDocument(Foo)
661
+ expect(`#{instance.dom_node}.innerHTML`).to eq('Modified')
662
+ end
648
663
  end
649
664
 
650
665
  describe '#render' do
@@ -670,7 +685,7 @@ describe React::Component do
670
685
  end
671
686
  end
672
687
 
673
- expect(React.render_to_static_markup(React.create_element(Bar))).to eq('<div><div><span>astring</span></div></div>')
688
+ expect(Bar).to render('<div><div><span>astring</span></div></div>')
674
689
  end
675
690
 
676
691
  it 'builds single node in top-level render without providing a block' do
@@ -683,10 +698,49 @@ describe React::Component do
683
698
  end
684
699
  end
685
700
 
686
- element = React.create_element(Foo)
687
- expect(React.render_to_static_markup(element)).to eq('<div></div>')
701
+ expect(Foo).to render('<div></div>')
688
702
  end
689
703
 
704
+ it 'redefines `p` to make method missing work' do
705
+ stub_const 'Foo', Class.new
706
+ Foo.class_eval do
707
+ include React::Component
708
+
709
+ def render
710
+ p(class_name: 'foo') do
711
+ p
712
+ div { 'lorem ipsum' }
713
+ p(id: '10')
714
+ end
715
+ end
716
+ end
717
+
718
+ markup = '<p class="foo"><p></p><div>lorem ipsum</div><p id="10"></p></p>'
719
+ expect(Foo).to render(markup)
720
+ end
721
+
722
+ it 'only overrides `p` in render context' do
723
+ stub_const 'Foo', Class.new
724
+ Foo.class_eval do
725
+ include React::Component
726
+
727
+ before_mount do
728
+ p 'first'
729
+ end
730
+
731
+ after_mount do
732
+ p 'second'
733
+ end
734
+
735
+ def render
736
+ div
737
+ end
738
+ end
739
+
740
+ expect(Kernel).to receive(:p).with('first')
741
+ expect(Kernel).to receive(:p).with('second')
742
+ renderToDocument(Foo)
743
+ end
690
744
  end
691
745
 
692
746
  describe 'isMounted()' do
@@ -705,6 +759,79 @@ describe React::Component do
705
759
  end
706
760
  end
707
761
 
762
+ describe '.params_changed?' do
763
+
764
+ before(:each) do
765
+ stub_const 'Foo', Class.new(React::Component::Base)
766
+ Foo.define_method :needs_update? do |next_params, next_state|
767
+ next_params.changed?
768
+ end
769
+ @foo = Foo.new
770
+ end
771
+
772
+ it "returns false if new and old params are the same" do
773
+ @foo.instance_variable_set("@native", `{props: {value1: 1, value2: 2}}`)
774
+ expect(@foo.should_component_update?(`{value2: 2, value1: 1}`, `null`)).to be_falsy
775
+ end
776
+
777
+ it "returns true if new and old params are have different values" do
778
+ @foo.instance_variable_set("@native", `{props: {value1: 1, value2: 2}}`)
779
+ expect(@foo.should_component_update?(`{value2: 2, value1: 2}`, `null`)).to be_truthy
780
+ end
781
+
782
+ it "returns true if new and old params are have different keys" do
783
+ @foo.instance_variable_set("@native", `{props: {value1: 1, value2: 2}}`)
784
+ expect(@foo.should_component_update?(`{value2: 2, value1: 1, value3: 3}`, `null`)).to be_truthy
785
+ end
786
+ end
787
+
788
+ describe '#state_changed?' do
789
+
790
+ empties = [`{}`, `undefined`, `null`, `false`]
791
+
792
+ before(:each) do
793
+ stub_const 'Foo', Class.new(React::Component::Base)
794
+ Foo.define_method :needs_update? do |next_params, next_state|
795
+ next_state.changed?
796
+ end
797
+ @foo = Foo.new
798
+ end
799
+
800
+ it "returns false if both new and old states are empty" do
801
+ empties.each do |empty1|
802
+ empties.each do |empty2|
803
+ @foo.instance_variable_set("@native", `{state: #{empty1}}`)
804
+ expect(@foo.should_component_update?(`{}`, empty2)).to be_falsy
805
+ end
806
+ end
807
+ end
808
+
809
+ it "returns true if old state is empty, but new state is not" do
810
+ empties.each do |empty|
811
+ @foo.instance_variable_set("@native", `{state: #{empty}}`)
812
+ expect(@foo.should_component_update?(`{}`, `{foo: 12}`)).to be_truthy
813
+ end
814
+ end
815
+
816
+ it "returns true if new state is empty, but old state is not" do
817
+ empties.each do |empty|
818
+ @foo.instance_variable_set("@native", `{state: {foo: 12}}`)
819
+ expect(@foo.should_component_update?(`{}`, empty)).to be_truthy
820
+ end
821
+ end
822
+
823
+ it "returns true if new state and old state have different time stamps" do
824
+ @foo.instance_variable_set("@native", `{state: {'***_state_updated_at-***': 12}}`)
825
+ expect(@foo.should_component_update?(`{}`, `{'***_state_updated_at-***': 13}`)).to be_truthy
826
+ end
827
+
828
+ it "returns false if new state and old state have the same time stamps" do
829
+ @foo.instance_variable_set("@native", `{state: {'***_state_updated_at-***': 12}}`)
830
+ expect(@foo.should_component_update?(`{}`, `{'***_state_updated_at-***': 12}`)).to be_falsy
831
+ end
832
+
833
+ end
834
+
708
835
  describe '#children' do
709
836
  before(:each) do
710
837
  stub_const 'Foo', Class.new
@@ -720,30 +847,24 @@ describe React::Component do
720
847
  end
721
848
  end
722
849
 
723
- it 'returns an Enumerable' do
850
+ it 'returns React::Children collection with child elements' do
724
851
  ele = React.create_element(Foo) {
725
852
  [React.create_element('a'), React.create_element('li')]
726
853
  }
727
854
  renderElementToDocument(ele)
728
- nodes = Foo.the_children.map { |ele| ele.element_type }
729
- expect(nodes).to eq(['a', 'li'])
730
- end
731
855
 
732
- it 'returns an Enumerator when not providing a block' do
733
- ele = React.create_element(Foo) {
734
- [React.create_element('a'), React.create_element('li')]
735
- }
736
- renderElementToDocument(ele)
737
- nodes = Foo.the_children.each
738
- expect(nodes).to be_a(Enumerator)
739
- expect(nodes.size).to eq(2)
856
+ children = Foo.the_children
857
+
858
+ expect(children).to be_a(React::Children)
859
+ expect(children.count).to eq(2)
860
+ expect(children.map(&:element_type)).to eq(['a', 'li'])
740
861
  end
741
862
 
742
863
  it 'returns an empty Enumerator if there are no children' do
743
864
  ele = React.create_element(Foo)
744
865
  renderElementToDocument(ele)
745
866
  nodes = Foo.the_children.each
746
- expect(nodes.size).to eq(nil)
867
+ expect(nodes.size).to eq(0)
747
868
  expect(nodes.count).to eq(0)
748
869
  end
749
870
  end
@@ -1,12 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  if opal?
4
-
5
- module TestMod123
6
- class Bar < React::Component::Base
7
- end
8
- end
9
-
10
4
  describe 'the React DSL' do
11
5
 
12
6
  context "render macro" do
@@ -50,26 +44,39 @@ describe 'the React DSL' do
50
44
  end
51
45
  end
52
46
 
53
- it "can use the upcase version of builtin tags" do
47
+ it "will turn the last string in a block into a element" do
54
48
  stub_const 'Foo', Class.new
55
49
  Foo.class_eval do
56
50
  include React::Component
57
51
  def render
58
- DIV { "hello" }
52
+ div { "hello" }
59
53
  end
60
54
  end
61
55
 
62
56
  expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<div>hello</div>')
63
57
  end
64
58
 
59
+ it "will pass converted props through event handlers" do
60
+ stub_const 'Foo', Class.new
61
+ Foo.class_eval do
62
+ include React::Component
63
+ def render
64
+ INPUT(data: {foo: 12}).on(:change) {}
65
+ end
66
+ end
67
+
68
+ expect(React.render_to_static_markup(React.create_element(Foo))).to match(/<input data-foo="12"(\/)?>/)
69
+ end
70
+
65
71
  it "will turn the last string in a block into a element" do
66
72
  stub_const 'Foo', Class.new
67
73
  Foo.class_eval do
68
74
  include React::Component
69
75
  def render
70
- div { "hello" }
76
+ DIV { "hello" }
71
77
  end
72
78
  end
79
+
73
80
  expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<div>hello</div>')
74
81
  end
75
82
 
@@ -184,21 +191,22 @@ describe 'the React DSL' do
184
191
  end
185
192
 
186
193
  it "can add class names by the haml .class notation" do
187
- # stub_const 'Mod::Barz', Class.new(React::Component::Base)
188
- TestMod123::Bar.class_eval do
194
+ stub_const 'Mod::Bar', Class.new
195
+ Mod::Bar.class_eval do
196
+ include React::Component
189
197
  collect_other_params_as :attributes
190
198
  def render
191
- "a man walks into a bar".span(attributes)
199
+ "a man walks into a bar".span(params.attributes)
192
200
  end
193
201
  end
194
202
  stub_const 'Foo', Class.new(React::Component::Base)
195
203
  Foo.class_eval do
196
204
  def render
197
- TestMod123::Bar().the_class
205
+ Mod::Bar().the_class.other_class
198
206
  end
199
207
  end
200
208
 
201
- expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<span class="the-class">a man walks into a bar</span>')
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>')
202
210
  end
203
211
 
204
212
  it "can use the 'class' keyword for classes" do
@@ -218,11 +226,11 @@ describe 'the React DSL' do
218
226
  Foo.class_eval do
219
227
  include React::Component
220
228
  def render
221
- span { "hello".span.as_node.class.name }.as_node.render
229
+ span(data: {size: 12}) { "hello".span.as_node.class.name }.as_node.render
222
230
  end
223
231
  end
224
232
 
225
- expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<span>React::Element</span>')
233
+ expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<span data-size="12">React::Element</span>')
226
234
  end
227
235
 
228
236
  it "can use the dangerously_set_inner_HTML param" do
@@ -267,11 +275,10 @@ describe 'the React DSL' do
267
275
  stub_const 'X2', Class.new
268
276
  X2.class_eval do
269
277
  include React::Component
270
- param :ele
271
278
  def render
272
279
  div do
273
- ele.render
274
- ele.render
280
+ params[:ele].render
281
+ params[:ele].render
275
282
  end
276
283
  end
277
284
  end