hyper-react 0.10.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.
- checksums.yaml +7 -0
- data/.codeclimate.yml +27 -0
- data/.gitignore +36 -0
- data/.rubocop.yml +1159 -0
- data/.travis.yml +29 -0
- data/Appraisals +20 -0
- data/CHANGELOG.md +93 -0
- data/Gemfile +6 -0
- data/LICENSE +19 -0
- data/README.md +121 -0
- data/Rakefile +33 -0
- data/UPGRADING.md +24 -0
- data/component-name-lookup.md +145 -0
- data/config.ru +25 -0
- data/gemfiles/opal_0.8_react_13.gemfile +13 -0
- data/gemfiles/opal_0.8_react_14.gemfile +13 -0
- data/gemfiles/opal_0.8_react_15.gemfile +13 -0
- data/gemfiles/opal_0.9_react_13.gemfile +13 -0
- data/gemfiles/opal_0.9_react_14.gemfile +13 -0
- data/gemfiles/opal_0.9_react_15.gemfile +13 -0
- data/hyper-react.gemspec +43 -0
- data/lib/generators/reactive_ruby/test_app/templates/assets/javascripts/components.rb +4 -0
- data/lib/generators/reactive_ruby/test_app/templates/assets/javascripts/test_application.rb +2 -0
- data/lib/generators/reactive_ruby/test_app/templates/boot.rb.erb +6 -0
- data/lib/generators/reactive_ruby/test_app/templates/script/rails +5 -0
- data/lib/generators/reactive_ruby/test_app/templates/test_application.rb.erb +13 -0
- data/lib/generators/reactive_ruby/test_app/templates/views/components/hello_world.rb +11 -0
- data/lib/generators/reactive_ruby/test_app/templates/views/components/todo.rb +14 -0
- data/lib/generators/reactive_ruby/test_app/templates/views/layouts/test_layout.html.erb +0 -0
- data/lib/generators/reactive_ruby/test_app/test_app_generator.rb +109 -0
- data/lib/hyper-react.rb +52 -0
- data/lib/rails-helpers/top_level_rails_component.rb +54 -0
- data/lib/react-sources/react-server.js +2 -0
- data/lib/react/api.rb +162 -0
- data/lib/react/callbacks.rb +42 -0
- data/lib/react/children.rb +30 -0
- data/lib/react/component.rb +139 -0
- data/lib/react/component/api.rb +50 -0
- data/lib/react/component/base.rb +9 -0
- data/lib/react/component/class_methods.rb +214 -0
- data/lib/react/component/dsl_instance_methods.rb +27 -0
- data/lib/react/component/params.rb +6 -0
- data/lib/react/component/props_wrapper.rb +83 -0
- data/lib/react/component/should_component_update.rb +98 -0
- data/lib/react/component/tags.rb +144 -0
- data/lib/react/element.rb +168 -0
- data/lib/react/event.rb +76 -0
- data/lib/react/ext/hash.rb +9 -0
- data/lib/react/ext/string.rb +8 -0
- data/lib/react/hash.rb +13 -0
- data/lib/react/native_library.rb +92 -0
- data/lib/react/object.rb +15 -0
- data/lib/react/observable.rb +29 -0
- data/lib/react/react-source.rb +9 -0
- data/lib/react/rendering_context.rb +142 -0
- data/lib/react/state.rb +190 -0
- data/lib/react/test.rb +16 -0
- data/lib/react/test/dsl.rb +17 -0
- data/lib/react/test/matchers/render_html_matcher.rb +49 -0
- data/lib/react/test/rspec.rb +15 -0
- data/lib/react/test/session.rb +46 -0
- data/lib/react/top_level.rb +132 -0
- data/lib/react/validator.rb +136 -0
- data/lib/reactive-ruby/component_loader.rb +49 -0
- data/lib/reactive-ruby/isomorphic_helpers.rb +197 -0
- data/lib/reactive-ruby/rails.rb +7 -0
- data/lib/reactive-ruby/rails/component_mount.rb +46 -0
- data/lib/reactive-ruby/rails/controller_helper.rb +15 -0
- data/lib/reactive-ruby/rails/railtie.rb +14 -0
- data/lib/reactive-ruby/serializers.rb +15 -0
- data/lib/reactive-ruby/server_rendering/contextual_renderer.rb +42 -0
- data/lib/reactive-ruby/version.rb +3 -0
- data/lib/reactrb/auto-import.rb +32 -0
- data/lib/reactrb/deep-compare.rb +24 -0
- data/lib/reactrb/new-event-name-convention.rb +11 -0
- data/lib/sources/react-latest.js +21169 -0
- data/lib/sources/react-v13.js +21645 -0
- data/lib/sources/react-v14.js +20821 -0
- data/lib/sources/react-v15.js +21170 -0
- data/logo1.png +0 -0
- data/logo2.png +0 -0
- data/logo3.png +0 -0
- data/path_release_steps.md +9 -0
- data/spec/controller_helper_spec.rb +34 -0
- data/spec/index.html.erb +10 -0
- data/spec/react/callbacks_spec.rb +106 -0
- data/spec/react/children_spec.rb +76 -0
- data/spec/react/component/base_spec.rb +32 -0
- data/spec/react/component_spec.rb +872 -0
- data/spec/react/dsl_spec.rb +296 -0
- data/spec/react/element_spec.rb +136 -0
- data/spec/react/event_spec.rb +24 -0
- data/spec/react/native_library_spec.rb +344 -0
- data/spec/react/observable_spec.rb +7 -0
- data/spec/react/opal_jquery_extensions_spec.rb +66 -0
- data/spec/react/param_declaration_spec.rb +258 -0
- data/spec/react/react_spec.rb +209 -0
- data/spec/react/state_spec.rb +55 -0
- data/spec/react/test/dsl_spec.rb +43 -0
- data/spec/react/test/matchers/render_html_matcher_spec.rb +83 -0
- data/spec/react/test/rspec_spec.rb +62 -0
- data/spec/react/test/session_spec.rb +100 -0
- data/spec/react/test/utils_spec.rb +45 -0
- data/spec/react/top_level_component_spec.rb +96 -0
- data/spec/react/tutorial/tutorial_spec.rb +36 -0
- data/spec/react/validator_spec.rb +124 -0
- data/spec/reactive-ruby/component_loader_spec.rb +71 -0
- data/spec/reactive-ruby/isomorphic_helpers_spec.rb +155 -0
- data/spec/reactive-ruby/rails/asset_pipeline_spec.rb +10 -0
- data/spec/reactive-ruby/rails/component_mount_spec.rb +66 -0
- data/spec/reactive-ruby/server_rendering/contextual_renderer_spec.rb +35 -0
- data/spec/spec_helper.rb +115 -0
- data/spec/support/react/spec_helpers.rb +64 -0
- data/spec/vendor/es5-shim.min.js +6 -0
- data/spec/vendor/jquery-2.2.4.min.js +4 -0
- metadata +387 -0
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
if opal?
|
|
4
|
+
describe 'the React DSL' do
|
|
5
|
+
|
|
6
|
+
context "render macro" do
|
|
7
|
+
|
|
8
|
+
it "can define the render method with the render macro with a html tag container" do
|
|
9
|
+
stub_const 'Foo', Class.new
|
|
10
|
+
Foo.class_eval do
|
|
11
|
+
include React::Component
|
|
12
|
+
render(:div, class: :foo) do
|
|
13
|
+
"hello"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<div class="foo">hello</div>')
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "can define the render method with the render macro without a container" do
|
|
21
|
+
stub_const 'Foo', Class.new
|
|
22
|
+
Foo.class_eval do
|
|
23
|
+
include React::Component
|
|
24
|
+
render do
|
|
25
|
+
"hello"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<span>hello</span>')
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "can define the render method with the render macro with a application defined container" do
|
|
33
|
+
stub_const 'Bar', Class.new(React::Component::Base)
|
|
34
|
+
Bar.class_eval do
|
|
35
|
+
param :p1
|
|
36
|
+
render { "hello #{params.p1}" }
|
|
37
|
+
end
|
|
38
|
+
stub_const 'Foo', Class.new(React::Component::Base)
|
|
39
|
+
Foo.class_eval do
|
|
40
|
+
render Bar, p1: "fred"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<span>hello fred</span>')
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "will turn the last string in a block into a element" do
|
|
48
|
+
stub_const 'Foo', Class.new
|
|
49
|
+
Foo.class_eval do
|
|
50
|
+
include React::Component
|
|
51
|
+
def render
|
|
52
|
+
div { "hello" }
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<div>hello</div>')
|
|
57
|
+
end
|
|
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
|
+
|
|
71
|
+
it "will turn the last string in a block into a element" do
|
|
72
|
+
stub_const 'Foo', Class.new
|
|
73
|
+
Foo.class_eval do
|
|
74
|
+
include React::Component
|
|
75
|
+
def render
|
|
76
|
+
DIV { "hello" }
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<div>hello</div>')
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it "has a .span short hand String method" do
|
|
84
|
+
stub_const 'Foo', Class.new
|
|
85
|
+
Foo.class_eval do
|
|
86
|
+
include React::Component
|
|
87
|
+
def render
|
|
88
|
+
div { "hello".span; "goodby".span }
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<div><span>hello</span><span>goodby</span></div>')
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it "has a .br short hand String method" do
|
|
96
|
+
stub_const 'Foo', Class.new
|
|
97
|
+
Foo.class_eval do
|
|
98
|
+
include React::Component
|
|
99
|
+
def render
|
|
100
|
+
div { "hello".br }
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
expect(React.render_to_static_markup(React.create_element(Foo)).gsub("<br/>", "<br>")).to eq('<div><span>hello<br></span></div>')
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it "has a .td short hand String method" do
|
|
108
|
+
stub_const 'Foo', Class.new
|
|
109
|
+
Foo.class_eval do
|
|
110
|
+
include React::Component
|
|
111
|
+
def render
|
|
112
|
+
table { tr { "hello".td } }
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<table><tr><td>hello</td></tr></table>')
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it "has a .para short hand String method" do
|
|
120
|
+
stub_const 'Foo', Class.new
|
|
121
|
+
Foo.class_eval do
|
|
122
|
+
include React::Component
|
|
123
|
+
def render
|
|
124
|
+
div { "hello".para }
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<div><p>hello</p></div>')
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
it 'can do a method call on a class name that is not a direct sibling' do
|
|
132
|
+
stub_const 'Mod', Module.new
|
|
133
|
+
stub_const 'Mod::NestedMod', Module.new
|
|
134
|
+
stub_const 'Mod::Comp', Class.new(React::Component::Base)
|
|
135
|
+
Mod::Comp.class_eval do
|
|
136
|
+
render { 'Mod::Comp' }
|
|
137
|
+
end
|
|
138
|
+
stub_const 'Mod::NestedMod::NestedComp', Class.new(React::Component::Base)
|
|
139
|
+
Mod::NestedMod::NestedComp.class_eval do
|
|
140
|
+
render do
|
|
141
|
+
Comp()
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
expect(React.render_to_static_markup(React.create_element(Mod::NestedMod::NestedComp)))
|
|
145
|
+
.to eq('<span>Mod::Comp</span>')
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it 'raises a meaningful error if a Constant Name is not actually a component' do
|
|
149
|
+
stub_const 'Mod', Module.new
|
|
150
|
+
stub_const 'Mod::NestedMod', Module.new
|
|
151
|
+
stub_const 'Mod::Comp', Class.new
|
|
152
|
+
stub_const 'Mod::NestedMod::NestedComp', Class.new(React::Component::Base)
|
|
153
|
+
Mod::NestedMod::NestedComp.class_eval do
|
|
154
|
+
backtrace :none
|
|
155
|
+
render do
|
|
156
|
+
Comp()
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
expect { React.render_to_static_markup(React.create_element(Mod::NestedMod::NestedComp)) }
|
|
160
|
+
.to raise_error('Comp does not appear to be a react component.')
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
it 'raises a method missing error' do
|
|
164
|
+
stub_const 'Foo', Class.new(React::Component::Base)
|
|
165
|
+
Foo.class_eval do
|
|
166
|
+
backtrace :none
|
|
167
|
+
render do
|
|
168
|
+
_undefined_method
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
expect { React.render_to_static_markup(React.create_element(Foo)) }
|
|
172
|
+
.to raise_error(NoMethodError)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
it "will treat the component class name as a first class component name" do
|
|
176
|
+
stub_const 'Mod::Bar', Class.new
|
|
177
|
+
Mod::Bar.class_eval do
|
|
178
|
+
include React::Component
|
|
179
|
+
def render
|
|
180
|
+
"a man walks into a bar"
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
stub_const 'Foo', Class.new(React::Component::Base)
|
|
184
|
+
Foo.class_eval do
|
|
185
|
+
def render
|
|
186
|
+
Mod::Bar()
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<span>a man walks into a bar</span>')
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
it "can add class names by the haml .class notation" do
|
|
194
|
+
stub_const 'Mod::Bar', Class.new
|
|
195
|
+
Mod::Bar.class_eval do
|
|
196
|
+
include React::Component
|
|
197
|
+
collect_other_params_as :attributes
|
|
198
|
+
def render
|
|
199
|
+
"a man walks into a bar".span(params.attributes)
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
stub_const 'Foo', Class.new(React::Component::Base)
|
|
203
|
+
Foo.class_eval do
|
|
204
|
+
def render
|
|
205
|
+
Mod::Bar().the_class.other_class
|
|
206
|
+
end
|
|
207
|
+
end
|
|
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>')
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
it "can use the 'class' keyword for classes" do
|
|
213
|
+
stub_const 'Foo', Class.new
|
|
214
|
+
Foo.class_eval do
|
|
215
|
+
include React::Component
|
|
216
|
+
def render
|
|
217
|
+
span(class: "the-class") { "hello" }
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<span class="the-class">hello</span>')
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
it "can generate a unrendered node using the .as_node method" do # div { "hello" }.as_node
|
|
225
|
+
stub_const 'Foo', Class.new #(React::Component::Base)
|
|
226
|
+
Foo.class_eval do
|
|
227
|
+
include React::Component
|
|
228
|
+
def render
|
|
229
|
+
span(data: {size: 12}) { "hello".span.as_node.class.name }.as_node.render
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<span data-size="12">React::Element</span>')
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
it "can use the dangerously_set_inner_HTML param" do
|
|
237
|
+
stub_const 'Foo', Class.new
|
|
238
|
+
Foo.class_eval do
|
|
239
|
+
include React::Component
|
|
240
|
+
def render
|
|
241
|
+
div(dangerously_set_inner_HTML: { __html: "Hello Goodby" })
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
expect(React.render_to_static_markup(React.create_element(Foo))).to eq('<div>Hello Goodby</div>')
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
it 'should convert a hash param to hyphenated html attributes if in React::HASH_ATTRIBUTES' do
|
|
249
|
+
stub_const 'Foo', Class.new
|
|
250
|
+
Foo.class_eval do
|
|
251
|
+
include React::Component
|
|
252
|
+
def render
|
|
253
|
+
div(data: { foo: :bar }, aria: { foo_bar: :foo })
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
expect(React.render_to_static_markup(React.create_element(Foo)))
|
|
258
|
+
.to eq('<div data-foo="bar" aria-foo-bar="foo"></div>')
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
it 'should not convert a hash param to hyphenated html attributes if not in React::HASH_ATTRIBUTES' do
|
|
262
|
+
stub_const 'Foo', Class.new
|
|
263
|
+
Foo.class_eval do
|
|
264
|
+
include React::Component
|
|
265
|
+
def render
|
|
266
|
+
div(title: { bar: :foo })
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
expect(React.render_to_static_markup(React.create_element(Foo)))
|
|
271
|
+
.to eq('<div title="{"bar"=>"foo"}"></div>')
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
it "will remove all elements passed as params from the rendering buffer" do
|
|
275
|
+
stub_const 'X2', Class.new
|
|
276
|
+
X2.class_eval do
|
|
277
|
+
include React::Component
|
|
278
|
+
def render
|
|
279
|
+
div do
|
|
280
|
+
params[:ele].render
|
|
281
|
+
params[:ele].render
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
stub_const 'Test', Class.new
|
|
286
|
+
Test.class_eval do
|
|
287
|
+
include React::Component
|
|
288
|
+
def render
|
|
289
|
+
X2(ele: b { "hello" })
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
expect(React.render_to_static_markup(React.create_element(Test))).to eq('<div><b>hello</b><b>hello</b></div>')
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
end
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
if opal?
|
|
4
|
+
# require 'reactrb/new-event-name-convention' # this require will get rid of any error messages but
|
|
5
|
+
# the on method will no longer attach to the param prefixed with _on
|
|
6
|
+
describe React::Element do
|
|
7
|
+
it 'bridges `type` of native React.Element attributes' do
|
|
8
|
+
element = React.create_element('div')
|
|
9
|
+
expect(element.element_type).to eq("div")
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
async 'is renderable' do
|
|
13
|
+
element = React.create_element('span')
|
|
14
|
+
div = `document.createElement("div")`
|
|
15
|
+
React.render(element, div) do
|
|
16
|
+
run_async {
|
|
17
|
+
expect(`div.children[0].tagName`).to eq("SPAN")
|
|
18
|
+
}
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe "Event Subscription" do
|
|
23
|
+
it "keeps the original params" do
|
|
24
|
+
stub_const 'Foo', Class.new
|
|
25
|
+
Foo.class_eval do
|
|
26
|
+
include React::Component
|
|
27
|
+
def render
|
|
28
|
+
INPUT(value: nil, type: 'text').on(:change) {}
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
expect(React.render_to_static_markup(React.create_element(Foo))).to match(/<input (type="text" value=""|value="" type="text")(\/)?>/)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
describe 'Component Event Subscription' do
|
|
37
|
+
|
|
38
|
+
it 'will subscribe to a component event param' do
|
|
39
|
+
stub_const 'Foo', Class.new(React::Component::Base)
|
|
40
|
+
Foo.class_eval do
|
|
41
|
+
param :on_event, type: Proc, default: nil, allow_nil: true
|
|
42
|
+
def render
|
|
43
|
+
params.on_event
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
expect(React.render_to_static_markup(React.create_element(Foo).on(:event) {'works!'})).to eq('<span>works!</span>')
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it 'will subscribe to multiple component event params' do
|
|
50
|
+
stub_const 'Foo', Class.new(React::Component::Base)
|
|
51
|
+
Foo.class_eval do
|
|
52
|
+
param :on_event1, type: Proc, default: nil, allow_nil: true
|
|
53
|
+
param :on_event2, type: Proc, default: nil, allow_nil: true
|
|
54
|
+
def render
|
|
55
|
+
params.on_event1+params.on_event2
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
expect(React.render_to_static_markup(React.create_element(Foo).on(:event1, :event2) {'works!'})).to eq('<span>works!works!</span>')
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it 'will subscribe to a native components event param' do
|
|
62
|
+
%x{
|
|
63
|
+
window.NativeComponent = React.createClass({
|
|
64
|
+
displayName: "HelloMessage",
|
|
65
|
+
render: function render() {
|
|
66
|
+
return React.createElement("span", null, this.props.onEvent());
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
}
|
|
70
|
+
stub_const 'Foo', Class.new(React::Component::Base)
|
|
71
|
+
Foo.class_eval do
|
|
72
|
+
imports "NativeComponent"
|
|
73
|
+
end
|
|
74
|
+
expect(React.render_to_static_markup(React.create_element(Foo).on(:event) {'works!'})).to eq('<span>works!</span>')
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it 'will subscribe to a component event param with a non-default name' do
|
|
78
|
+
stub_const 'Foo', Class.new(React::Component::Base)
|
|
79
|
+
Foo.class_eval do
|
|
80
|
+
param :my_event, type: Proc, default: nil, allow_nil: true
|
|
81
|
+
def render
|
|
82
|
+
params.my_event
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
expect(React.render_to_static_markup(React.create_element(Foo).on("<my_event>") {'works!'})).to eq('<span>works!</span>')
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it 'will subscribe to a component event param using the deprecated naming convention and generate a message' do
|
|
89
|
+
stub_const 'Foo', Class.new(React::Component::Base)
|
|
90
|
+
Foo.class_eval do
|
|
91
|
+
param :_onEvent, type: Proc, default: nil, allow_nil: true
|
|
92
|
+
def render
|
|
93
|
+
params._onEvent
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
%x{
|
|
97
|
+
var log = [];
|
|
98
|
+
var org_warn_console = window.console.warn;
|
|
99
|
+
var org_error_console = window.console.error;
|
|
100
|
+
window.console.warn = window.console.error = function(str){log.push(str)}
|
|
101
|
+
}
|
|
102
|
+
expect(React.render_to_static_markup(React.create_element(Foo).on(:event) {'works!'})).to eq('<span>works!</span>')
|
|
103
|
+
`window.console.warn = org_warn_console; window.console.error = org_error_console;`
|
|
104
|
+
expect(`log[0]`).to match(/Warning: Failed prop( type|Type): In component `Foo`\nProvided prop `on_event` not specified in spec/)
|
|
105
|
+
expect(`log[1]`).to eq("Warning: Deprecated feature used in React::Component. In future releases React::Element#on('event') will no longer respond to the '_onEvent' emitter.\nRename your emitter param to 'on_event' or use .on('<_onEvent>')")
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
describe 'Builtin Event subscription' do
|
|
110
|
+
it 'is subscribable through `on(:event_name)` method' do
|
|
111
|
+
expect { |b|
|
|
112
|
+
element = React.create_element("div").on(:click, &b)
|
|
113
|
+
instance = renderElementToDocument(element)
|
|
114
|
+
simulateEvent(:click, instance)
|
|
115
|
+
}.to yield_with_args(React::Event)
|
|
116
|
+
|
|
117
|
+
expect { |b|
|
|
118
|
+
element = React.create_element("div").on(:key_down, &b)
|
|
119
|
+
instance = renderElementToDocument(element)
|
|
120
|
+
simulateEvent(:keyDown, instance, {key: "Enter"})
|
|
121
|
+
}.to yield_control
|
|
122
|
+
|
|
123
|
+
expect { |b|
|
|
124
|
+
element = React.create_element("form").on(:submit, &b)
|
|
125
|
+
instance = renderElementToDocument(element)
|
|
126
|
+
simulateEvent(:submit, instance, {})
|
|
127
|
+
}.to yield_control
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
it 'returns self for `on` method' do
|
|
131
|
+
element = React.create_element("div")
|
|
132
|
+
expect(element.on(:click){}).to eq(element)
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
if opal?
|
|
4
|
+
describe React::Event do
|
|
5
|
+
it "should bridge attributes of native SyntheticEvent (see http://facebook.github.io/react/docs/events.html#syntheticevent)" do
|
|
6
|
+
element = React.create_element('div').on(:click) do |event|
|
|
7
|
+
expect(event.bubbles).to eq(`#{event.to_n}.bubbles`)
|
|
8
|
+
expect(event.cancelable).to eq(`#{event.to_n}.cancelable`)
|
|
9
|
+
expect(event.current_target).to eq(`#{event.to_n}.currentTarget`)
|
|
10
|
+
expect(event.default_prevented).to eq(`#{event.to_n}.defaultPrevented`)
|
|
11
|
+
expect(event.event_phase).to eq(`#{event.to_n}.eventPhase`)
|
|
12
|
+
expect(event.is_trusted?).to eq(`#{event.to_n}.isTrusted`)
|
|
13
|
+
expect(event.native_event).to eq(`#{event.to_n}.nativeEvent`)
|
|
14
|
+
expect(event.target).to eq(`#{event.to_n}.target`)
|
|
15
|
+
expect(event.timestamp).to eq(`#{event.to_n}.timeStamp`)
|
|
16
|
+
expect(event.event_type).to eq(`#{event.to_n}.type`)
|
|
17
|
+
expect(event).to respond_to(:prevent_default)
|
|
18
|
+
expect(event).to respond_to(:stop_propagation)
|
|
19
|
+
end
|
|
20
|
+
instance = renderElementToDocument(element)
|
|
21
|
+
simulateEvent(:click, instance)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|