hyper-react 0.99.6 → 1.0.0.lap21
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 +5 -5
- data/.codeclimate.yml +27 -0
- data/.gitignore +30 -37
- data/.rubocop.yml +1159 -0
- data/.travis.yml +32 -0
- data/Appraisals +31 -0
- data/CHANGELOG.md +143 -0
- data/DOCS.md +1515 -0
- data/Gemfile +2 -5
- data/LICENSE +19 -0
- data/README.md +5 -33
- data/Rakefile +25 -6
- data/UPGRADING.md +24 -0
- data/component-name-lookup.md +145 -0
- data/dciy.toml +3 -0
- data/dciy_prepare.sh +8 -0
- data/dciy_run.sh +10 -0
- data/hyper-react.gemspec +24 -18
- data/lib/generators/reactive_ruby/test_app/templates/assets/javascripts/components.rb +3 -0
- data/lib/generators/reactive_ruby/test_app/templates/assets/javascripts/server_rendering.js +5 -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 +117 -0
- data/lib/hyper-react.rb +66 -4
- data/lib/rails-helpers/top_level_rails_component.rb +75 -0
- data/lib/react/api.rb +203 -0
- data/lib/react/callbacks.rb +41 -0
- data/lib/react/children.rb +30 -0
- data/lib/react/component.rb +177 -0
- data/lib/react/component/api.rb +69 -0
- data/lib/react/component/base.rb +13 -0
- data/lib/react/component/class_methods.rb +181 -0
- data/lib/react/component/dsl_instance_methods.rb +23 -0
- data/lib/react/component/params.rb +6 -0
- data/lib/react/component/props_wrapper.rb +78 -0
- data/lib/react/component/should_component_update.rb +99 -0
- data/lib/react/component/tags.rb +108 -0
- data/lib/react/config.rb +5 -0
- data/lib/react/config/client.rb.erb +19 -0
- data/lib/react/config/server.rb +23 -0
- data/lib/react/element.rb +150 -0
- data/lib/react/event.rb +76 -0
- data/lib/react/ext/hash.rb +9 -0
- data/lib/react/ext/opal-jquery/element.rb +26 -0
- data/lib/react/ext/string.rb +8 -0
- data/lib/react/hash.rb +13 -0
- data/lib/react/native_library.rb +87 -0
- data/lib/react/object.rb +15 -0
- data/lib/react/react-source-browser.rb +3 -0
- data/lib/react/react-source-server.rb +3 -0
- data/lib/react/react-source.rb +16 -0
- data/lib/react/ref_callback.rb +31 -0
- data/lib/react/rendering_context.rb +146 -0
- data/lib/react/server.rb +19 -0
- data/lib/react/state_wrapper.rb +23 -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 +56 -0
- data/lib/react/test/rspec.rb +15 -0
- data/lib/react/test/session.rb +37 -0
- data/lib/react/test/utils.rb +71 -0
- data/lib/react/top_level.rb +110 -0
- data/lib/react/top_level_render.rb +28 -0
- data/lib/react/validator.rb +136 -0
- data/lib/reactive-ruby/component_loader.rb +43 -0
- data/lib/reactive-ruby/isomorphic_helpers.rb +235 -0
- data/lib/reactive-ruby/rails.rb +8 -0
- data/lib/reactive-ruby/rails/component_mount.rb +48 -0
- data/lib/reactive-ruby/rails/controller_helper.rb +14 -0
- data/lib/reactive-ruby/rails/railtie.rb +20 -0
- data/lib/reactive-ruby/serializers.rb +15 -0
- data/lib/reactive-ruby/server_rendering/contextual_renderer.rb +41 -0
- data/lib/reactive-ruby/server_rendering/hyper_asset_container.rb +46 -0
- data/lib/reactive-ruby/version.rb +3 -0
- data/lib/reactrb/auto-import.rb +27 -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 +35 -0
- data/spec/index.html.erb +11 -0
- data/spec/react/callbacks_spec.rb +142 -0
- data/spec/react/children_spec.rb +132 -0
- data/spec/react/component/base_spec.rb +36 -0
- data/spec/react/component_spec.rb +1073 -0
- data/spec/react/dsl_spec.rb +323 -0
- data/spec/react/element_spec.rb +132 -0
- data/spec/react/event_spec.rb +39 -0
- data/spec/react/native_library_spec.rb +387 -0
- data/spec/react/observable_spec.rb +31 -0
- data/spec/react/opal_jquery_extensions_spec.rb +68 -0
- data/spec/react/param_declaration_spec.rb +253 -0
- data/spec/react/react_spec.rb +278 -0
- data/spec/react/refs_callback_spec.rb +65 -0
- data/spec/react/server_spec.rb +25 -0
- data/spec/react/state_spec.rb +52 -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 +88 -0
- data/spec/react/test/utils_spec.rb +28 -0
- data/spec/react/top_level_component_spec.rb +103 -0
- data/spec/react/tutorial/tutorial_spec.rb +42 -0
- data/spec/react/validator_spec.rb +134 -0
- data/spec/reactive-ruby/component_loader_spec.rb +74 -0
- data/spec/reactive-ruby/isomorphic_helpers_spec.rb +157 -0
- data/spec/reactive-ruby/rails/asset_pipeline_spec.rb +17 -0
- data/spec/reactive-ruby/rails/component_mount_spec.rb +64 -0
- data/spec/reactive-ruby/server_rendering/contextual_renderer_spec.rb +39 -0
- data/spec/spec_helper.rb +55 -0
- data/spec/test_app/README.md +24 -0
- data/spec/test_app/Rakefile +6 -0
- data/spec/test_app/app/assets/config/manifest.js +3 -0
- data/spec/test_app/app/assets/images/.keep +0 -0
- data/spec/test_app/app/assets/javascripts/application.rb +7 -0
- data/spec/test_app/app/assets/javascripts/cable.js +13 -0
- data/spec/test_app/app/assets/javascripts/channels/.keep +0 -0
- data/spec/test_app/app/assets/javascripts/server_rendering.js +5 -0
- data/spec/test_app/app/assets/stylesheets/application.css +15 -0
- data/spec/test_app/app/channels/application_cable/channel.rb +4 -0
- data/spec/test_app/app/channels/application_cable/connection.rb +4 -0
- data/spec/test_app/app/controllers/application_controller.rb +3 -0
- data/spec/test_app/app/controllers/concerns/.keep +0 -0
- data/spec/test_app/app/helpers/application_helper.rb +2 -0
- data/spec/test_app/app/jobs/application_job.rb +2 -0
- data/spec/test_app/app/mailers/application_mailer.rb +4 -0
- data/spec/test_app/app/models/application_record.rb +3 -0
- data/spec/test_app/app/models/concerns/.keep +0 -0
- data/spec/test_app/app/views/components.rb +11 -0
- data/spec/test_app/app/views/components/hello_world.rb +11 -0
- data/spec/test_app/app/views/components/todo.rb +14 -0
- data/spec/test_app/app/views/layouts/application.html.erb +14 -0
- data/spec/test_app/app/views/layouts/explicit_layout.html.erb +0 -0
- data/spec/test_app/app/views/layouts/mailer.html.erb +13 -0
- data/spec/test_app/app/views/layouts/mailer.text.erb +1 -0
- data/spec/test_app/app/views/layouts/test_layout.html.erb +0 -0
- data/spec/test_app/bin/bundle +3 -0
- data/spec/test_app/bin/rails +4 -0
- data/spec/test_app/bin/rake +4 -0
- data/spec/test_app/bin/setup +38 -0
- data/spec/test_app/bin/update +29 -0
- data/spec/test_app/bin/yarn +11 -0
- data/spec/test_app/config.ru +5 -0
- data/spec/test_app/config/application.rb +45 -0
- data/spec/test_app/config/boot.rb +6 -0
- data/spec/test_app/config/cable.yml +10 -0
- data/spec/test_app/config/database.yml +25 -0
- data/spec/test_app/config/environment.rb +5 -0
- data/spec/test_app/config/environments/development.rb +54 -0
- data/spec/test_app/config/environments/production.rb +91 -0
- data/spec/test_app/config/environments/test.rb +42 -0
- data/spec/test_app/config/initializers/application_controller_renderer.rb +8 -0
- data/spec/test_app/config/initializers/assets.rb +14 -0
- data/spec/test_app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/test_app/config/initializers/cookies_serializer.rb +5 -0
- data/spec/test_app/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/test_app/config/initializers/inflections.rb +16 -0
- data/spec/test_app/config/initializers/mime_types.rb +4 -0
- data/spec/test_app/config/initializers/wrap_parameters.rb +14 -0
- data/spec/test_app/config/locales/en.yml +33 -0
- data/spec/test_app/config/puma.rb +56 -0
- data/spec/test_app/config/routes.rb +3 -0
- data/spec/test_app/config/secrets.yml +32 -0
- data/spec/test_app/config/spring.rb +6 -0
- data/spec/test_app/db/development.sqlite3 +0 -0
- data/spec/test_app/db/schema.rb +15 -0
- data/spec/test_app/db/seeds.rb +7 -0
- data/spec/test_app/db/test.sqlite3 +0 -0
- data/spec/test_app/lib/assets/.keep +0 -0
- data/spec/test_app/log/.keep +0 -0
- data/spec/test_app/package.json +5 -0
- data/spec/test_app/public/404.html +67 -0
- data/spec/test_app/public/422.html +67 -0
- data/spec/test_app/public/500.html +66 -0
- data/spec/test_app/public/apple-touch-icon-precomposed.png +0 -0
- data/spec/test_app/public/apple-touch-icon.png +0 -0
- data/spec/test_app/public/favicon.ico +0 -0
- data/spec/vendor/es5-shim.min.js +7 -0
- data/spec/vendor/jquery-2.2.4.min.js +4 -0
- metadata +401 -61
- data/CODE_OF_CONDUCT.md +0 -49
- data/lib/react/version.rb +0 -3
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'the React DSL', js: true do
|
|
4
|
+
|
|
5
|
+
context "render macro" do
|
|
6
|
+
|
|
7
|
+
it "can define the render method with the render macro with a html tag container" do
|
|
8
|
+
mount 'Foo' do
|
|
9
|
+
class Foo
|
|
10
|
+
include React::Component
|
|
11
|
+
render(:div, class: :foo) do
|
|
12
|
+
"hello"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
expect(page.body[-60..-19]).to include('<div class="foo">hello</div>')
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "can define the render method with the render macro without a container" do
|
|
20
|
+
mount 'Foo' do
|
|
21
|
+
class Foo
|
|
22
|
+
include React::Component
|
|
23
|
+
render do
|
|
24
|
+
"hello"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
expect(page.body[-60..-19]).to include('<span>hello</span>')
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "can define the render method with the render macro with a application defined container" do
|
|
32
|
+
on_client do
|
|
33
|
+
class Bar < React::Component::Base
|
|
34
|
+
param :p1
|
|
35
|
+
render { "hello #{params.p1}" }
|
|
36
|
+
end
|
|
37
|
+
class Foo < React::Component::Base
|
|
38
|
+
render Bar, p1: "fred"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
mount 'Foo'
|
|
42
|
+
expect(page.body[-60..-19]).to include('<span>hello fred</span>')
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "will turn the last string in a block into a element" do
|
|
47
|
+
mount 'Foo' do
|
|
48
|
+
class Foo
|
|
49
|
+
include React::Component
|
|
50
|
+
def render
|
|
51
|
+
div { "hello" }
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
expect(page.body[-60..-19]).to include('<div>hello</div>')
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "in prerender will pass converted props through event handlers" do
|
|
59
|
+
client_option render_on: :both
|
|
60
|
+
mount 'Foo' do
|
|
61
|
+
class Foo
|
|
62
|
+
include React::Component
|
|
63
|
+
def render
|
|
64
|
+
INPUT(data: {foo: 12}).on(:change) {}
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
expect(page.body).to match(/<input data-foo="12" data-reactroot="" \/>/)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "will turn the last string in a block into a element" do
|
|
72
|
+
mount 'Foo' do
|
|
73
|
+
class Foo
|
|
74
|
+
include React::Component
|
|
75
|
+
def render
|
|
76
|
+
DIV { "hello" }
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
expect(page.body[-60..-19]).to include('<div>hello</div>')
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it "has a .span short hand String method" do
|
|
84
|
+
mount 'Foo' do
|
|
85
|
+
class Foo
|
|
86
|
+
include React::Component
|
|
87
|
+
def render
|
|
88
|
+
div { "hello".span; "goodby".span }
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
expect(page.body[-70..-19]).to include('<div><span>hello</span><span>goodby</span></div>')
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it "in prerendering has a .br short hand String method" do
|
|
96
|
+
client_option render_on: :both
|
|
97
|
+
client_option raise_on_js_errors: :off
|
|
98
|
+
mount 'Foo' do
|
|
99
|
+
class Foo
|
|
100
|
+
include React::Component
|
|
101
|
+
def render
|
|
102
|
+
div { "hello".br }
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
expect(page.body[-80..-19]).to match(/(<div data-reactroot=""|<div)><span>hello<(br|br\/|br \/)><\/span><\/div>/)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it "has a .td short hand String method" do
|
|
110
|
+
mount 'Foo' do
|
|
111
|
+
class Foo
|
|
112
|
+
include React::Component
|
|
113
|
+
def render
|
|
114
|
+
table {
|
|
115
|
+
tbody {
|
|
116
|
+
tr { "hello".td }
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
expect(page.body[-90..-19]).to include('<table><tbody><tr><td>hello</td></tr></tbody></table>')
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it "has a .para short hand String method" do
|
|
126
|
+
mount 'Foo' do
|
|
127
|
+
class Foo
|
|
128
|
+
include React::Component
|
|
129
|
+
def render
|
|
130
|
+
div { "hello".para }
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
expect(page.body[-60..-19]).to include('<div><p>hello</p></div>')
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it 'can do a method call on a class name that is not a direct sibling' do
|
|
138
|
+
# this test is failing because Comp() is not serialized/compiled to a method call,
|
|
139
|
+
# but instead to a $scope.get("Comp"); which returns the Component Class Mod::Comp
|
|
140
|
+
# instead it sould serialize/compile to a $scope.$Comp();
|
|
141
|
+
# this is a bug in unparser, workaround is to pass a argument to comp
|
|
142
|
+
mount 'Mod::NestedMod::NestedComp' do
|
|
143
|
+
module Mod
|
|
144
|
+
class Comp
|
|
145
|
+
include React::Component
|
|
146
|
+
param :test
|
|
147
|
+
def render
|
|
148
|
+
"Mod::Comp"
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
module NestedMod
|
|
152
|
+
class NestedComp
|
|
153
|
+
include React::Component
|
|
154
|
+
def render
|
|
155
|
+
Comp(test: 'string')
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
expect(page.body[-60..-19]).to include('<span>Mod::Comp</span>')
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
it 'raises a meaningful error if a Constant Name is not actually a component' do
|
|
165
|
+
client_option raise_on_js_errors: :off
|
|
166
|
+
mount 'Mod::NestedMod::NestedComp' do
|
|
167
|
+
module Mod
|
|
168
|
+
module NestedMod
|
|
169
|
+
class NestedComp < React::Component::Base
|
|
170
|
+
backtrace :none
|
|
171
|
+
render do
|
|
172
|
+
Comp(test: 'string')
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
class Comp; end
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
expect(page.driver.browser.manage.logs.get(:browser).map { |m| m.message.gsub(/\\n/, "\n") }.to_a.join("\n"))
|
|
180
|
+
.to match(/Comp does not appear to be a react component./)
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
it 'raises a method missing error' do
|
|
184
|
+
client_option render_on: :both
|
|
185
|
+
client_option raise_on_js_errors: :off
|
|
186
|
+
expect_evaluate_ruby do
|
|
187
|
+
class Foo < React::Component::Base
|
|
188
|
+
backtrace :none
|
|
189
|
+
render do
|
|
190
|
+
_undefined_method
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
begin
|
|
194
|
+
React::Test::Utils.render_component_into_document(Foo)
|
|
195
|
+
'not raised'
|
|
196
|
+
rescue NoMethodError
|
|
197
|
+
'raised for sure!'
|
|
198
|
+
end
|
|
199
|
+
end.to eq('raised for sure!')
|
|
200
|
+
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
it "will treat the component class name as a first class component name" do
|
|
204
|
+
mount 'Foo' do
|
|
205
|
+
module Mod
|
|
206
|
+
class Bar
|
|
207
|
+
include React::Component
|
|
208
|
+
def render
|
|
209
|
+
"a man walks into a bar"
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
class Foo < React::Component::Base
|
|
214
|
+
def render
|
|
215
|
+
Mod::Bar()
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
expect(page.body[-60..-19]).to include('<span>a man walks into a bar</span>')
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
it "can add class names by the haml .class notation" do
|
|
223
|
+
mount 'Foo' do
|
|
224
|
+
module Mod
|
|
225
|
+
class Bar
|
|
226
|
+
include React::Component
|
|
227
|
+
collect_other_params_as :attributes
|
|
228
|
+
def render
|
|
229
|
+
"a man walks into a bar".span(params.attributes)
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
class Foo < React::Component::Base
|
|
234
|
+
def render
|
|
235
|
+
Mod::Bar().the_class.other_class
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
expect(page.body[-90..-19]).to include('<span class="other-class the-class">a man walks into a bar</span>')
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
it "can use the 'class' keyword for classes" do
|
|
243
|
+
mount 'Foo' do
|
|
244
|
+
class Foo
|
|
245
|
+
include React::Component
|
|
246
|
+
def render
|
|
247
|
+
span(class: "the-class") { "hello" }
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
expect(page.body[-60..-19]).to include('<span class="the-class">hello</span>')
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
it "can generate a unrendered node using the .as_node method" do # div { "hello" }.as_node
|
|
255
|
+
mount 'Foo' do
|
|
256
|
+
class Foo
|
|
257
|
+
include React::Component
|
|
258
|
+
def render
|
|
259
|
+
span(data: {size: 12}) { "hello".span.as_node.class.name }.as_node.render
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
expect(page.body[-80..-19]).to include('<span data-size="12">React::Element</span>')
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
it "can use the dangerously_set_inner_HTML param" do
|
|
267
|
+
mount 'Foo' do
|
|
268
|
+
class Foo
|
|
269
|
+
include React::Component
|
|
270
|
+
def render
|
|
271
|
+
div(dangerously_set_inner_HTML: { __html: "Hello and Goodby" })
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
expect(page.body[-60..-19]).to include('<div>Hello and Goodby</div>')
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
it 'should convert a hash param to hyphenated html attributes if in React::HASH_ATTRIBUTES' do
|
|
279
|
+
mount 'Foo' do
|
|
280
|
+
class Foo
|
|
281
|
+
include React::Component
|
|
282
|
+
def render
|
|
283
|
+
div(data: { foo: :bar }, aria: { label: "title" })
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
expect(page.body[-70..-19]).to include('<div data-foo="bar" aria-label="title"></div>')
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
it 'should not convert a hash param to hyphenated html attributes if not in React::HASH_ATTRIBUTES' do
|
|
291
|
+
mount 'Foo' do
|
|
292
|
+
class Foo
|
|
293
|
+
include React::Component
|
|
294
|
+
def render
|
|
295
|
+
div(title: { bar: :foo })
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
expect(page.body[-80..-19]).to include('<div title="{"bar"=>"foo"}"></div>')
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
it "will remove all elements passed as params from the rendering buffer" do
|
|
303
|
+
mount 'Foo' do
|
|
304
|
+
class X2
|
|
305
|
+
include React::Component
|
|
306
|
+
param :ele
|
|
307
|
+
def render
|
|
308
|
+
div do
|
|
309
|
+
params[:ele].render
|
|
310
|
+
params[:ele].render
|
|
311
|
+
end
|
|
312
|
+
end
|
|
313
|
+
end
|
|
314
|
+
class Foo
|
|
315
|
+
include React::Component
|
|
316
|
+
def render
|
|
317
|
+
X2(ele: b { "hello" })
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
expect(page.body[-60..-19]).to include('<div><b>hello</b><b>hello</b></div>')
|
|
322
|
+
end
|
|
323
|
+
end
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe 'React::Element', js: true do
|
|
4
|
+
it 'bridges `type` of native React.Element attributes' do
|
|
5
|
+
expect_evaluate_ruby do
|
|
6
|
+
element = React.create_element('div')
|
|
7
|
+
element.element_type
|
|
8
|
+
end.to eq("div")
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it 'is renderable' do
|
|
12
|
+
expect_evaluate_ruby do
|
|
13
|
+
element = React.create_element('span')
|
|
14
|
+
div = JS.call(:eval, 'document.createElement("div")')
|
|
15
|
+
React.render(element, div)
|
|
16
|
+
div.JS[:children].JS[0].JS[:tagName]
|
|
17
|
+
end.to eq("SPAN")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe "Event Subscription" do
|
|
21
|
+
it "keeps the original params" do
|
|
22
|
+
client_option render_on: :both
|
|
23
|
+
mount 'Foo' do
|
|
24
|
+
class Foo
|
|
25
|
+
include React::Component
|
|
26
|
+
def render
|
|
27
|
+
INPUT(value: nil, type: 'text').on(:change) {}
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
expect(page.body[-80..-19]).to match(/<input (type="text" value=""|value="" type="text").*\/>/)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
describe 'Component Event Subscription' do
|
|
36
|
+
|
|
37
|
+
it 'will subscribe to a component event param' do
|
|
38
|
+
evaluate_ruby do
|
|
39
|
+
class Foo < React::Component::Base
|
|
40
|
+
param :on_event, type: Proc, default: nil, allow_nil: true
|
|
41
|
+
def render
|
|
42
|
+
params.on_event
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
React::Test::Utils.render_into_document(React.create_element(Foo).on(:event) {'works!'})
|
|
46
|
+
end
|
|
47
|
+
expect(page.body[-50..-19]).to include('<span>works!</span>')
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'will subscribe to multiple component event params' do
|
|
51
|
+
evaluate_ruby do
|
|
52
|
+
class Foo < React::Component::Base
|
|
53
|
+
param :on_event1, type: Proc, default: nil, allow_nil: true
|
|
54
|
+
param :on_event2, type: Proc, default: nil, allow_nil: true
|
|
55
|
+
def render
|
|
56
|
+
params.on_event1+params.on_event2
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
React::Test::Utils.render_into_document(React.create_element(Foo).on(:event1, :event2) {'works!'})
|
|
60
|
+
end
|
|
61
|
+
expect(page.body[-60..-19]).to include('<span>works!works!</span>')
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it 'will subscribe to a native components event param' do
|
|
65
|
+
|
|
66
|
+
evaluate_ruby do
|
|
67
|
+
"this makes sure everything is loaded"
|
|
68
|
+
end
|
|
69
|
+
page.execute_script('window.NativeComponent = class extends React.Component {
|
|
70
|
+
constructor(props) {
|
|
71
|
+
super(props);
|
|
72
|
+
this.displayName = "HelloMessage";
|
|
73
|
+
}
|
|
74
|
+
render() { return React.createElement("span", null, this.props.onEvent()); }
|
|
75
|
+
}')
|
|
76
|
+
evaluate_ruby do
|
|
77
|
+
class Foo < React::Component::Base
|
|
78
|
+
imports "NativeComponent"
|
|
79
|
+
end
|
|
80
|
+
React::Test::Utils.render_into_document(React.create_element(Foo).on(:event) {'works!'})
|
|
81
|
+
true
|
|
82
|
+
end
|
|
83
|
+
expect(page.body[-60..-19]).to include('<span>works!</span>')
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it 'will subscribe to a component event param with a non-default name' do
|
|
87
|
+
|
|
88
|
+
evaluate_ruby do
|
|
89
|
+
class Foo < React::Component::Base
|
|
90
|
+
param :my_event, type: Proc, default: nil, allow_nil: true
|
|
91
|
+
def render
|
|
92
|
+
params.my_event
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
React::Test::Utils.render_into_document(React.create_element(Foo).on("<my_event>") {'works!'})
|
|
96
|
+
end
|
|
97
|
+
expect(page.body[-60..-19]).to include('<span>works!</span>')
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
describe 'Builtin Event subscription' do
|
|
102
|
+
it 'is subscribable through `on(:event_name)` method' do
|
|
103
|
+
expect_evaluate_ruby do
|
|
104
|
+
element = React.create_element("div").on(:click) { |event| RESULT_C = 'clicked' if event.is_a? React::Event }
|
|
105
|
+
dom_node = React::Test::Utils.render_into_document(element)
|
|
106
|
+
React::Test::Utils.simulate_click(dom_node)
|
|
107
|
+
RESULT_C rescue 'not clicked'
|
|
108
|
+
end.to eq('clicked')
|
|
109
|
+
|
|
110
|
+
expect_evaluate_ruby do
|
|
111
|
+
element = React.create_element("div").on(:key_down) { |event| RESULT_P = 'pressed' if event.is_a? React::Event }
|
|
112
|
+
dom_node = React::Test::Utils.render_into_document(element)
|
|
113
|
+
React::Test::Utils.simulate_keydown(dom_node, "Enter")
|
|
114
|
+
RESULT_P rescue 'not pressed'
|
|
115
|
+
end.to eq('pressed')
|
|
116
|
+
|
|
117
|
+
expect_evaluate_ruby do
|
|
118
|
+
element = React.create_element("form").on(:submit) { |event| RESULT_S = 'submitted' if event.is_a? React::Event }
|
|
119
|
+
dom_node = React::Test::Utils.render_into_document(element)
|
|
120
|
+
React::Test::Utils.simulate_submit(dom_node)
|
|
121
|
+
RESULT_S rescue 'not submitted'
|
|
122
|
+
end.to eq('submitted')
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it 'returns self for `on` method' do
|
|
126
|
+
expect_evaluate_ruby do
|
|
127
|
+
element = React.create_element("div")
|
|
128
|
+
element.on(:click){} == element
|
|
129
|
+
end.to be_truthy
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|