require "spec_helper" describe 'React', js: true do describe "is_valid_element?" do it "should return true if passed a valid element" do expect_evaluate_ruby do element = React::Element.new(JS.call(:eval, "React.createElement('div')")) React.is_valid_element?(element) end.to eq(true) end it "should return false is passed a non React element" do expect_evaluate_ruby do element = React::Element.new(JS.call(:eval, "{}")) React.is_valid_element?(element) end.to eq(false) end end describe "create_element" do it "should create a valid element with only tag" do expect_evaluate_ruby do element = React.create_element('div') React.is_valid_element?(element) end.to eq(true) end context "with block" do it "should create a valid element with text as only child when block yield String" do evaluate_ruby do ELEMENT = React.create_element('div') { "lorem ipsum" } end expect_evaluate_ruby("React.is_valid_element?(ELEMENT)").to eq(true) expect_evaluate_ruby("ELEMENT.props.children").to eq("lorem ipsum") end it "should create a valid element with children as array when block yield Array of element" do evaluate_ruby do ELEMENT = React.create_element('div') do [React.create_element('span'), React.create_element('span'), React.create_element('span')] end end expect_evaluate_ruby("React.is_valid_element?(ELEMENT)").to eq(true) expect_evaluate_ruby("ELEMENT.props.children.length").to eq(3) end it "should render element with children as array when block yield Array of element" do expect_evaluate_ruby do element = React.create_element('div') do [React.create_element('span'), React.create_element('span'), React.create_element('span')] end dom_node = React::Test::Utils.render_into_document(element) dom_node.JS[:children].JS[:length] end.to eq(3) end end describe "custom element" do before :each do on_client do class Foo < React::Component::Base def initialize(native) @native = native end def render React.create_element("div") { "lorem" } end def props Hash.new(@native.JS[:props]) end end end end it "should render element with only one children correctly" do evaluate_ruby do element = React.create_element(Foo) { React.create_element('span') } INSTANCE = React::Test::Utils.render_into_document(element) true end expect_evaluate_ruby("INSTANCE.props[:children].is_a?(Array)").to be_falsy expect_evaluate_ruby("INSTANCE.props[:children][:type]").to eq("span") end it "should render element with more than one children correctly" do evaluate_ruby do element = React.create_element(Foo) { [React.create_element('span'), React.create_element('span')] } INSTANCE = React::Test::Utils.render_into_document(element) true end expect_evaluate_ruby("INSTANCE.props[:children].is_a?(Array)").to be_truthy expect_evaluate_ruby("INSTANCE.props[:children].length").to eq(2) end it "should create a valid element provided class defined `render`" do expect_evaluate_ruby do element = React.create_element(Foo) React.is_valid_element?(element) end.to eq(true) end it "should allow creating with properties" do expect_evaluate_ruby do Foo.class_eval do param :foo end element = React.create_element(Foo, foo: "bar") element.props.foo end.to eq("bar") end it "should raise error if provided class doesn't defined `render`" do expect_evaluate_ruby do begin React.create_element(Array) rescue 'failed' end end.to eq('failed') end it "should use the same instance for the same ReactComponent" do mount 'Foo' do Foo.class_eval do attr_accessor :a def initialize(n) self.a = 10 end def component_will_mount self.a = 20 end def render React.create_element("div") { self.a.to_s } end end end expect(page.body[-60..-19]).to include("