hyper-react 0.12.7 → 0.99.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 (129) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +48 -34
  3. data/CODE_OF_CONDUCT.md +49 -0
  4. data/Gemfile +5 -6
  5. data/README.md +47 -98
  6. data/Rakefile +6 -28
  7. data/hyper-react.gemspec +36 -43
  8. data/lib/hyper-react.rb +4 -73
  9. data/lib/react/version.rb +3 -0
  10. metadata +91 -249
  11. data/.codeclimate.yml +0 -27
  12. data/.rubocop.yml +0 -1159
  13. data/.travis.yml +0 -62
  14. data/Appraisals +0 -31
  15. data/CHANGELOG.md +0 -143
  16. data/LICENSE +0 -19
  17. data/UPGRADING.md +0 -24
  18. data/component-name-lookup.md +0 -145
  19. data/config.ru +0 -26
  20. data/gemfiles/opal_0.10_react_13.gemfile +0 -15
  21. data/gemfiles/opal_0.10_react_14.gemfile +0 -15
  22. data/gemfiles/opal_0.10_react_15.gemfile +0 -15
  23. data/gemfiles/opal_0.8_react_13.gemfile +0 -15
  24. data/gemfiles/opal_0.8_react_14.gemfile +0 -15
  25. data/gemfiles/opal_0.8_react_15.gemfile +0 -15
  26. data/gemfiles/opal_0.9_react_13.gemfile +0 -15
  27. data/gemfiles/opal_0.9_react_14.gemfile +0 -15
  28. data/gemfiles/opal_0.9_react_15.gemfile +0 -15
  29. data/gemfiles/opal_master_react_15.gemfile +0 -16
  30. data/lib/generators/reactive_ruby/test_app/templates/assets/javascripts/components.rb +0 -3
  31. data/lib/generators/reactive_ruby/test_app/templates/assets/javascripts/test_application.rb +0 -2
  32. data/lib/generators/reactive_ruby/test_app/templates/boot.rb.erb +0 -6
  33. data/lib/generators/reactive_ruby/test_app/templates/script/rails +0 -5
  34. data/lib/generators/reactive_ruby/test_app/templates/test_application.rb.erb +0 -13
  35. data/lib/generators/reactive_ruby/test_app/templates/views/components/hello_world.rb +0 -11
  36. data/lib/generators/reactive_ruby/test_app/templates/views/components/todo.rb +0 -14
  37. data/lib/generators/reactive_ruby/test_app/templates/views/layouts/test_layout.html.erb +0 -0
  38. data/lib/generators/reactive_ruby/test_app/test_app_generator.rb +0 -111
  39. data/lib/rails-helpers/top_level_rails_component.rb +0 -54
  40. data/lib/react-sources/react-server.js +0 -2
  41. data/lib/react/api.rb +0 -173
  42. data/lib/react/callbacks.rb +0 -41
  43. data/lib/react/children.rb +0 -30
  44. data/lib/react/component.rb +0 -168
  45. data/lib/react/component/api.rb +0 -50
  46. data/lib/react/component/base.rb +0 -13
  47. data/lib/react/component/class_methods.rb +0 -189
  48. data/lib/react/component/dsl_instance_methods.rb +0 -23
  49. data/lib/react/component/params.rb +0 -6
  50. data/lib/react/component/props_wrapper.rb +0 -78
  51. data/lib/react/component/should_component_update.rb +0 -94
  52. data/lib/react/component/tags.rb +0 -129
  53. data/lib/react/config.rb +0 -5
  54. data/lib/react/config/client.rb.erb +0 -19
  55. data/lib/react/config/server.rb +0 -23
  56. data/lib/react/element.rb +0 -169
  57. data/lib/react/event.rb +0 -76
  58. data/lib/react/ext/hash.rb +0 -9
  59. data/lib/react/ext/opal-jquery/element.rb +0 -26
  60. data/lib/react/ext/string.rb +0 -8
  61. data/lib/react/hash.rb +0 -13
  62. data/lib/react/native_library.rb +0 -87
  63. data/lib/react/object.rb +0 -15
  64. data/lib/react/react-source-browser.rb +0 -3
  65. data/lib/react/react-source-server.rb +0 -3
  66. data/lib/react/react-source.rb +0 -20
  67. data/lib/react/ref_callback.rb +0 -31
  68. data/lib/react/rendering_context.rb +0 -144
  69. data/lib/react/server.rb +0 -23
  70. data/lib/react/state_wrapper.rb +0 -23
  71. data/lib/react/test.rb +0 -16
  72. data/lib/react/test/dsl.rb +0 -17
  73. data/lib/react/test/matchers/render_html_matcher.rb +0 -56
  74. data/lib/react/test/rspec.rb +0 -15
  75. data/lib/react/test/session.rb +0 -37
  76. data/lib/react/test/utils.rb +0 -25
  77. data/lib/react/top_level.rb +0 -118
  78. data/lib/react/top_level_render.rb +0 -29
  79. data/lib/react/validator.rb +0 -136
  80. data/lib/reactive-ruby/component_loader.rb +0 -50
  81. data/lib/reactive-ruby/isomorphic_helpers.rb +0 -212
  82. data/lib/reactive-ruby/rails.rb +0 -7
  83. data/lib/reactive-ruby/rails/component_mount.rb +0 -46
  84. data/lib/reactive-ruby/rails/controller_helper.rb +0 -15
  85. data/lib/reactive-ruby/rails/railtie.rb +0 -33
  86. data/lib/reactive-ruby/serializers.rb +0 -15
  87. data/lib/reactive-ruby/server_rendering/contextual_renderer.rb +0 -42
  88. data/lib/reactive-ruby/version.rb +0 -3
  89. data/lib/reactrb/auto-import.rb +0 -27
  90. data/lib/reactrb/deep-compare.rb +0 -24
  91. data/lib/reactrb/new-event-name-convention.rb +0 -11
  92. data/logo1.png +0 -0
  93. data/logo2.png +0 -0
  94. data/logo3.png +0 -0
  95. data/path_release_steps.md +0 -9
  96. data/spec/controller_helper_spec.rb +0 -34
  97. data/spec/index.html.erb +0 -11
  98. data/spec/react/callbacks_spec.rb +0 -138
  99. data/spec/react/children_spec.rb +0 -76
  100. data/spec/react/component/base_spec.rb +0 -32
  101. data/spec/react/component_spec.rb +0 -884
  102. data/spec/react/dsl_spec.rb +0 -303
  103. data/spec/react/element_spec.rb +0 -136
  104. data/spec/react/event_spec.rb +0 -24
  105. data/spec/react/native_library_spec.rb +0 -322
  106. data/spec/react/observable_spec.rb +0 -42
  107. data/spec/react/opal_jquery_extensions_spec.rb +0 -68
  108. data/spec/react/param_declaration_spec.rb +0 -269
  109. data/spec/react/react_spec.rb +0 -215
  110. data/spec/react/refs_callback_spec.rb +0 -56
  111. data/spec/react/server_spec.rb +0 -25
  112. data/spec/react/state_spec.rb +0 -55
  113. data/spec/react/test/dsl_spec.rb +0 -43
  114. data/spec/react/test/matchers/render_html_matcher_spec.rb +0 -83
  115. data/spec/react/test/rspec_spec.rb +0 -62
  116. data/spec/react/test/session_spec.rb +0 -88
  117. data/spec/react/test/utils_spec.rb +0 -28
  118. data/spec/react/top_level_component_spec.rb +0 -101
  119. data/spec/react/tutorial/tutorial_spec.rb +0 -36
  120. data/spec/react/validator_spec.rb +0 -124
  121. data/spec/reactive-ruby/component_loader_spec.rb +0 -77
  122. data/spec/reactive-ruby/isomorphic_helpers_spec.rb +0 -160
  123. data/spec/reactive-ruby/rails/asset_pipeline_spec.rb +0 -10
  124. data/spec/reactive-ruby/rails/component_mount_spec.rb +0 -66
  125. data/spec/reactive-ruby/server_rendering/contextual_renderer_spec.rb +0 -35
  126. data/spec/spec_helper.rb +0 -149
  127. data/spec/support/react/spec_helpers.rb +0 -44
  128. data/spec/vendor/es5-shim.min.js +0 -6
  129. data/spec/vendor/jquery-2.2.4.min.js +0 -4
