test-xml-0.1.8/0000755000175000017500000000000013137606226012327 5ustar pravipravitest-xml-0.1.8/test_xml.gemspec0000644000175000017500000000223713137606226015537 0ustar pravipravilib = File.expand_path('../lib/', __FILE__) $:.unshift lib unless $:.include?(lib) require 'test_xml/version' Gem::Specification.new do |s| s.name = "test_xml" s.version = TestXml::VERSION s.authors = ["Pavel Gabriel", "Nick Sutterer"] s.homepage = "http://github.com/alovak/test_xml" s.summary = "Test your XML with Test::Unit, MiniTest, RSpec, or Cucumber." s.description = "Test your XML with Test::Unit, MiniTest, RSpec, or Cucumber using handy assertions like #assert_xml_equal or #assert_xml_structure_contain." s.email = ["alovak@gmail.com", "apotonick@gmail.com"] s.require_path = "lib" s.has_rdoc = true s.extra_rdoc_files = ['README.rdoc'] s.rdoc_options = ['--main', 'README.rdoc'] s.files = `git ls-files`.split("\n") s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") s.license = "MIT" s.add_dependency("diffy", "~> 3.0") s.add_dependency("nokogiri", ">= 1.3.2") s.add_development_dependency("rake") s.add_development_dependency("rdoc") s.add_development_dependency("test-unit", "~> 3.1") s.add_development_dependency("rspec", ">= 2.2") end test-xml-0.1.8/lib/0000755000175000017500000000000013137606226013075 5ustar pravipravitest-xml-0.1.8/lib/test_xml/0000755000175000017500000000000013137606226014734 5ustar pravipravitest-xml-0.1.8/lib/test_xml/mini_test.rb0000644000175000017500000000040113137606226017247 0ustar pravipravirequire "test_xml" # TODO: should we remove test_xml/spec? MiniTest::Expectations.class_eval do TestXml::ASSERTIONS.each do |cfg| infect_an_assertion(cfg.assert_name, cfg.expectation) end end class MiniTest::Test include TestXml::Assertions end test-xml-0.1.8/lib/test_xml/assertions.rb0000644000175000017500000000527613137606226017465 0ustar pravipravirequire 'ostruct' require 'diffy' module TestXml class AssertionConfig < OpenStruct def assert_name "assert_#{name}" end def assert_not_name "assert_not_#{name}" end def expectation "must_#{matcher}" end end ASSERTIONS = [ AssertionConfig.new( :name => :xml_contain, :matcher => :contain_xml, :message => lambda { |expect, actual| "the xml:\n#{actual}\nshould contain xml:\n#{expect}" }, :message_when_negated => lambda { |expect, actual| "the xml:\n#{actual}\nshould not contain xml:\n#{expect} but it does" } ), AssertionConfig.new( :name => :xml_structure_contain, :matcher => :contain_xml_structure, :message => lambda { |expect, actual| "the xml:\n#{actual}\nshould match xml structure:\n#{expect}" }, :message_when_negated => lambda { |expect, actual| "the xml:\n#{actual}\nshould not match xml structure:\n#{expect} but it does" } ), AssertionConfig.new( :name => :xml_equal, :matcher => :equal_xml, :message => lambda { |expect, actual| sprintf "the xml:\n%s\nshould exactly match xml:\n%s\n\nDiff:\n%s", actual, expect, diff(expect, actual) }, :message_when_negated => lambda { |expect, actual| "the xml:\n#{actual}\nshould not exactly match xml:\n#{expect} but it does" } ), AssertionConfig.new( :name => :xml_structure_equal, :matcher => :equal_xml_structure, :message => lambda { |expect, actual| "the xml:\n#{actual}\nshould exactly match xml structure:\n#{expect}" }, :message_when_negated => lambda { |expect, actual| "the xml:\n#{actual}\nshould not exactly match xml structure:\n#{expect} but it does" } ) ] def self.diff(expect, actual) doc_actual = Nokogiri::XML.parse(actual, &:noblanks) doc_expect = Nokogiri::XML.parse(expect, &:noblanks) diff = Diffy::Diff.new(doc_expect.to_xml, doc_actual.to_xml, :context => 3, :include_diff_info => true).to_a return "" if diff.empty? # Skip diff headers, they're useless since they refer to tempfiles diff[2..-1].join("") end module Assertions ASSERTIONS.each do |cfg| define_method(cfg.assert_name) do |a, b| correct_assert(MatcherMethods.send(cfg.name, a, b), cfg.message.call(a, b)) end define_method(cfg.assert_not_name) do |a, b| correct_assert(! MatcherMethods.send(cfg.name, a, b), cfg.message_when_negated.call(a, b)) end end private def correct_assert(boolean, message) if RUBY_VERSION =~ /1.9.2/ or defined?(MiniTest) assert(boolean, message) else assert_block(message) do boolean end end end end end test-xml-0.1.8/lib/test_xml/spec.rb0000644000175000017500000000133213137606226016212 0ustar pravipravirequire 'test_xml' # Adds assertions to RSpec. TestXml::ASSERTIONS.each do |cfg| RSpec::Matchers.define cfg.matcher do |expected| match do |actual| TestXml::MatcherMethods.send(cfg.name, actual, expected) end # RSpec 2 and 3 use different methods # to access failure messages. if RSpec::Expectations::Version::STRING[0] == "2" failure_message_for_should { |actual| cfg.message.call(expected, actual) } failure_message_for_should_not { |actual| cfg.message_when_negated.call(expected, actual) } else failure_message { |actual| cfg.message.call(expected, actual) } failure_message_when_negated { |actual| cfg.message_when_negated.call(expected, actual) } end end end test-xml-0.1.8/lib/test_xml/matcher_methods.rb0000644000175000017500000000160313137606226020427 0ustar pravipravimodule TestXml # This module implements the actual matchers with their conditions. module MatcherMethods def self.xml_contain(subject, pattern) actual, expected = parse_xml(subject, pattern) actual.match?(expected, true) end def self.xml_equal(subject, pattern) actual, expected = parse_xml(subject, pattern) actual.match?(expected, true) && expected.match?(actual, true) end def self.xml_structure_contain(subject, pattern) actual, expected = parse_xml(subject, pattern) actual.match?(expected) end def self.xml_structure_equal(subject, pattern) actual, expected = parse_xml(subject, pattern) actual.match?(expected) && expected.match?(actual) end private def self.parse_xml(subject, pattern) [Nokogiri::XML.parse(subject).root, Nokogiri::XML.parse(pattern).root] end end end test-xml-0.1.8/lib/test_xml/test_unit.rb0000644000175000017500000000014413137606226017276 0ustar pravipravirequire "test/unit" require "test_xml" class Test::Unit::TestCase include TestXml::Assertions endtest-xml-0.1.8/lib/test_xml/nokogiri.rb0000644000175000017500000000010313137606226017074 0ustar pravipraviclass Nokogiri::XML::Node include TestXml::NokogiriExt::Node end test-xml-0.1.8/lib/test_xml/nokogiri/0000755000175000017500000000000013137606226016555 5ustar pravipravitest-xml-0.1.8/lib/test_xml/nokogiri/node.rb0000644000175000017500000000340313137606226020027 0ustar pravipravimodule TestXml module NokogiriExt module Node def match?(element, compare_value = false) if compare_value && element.leaf? comparable_attributes == element.comparable_attributes and equal_text?(element) else #TODO clean this part of the code if compare_value (comparable_attributes == element.comparable_attributes) && contains_elements_of?(element) && element.elements.all? {|el| matches_at_least_one?(el, compare_value) } else contains_elements_of?(element) && element.elements.all? {|el| matches_at_least_one?(el, compare_value) } end end end def elements children.collect {|node| node if node.element? }.delete_if {|node| node.nil?} end # Attributes of the current node. def comparable_attributes attributes.collect {|k,a| [k.downcase, a.value]}.sort end # Check if node is either childless, self-closing, or has content text. def leaf? children.size == 0 or (children.size == 1 && children.first.text?) end def placeholder? TestXml.placeholders_enabled? and (content =~ /^`.*`$/) end private def equal_text?(element) element.content = content if element.placeholder? content == element.content end def contains_elements_of?(element) element.elements.find {|el| not contains?(el)}.nil? end def contains?(element) children.find {|node| node.element? && node.name == element.name } end def matches_at_least_one?(element, compare_value) search(element.name).find { |el| el.match?(element, compare_value) } end end end end test-xml-0.1.8/lib/test_xml/version.rb0000644000175000017500000000004713137606226016747 0ustar pravipravimodule TestXml VERSION = "0.1.8" end test-xml-0.1.8/lib/test_xml.rb0000644000175000017500000000044613137606226015265 0ustar pravipravirequire 'nokogiri' require 'test_xml/nokogiri/node' require 'test_xml/nokogiri' require 'test_xml/assertions' require 'test_xml/matcher_methods' module TestXml class << self attr_accessor :enable_placeholders def placeholders_enabled? !!enable_placeholders end end end test-xml-0.1.8/README.rdoc0000644000175000017500000000524413137606226014142 0ustar pravipravi= TestXml == DESCRIPTION TestXml is a small extension for testing XML/HTML. Extending RSpec and TestUnit it makes asserting and comparing XML snippets easy, and is especially helpful for testing RESTful web services and their XML representations. == FEATURES * Runs with RSpec 2 or 3, Test::Unit, MiniTest and Cucumber * Ruby >= 1.8 * Test XML structure and content == INSTALL gem install test_xml == EXAMPLES === Test::Unit and MiniTest def test_item_representation assert_xml_equal "1", @item.to_xml end === RSpec it "should contain the id" do @item.to_xml.should equal_xml(<<-XML) 1 XML end === Cucumber Scenario: When I post some data Then the response should match the following xml """ success """ == USAGE: === RSpec In your spec_helper.rb require 'test_xml/spec' And in the actual spec, use these matchers: * equal_xml * contain_xml * equal_xml_structure * contain_xml_structure === Test::Unit In the test_helper.rb require 'test_xml/test_unit' In your test file, use these matchers: * assert_xml_equal * assert_xml_contain * assert_xml_structure_equal * assert_xml_structure_contain Negative assertions are available as assert_not_*. === MiniTest In the test_helper.rb require 'test_xml/mini_test' Check the Test::Unit section for available assertions. === Cucumber In the features/env.rb require 'test_xml' require 'test_xml/spec' World(TestXml::Spec) In your steps file e.g. features/step_definitions/xml_steps.rb add this step: Then /^the response should match the following xml$/ do |xml| response.body.should equal_xml(xml) end == ASSERTIONS === XML is Equal Elements, attributes and text nodes are all the same === XML Contains The XML contains the given structure. Checks ancestral relationships, elements, attributes and text nodes starting from and including the root node. For example, given this XML: Cee Dee This will fail: Cee as +b+ is not the root node. The check must be written as: Cee === XML Structure is Equal Like XML is equal, but ignores attributes and text nodes === XML Structure Contains Like XML contains, but ignores attributes and text nodes == REQUIREMENTS * nokogiri == Many Thanks {Nick Sutterer}[http://github.com/apotonick] thank you for bringing RSpec 2, Ruby 1.9.2 and MiniTest! You revived the gem! :) == LICENSE Copyright © 2010-2011, Pavel Gabriel Released under the MIT License. test-xml-0.1.8/.gitignore0000644000175000017500000000014013137606226014312 0ustar pravipravispec/**/*.xml rdoc build doc Rake.config pkg .project .bundle Gemfile.lock *.swp *.swo bin *.gemtest-xml-0.1.8/LICENSE0000644000175000017500000000206613137606226013340 0ustar pravipravihe MIT License (MIT) Copyright (c) 2010 Pavel Gabriel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. test-xml-0.1.8/Rakefile0000644000175000017500000000070313137606226013774 0ustar pravipravirequire 'bundler/gem_tasks' require 'rake/testtask' require 'rspec/core/rake_task' require 'rdoc/task' task :default => ['test', :spec] Rake::TestTask.new(:test) do |t| t.test_files = FileList['test/**/test_*.rb'] t.libs << "test" t.verbose = true end RSpec::Core::RakeTask.new do |t| #t.libs << "spec" t.verbose = true end RDoc::Task.new do |rd| rd.main = "README.rdoc" rd.rdoc_files.include("README.rdoc", "lib/**/*.rb") end test-xml-0.1.8/Gemfile0000644000175000017500000000004713137606226013623 0ustar pravipravisource 'https://rubygems.org' gemspec test-xml-0.1.8/spec/0000755000175000017500000000000013137606226013261 5ustar pravipravitest-xml-0.1.8/spec/spec_helper.rb0000644000175000017500000000003013137606226016070 0ustar pravipravirequire 'test_xml/spec' test-xml-0.1.8/spec/matchers/0000755000175000017500000000000013137606226015067 5ustar pravipravitest-xml-0.1.8/spec/matchers/equal_xml_spec.rb0000644000175000017500000000432013137606226020414 0ustar pravipravirequire 'spec_helper' # TODO: attributes are not matched. describe "equal_xml(xml)" do subject { <<-XML 1 2 XML } before { TestXml.enable_placeholders = false } context "when placeholders are enabled" do before { TestXml.enable_placeholders = true } context "and xml with equal structure contains placeholder" do it "should pass" do should equal_xml(<<-XML) `example` 2 XML end end end context "when subject has elements with attributes" do subject { <<-XML 1 2 XML } context "and xml has similar elements with attributes" do it "should pass" do should equal_xml(<<-XML) 1 2 XML end end context "and xml has elements with different attributes" do it "should fail" do should_not equal_xml(<<-XML) 1 2 XML end end end context "when xml is equal with subject" do it "should pass" do should equal_xml(<<-XML) 1 2 XML end end context "when xml structure is equal with subject but elements have different content" do it "should fail" do should_not equal_xml(<<-XML) 4 5 XML end end context "when xml has less elements" do it "should fail" do should_not equal_xml(<<-XML) 1 XML end end context "when xml has more elements" do it "should fail" do should_not equal_xml(<<-XML) 1 2 3 XML end end end test-xml-0.1.8/spec/matchers/equal_xml_structure_spec.rb0000644000175000017500000000201213137606226022530 0ustar pravipravirequire 'spec_helper' describe "equal_xml_structure(xml)" do subject { <<-XML 1 2 XML } context "when xml structure is equal with subject" do it "should pass" do should equal_xml_structure(<<-XML) XML end end context "when xml structure is equal with subject and elements have different content" do it "should pass" do should equal_xml_structure(<<-XML) 4 5 XML end end context "when xml has less elements" do it "should fail" do should_not equal_xml_structure(<<-XML) XML end end context "when xml has more elements" do it "should fail" do should_not equal_xml_structure(<<-XML) XML end end end test-xml-0.1.8/spec/matchers/contain_xml_structure_spec.rb0000644000175000017500000000202213137606226023055 0ustar pravipravirequire 'spec_helper' describe "contain_xml_structure(xml)" do subject { <<-XML 1 2 XML } context "when xml is equal" do it "should pass" do should contain_xml_structure(<<-XML) 1 2 XML end end context "when xml structure is equal but elements have different content" do it "should pass" do should contain_xml_structure(<<-XML) 4 5 XML end end context "when xml has less elements" do it "should pass" do should contain_xml_structure(<<-XML) 1 XML end end context "when xml has more elements" do it "should fail" do should_not contain_xml_structure(<<-XML) 1 2 3 XML end end end test-xml-0.1.8/spec/matchers/contain_xml_spec.rb0000644000175000017500000000266513137606226020752 0ustar pravipravirequire 'spec_helper' describe "contain_xml(xml)" do subject { <<-XML 1 2 XML } context "when xml is equal" do it "should pass" do should contain_xml(<<-XML) 1 2 XML end end context "when xml has less elements" do it "should pass" do should contain_xml(<<-XML) 1 XML end end context "when xml structure is equal but elements have different content" do it "should fail" do should_not contain_xml(<<-XML) 4 5 XML end end context "when xml has more elements" do it "should fail" do should_not contain_xml(<<-XML) 1 2 3 XML end end context "when xml has elements with the same name within parent element" do subject { <<-XML one two XML } it "should pass" do should contain_xml(<<-XML) one two XML end end end test-xml-0.1.8/test/0000755000175000017500000000000013137606226013306 5ustar pravipravitest-xml-0.1.8/test/test_unit/0000755000175000017500000000000013137606226015324 5ustar pravipravitest-xml-0.1.8/test/test_unit/test_assertions.rb0000644000175000017500000001142713137606226021107 0ustar pravipravirequire 'test_helper' class TestAssertions < Test::Unit::TestCase def test_assert_xml_contain_message_if_fails begin assert_xml_contain("12", "3") rescue Exception => e assert_match %r{the xml:\n3\nshould contain xml:\n12}, e.message end end def test_assert_xml_not_contain_message_if_fails begin assert_not_xml_contain("12", "12") rescue Exception => e assert_match %r{the xml:\n12\nshould not contain xml:\n12 but it does}, e.message end end def test_assert_xml_contain expected = <<-XML 1 2 XML actual = <<-XML 1 XML assert_xml_contain expected, actual end def test_assert_not_xml_contain expected = <<-XML 1 XML actual = <<-XML 2 XML assert_not_xml_contain expected, actual end def test_assert_xml_structure_contain expected = <<-XML 1 3 XML actual = <<-XML 2 4 XML assert_xml_structure_contain expected, actual end def test_assert_not_xml_structure_contain expected = <<-XML 1 3 XML actual = <<-XML 2 XML assert_not_xml_structure_contain expected, actual end def test_assert_xml_equal expected = <<-XML 1 2 XML actual = <<-XML 1 2 XML assert_xml_equal expected, actual end def test_assert_xml_equal_with_attributes expected = <<-XML 1 XML actual = <<-XML 1 XML assert_xml_equal expected, actual end def test_assert_xml_equal_with_attributes_in_branch_element expected = <<-XML 1 XML actual = <<-XML 1 XML assert_xml_equal expected, actual end def test_assert_not_xml_equal_with_attributes expected = <<-XML 1 XML actual = <<-XML 1 XML assert_not_xml_equal expected, actual end def test_assert_not_xml_equal_with_attributes_and_no_text expected = <<-XML XML actual = <<-XML XML assert_not_xml_equal expected, actual end def test_assert_not_xml_equal_with_attributes_in_branch_element expected = <<-XML 1 XML actual = <<-XML 1 XML assert_not_xml_equal expected, actual end def test_assert_not_xml_equal expected = <<-XML 1 2 XML actual = <<-XML 1 XML assert_not_xml_equal expected, actual end def test_assert_xml_structure_equal expected = <<-XML 1 3 XML actual = <<-XML 2 4 XML assert_xml_structure_equal expected, actual end def test_assert_not_xml_structure_equal expected = <<-XML 1 3 XML actual = <<-XML 2 3 XML assert_not_xml_structure_equal expected, actual end end test-xml-0.1.8/test/nokogiri/0000755000175000017500000000000013137606226015127 5ustar pravipravitest-xml-0.1.8/test/nokogiri/test_node.rb0000644000175000017500000000472213137606226017445 0ustar pravipravirequire 'test_helper' class TestNode < Test::Unit::TestCase def test_elements assert doc.elements.size == 1 assert doc.at('root').elements.size == 2 end def test_leaf? assert root("").leaf? assert root("Yo").leaf? assert root("").leaf? assert !root("
").leaf? end def test_match_of_elements_without_comparing_values subject = root(<<-XML) 1 3 XML pattern = root(<<-XML) 2 XML assert subject.match?(pattern) end def test_no_match_of_elements_without_comparing_values subject = root(<<-XML) 1 XML pattern = root(<<-XML) 5 XML assert !subject.match?(pattern) end def test_match_with_values subject = root(<<-XML) 1 3 XML pattern = root(<<-XML) 3 1 XML assert subject.match?(pattern, true) end def test_no_match_with_values subject = root(<<-XML) 1 XML not_matched_pattern = root(<<-XML) 2 XML assert !subject.match?(not_matched_pattern, true) end def test_element_contains_another_element element = create_element('') assert !doc.send(:contains?,element) assert doc.at('root').send(:contains?,element) end def test_element_contains_elements assert doc.root.send(:contains_elements_of?, doc.root) assert !doc.root.send(:contains_elements_of?, doc('')) end def test_comparable_attributes assert_equal [["id", "boss"], ["name", "Dude"]], create_element(%{
  • }).comparable_attributes assert_equal [["name", "Dude"]], create_element(%{
  • }).comparable_attributes end private def create_element(xml) Nokogiri::XML::Document.parse(xml).root end def root(xml) doc(xml).root end def doc(xml = nil) xml ||= <<-XML 1 2 XML Nokogiri::XML::Document.parse(xml) end end test-xml-0.1.8/test/test_helper.rb0000644000175000017500000000003513137606226016147 0ustar pravipravirequire 'test_xml/test_unit' test-xml-0.1.8/CHANGES.md0000644000175000017500000000102513137606226013717 0ustar pravipravi# 0.1.8 * Add license file and update gemspec with license name * Add test-unit to development dependencies, removed rspec-core and added rspec # 0.1.7 * Add diff output to xml_equal * Add support for RSpec 3 * Fix order of expected result and actual result for RSpec # 0.1.6 * Fix dependencies so that Minitest doesn't rely on Test::Unit anymore. If you having trouble, update to minitest > 4.0.0 :) # 0.1.5 * Make minitest-5 compatible. # 0.1.4 * Require bug fix. # 0.1.3 * Adding support for `MiniTest::Spec` matchers.