Skip to content
This repository was archived by the owner on Oct 19, 2018. It is now read-only.

Commit b24de9f

Browse files
committed
extract children collection into it’s own class
1 parent dc0fd73 commit b24de9f

File tree

4 files changed

+115
-41
lines changed

4 files changed

+115
-41
lines changed

lib/react/children.rb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
module React
2+
class Children
3+
include Enumerable
4+
attr_reader :children
5+
6+
def initialize(children)
7+
@children = children
8+
end
9+
10+
def each(&block)
11+
return to_enum(__callee__) { length } unless block_given?
12+
return [] unless length > 0
13+
collection = []
14+
%x{
15+
React.Children.forEach(#{children}, function(context){
16+
#{
17+
element = React::Element.new(`context`)
18+
block.call(element)
19+
collection << element
20+
}
21+
})
22+
}
23+
collection
24+
end
25+
26+
def length
27+
@length ||= `React.Children.count(#{children})`
28+
end
29+
alias_method :size, :length
30+
end
31+
end

lib/react/component.rb

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
require 'react/ext/hash'
33
require 'active_support/core_ext/class/attribute'
44
require 'react/callbacks'
5+
require 'react/children'
56
require 'react/rendering_context'
67
require 'react/observable'
78
require 'react/state'
@@ -61,35 +62,7 @@ def render
6162
end unless method_defined?(:render)
6263

6364
def children
64-
nodes = [`#{@native}.props.children`].flatten
65-
class << nodes
66-
include Enumerable
67-
68-
def to_n
69-
self
70-
end
71-
72-
def each(&block)
73-
if block_given?
74-
%x{
75-
React.Children.forEach(#{self.to_n}, function(context){
76-
#{block.call(React::Element.new(`context`))}
77-
})
78-
}
79-
nil
80-
else
81-
Enumerator.new(`React.Children.count(#{self.to_n})`) do |y|
82-
%x{
83-
React.Children.forEach(#{self.to_n}, function(context){
84-
#{y << React::Element.new(`context`)}
85-
})
86-
}
87-
end
88-
end
89-
end
90-
end
91-
92-
nodes
65+
Children.new(`#{@native}.props.children`)
9366
end
9467

9568
def params

spec/react/children_spec.rb

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
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+
renderElementToDocument(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

spec/react/component_spec.rb

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -687,23 +687,17 @@ def render
687687
end
688688
end
689689

690-
it 'returns an Enumerable' do
690+
it 'returns React::Children collection with child elements' do
691691
ele = React.create_element(Foo) {
692692
[React.create_element('a'), React.create_element('li')]
693693
}
694694
renderElementToDocument(ele)
695-
nodes = Foo.the_children.map { |ele| ele.element_type }
696-
expect(nodes).to eq(['a', 'li'])
697-
end
698695

699-
it 'returns an Enumerator when not providing a block' do
700-
ele = React.create_element(Foo) {
701-
[React.create_element('a'), React.create_element('li')]
702-
}
703-
renderElementToDocument(ele)
704-
nodes = Foo.the_children.each
705-
expect(nodes).to be_a(Enumerator)
706-
expect(nodes.size).to eq(2)
696+
children = Foo.the_children
697+
698+
expect(children).to be_a(React::Children)
699+
expect(children.size).to eq(2)
700+
expect(children.map(&:element_type)).to eq(['a', 'li'])
707701
end
708702
end
709703
end

0 commit comments

Comments
 (0)