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.
- checksums.yaml +4 -4
- data/.codeclimate.yml +24 -3
- data/.gitignore +3 -0
- data/.rubocop.yml +1154 -3
- data/.travis.yml +20 -0
- data/Appraisals +20 -0
- data/CHANGELOG.md +28 -3
- data/Gemfile +4 -5
- data/README.md +6 -9
- data/Rakefile +6 -1
- data/config.ru +7 -6
- 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/lib/generators/reactive_ruby/test_app/templates/assets/javascripts/components.rb +1 -1
- data/lib/rails-helpers/top_level_rails_component.rb +1 -1
- data/lib/react-sources/react-server.js +2 -0
- data/lib/react/api.rb +13 -12
- data/lib/react/children.rb +30 -0
- data/lib/react/component.rb +27 -46
- data/lib/react/component/class_methods.rb +28 -32
- data/lib/react/component/dsl_instance_methods.rb +4 -34
- data/lib/react/component/params.rb +6 -0
- data/lib/react/component/props_wrapper.rb +22 -27
- data/lib/react/component/should_component_update.rb +98 -0
- data/lib/react/component/tags.rb +45 -4
- data/lib/react/element.rb +26 -13
- data/lib/react/object.rb +15 -0
- data/lib/react/react-source.rb +9 -0
- data/lib/react/rendering_context.rb +97 -93
- data/lib/react/state.rb +27 -21
- 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 +50 -14
- data/lib/react/validator.rb +5 -5
- data/lib/reactive-ruby/isomorphic_helpers.rb +0 -7
- data/lib/reactive-ruby/version.rb +1 -1
- data/lib/reactrb.rb +14 -14
- data/lib/reactrb/deep-compare.rb +24 -0
- data/lib/sources/react-latest.js +2 -0
- data/lib/sources/react-v13.js +4 -1
- data/lib/sources/react-v14.js +3 -84
- data/lib/sources/react-v15.js +3 -0
- data/logo1.png +0 -0
- data/logo2.png +0 -0
- data/logo3.png +0 -0
- data/path_release_steps.md +1 -1
- data/reactrb.gemspec +2 -3
- data/spec/react/children_spec.rb +76 -0
- data/spec/react/component/base_spec.rb +3 -7
- data/spec/react/component_spec.rb +181 -60
- data/spec/react/dsl_spec.rb +26 -19
- data/spec/react/element_spec.rb +16 -1
- data/spec/react/native_library_spec.rb +20 -0
- data/spec/react/opal_jquery_extensions_spec.rb +27 -0
- data/spec/react/param_declaration_spec.rb +47 -78
- data/spec/react/react_spec.rb +7 -9
- data/spec/react/state_spec.rb +29 -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 +33 -5
- data/spec/react/tutorial/tutorial_spec.rb +5 -5
- data/spec/react/validator_spec.rb +10 -13
- data/spec/reactive-ruby/component_loader_spec.rb +3 -0
- data/spec/reactive-ruby/rails/asset_pipeline_spec.rb +5 -4
- data/spec/spec_helper.rb +6 -3
- data/spec/support/react/spec_helpers.rb +9 -2
- metadata +47 -124
- data/example/examples/Gemfile +0 -7
- data/example/examples/app/basics.js.rb +0 -42
- data/example/examples/app/items.rb +0 -11
- data/example/examples/app/jquery.js +0 -5
- data/example/examples/app/nodes.rb +0 -61
- data/example/examples/app/react-router.js +0 -6
- data/example/examples/app/react_api_demo.rb +0 -29
- data/example/examples/app/rerendering.rb +0 -72
- data/example/examples/app/reuse.rb +0 -59
- data/example/examples/app/show.rb +0 -52
- data/example/examples/config.ru +0 -38
- data/example/rails-tutorial/.gitignore +0 -17
- data/example/rails-tutorial/Gemfile +0 -51
- data/example/rails-tutorial/README.rdoc +0 -28
- data/example/rails-tutorial/Rakefile +0 -6
- data/example/rails-tutorial/app/assets/images/.keep +0 -0
- data/example/rails-tutorial/app/assets/javascripts/application.rb +0 -15
- data/example/rails-tutorial/app/assets/stylesheets/application.css +0 -15
- data/example/rails-tutorial/app/controllers/application_controller.rb +0 -6
- data/example/rails-tutorial/app/controllers/concerns/.keep +0 -0
- data/example/rails-tutorial/app/controllers/home_controller.rb +0 -6
- data/example/rails-tutorial/app/helpers/application_helper.rb +0 -2
- data/example/rails-tutorial/app/mailers/.keep +0 -0
- data/example/rails-tutorial/app/models/.keep +0 -0
- data/example/rails-tutorial/app/models/concerns/.keep +0 -0
- data/example/rails-tutorial/app/views/components.rb +0 -3
- data/example/rails-tutorial/app/views/components/home/show.rb +0 -47
- data/example/rails-tutorial/app/views/layouts/application.html.erb +0 -14
- data/example/rails-tutorial/bin/bundle +0 -3
- data/example/rails-tutorial/bin/rails +0 -8
- data/example/rails-tutorial/bin/rake +0 -8
- data/example/rails-tutorial/bin/setup +0 -29
- data/example/rails-tutorial/bin/spring +0 -15
- data/example/rails-tutorial/config.ru +0 -4
- data/example/rails-tutorial/config/application.rb +0 -26
- data/example/rails-tutorial/config/boot.rb +0 -3
- data/example/rails-tutorial/config/database.yml +0 -25
- data/example/rails-tutorial/config/environment.rb +0 -5
- data/example/rails-tutorial/config/environments/development.rb +0 -41
- data/example/rails-tutorial/config/environments/production.rb +0 -79
- data/example/rails-tutorial/config/environments/test.rb +0 -42
- data/example/rails-tutorial/config/initializers/assets.rb +0 -11
- data/example/rails-tutorial/config/initializers/backtrace_silencers.rb +0 -7
- data/example/rails-tutorial/config/initializers/cookies_serializer.rb +0 -3
- data/example/rails-tutorial/config/initializers/filter_parameter_logging.rb +0 -4
- data/example/rails-tutorial/config/initializers/inflections.rb +0 -16
- data/example/rails-tutorial/config/initializers/mime_types.rb +0 -4
- data/example/rails-tutorial/config/initializers/session_store.rb +0 -3
- data/example/rails-tutorial/config/initializers/wrap_parameters.rb +0 -14
- data/example/rails-tutorial/config/locales/en.yml +0 -23
- data/example/rails-tutorial/config/routes.rb +0 -59
- data/example/rails-tutorial/config/secrets.yml +0 -22
- data/example/rails-tutorial/db/seeds.rb +0 -7
- data/example/rails-tutorial/lib/assets/.keep +0 -0
- data/example/rails-tutorial/lib/tasks/.keep +0 -0
- data/example/rails-tutorial/log/.keep +0 -0
- data/example/rails-tutorial/public/404.html +0 -67
- data/example/rails-tutorial/public/422.html +0 -67
- data/example/rails-tutorial/public/500.html +0 -66
- data/example/rails-tutorial/public/favicon.ico +0 -0
- data/example/rails-tutorial/public/robots.txt +0 -5
- data/example/rails-tutorial/test/controllers/.keep +0 -0
- data/example/rails-tutorial/test/fixtures/.keep +0 -0
- data/example/rails-tutorial/test/helpers/.keep +0 -0
- data/example/rails-tutorial/test/integration/.keep +0 -0
- data/example/rails-tutorial/test/mailers/.keep +0 -0
- data/example/rails-tutorial/test/models/.keep +0 -0
- data/example/rails-tutorial/test/test_helper.rb +0 -10
- data/example/rails-tutorial/vendor/assets/javascripts/.keep +0 -0
- data/example/rails-tutorial/vendor/assets/stylesheets/.keep +0 -0
- data/example/sinatra-tutorial/.DS_Store +0 -0
- data/example/sinatra-tutorial/Gemfile +0 -5
- data/example/sinatra-tutorial/README.md +0 -8
- data/example/sinatra-tutorial/_comments.json +0 -42
- data/example/sinatra-tutorial/app/example.rb +0 -290
- data/example/sinatra-tutorial/app/jquery.js +0 -5
- data/example/sinatra-tutorial/config.ru +0 -58
- data/example/sinatra-tutorial/public/base.css +0 -62
- data/example/todos/Gemfile +0 -11
- data/example/todos/README.md +0 -37
- data/example/todos/Rakefile +0 -8
- data/example/todos/app/application.rb +0 -22
- data/example/todos/app/components/app.react.rb +0 -61
- data/example/todos/app/components/footer.react.rb +0 -31
- data/example/todos/app/components/todo_item.react.rb +0 -46
- data/example/todos/app/components/todo_list.react.rb +0 -25
- data/example/todos/app/models/todo.rb +0 -19
- data/example/todos/config.ru +0 -14
- data/example/todos/index.html.haml +0 -16
- data/example/todos/spec/todo_spec.rb +0 -28
- data/example/todos/vendor/base.css +0 -410
- data/example/todos/vendor/bg.png +0 -0
- data/example/todos/vendor/jquery.js +0 -4
data/spec/react/element_spec.rb
CHANGED
|
@@ -19,6 +19,20 @@ describe React::Element do
|
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
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
|
+
|
|
22
36
|
describe 'Component Event Subscription' do
|
|
23
37
|
|
|
24
38
|
it 'will subscribe to a component event param' do
|
|
@@ -87,7 +101,8 @@ describe React::Element do
|
|
|
87
101
|
}
|
|
88
102
|
expect(React.render_to_static_markup(React.create_element(Foo).on(:event) {'works!'})).to eq('<span>works!</span>')
|
|
89
103
|
`window.console.warn = org_warn_console; window.console.error = org_error_console;`
|
|
90
|
-
expect(`log`).to
|
|
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>')")
|
|
91
106
|
end
|
|
92
107
|
end
|
|
93
108
|
|
|
@@ -65,6 +65,26 @@ describe "React::NativeLibrary" do
|
|
|
65
65
|
React.create_element(Foo::NativeComponent, name: "There"))).to eq('<div>Hello There</div>')
|
|
66
66
|
end
|
|
67
67
|
|
|
68
|
+
it "will import a nested React.js library into the Ruby name space" do
|
|
69
|
+
%x{
|
|
70
|
+
window.NativeLibrary = {
|
|
71
|
+
NestedLibrary: {
|
|
72
|
+
NativeComponent: React.createClass({
|
|
73
|
+
displayName: "HelloMessage",
|
|
74
|
+
render: function render() {
|
|
75
|
+
return React.createElement("div", null, "Hello ", this.props.name);
|
|
76
|
+
}
|
|
77
|
+
})}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
stub_const 'Foo', Class.new(React::NativeLibrary)
|
|
81
|
+
Foo.class_eval do
|
|
82
|
+
imports "NativeLibrary"
|
|
83
|
+
end
|
|
84
|
+
expect(React.render_to_static_markup(
|
|
85
|
+
React.create_element(Foo::NestedLibrary::NativeComponent, name: "There"))).to eq('<div>Hello There</div>')
|
|
86
|
+
end
|
|
87
|
+
|
|
68
88
|
it "will rename an imported a React.js component" do
|
|
69
89
|
%x{
|
|
70
90
|
window.NativeLibrary = {
|
|
@@ -6,6 +6,27 @@ describe 'Element' do
|
|
|
6
6
|
React::API.clear_component_class_cache
|
|
7
7
|
end
|
|
8
8
|
|
|
9
|
+
it 'will reuse the wrapper componet class for the same Element' do
|
|
10
|
+
stub_const 'Foo', Class.new(React::Component::Base)
|
|
11
|
+
Foo.class_eval do
|
|
12
|
+
param :name
|
|
13
|
+
def render
|
|
14
|
+
"hello #{params.name}"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def component_will_unmount
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
expect_any_instance_of(Foo).to_not receive(:component_will_unmount)
|
|
23
|
+
|
|
24
|
+
test_div = Element.new(:div)
|
|
25
|
+
test_div.render { Foo(name: 'fred') }
|
|
26
|
+
test_div.render { Foo(name: 'freddy') }
|
|
27
|
+
expect(Element[test_div].find('span').html).to eq('hello freddy')
|
|
28
|
+
end
|
|
29
|
+
|
|
9
30
|
it 'renders a top level component using render with a block' do
|
|
10
31
|
stub_const 'Foo', Class.new(React::Component::Base)
|
|
11
32
|
Foo.class_eval do
|
|
@@ -35,5 +56,11 @@ describe 'Element' do
|
|
|
35
56
|
|
|
36
57
|
expect(Element[renderToDocument(Foo)].html).to eq('hello')
|
|
37
58
|
end
|
|
59
|
+
|
|
60
|
+
it "accepts plain js object as selector" do
|
|
61
|
+
expect {
|
|
62
|
+
Element[`window`]
|
|
63
|
+
}.not_to raise_error
|
|
64
|
+
end
|
|
38
65
|
end
|
|
39
66
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
if opal?
|
|
4
|
-
describe 'the param macro' do
|
|
4
|
+
describe 'the param macro', type: :component do
|
|
5
5
|
it 'defines collect_other_params_as method on params proxy' do
|
|
6
6
|
stub_const 'Foo', Class.new(React::Component::Base)
|
|
7
7
|
Foo.class_eval do
|
|
@@ -12,36 +12,7 @@ describe 'the param macro' do
|
|
|
12
12
|
end
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
expect(html).to eq('<div>biz</div>')
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
it 'still defines deprecated collect_other_params_as method' do
|
|
20
|
-
stub_const 'Foo', Class.new(React::Component::Base)
|
|
21
|
-
Foo.class_eval do
|
|
22
|
-
collect_other_params_as :foo
|
|
23
|
-
|
|
24
|
-
def render
|
|
25
|
-
div { foo[:bar] }
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
html = React.render_to_static_markup(React.create_element(Foo, { bar: 'biz' }))
|
|
30
|
-
expect(html).to eq('<div>biz</div>')
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
it 'still defines deprecated param accessor method' do
|
|
34
|
-
stub_const 'Foo', Class.new(React::Component::Base)
|
|
35
|
-
Foo.class_eval do
|
|
36
|
-
param :foo
|
|
37
|
-
|
|
38
|
-
def render
|
|
39
|
-
div { foo }
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
html = React.render_to_static_markup(React.create_element(Foo, {foo: :bar}))
|
|
44
|
-
expect(html).to eq('<div>bar</div>')
|
|
15
|
+
expect(Foo).to render('<div>biz</div>').with_params(bar: 'biz')
|
|
45
16
|
end
|
|
46
17
|
|
|
47
18
|
it "can create and access a required param" do
|
|
@@ -54,7 +25,7 @@ describe 'the param macro' do
|
|
|
54
25
|
end
|
|
55
26
|
end
|
|
56
27
|
|
|
57
|
-
expect(
|
|
28
|
+
expect(Foo).to render('<div>bar</div>').with_params(foo: :bar)
|
|
58
29
|
end
|
|
59
30
|
|
|
60
31
|
it "can create and access an optional params" do
|
|
@@ -71,7 +42,7 @@ describe 'the param macro' do
|
|
|
71
42
|
end
|
|
72
43
|
end
|
|
73
44
|
|
|
74
|
-
expect(
|
|
45
|
+
expect(Foo).to render('<div>bar1-no_bar2-bar3-no_bar4</div>').with_params(foo1: :bar1, foo3: :bar3)
|
|
75
46
|
end
|
|
76
47
|
|
|
77
48
|
it 'can specify validation rules with the type option' do
|
|
@@ -95,7 +66,7 @@ describe 'the param macro' do
|
|
|
95
66
|
end
|
|
96
67
|
end
|
|
97
68
|
|
|
98
|
-
expect(
|
|
69
|
+
expect(Foo).to render('<div>12-string</div>').with_params(foo1: 12, foo2: "string")
|
|
99
70
|
end
|
|
100
71
|
|
|
101
72
|
it 'logs error in warning if validation failed' do
|
|
@@ -117,7 +88,7 @@ describe 'the param macro' do
|
|
|
117
88
|
renderToDocument(Foo2, bar: 10, lorem: Lorem.new)
|
|
118
89
|
`window.console.warn = org_warn_console; window.console.error = org_error_console;`
|
|
119
90
|
|
|
120
|
-
expect(`log`).to
|
|
91
|
+
expect(`log[0]`).to match(/Warning: Failed prop( type|Type): In component `Foo2`\nRequired prop `foo` was not specified\nProvided prop `bar` could not be converted to String/)
|
|
121
92
|
end
|
|
122
93
|
|
|
123
94
|
it 'should not log anything if validation passes' do
|
|
@@ -163,7 +134,7 @@ describe 'the param macro' do
|
|
|
163
134
|
param :bar, type: []
|
|
164
135
|
end
|
|
165
136
|
renderToDocument(Foo, foo: 10, bar: [10])
|
|
166
|
-
expect(`window.dummy_log`).to
|
|
137
|
+
expect(`window.dummy_log[0]`).to match(/Warning: Failed prop( type|Type): In component `Foo`\nProvided prop `foo` could not be converted to Array/)
|
|
167
138
|
end
|
|
168
139
|
|
|
169
140
|
it "can use the [xxx] notation for arrays of a specific type" do
|
|
@@ -172,7 +143,7 @@ describe 'the param macro' do
|
|
|
172
143
|
param :bar, type: [String]
|
|
173
144
|
end
|
|
174
145
|
renderToDocument(Foo, foo: [10], bar: ["10"])
|
|
175
|
-
expect(`window.dummy_log`).to
|
|
146
|
+
expect(`window.dummy_log[0]`).to match(/Warning: Failed prop( type|Type): In component `Foo`\nProvided prop `foo`\[0\] could not be converted to String/)
|
|
176
147
|
end
|
|
177
148
|
|
|
178
149
|
it "can convert a json hash to a type" do
|
|
@@ -194,13 +165,13 @@ describe 'the param macro' do
|
|
|
194
165
|
"#{params.bar.kind}, #{params.baz[0].kind}"
|
|
195
166
|
end
|
|
196
167
|
end
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
expect(
|
|
168
|
+
|
|
169
|
+
params = { foo: "", bar: { bazwoggle: 1 }, baz: [{ bazwoggle: 2 }] }
|
|
170
|
+
expect(Foo).to render('<span>1, 2</span>').with_params(params)
|
|
171
|
+
expect(`window.dummy_log[0]`).to match(/Warning: Failed prop( type|Type): In component `Foo`\nProvided prop `foo` could not be converted to BazWoggle/)
|
|
200
172
|
end
|
|
201
173
|
|
|
202
174
|
describe "converts params only once" do
|
|
203
|
-
|
|
204
175
|
it "not on every access" do
|
|
205
176
|
stub_const "BazWoggle", Class.new
|
|
206
177
|
BazWoggle.class_eval do
|
|
@@ -222,41 +193,39 @@ describe 'the param macro' do
|
|
|
222
193
|
expect(React.render_to_static_markup(React.create_element(Foo, foo: {bazwoggle: 1}))).to eq('<span>2</span>')
|
|
223
194
|
end
|
|
224
195
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
# expect(`div.children[0].innerHTML`).to eq("updated")
|
|
259
|
-
# end
|
|
196
|
+
it "even if contains an embedded native object" do
|
|
197
|
+
pending 'Fix after merging'
|
|
198
|
+
stub_const "Bar", Class.new(React::Component::Base)
|
|
199
|
+
stub_const "BazWoggle", Class.new
|
|
200
|
+
BazWoggle.class_eval do
|
|
201
|
+
def initialize(kind)
|
|
202
|
+
@kind = kind
|
|
203
|
+
end
|
|
204
|
+
attr_accessor :kind
|
|
205
|
+
def self._react_param_conversion(json, validate_only)
|
|
206
|
+
new(JSON.from_object(json[0])[:bazwoggle]) if JSON.from_object(json[0])[:bazwoggle]
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
Bar.class_eval do
|
|
210
|
+
param :foo, type: BazWoggle
|
|
211
|
+
def render
|
|
212
|
+
params.foo.kind.to_s
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
Foo.class_eval do
|
|
216
|
+
export_state :change_me
|
|
217
|
+
before_mount do
|
|
218
|
+
Foo.change_me! "initial"
|
|
219
|
+
end
|
|
220
|
+
def render
|
|
221
|
+
Bar(foo: Native([`{bazwoggle: #{Foo.change_me}}`]))
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
div = `document.createElement("div")`
|
|
225
|
+
React.render(React.create_element(Foo, {}), div)
|
|
226
|
+
Foo.change_me! "updated"
|
|
227
|
+
expect(`div.children[0].innerHTML`).to eq("updated")
|
|
228
|
+
end
|
|
260
229
|
end
|
|
261
230
|
|
|
262
231
|
it "will alias a Proc type param" do
|
|
@@ -266,7 +235,7 @@ describe 'the param macro' do
|
|
|
266
235
|
params.foo
|
|
267
236
|
end
|
|
268
237
|
end
|
|
269
|
-
expect(
|
|
238
|
+
expect(Foo).to render('<span>works!</span>').with_params(foo: lambda { 'works!' })
|
|
270
239
|
end
|
|
271
240
|
|
|
272
241
|
it "will create a 'bang' (i.e. update) method if the type is React::Observable" do
|
|
@@ -281,7 +250,7 @@ describe 'the param macro' do
|
|
|
281
250
|
end
|
|
282
251
|
current_state = ""
|
|
283
252
|
observer = React::Observable.new(current_state) { |new_state| current_state = new_state }
|
|
284
|
-
expect(
|
|
253
|
+
expect(Foo).to render('<span>ha!</span>').with_params(foo: observer)
|
|
285
254
|
expect(current_state).to eq("ha!")
|
|
286
255
|
end
|
|
287
256
|
end
|
data/spec/react/react_spec.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require "spec_helper"
|
|
2
2
|
|
|
3
3
|
if opal?
|
|
4
|
-
describe React do
|
|
4
|
+
RSpec.describe React, type: :component do
|
|
5
5
|
after(:each) do
|
|
6
6
|
React::API.clear_component_class_cache
|
|
7
7
|
end
|
|
@@ -102,7 +102,7 @@ describe React do
|
|
|
102
102
|
end
|
|
103
103
|
end
|
|
104
104
|
|
|
105
|
-
expect(
|
|
105
|
+
expect(Foo).to render("<div>20</div>")
|
|
106
106
|
end
|
|
107
107
|
|
|
108
108
|
it "should match the instance cycle to ReactComponent life cycle" do
|
|
@@ -142,13 +142,11 @@ describe React do
|
|
|
142
142
|
end
|
|
143
143
|
|
|
144
144
|
describe "class_name helpers (React.addons.classSet)" do
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
# expect(element.props.className).to eq("foo lorem")
|
|
151
|
-
# end
|
|
145
|
+
it "should transform Hash provided to `class_name` props as string", v13_only: true do
|
|
146
|
+
classes = {foo: true, bar: false, lorem: true}
|
|
147
|
+
element = React.create_element("div", class_name: classes)
|
|
148
|
+
expect(element.props.className).to eq("foo lorem")
|
|
149
|
+
end
|
|
152
150
|
|
|
153
151
|
it "should not alter behavior when passing a string" do
|
|
154
152
|
element = React.create_element("div", class_name: "foo bar")
|
data/spec/react/state_spec.rb
CHANGED
|
@@ -22,5 +22,34 @@ describe 'React::State' do
|
|
|
22
22
|
# React::State.set_state(object, attribute, value) +
|
|
23
23
|
# React::State.get_state(object, attribute)
|
|
24
24
|
it "can be accessed outside of react using get/set_state"
|
|
25
|
+
|
|
26
|
+
it 'ignores state updates during rendering' do
|
|
27
|
+
stub_const 'StateTest', Class.new(React::Component::Base)
|
|
28
|
+
StateTest.class_eval do
|
|
29
|
+
export_state :boom
|
|
30
|
+
before_mount do
|
|
31
|
+
# force boom to be on the observing list during the current rendering cycle
|
|
32
|
+
StateTest.boom! !StateTest.boom
|
|
33
|
+
# this is automatically called by after_mount / after_update, but we don't want
|
|
34
|
+
# to have to setup a complicated async test, so we just force it now.
|
|
35
|
+
# if we don't do this, then updating boom will have no effect on the first render
|
|
36
|
+
React::State.update_states_to_observe
|
|
37
|
+
end
|
|
38
|
+
def render
|
|
39
|
+
(StateTest.boom ? "Boom" : "No Boom").tap { StateTest.boom! !StateTest.boom }
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
%x{
|
|
43
|
+
var log = [];
|
|
44
|
+
var org_warn_console = window.console.warn;
|
|
45
|
+
var org_error_console = window.console.error;
|
|
46
|
+
window.console.warn = window.console.error = function(str){log.push(str)}
|
|
47
|
+
}
|
|
48
|
+
markup = React.render_to_static_markup(React.create_element(StateTest))
|
|
49
|
+
`window.console.warn = org_warn_console; window.console.error = org_error_console;`
|
|
50
|
+
expect(markup).to eq('<span>Boom</span>')
|
|
51
|
+
expect(StateTest.boom).to be_falsy
|
|
52
|
+
expect(`log`).to eq([])
|
|
53
|
+
end
|
|
25
54
|
end
|
|
26
55
|
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
if opal?
|
|
4
|
+
RSpec.describe React::Test::DSL do
|
|
5
|
+
describe 'the DSL' do
|
|
6
|
+
let(:session) { Class.new { include React::Test::DSL }.new }
|
|
7
|
+
|
|
8
|
+
before do
|
|
9
|
+
React::Test.reset_session!
|
|
10
|
+
|
|
11
|
+
stub_const 'Greeter', Class.new
|
|
12
|
+
Greeter.class_eval do
|
|
13
|
+
include React::Component
|
|
14
|
+
|
|
15
|
+
params do
|
|
16
|
+
optional :message
|
|
17
|
+
optional :from
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def render
|
|
21
|
+
span { "Hello #{params.message}" }
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'is possible to include it in another class' do
|
|
27
|
+
session.mount(Greeter)
|
|
28
|
+
expect(session.instance).to be_a(Greeter)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "should provide a 'component' shortcut for more expressive tests" do
|
|
32
|
+
session.component.mount(Greeter)
|
|
33
|
+
expect(session.component.instance).to be_a(Greeter)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
React::Test::Session::DSL_METHODS.each do |method|
|
|
37
|
+
it "responds to all DSL method: #{method}" do
|
|
38
|
+
expect(session).to respond_to(method)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
if opal?
|
|
4
|
+
describe React::Test::Matchers::RenderHTMLMatcher do
|
|
5
|
+
let(:component) {
|
|
6
|
+
Class.new do
|
|
7
|
+
include React::Component
|
|
8
|
+
params do
|
|
9
|
+
optional :string
|
|
10
|
+
end
|
|
11
|
+
def render
|
|
12
|
+
div do
|
|
13
|
+
span { params.string } if params.string
|
|
14
|
+
'lorem'
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
}
|
|
19
|
+
let(:expected) { '<div>lorem</div>' }
|
|
20
|
+
let(:matcher) { described_class.new(expected) }
|
|
21
|
+
|
|
22
|
+
describe '#matches?' do
|
|
23
|
+
it 'is truthy when rendered component html equals expected html' do
|
|
24
|
+
expect(matcher.matches?(component)).to be_truthy
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'is falsey when rendered component html does not equal expected html' do
|
|
28
|
+
matcher = described_class.new('foo')
|
|
29
|
+
expect(matcher.matches?(component)).to be_falsey
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
describe '#with_params' do
|
|
34
|
+
let(:expected) { '<div><span>str</span>lorem</div>' }
|
|
35
|
+
|
|
36
|
+
it 'renders the component with the given params' do
|
|
37
|
+
matcher.with_params(string: 'str')
|
|
38
|
+
expect(matcher.matches?(component)).to be_truthy
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe '#failure_message' do
|
|
43
|
+
let(:expected) { '<div><span>str</span>lorem</div>' }
|
|
44
|
+
|
|
45
|
+
it 'includes the name of the component' do
|
|
46
|
+
stub_const 'Foo', component
|
|
47
|
+
matcher.matches?(Foo)
|
|
48
|
+
expect(matcher.failure_message).to match(/expected 'Foo'/)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it 'includes the params hash' do
|
|
52
|
+
matcher.with_params(string: 'bar')
|
|
53
|
+
matcher.matches?(component)
|
|
54
|
+
expect(matcher.failure_message).to match(/with params '{"string"=>"bar"}'/)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it 'includes the expected html value' do
|
|
58
|
+
matcher.matches?(component)
|
|
59
|
+
expect(matcher.failure_message).to match(/to render '#{expected}'/)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'includes the actual html value' do
|
|
63
|
+
actual = '<div>lorem<\/div>'
|
|
64
|
+
matcher.matches?(component)
|
|
65
|
+
expect(matcher.failure_message).to match(/, but '#{actual}' was rendered/)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'does not include "to not render"' do
|
|
69
|
+
matcher.matches?(component)
|
|
70
|
+
expect(matcher.failure_message).to_not match(/to not render/)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
describe '#negative_failure_message' do
|
|
75
|
+
let(:expected) { '<div><span>str</span>lorem</div>' }
|
|
76
|
+
|
|
77
|
+
it 'includes "to not render"' do
|
|
78
|
+
matcher.matches?(component)
|
|
79
|
+
expect(matcher.negative_failure_message).to match(/to not render/)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|