From 554399fd209c070c122bb97b36d5aa136172afd0 Mon Sep 17 00:00:00 2001 From: Joshua Young Date: Wed, 13 Dec 2023 21:31:43 +1000 Subject: [PATCH] Add `assert_not_dom`, `refute_dom`, `assert_not_select`, `refute_select` & `refute_dom_equal` --- README.md | 3 ++ .../dom/testing/assertions/dom_assertions.rb | 1 + .../testing/assertions/selector_assertions.rb | 26 ++++++++++- .../selector_assertions/html_selector.rb | 17 ++++++-- test/selector_assertions_test.rb | 43 ++++++++++++++++++- 5 files changed, 84 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 0e118ab..5250305 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,9 @@ 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' +# select from a supplied node. assert_not_dom asserts elements do not exist. +assert_not_dom document_root_element.at('.hello'), '.goodbye' + # elements in CDATA encoded sections can also be selected assert_dom_encoded '#out-of-your-element' diff --git a/lib/rails/dom/testing/assertions/dom_assertions.rb b/lib/rails/dom/testing/assertions/dom_assertions.rb index eb32e1e..a7140e5 100644 --- a/lib/rails/dom/testing/assertions/dom_assertions.rb +++ b/lib/rails/dom/testing/assertions/dom_assertions.rb @@ -70,6 +70,7 @@ def assert_dom_not_equal(expected, actual, message = nil, strict: false, html_ve message ||= "Expected: #{expected}\nActual: #{actual}" assert_not compare_doms(expected_dom, actual_dom, strict), message end + alias_method :refute_dom_equal, :assert_dom_not_equal protected def compare_doms(expected, actual, strict) diff --git a/lib/rails/dom/testing/assertions/selector_assertions.rb b/lib/rails/dom/testing/assertions/selector_assertions.rb index d0aee75..ed67070 100644 --- a/lib/rails/dom/testing/assertions/selector_assertions.rb +++ b/lib/rails/dom/testing/assertions/selector_assertions.rb @@ -164,7 +164,32 @@ def assert_dom(*args, &block) @selected ||= nil selector = HTMLSelector.new(args, @selected) { nodeset document_root_element } + dom_assertions(selector, &block) + end + alias_method :assert_select, :assert_dom + + # The negated form of +assert_dom+. + # + # === Equality Tests + # + # Supports the same equality tests as +assert_dom+ except for: + # * true + # * false + # * Integer + # * :count + # * :minimum + # * :maximum + def assert_not_dom(*args, &block) + @selected ||= nil + selector = HTMLSelector.new(args, @selected, refute: true) { nodeset document_root_element } + dom_assertions(selector, &block) + end + alias_method :refute_dom, :assert_not_dom + alias_method :assert_not_select, :assert_not_dom + alias_method :refute_select, :assert_not_select + + private def dom_assertions(selector, &block) if selector.selecting_no_body? assert true return @@ -177,7 +202,6 @@ def assert_dom(*args, &block) nest_selection(matches, &block) if block_given? && !matches.empty? end end - alias_method :assert_select, :assert_dom # Extracts the content of an element, treats it as encoded HTML and runs # nested assertion on it. diff --git a/lib/rails/dom/testing/assertions/selector_assertions/html_selector.rb b/lib/rails/dom/testing/assertions/selector_assertions/html_selector.rb index 7ee0cf2..84d83d1 100644 --- a/lib/rails/dom/testing/assertions/selector_assertions/html_selector.rb +++ b/lib/rails/dom/testing/assertions/selector_assertions/html_selector.rb @@ -14,11 +14,11 @@ class HTMLSelector # :nodoc: include Minitest::Assertions - def initialize(values, previous_selection = nil, &root_fallback) + def initialize(values, previous_selection = nil, refute: false, &root_fallback) @values = values @root = extract_root(previous_selection, root_fallback) extract_selectors - @tests = extract_equality_tests + @tests = extract_equality_tests(refute) @message = @values.shift if @message.is_a?(Hash) @@ -97,7 +97,7 @@ def extract_selectors @selector = context.substitute!(selector, @values) end - def extract_equality_tests + def extract_equality_tests(refute) comparisons = {} case comparator = @values.shift when Hash @@ -113,7 +113,16 @@ def extract_equality_tests comparisons[:count] = 0 when NilClass, TrueClass comparisons[:minimum] = 1 - else raise ArgumentError, "I don't understand what you're trying to match" + else + raise ArgumentError, "I don't understand what you're trying to match" + end + + if refute + if comparisons[:count] || (comparisons[:minimum] && !comparator.nil?) || comparisons[:maximum] + raise ArgumentError, "Cannot use true, false, Integer, :count, :minimum and :maximum when asserting that a selector does not match" + end + + comparisons[:count] = 0 end # By default we're looking for at least one match. diff --git a/test/selector_assertions_test.rb b/test/selector_assertions_test.rb index bc3a2a1..1faf644 100644 --- a/test/selector_assertions_test.rb +++ b/test/selector_assertions_test.rb @@ -16,7 +16,7 @@ def assert_failure(message, &block) end # - # Test assert select. + # Test assert_select. # def test_assert_select @@ -210,6 +210,47 @@ def test_assert_select_text_match end end + # + # Test assert_not_select. + # + + def test_not_select + render_html '
' + assert_not_select "p" + assert_failure(/Expected exactly 0 elements matching "div", found 1/) { assert_not_select "div" } + assert_failure(/Expected exactly 0 elements matching "div#1", found 1/) { assert_not_select "div#1" } + end + + def test_not_select_with_true + render_html '
' + assert_raises(ArgumentError) { assert_not_select "div", true } + end + + def test_not_select_with_false + render_html '
' + assert_raises(ArgumentError) { assert_not_select "div", false } + end + + def test_not_select_with_integer + render_html '
' + assert_raises(ArgumentError) { assert_not_select "div", 1 } + end + + def test_not_select_with_count + render_html '
' + assert_raises(ArgumentError) { assert_not_select "div", count: 1 } + end + + def test_not_select_with_minimum + render_html '
' + assert_raises(ArgumentError) { assert_not_select "div", minimum: 1 } + end + + def test_not_select_with_maximum + render_html '
' + assert_raises(ArgumentError) { assert_not_select "div", maximum: 1 } + end + # # Test css_select. #