Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change assert_dom to scope with NodeSet #94

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Expand Up @@ -44,6 +44,11 @@ css_select '.hello' # => Nokogiri::XML::NodeSet of elements with hello class
# select from a supplied node. assert_dom asserts elements exist.
assert_dom document_root_element.at('.hello'), '.goodbye'

# explicitly modifies the document_root_element for the supplied node and block
assert_dom document_root_element.at('.hello') do
assert_dom 'p', 'Hello!'
end

# elements in CDATA encoded sections can also be selected
assert_dom_encoded '#out-of-your-element'

Expand Down
14 changes: 14 additions & 0 deletions lib/rails/dom/testing/assertions/selector_assertions.rb
Expand Up @@ -160,6 +160,16 @@ def css_select(*args)
# assert_dom "form input" do
# assert_dom ":match('name', ?)", /.+/ # Not empty
# end
#
# # move the document_root_element to a node
# assert_dom document_root_element.at_css("main") do
# assert_dom "h1", "Hello, World"
# end
#
# # move the document_root_element to a Nodeset
# assert_dom css_select("section") do
# assert_dom "h1"
# end
def assert_dom(*args, &block)
@selected ||= nil

Expand Down Expand Up @@ -271,6 +281,10 @@ def document_root_element
'assert_dom work without needing to specify an element to select from.'
end

def current_root_element
@selected || document_root_element
end

# +equals+ must contain :minimum, :maximum and :count keys
def assert_size_match!(size, equals, css_selector, message = nil)
min, max, count = equals[:minimum], equals[:maximum], equals[:count]
Expand Down
Expand Up @@ -6,8 +6,7 @@ class HTMLSelector #:nodoc:

def initialize(values, previous_selection = nil, &root_fallback)
@values = values
@root = extract_root(previous_selection, root_fallback)
extract_selectors
@root, @css_selector, @selector = extract_root_and_selectors(previous_selection, &root_fallback)
@tests = extract_equality_tests
@message = @values.shift

Expand All @@ -23,7 +22,16 @@ def selecting_no_body? #:nodoc:
end

def select
filter @root.css(@selector, context)
nodeset =
if @selector.present?
@root.css(@selector, context)
elsif @root.is_a? Nokogiri::XML::NodeSet
@root
else
Nokogiri::XML::NodeSet.new(@root.document, [@root])
end

filter nodeset
end

private
Expand Down Expand Up @@ -56,7 +64,7 @@ def filter(matches)
Nokogiri::XML::NodeSet.new(matches.document, remaining)
end

def extract_root(previous_selection, root_fallback)
def extract_root(previous_selection)
possible_root = @values.first

if possible_root == nil
Expand All @@ -68,20 +76,21 @@ def extract_root(previous_selection, root_fallback)
possible_root
elsif previous_selection
previous_selection
else
root_fallback.call
end
end

def extract_selectors
selector = @values.shift
def extract_root_and_selectors(previous_selection, &root_fallback)
root = extract_root(previous_selection)

unless selector.is_a? String
raise ArgumentError, "Expecting a selector as the first argument"
end
if @values.first.is_a? String
selector = @values.shift

@css_selector = context.substitute!(selector, @values.dup, true)
@selector = context.substitute!(selector, @values)
[ root || root_fallback.call, context.substitute!(selector, @values.dup, true), context.substitute!(selector, @values) ]
elsif root.present?
[ root ]
else
raise ArgumentError, "Expecting a selector or node as the first argument"
end
end

def extract_equality_tests
Expand Down
68 changes: 68 additions & 0 deletions test/selector_assertions_test.rb
Expand Up @@ -199,6 +199,74 @@ def test_assert_select_text_match
end
end

def test_assert_dom_with_node
render_html <<~HTML
<aside>other</aside>
<div id="1">
<span>foo</span>
</div>
<div id="2">
<span>bar</span>
</div>
HTML
root = document_root_element.at_css("div")
assert_dom root do
assert_equal Nokogiri::XML::NodeSet.new(root.document, [root]), current_root_element
assert_dom "div", text: "foo", count: 1
assert_dom "span", text: "foo", count: 1
assert_dom "div", text: "bar", count: 0
assert_dom "span", text: "bar", count: 0
assert_dom "aside", text: "other", count: 0
end
assert_dom "div", text: "foo", count: 1
assert_dom "div", text: "bar", count: 1
assert_dom "aside", text: "other", count: 1
end

def test_assert_dom_with_nodeset
render_html <<~HTML
<aside>other</aside>
<div id="1">
<span>foo</span>
</div>
<div id="2">
<span>bar</span>
</div>
HTML

assert_dom css_select("div") do
assert_dom "div", text: "foo", count: 1
assert_dom "span", text: "foo", count: 1
assert_dom "div", text: "bar", count: 1
assert_dom "span", text: "bar", count: 1
assert_dom "aside", text: "other", count: 0
end
assert_dom "div", text: "foo", count: 1
assert_dom "div", text: "bar", count: 1
assert_dom "aside", text: "other", count: 1
end

def test_assert_dom_with_nodeset_and_options
render_html <<~HTML
<div>
<span>foo</span>
</div>
<div>
<span>bar</span>
</div>
HTML

assert_dom css_select("div"), count: 2
assert_dom css_select("div"), minimum: 1, maximum: 2

assert_raises Minitest::Assertion do
assert_dom css_select("div"), count: 1
end
assert_raises Minitest::Assertion do
assert_dom css_select("div"), minimum: 3
end
end

#
# Test css_select.
#
Expand Down