@@ -1,24 +0,0 @@
1
- # rubocop:disable Style/FileName
2
- # require 'reactrb/deep-compare' to get 0.9 deep compare behavior
3
- module React
4
- module Component
5
- module ShouldComponentUpdate
6
-
7
- def props_changed?(next_params)
8
- next_params != props
9
- end
10
-
11
- def call_needs_update(next_params, native_next_state)
12
- component = self
13
- next_params.define_singleton_method(:changed?) do
14
- next_params != props
15
- end
16
- next_state = Hash.new(native_next_state)
17
- next_state.define_singleton_method(:changed?) do
18
- component.native_state_changed?(native_next_state)
19
- end
20
- needs_update?(next_params, next_state)
21
- end
22
- end
23
- end
24
- end
@@ -1,11 +0,0 @@
1
- # rubocop:disable Style/FileName
2
- # require 'reactrb/new-event-name-convention' to remove missing param declaration "_onXXXX"
3
- if RUBY_ENGINE == 'opal'
4
- # removes generation of the deprecated "_onXXXX" event param syntax
5
- module React
6
- class Element
7
- def merge_deprecated_component_event_prop!(event_name)
8
- end
9
- end
10
- end
11
- end
data/logo1.png DELETED
Binary file
data/logo2.png DELETED
Binary file
data/logo3.png DELETED
Binary file
@@ -1,9 +0,0 @@
1
-
2
- For example assuming you are releasing fix to 0.8.18
3
-
4
- 1. Checkout 0-8-stable
5
- 2. Update tests, fix the bug and commit the changes.
6
- 3. Build & Release to RubyGems (Remember the version in version.rb should already be 0.8.19)
7
- 4. Create a tag 'v0.8.19' pointing to that commit.
8
- 5. Bump the version in 0-8-stable to 0.8.20 so it will be ready for the next patch level release.
9
- 6. Commit the version bump, and do a `git push --tags` so the new tag goes up
@@ -1,34 +0,0 @@
1
- require 'spec_helper'
2
-
3
- if ruby?
4
- class TestController < ActionController::Base; end
5
-
6
- RSpec.describe TestController, type: :controller do
7
- render_views
8
-
9
- describe '#render_component' do
10
- controller do
11
-
12
- layout "test_layout"
13
-
14
- def index
15
- render_component
16
- end
17
-
18
- def new
19
- render_component "Index", {}, layout: :explicit_layout
20
- end
21
- end
22
-
23
- it 'renders with the default layout' do
24
- get :index, no_prerender: true
25
- expect(response).to render_template(layout: :test_layout)
26
- end
27
-
28
- it "renders with a specified layout" do
29
- get :new, no_prerender: true
30
- expect(response).to render_template(layout: :explicit_layout)
31
- end
32
- end
33
- end
34
- end
@@ -1,11 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <meta charset="UTF-8" />
5
- </head>
6
- <body>
7
- <%= javascript_include_tag 'vendor/es5-shim.min' %>
8
- <%= javascript_include_tag 'vendor/jquery-2.2.4.min' %>
9
- <%= javascript_include_tag @server.main %>
10
- </body>
11
- </html>
@@ -1,138 +0,0 @@
1
- require 'spec_helper'
2
-
3
- if opal?
4
- describe React::Callbacks do
5
- it 'defines callback' do
6
- stub_const 'Foo', Class.new
7
- Foo.class_eval do
8
- include React::Callbacks
9
- define_callback :before_dinner
10
- before_dinner :wash_hand
11
-
12
- def wash_hand
13
- end
14
- end
15
-
16
- instance = Foo.new
17
- expect(instance).to receive(:wash_hand)
18
- instance.run_callback(:before_dinner)
19
- end
20
-
21
- it 'defines multiple callbacks' do
22
- stub_const 'Foo', Class.new
23
- Foo.class_eval do
24
- include React::Callbacks
25
- define_callback :before_dinner
26
-
27
- before_dinner :wash_hand, :turn_off_laptop
28
-
29
- def wash_hand;end
30
-
31
- def turn_off_laptop;end
32
- end
33
-
34
- instance = Foo.new
35
- expect(instance).to receive(:wash_hand)
36
- expect(instance).to receive(:turn_off_laptop)
37
- instance.run_callback(:before_dinner)
38
- end
39
-
40
- context 'using Hyperloop::Context.reset!' do
41
- after(:all) do
42
- Hyperloop::Context.instance_variable_set(:@context, nil)
43
- end
44
- it 'clears callbacks on Hyperloop::Context.reset!' do
45
- Hyperloop::Context.reset!
46
- stub_const 'Foo', Class.new
47
- Foo.class_eval do
48
- include React::Callbacks
49
- define_callback :before_dinner
50
-
51
- before_dinner :wash_hand, :turn_off_laptop
52
-
53
- def wash_hands;end
54
-
55
- def turn_off_laptop;end
56
- end
57
- instance = Foo.new
58
- expect(instance).to receive(:wash_hand).once
59
- expect(instance).not_to receive(:turn_off_laptop)
60
-
61
- Hyperloop::Context.reset!
62
-
63
- instance.run_callback(:before_dinner)
64
- Foo.class_eval do
65
- before_dinner :wash_hand
66
- end
67
- instance.run_callback(:before_dinner)
68
- end
69
- end # moved elswhere cause its just hard to get anything to work in this environment
70
-
71
- it 'defines block callback' do
72
- stub_const 'Foo', Class.new
73
- Foo.class_eval do
74
- include React::Callbacks
75
- attr_accessor :a
76
- attr_accessor :b
77
-
78
- define_callback :before_dinner
79
-
80
- before_dinner do
81
- self.a = 10
82
- end
83
- before_dinner do
84
- self.b = 20
85
- end
86
- end
87
-
88
- foo = Foo.new
89
- foo.run_callback(:before_dinner)
90
- expect(foo.a).to eq(10)
91
- expect(foo.b).to eq(20)
92
- end
93
-
94
- it 'defines multiple callback group' do
95
- stub_const 'Foo', Class.new
96
- Foo.class_eval do
97
- include React::Callbacks
98
- define_callback :before_dinner
99
- define_callback :after_dinner
100
- attr_accessor :a
101
-
102
- before_dinner do
103
- self.a = 10
104
- end
105
- end
106
-
107
- foo = Foo.new
108
- foo.run_callback(:before_dinner)
109
- foo.run_callback(:after_dinner)
110
-
111
- expect(foo.a).to eq(10)
112
- end
113
-
114
- it 'receives args as callback' do
115
- stub_const 'Foo', Class.new
116
- Foo.class_eval do
117
- include React::Callbacks
118
- define_callback :before_dinner
119
- define_callback :after_dinner
120
-
121
- attr_accessor :lorem
122
-
123
- before_dinner do |a, b|
124
- self.lorem = "#{a}-#{b}"
125
- end
126
-
127
- after_dinner :eat_ice_cream
128
- def eat_ice_cream(a,b,c); end
129
- end
130
-
131
- foo = Foo.new
132
- expect(foo).to receive(:eat_ice_cream).with(4,5,6)
133
- foo.run_callback(:before_dinner, 1, 2)
134
- foo.run_callback(:after_dinner, 4, 5, 6)
135
- expect(foo.lorem).to eq('1-2')
136
- end
137
- end
138
- end
@@ -1,76 +0,0 @@
1
- require 'spec_helper'
2
-
3
- if opal?
4
- describe React::Children do
5
- let(:component) {
6
- Class.new do
7
- include React::Component
8
- def render
9
- div { 'lorem' }
10
- end
11
- end
12
- }
13
- let(:childs) { [React.create_element('a'), React.create_element('li')] }
14
- let(:element) { React.create_element(component) { childs } }
15
- let(:children) { described_class.new(`#{element.to_n}.props.children`) }
16
-
17
- before(:each) do
18
- React::Test::Utils.render_into_document(element)
19
- end
20
-
21
- it 'is enumerable' do
22
- nodes = children.map { |elem| elem.element_type }
23
- expect(nodes).to eq(['a', 'li'])
24
- end
25
-
26
- it 'returns an Enumerator when not providing a block' do
27
- nodes = children.each
28
- expect(nodes).to be_a(Enumerator)
29
- expect(nodes.size).to eq(2)
30
- end
31
-
32
- describe '#each' do
33
- it 'returns an array of elements' do
34
- nodes = children.each { |elem| elem.element_type }
35
- expect(nodes).to be_a(Array)
36
- expect(nodes.map(&:class)).to eq(childs.map(&:class))
37
- end
38
- end
39
-
40
- describe '#length' do
41
- it 'returns the number of child elements' do
42
- expect(children.length).to eq(2)
43
- end
44
- end
45
-
46
- describe 'with single child element' do
47
- let(:childs) { [React.create_element('a')] }
48
-
49
- it 'is enumerable containing single element' do
50
- nodes = children.map { |elem| elem.element_type }
51
- expect(nodes).to eq(['a'])
52
- end
53
-
54
- describe '#length' do
55
- it 'returns the number of child elements' do
56
- expect(children.length).to eq(1)
57
- end
58
- end
59
- end
60
-
61
- describe 'with no child element' do
62
- let(:element) { React.create_element(component) }
63
-
64
- it 'is enumerable containing no elements' do
65
- nodes = children.map { |elem| elem.element_type }
66
- expect(nodes).to eq([])
67
- end
68
-
69
- describe '#length' do
70
- it 'returns the number of child elements' do
71
- expect(children.length).to eq(0)
72
- end
73
- end
74
- end
75
- end
76
- end
@@ -1,32 +0,0 @@
1
- require 'spec_helper'
2
-
3
- if opal?
4
- RSpec.describe React::Component::Base, type: :component do
5
- after(:each) do
6
- React::API.clear_component_class_cache
7
- end
8
-
9
- it 'can be inherited to create a component class' do
10
- stub_const 'Foo', Class.new(React::Component::Base)
11
- Foo.class_eval do
12
- before_mount do
13
- @instance_data = ["working"]
14
- end
15
- def render
16
- @instance_data.first
17
- end
18
- end
19
- stub_const 'Bar', Class.new(Foo)
20
- Bar.class_eval do
21
- before_mount do
22
- @instance_data << "well"
23
- end
24
- def render
25
- @instance_data.join(" ")
26
- end
27
- end
28
- expect(Foo).to render_static_html("<span>working</span>")
29
- expect(Bar).to render_static_html("<span>working well</span>")
30
- end
31
- end
32
- end
@@ -1,884 +0,0 @@
1
- require 'spec_helper'
2
-
3
- if opal?
4
- describe React::Component, type: :component do
5
- after(:each) do
6
- React::API.clear_component_class_cache
7
- end
8
-
9
- it 'defines component spec methods' do
10
- stub_const 'Foo', Class.new
11
- Foo.class_eval do
12
- include React::Component
13
- def initialize(native = nil)
14
- end
15
-
16
- def render
17
- React.create_element('div')
18
- end
19
- end
20
-
21
- # Class Methods
22
- expect(Foo).to respond_to('initial_state')
23
- expect(Foo).to respond_to('default_props')
24
- expect(Foo).to respond_to('prop_types')
25
-
26
- # Instance method
27
- expect(Foo.new).to respond_to('component_will_mount')
28
- expect(Foo.new).to respond_to('component_did_mount')
29
- expect(Foo.new).to respond_to('component_will_receive_props')
30
- expect(Foo.new).to respond_to('should_component_update?')
31
- expect(Foo.new).to respond_to('component_will_update')
32
- expect(Foo.new).to respond_to('component_did_update')
33
- expect(Foo.new).to respond_to('component_will_unmount')
34
- end
35
-
36
- describe 'Life Cycle' do
37
- let(:element_to_render) { React.create_element(Foo) }
38
-
39
- before(:each) do
40
- stub_const 'Foo', Class.new
41
- Foo.class_eval do
42
- include React::Component
43
- def render
44
- React.create_element('div') { 'lorem' }
45
- end
46
- end
47
- end
48
-
49
- it 'invokes `before_mount` registered methods when `componentWillMount()`' do
50
- Foo.class_eval do
51
- before_mount :bar, :bar2
52
- def bar; end
53
- def bar2; end
54
- end
55
-
56
- expect_any_instance_of(Foo).to receive(:bar)
57
- expect_any_instance_of(Foo).to receive(:bar2)
58
-
59
- React::Test::Utils.render_into_document(element_to_render)
60
- end
61
-
62
- it 'invokes `after_mount` registered methods when `componentDidMount()`' do
63
- Foo.class_eval do
64
- after_mount :bar3, :bar4
65
- def bar3; end
66
- def bar4; end
67
- end
68
-
69
- expect_any_instance_of(Foo).to receive(:bar3)
70
- expect_any_instance_of(Foo).to receive(:bar4)
71
-
72
- React::Test::Utils.render_into_document(element_to_render)
73
- end
74
-
75
- it 'allows multiple class declared life cycle hooker' do
76
- stub_const 'FooBar', Class.new
77
- Foo.class_eval do
78
- before_mount :bar
79
- def bar; end
80
- end
81
-
82
- FooBar.class_eval do
83
- include React::Component
84
- after_mount :bar2
85
- def bar2; end
86
- def render
87
- React.create_element('div') { 'lorem' }
88
- end
89
- end
90
-
91
- expect_any_instance_of(Foo).to receive(:bar)
92
-
93
- React::Test::Utils.render_into_document(element_to_render)
94
- end
95
-
96
- it 'allows block for life cycle callback' do
97
- Foo.class_eval do
98
- before_mount do
99
- set_state({ foo: "bar" })
100
- end
101
- end
102
-
103
- instance = React::Test::Utils.render_into_document(element_to_render)
104
- expect(instance.state[:foo]).to be('bar')
105
- end
106
- end
107
-
108
- describe 'New style setter & getter' do
109
- before(:each) do
110
- stub_const 'Foo', Class.new
111
- Foo.class_eval do
112
- include React::Component
113
- def render
114
- div { state.foo }
115
- end
116
- end
117
- end
118
-
119
- it 'implicitly will create a state variable when first written' do
120
- Foo.class_eval do
121
- before_mount do
122
- state.foo! 'bar'
123
- end
124
- end
125
-
126
- expect(Foo).to render_static_html('<div>bar</div>')
127
- end
128
-
129
- it 'allows kernal method names like "format" to be used as state variable names' do
130
- Foo.class_eval do
131
- before_mount do
132
- state.format! 'yes'
133
- state.foo! state.format
134
- end
135
- end
136
-
137
- expect(Foo).to render_static_html('<div>yes</div>')
138
- end
139
-
140
- it 'returns an observer with the bang method and no arguments' do
141
- Foo.class_eval do
142
- before_mount do
143
- state.foo!(state.baz!.class.name)
144
- end
145
- end
146
-
147
- expect(Foo).to render_static_html('<div>React::Observable</div>')
148
- end
149
-
150
- it 'returns the current value of a state when written' do
151
- Foo.class_eval do
152
- before_mount do
153
- state.baz! 'bar'
154
- state.foo!(state.baz!('pow'))
155
- end
156
- end
157
-
158
- expect(Foo).to render_static_html('<div>bar</div>')
159
- end
160
-
161
- it 'can access an explicitly defined state`' do
162
- Foo.class_eval do
163
- define_state foo: :bar
164
- end
165
-
166
- expect(Foo).to render_static_html('<div>bar</div>')
167
- end
168
-
169
- end
170
-
171
- describe 'State setter & getter' do
172
- let(:element_to_render) { React.create_element(Foo) }
173
-
174
- before(:each) do
175
- stub_const 'Foo', Class.new
176
- Foo.class_eval do
177
- include React::Component
178
- def render
179
- React.create_element('div') { 'lorem' }
180
- end
181
- end
182
- end
183
-
184
- it 'defines setter using `define_state`' do
185
- Foo.class_eval do
186
- define_state :foo
187
- before_mount :set_up
188
- def set_up
189
- mutate.foo 'bar'
190
- end
191
- end
192
-
193
- instance = React::Test::Utils.render_into_document(element_to_render)
194
- expect(instance.state.foo).to be('bar')
195
- end
196
-
197
- it 'defines init state by passing a block to `define_state`' do
198
- Foo.class_eval do
199
- define_state(:foo) { 10 }
200
- end
201
-
202
- instance = React::Test::Utils.render_into_document(element_to_render)
203
- expect(instance.state.foo).to be(10)
204
- end
205
-
206
- it 'defines getter using `define_state`' do
207
- Foo.class_eval do
208
- define_state(:foo) { 10 }
209
- before_mount :bump
210
- def bump
211
- mutate.foo(state.foo + 20)
212
- end
213
- end
214
-
215
- instance = React::Test::Utils.render_into_document(element_to_render)
216
- expect(instance.state.foo).to be(30)
217
- end
218
-
219
- it 'defines multiple state accessors by passing array to `define_state`' do
220
- Foo.class_eval do
221
- define_state :foo, :foo2
222
- before_mount :set_up
223
- def set_up
224
- mutate.foo 10
225
- mutate.foo2 20
226
- end
227
- end
228
-
229
- instance = React::Test::Utils.render_into_document(element_to_render)
230
- expect(instance.state.foo).to be(10)
231
- expect(instance.state.foo2).to be(20)
232
- end
233
-
234
- it 'invokes `define_state` multiple times to define states' do
235
- Foo.class_eval do
236
- define_state(:foo) { 30 }
237
- define_state(:foo2) { 40 }
238
- end
239
-
240
- instance = React::Test::Utils.render_into_document(element_to_render)
241
- expect(instance.state.foo).to be(30)
242
- expect(instance.state.foo2).to be(40)
243
- end
244
-
245
- it 'can initialize multiple state variables with a block' do
246
- Foo.class_eval do
247
- define_state(:foo, :foo2) { 30 }
248
- end
249
-
250
- instance = React::Test::Utils.render_into_document(element_to_render)
251
- expect(instance.state.foo).to be(30)
252
- expect(instance.state.foo2).to be(30)
253
- end
254
-
255
- it 'can mix multiple state variables with initializers and a block' do
256
- Foo.class_eval do
257
- define_state(:x, :y, foo: 1, bar: 2) {3}
258
- end
259
- instance = React::Test::Utils.render_into_document(element_to_render)
260
- expect(instance.state.x).to be(3)
261
- expect(instance.state.y).to be(3)
262
- expect(instance.state.foo).to be(1)
263
- expect(instance.state.bar).to be(2)
264
- end
265
-
266
- it 'gets state in render method' do
267
- Foo.class_eval do
268
- define_state(:foo) { 10 }
269
- def render
270
- React.create_element('div') { state.foo }
271
- end
272
- end
273
-
274
- instance = React::Test::Utils.render_into_document(element_to_render)
275
- expect(`#{instance.dom_node}.textContent`).to eq('10')
276
- end
277
-
278
- it 'supports original `setState` as `set_state` method' do
279
- Foo.class_eval do
280
- before_mount do
281
- self.set_state(foo: 'bar')
282
- end
283
- end
284
-
285
- instance = renderToDocument(Foo)
286
- expect(instance.state[:foo]).to be('bar')
287
- end
288
-
289
- it 'supports original `replaceState` as `set_state!` method' do
290
- Foo.class_eval do
291
- before_mount do
292
- set_state(foo: 'bar')
293
- set_state!(bar: 'lorem')
294
- end
295
- end
296
-
297
- element = renderToDocument(Foo)
298
- puts "*************************************************************************************"
299
- puts "element.state[:foo] = #{element.state[:foo]}"
300
- puts "element.state[:bar] = #{element.state[:bar]}"
301
- puts "*************************************************************************************"
302
- expect(element.state[:foo]).to be_nil
303
- expect(element.state[:bar]).to eq('lorem')
304
- end
305
-
306
- it 'supports original `state` method' do
307
- Foo.class_eval do
308
- before_mount do
309
- self.set_state(foo: 'bar')
310
- end
311
-
312
- def render
313
- div { self.state[:foo] }
314
- end
315
- end
316
-
317
- expect(Foo).to render_static_html('<div>bar</div>')
318
- end
319
-
320
- it 'transforms state getter to Ruby object' do
321
- Foo.class_eval do
322
- define_state :foo
323
-
324
- before_mount do
325
- mutate.foo [{a: "Hello"}]
326
- end
327
-
328
- def render
329
- div { state.foo[0][:a] }
330
- end
331
- end
332
-
333
- expect(Foo).to render_static_html('<div>Hello</div>')
334
- end
335
- end
336
-
337
- describe 'Props' do
338
- describe 'this.props could be accessed through `params` method' do
339
- before do
340
- stub_const 'Foo', Class.new
341
- Foo.class_eval do
342
- include React::Component
343
- end
344
- end
345
-
346
- it 'reads from parent passed properties through `params`' do
347
- Foo.class_eval do
348
- def render
349
- React.create_element('div') { params[:prop] }
350
- end
351
- end
352
-
353
- element = renderToDocument(Foo, prop: 'foobar')
354
- expect(`#{element.dom_node}.textContent`).to eq('foobar')
355
- end
356
-
357
- it 'accesses nested params as orignal Ruby object' do
358
- Foo.class_eval do
359
- def render
360
- React.create_element('div') { params[:prop][0][:foo] }
361
- end
362
- end
363
-
364
- element = renderToDocument(Foo, prop: [{foo: 10}])
365
- expect(`#{element.dom_node}.textContent`).to eq('10')
366
- end
367
- end
368
-
369
- describe 'Props Updating', v13_only: true do
370
- before do
371
- stub_const 'Foo', Class.new
372
- Foo.class_eval do
373
- include React::Component
374
- end
375
- end
376
-
377
- it 'supports original `setProps` as method `set_props`' do
378
- Foo.class_eval do
379
- def render
380
- React.create_element('div') { params[:foo] }
381
- end
382
- end
383
-
384
- element = renderToDocument(Foo, {foo: 10})
385
- element.set_props(foo: 20)
386
- expect(`#{element.dom_node}.innerHTML`).to eq('20')
387
- end
388
-
389
- it 'supports original `replaceProps` as method `set_props!`' do
390
- Foo.class_eval do
391
- def render
392
- React.create_element('div') { params[:foo] ? 'exist' : 'null' }
393
- end
394
- end
395
-
396
- instance = renderToDocument(Foo, {foo: 10})
397
- instance.set_props!(bar: 20)
398
- expect(`#{instance.dom_node}.innerHTML`).to eq('null')
399
- end
400
- end
401
-
402
- describe 'Prop validation' do
403
- before do
404
- stub_const 'Foo', Class.new
405
- Foo.class_eval do
406
- include React::Component
407
- end
408
- end
409
-
410
- it 'specifies validation rules using `params` class method' do
411
- Foo.class_eval do
412
- params do
413
- requires :foo, type: String
414
- optional :bar
415
- end
416
- end
417
-
418
- expect(Foo.prop_types).to have_key(:_componentValidator)
419
- end
420
-
421
- it 'logs error in warning if validation failed' do
422
- stub_const 'Lorem', Class.new
423
- Foo.class_eval do
424
- params do
425
- requires :foo
426
- requires :lorem, type: Lorem
427
- optional :bar, type: String
428
- end
429
-
430
- def render; div; end
431
- end
432
-
433
- %x{
434
- var log = [];
435
- var org_warn_console = window.console.warn;
436
- var org_error_console = window.console.error;
437
- window.console.warn = window.console.error = function(str){log.push(str)}
438
- }
439
- renderToDocument(Foo, bar: 10, lorem: Lorem.new)
440
- `window.console.warn = org_warn_console; window.console.error = org_error_console;`
441
- 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/)
442
- end
443
-
444
- it 'should not log anything if validation pass' do
445
- stub_const 'Lorem', Class.new
446
- Foo.class_eval do
447
- params do
448
- requires :foo
449
- requires :lorem, type: Lorem
450
- optional :bar, type: String
451
- end
452
-
453
- def render; div; end
454
- end
455
-
456
- %x{
457
- var log = [];
458
- var org_warn_console = window.console.warn;
459
- var org_error_console = window.console.error
460
- window.console.warn = window.console.error = function(str){log.push(str)}
461
- }
462
- renderToDocument(Foo, foo: 10, bar: '10', lorem: Lorem.new)
463
- `window.console.warn = org_warn_console; window.console.error = org_error_console;`
464
- expect(`log`).to eq([])
465
- end
466
- end
467
-
468
- describe 'Default props' do
469
- it 'sets default props using validation helper' do
470
- stub_const 'Foo', Class.new
471
- Foo.class_eval do
472
- include React::Component
473
- params do
474
- optional :foo, default: 'foo'
475
- optional :bar, default: 'bar'
476
- end
477
-
478
- def render
479
- div { params[:foo] + '-' + params[:bar]}
480
- end
481
- end
482
-
483
- expect(Foo).to render_static_html('<div>lorem-bar</div>').with_params(foo: 'lorem')
484
- expect(Foo).to render_static_html('<div>foo-bar</div>')
485
- end
486
- end
487
- end
488
-
489
- describe 'Anonymous Component' do
490
- it "will not generate spurious warning messages" do
491
- foo = Class.new(React::Component::Base)
492
- foo.class_eval do
493
- def render; "hello" end
494
- end
495
-
496
- %x{
497
- var log = [];
498
- var org_warn_console = window.console.warn;
499
- var org_error_console = window.console.error
500
- window.console.warn = window.console.error = function(str){log.push(str)}
501
- }
502
- renderToDocument(foo)
503
- `window.console.warn = org_warn_console; window.console.error = org_error_console;`
504
- expect(`log`).to eq([])
505
- end
506
- end
507
-
508
- describe 'Render Error Handling' do
509
- before(:each) do
510
- %x{
511
- window.test_log = [];
512
- window.org_warn_console = window.console.warn;
513
- window.org_error_console = window.console.error
514
- window.console.warn = window.console.error = function(str){window.test_log.push(str)}
515
- }
516
- end
517
- it "will generate a message if render returns something other than an Element or a String" do
518
- foo = Class.new(React::Component::Base)
519
- foo.class_eval do
520
- def render; Hash.new; end
521
- end
522
-
523
- renderToDocument(foo)
524
- `window.console.warn = window.org_warn_console; window.console.error = window.org_error_console;`
525
- expect(`test_log`.first).to match /Instead the Hash \{\} was returned/
526
- end
527
- it "will generate a message if render returns a Component class" do
528
- stub_const 'Foo', Class.new(React::Component::Base)
529
- foo = Class.new(React::Component::Base)
530
- foo.class_eval do
531
- def render; Foo; end
532
- end
533
-
534
- renderToDocument(foo)
535
- `window.console.warn = window.org_warn_console; window.console.error = window.org_error_console;`
536
- expect(`test_log`.first).to match /Did you mean Foo()/
537
- end
538
- it "will generate a message if more than 1 element is generated" do
539
- foo = Class.new(React::Component::Base)
540
- foo.class_eval do
541
- def render; "hello".span; "goodby".span; end
542
- end
543
-
544
- renderToDocument(foo)
545
- `window.console.warn = window.org_warn_console; window.console.error = window.org_error_console;`
546
- expect(`test_log`.first).to match /Instead 2 elements were generated/
547
- end
548
- it "will generate a message if the element generated is not the element returned" do
549
- foo = Class.new(React::Component::Base)
550
- foo.class_eval do
551
- def render; "hello".span; "goodby".span.delete; end
552
- end
553
-
554
- renderToDocument(foo)
555
- `window.console.warn = window.org_warn_console; window.console.error = window.org_error_console;`
556
- expect(`test_log`.first).to match /A different element was returned than was generated within the DSL/
557
- end
558
- end
559
-
560
- describe 'Event handling' do
561
- before do
562
- stub_const 'Foo', Class.new
563
- Foo.class_eval do
564
- include React::Component
565
- end
566
- end
567
-
568
- it 'works in render method' do
569
- Foo.class_eval do
570
- define_state(:clicked) { false }
571
-
572
- def render
573
- React.create_element('div').on(:click) do
574
- mutate.clicked true
575
- end
576
- end
577
- end
578
-
579
- element = React.create_element(Foo)
580
- instance = React::Test::Utils.render_into_document(element)
581
- React::Test::Utils.simulate(:click, instance)
582
- expect(instance.state.clicked).to eq(true)
583
- end
584
-
585
- it 'invokes handler on `this.props` using emit' do
586
- Foo.class_eval do
587
- param :_onFooSubmit, type: Proc
588
- after_mount :setup
589
-
590
- def setup
591
- puts "***************************** about to emit******************************"
592
- self.emit(:foo_submit, 'bar')
593
- puts "***************************** emitted!!! ********************************"
594
- rescue Exception => e
595
- puts "FAILED FAILED FAILED #{e}"
596
- end
597
-
598
- def render
599
- React.create_element('div')
600
- end
601
- end
602
-
603
- expect { |b|
604
- element = React.create_element(Foo).on(:foo_submit, &b)
605
- React::Test::Utils.render_into_document(element)
606
- }.to yield_with_args('bar')
607
- end
608
-
609
- it 'invokes handler with multiple params using emit' do
610
- Foo.class_eval do
611
- param :_onFooInvoked, type: Proc
612
- after_mount :setup
613
-
614
- def setup
615
- self.emit(:foo_invoked, [1,2,3], 'bar')
616
- end
617
-
618
- def render
619
- React.create_element('div')
620
- end
621
- end
622
-
623
- expect { |b|
624
- element = React.create_element(Foo).on(:foo_invoked, &b)
625
- React::Test::Utils.render_into_document(element)
626
- }.to yield_with_args([1,2,3], 'bar')
627
- end
628
- end
629
-
630
- describe '#refs' do
631
- before do
632
- stub_const 'Foo', Class.new
633
- Foo.class_eval do
634
- include React::Component
635
- end
636
- end
637
-
638
- it 'correctly assigns refs' do
639
- Foo.class_eval do
640
- def render
641
- React.create_element('input', type: :text, ref: :field)
642
- end
643
- end
644
-
645
- instance = renderToDocument(Foo)
646
- expect(instance.refs[:field]).not_to be_nil
647
- end
648
-
649
- it 'accesses refs through `refs` method' do
650
- Foo.class_eval do
651
- def render
652
- React.create_element('input', type: :text, ref: :field).on(:click) do
653
- refs[:field].value = 'some_stuff'
654
- end
655
- end
656
- end
657
-
658
- instance = React::Test::Utils.render_into_document(React.create_element(Foo))
659
- React::Test::Utils.simulate(:click, instance)
660
- expect(instance.refs[:field].value).to eq('some_stuff')
661
- end
662
-
663
- it "allows access the actual DOM node", v13_exclude: true do
664
- Foo.class_eval do
665
- after_mount do
666
- dom = refs[:my_div].to_n
667
- `dom.innerHTML = 'Modified'`
668
- end
669
-
670
- def render
671
- React.create_element('div', ref: :my_div) { "Original Content" }
672
- end
673
- end
674
-
675
- instance = renderToDocument(Foo)
676
- expect(`#{instance.dom_node}.innerHTML`).to eq('Modified')
677
- end
678
- end
679
-
680
- describe '#render' do
681
- it 'supports element building helpers' do
682
- stub_const 'Foo', Class.new
683
- Foo.class_eval do
684
- include React::Component
685
-
686
- def render
687
- div do
688
- span { params[:foo] }
689
- end
690
- end
691
- end
692
-
693
- stub_const 'Bar', Class.new
694
- Bar.class_eval do
695
- include React::Component
696
- def render
697
- div do
698
- present Foo, foo: 'astring'
699
- end
700
- end
701
- end
702
-
703
- expect(Bar).to render_static_html('<div><div><span>astring</span></div></div>')
704
- end
705
-
706
- it 'builds single node in top-level render without providing a block' do
707
- stub_const 'Foo', Class.new
708
- Foo.class_eval do
709
- include React::Component
710
-
711
- def render
712
- div
713
- end
714
- end
715
-
716
- expect(Foo).to render_static_html('<div></div>')
717
- end
718
-
719
- it 'redefines `p` to make method missing work' do
720
- stub_const 'Foo', Class.new
721
- Foo.class_eval do
722
- include React::Component
723
-
724
- def render
725
- div {
726
- p(class_name: 'foo')
727
- p
728
- div { 'lorem ipsum' }
729
- p(id: '10')
730
- }
731
- end
732
- end
733
-
734
- markup = '<div><p class="foo"></p><p></p><div>lorem ipsum</div><p id="10"></p></div>'
735
- expect(Foo).to render_static_html(markup)
736
- end
737
-
738
- it 'only overrides `p` in render context' do
739
- stub_const 'Foo', Class.new
740
- Foo.class_eval do
741
- include React::Component
742
-
743
- before_mount do
744
- p 'first'
745
- end
746
-
747
- after_mount do
748
- p 'second'
749
- end
750
-
751
- def render
752
- div
753
- end
754
- end
755
-
756
- expect(Kernel).to receive(:p).with('first')
757
- expect(Kernel).to receive(:p).with('second')
758
- renderToDocument(Foo)
759
- end
760
- end
761
-
762
- describe 'isMounted()' do
763
- it 'returns true if after mounted' do
764
- stub_const 'Foo', Class.new
765
- Foo.class_eval do
766
- include React::Component
767
-
768
- def render
769
- React.create_element('div')
770
- end
771
- end
772
-
773
- component = renderToDocument(Foo)
774
- expect(component.mounted?).to eq(true)
775
- end
776
- end
777
-
778
- describe '.params_changed?' do
779
-
780
- before(:each) do
781
- stub_const 'Foo', Class.new(React::Component::Base)
782
- Foo.define_method :needs_update? do |next_params, next_state|
783
- next_params.changed?
784
- end
785
- @foo = Foo.new(nil)
786
- end
787
-
788
- it "returns false if new and old params are the same" do
789
- @foo.instance_variable_set("@native", `{props: {value1: 1, value2: 2}}`)
790
- expect(@foo.should_component_update?(`{value2: 2, value1: 1}`, `null`)).to be_falsy
791
- end
792
-
793
- it "returns true if new and old params are have different values" do
794
- @foo.instance_variable_set("@native", `{props: {value1: 1, value2: 2}}`)
795
- expect(@foo.should_component_update?(`{value2: 2, value1: 2}`, `null`)).to be_truthy
796
- end
797
-
798
- it "returns true if new and old params are have different keys" do
799
- @foo.instance_variable_set("@native", `{props: {value1: 1, value2: 2}}`)
800
- expect(@foo.should_component_update?(`{value2: 2, value1: 1, value3: 3}`, `null`)).to be_truthy
801
- end
802
- end
803
-
804
- describe '#state_changed?' do
805
-
806
- empties = [`{}`, `undefined`, `null`, `false`]
807
-
808
- before(:each) do
809
- stub_const 'Foo', Class.new(React::Component::Base)
810
- Foo.define_method :needs_update? do |next_params, next_state|
811
- next_state.changed?
812
- end
813
- @foo = Foo.new(nil)
814
- end
815
-
816
- it "returns false if both new and old states are empty" do
817
- empties.each do |empty1|
818
- empties.each do |empty2|
819
- @foo.instance_variable_set("@native", `{state: #{empty1}}`)
820
- expect(@foo.should_component_update?(`{}`, empty2)).to be_falsy
821
- end
822
- end
823
- end
824
-
825
- it "returns true if old state is empty, but new state is not" do
826
- empties.each do |empty|
827
- @foo.instance_variable_set("@native", `{state: #{empty}}`)
828
- expect(@foo.should_component_update?(`{}`, `{foo: 12}`)).to be_truthy
829
- end
830
- end
831
-
832
- it "returns true if new state is empty, but old state is not" do
833
- empties.each do |empty|
834
- @foo.instance_variable_set("@native", `{state: {foo: 12}}`)
835
- expect(@foo.should_component_update?(`{}`, empty)).to be_truthy
836
- end
837
- end
838
-
839
- it "returns true if new state and old state have different time stamps" do
840
- @foo.instance_variable_set("@native", `{state: {'***_state_updated_at-***': 12}}`)
841
- expect(@foo.should_component_update?(`{}`, `{'***_state_updated_at-***': 13}`)).to be_truthy
842
- end
843
-
844
- it "returns false if new state and old state have the same time stamps" do
845
- @foo.instance_variable_set("@native", `{state: {'***_state_updated_at-***': 12}}`)
846
- expect(@foo.should_component_update?(`{}`, `{'***_state_updated_at-***': 12}`)).to be_falsy
847
- end
848
-
849
- end
850
-
851
- describe '#children' do
852
- before(:each) do
853
- stub_const 'Foo', Class.new
854
- Foo.class_eval do
855
- include React::Component
856
- def render
857
- React.create_element('div') { 'lorem' }
858
- end
859
- end
860
- end
861
-
862
- it 'returns React::Children collection with child elements' do
863
- ele = React.create_element(Foo) {
864
- [React.create_element('a'), React.create_element('li')]
865
- }
866
- instance = React::Test::Utils.render_into_document(ele)
867
-
868
- children = instance.children
869
-
870
- expect(children).to be_a(React::Children)
871
- expect(children.count).to eq(2)
872
- expect(children.map(&:element_type)).to eq(['a', 'li'])
873
- end
874
-
875
- it 'returns an empty Enumerator if there are no children' do
876
- ele = React.create_element(Foo)
877
- instance = React::Test::Utils.render_into_document(ele)
878
- nodes = instance.children.each
879
- expect(nodes.size).to eq(0)
880
- expect(nodes.count).to eq(0)
881
- end
882
- end
883
- end
884
- end