Module: RSpec::React::ComponentHelpers

Defined in:
lib/rspec/react/component_helpers.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(klass) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/rspec/react/component_helpers.rb', line 19

def self.included(klass)
  include Capybara::RSpecMatchers

  Tilt::ReactTemplate.load_context(RSpec::React.js_libs)

  klass.around do |example|
    group = example.[:example_group]
    loop do
      break if group[:parent_example_group].nil?
      group = group[:parent_example_group]
    end

    component = group[:description]
    snake_cased = component.gsub(/::/, '/').
      gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
      gsub(/([a-z\d])([A-Z])/,'\1_\2').
      tr("-", "_").
      downcase
    filename = File.expand_path("#{snake_cased}.jsx", RSpec::React.components)

    Tilt::ReactTemplate.compile(filename)
    @template = Tilt::ReactTemplate.new(filename)
    
    example.run
  end

  klass.subject(:rendered_component) { html_from_component(props) }
end

Instance Method Details

#html_from_component(props = {}) ⇒ Nokogiri::XML::Element

Renders the component defined in the describe block using the given props blob.

This returns a Nokogiri element, so you can do the following to make your tests clean:

let(:props) { { name: 'JP' } }
subject { html_from_component(props) }
its(:content) { should include('JP') }

Returns:

  • (Nokogiri::XML::Element)

    The (necessarily singular) root HTML element that the component returns as a parsed XML object



57
58
59
60
61
62
# File 'lib/rspec/react/component_helpers.rb', line 57

def html_from_component(props = {})
  fragment = Nokogiri::HTML.fragment(@template.render(nil, props))

  # React components can only ever have one top-level element, so we just return that
  fragment.children.first
end