test_xml 0.0.4 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +2 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +31 -0
- data/README.rdoc +56 -73
- data/Rakefile +12 -12
- data/lib/test_xml.rb +0 -2
- data/lib/test_xml/matcher_methods.rb +29 -0
- data/lib/test_xml/mini_test.rb +6 -0
- data/lib/test_xml/nokogiri/node.rb +13 -8
- data/lib/test_xml/spec.rb +1 -4
- data/lib/test_xml/spec/matchers.rb +5 -4
- data/lib/test_xml/spec/matchers/{match_xml.rb → contain_xml.rb} +2 -7
- data/lib/test_xml/spec/matchers/{match_xml_structure.rb → contain_xml_structure.rb} +2 -5
- data/lib/test_xml/spec/matchers/{exactly_match_xml.rb → equal_xml.rb} +2 -7
- data/lib/test_xml/spec/matchers/{exactly_match_xml_structure.rb → equal_xml_structure.rb} +2 -4
- data/lib/test_xml/test_unit.rb +2 -0
- data/lib/test_xml/test_unit/assertions.rb +29 -32
- data/lib/test_xml/version.rb +1 -1
- data/spec/{lib/test_xml/spec/matchers/match_xml_spec.rb → matchers/contain_xml_spec.rb} +5 -5
- data/spec/{lib/test_xml/spec/matchers/match_xml_structure_spec.rb → matchers/contain_xml_structure_spec.rb} +4 -4
- data/spec/{lib/test_xml/spec/matchers/exactly_match_xml_spec.rb → matchers/equal_xml_spec.rb} +6 -4
- data/spec/{lib/test_xml/spec/matchers/exactly_match_xml_structure_spec.rb → matchers/equal_xml_structure_spec.rb} +4 -4
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +1 -4
- data/test/{test_xml/nokogiri → nokogiri}/test_node.rb +14 -7
- data/test/test_helper.rb +1 -4
- data/test/test_unit/test_assertions.rb +227 -0
- data/test_xml.gemspec +28 -0
- metadata +77 -42
- data/test/test_xml/test_unit/test_assertions.rb +0 -159
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
test_xml (0.0.4)
|
5
|
+
nokogiri (>= 1.3.2)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
diff-lcs (1.1.2)
|
11
|
+
nokogiri (1.4.4)
|
12
|
+
rake (0.8.7)
|
13
|
+
rdoc (3.5.3)
|
14
|
+
rspec (2.5.0)
|
15
|
+
rspec-core (~> 2.5.0)
|
16
|
+
rspec-expectations (~> 2.5.0)
|
17
|
+
rspec-mocks (~> 2.5.0)
|
18
|
+
rspec-core (2.5.1)
|
19
|
+
rspec-expectations (2.5.0)
|
20
|
+
diff-lcs (~> 1.1.2)
|
21
|
+
rspec-mocks (2.5.0)
|
22
|
+
|
23
|
+
PLATFORMS
|
24
|
+
ruby
|
25
|
+
|
26
|
+
DEPENDENCIES
|
27
|
+
rake
|
28
|
+
rdoc
|
29
|
+
rspec (>= 2.2)
|
30
|
+
rspec-core (~> 2.2)
|
31
|
+
test_xml!
|
data/README.rdoc
CHANGED
@@ -1,24 +1,46 @@
|
|
1
1
|
= TestXml
|
2
2
|
|
3
|
+
|
3
4
|
== DESCRIPTION:
|
4
5
|
|
5
|
-
TestXml is a small extension for RSpec and TestUnit
|
6
|
+
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.
|
7
|
+
|
6
8
|
|
7
9
|
== FEATURES:
|
8
10
|
|
9
|
-
*
|
10
|
-
*
|
11
|
-
* test
|
11
|
+
* runs with RSpec2, Test::Unit, MiniTest and Cucumber
|
12
|
+
* Ruby 1.8 and 1.9
|
13
|
+
* test XML structure and content
|
14
|
+
|
15
|
+
|
16
|
+
== INSTALL
|
17
|
+
|
18
|
+
gem install test_xml
|
19
|
+
|
12
20
|
|
13
21
|
== EXAMPLES:
|
14
22
|
|
15
|
-
===
|
23
|
+
=== Test::Unit and MiniTest
|
24
|
+
|
25
|
+
def test_item_representation
|
26
|
+
assert_xml_equal "<item><id>1</id></item>", @item.to_xml
|
27
|
+
end
|
28
|
+
|
29
|
+
=== RSpec
|
30
|
+
|
31
|
+
it "should contain the id" do
|
32
|
+
@item.to_xml.should equal_xml(<<-XML)
|
33
|
+
<item>
|
34
|
+
<id>1</id>
|
35
|
+
</item>
|
36
|
+
XML
|
37
|
+
end
|
38
|
+
|
39
|
+
=== Cucumber
|
16
40
|
|
17
41
|
Scenario:
|
18
|
-
|
19
|
-
|
20
|
-
The I receive successful response
|
21
|
-
And response matches the following xml
|
42
|
+
When I post some data
|
43
|
+
Then the response should match the following xml
|
22
44
|
"""
|
23
45
|
<transaction>
|
24
46
|
<status>success</status>
|
@@ -27,97 +49,58 @@ TestXml is a small extension for RSpec and TestUnit for XML/HTML testing. I have
|
|
27
49
|
</transaction>
|
28
50
|
"""
|
29
51
|
|
30
|
-
The scenario will check:
|
31
|
-
|
32
|
-
* 'status' element and its value.
|
33
|
-
* 'id' and 'order_id' elements are present in XML
|
34
|
-
|
35
52
|
== USAGE:
|
36
53
|
|
37
54
|
=== RSpec
|
38
55
|
|
39
|
-
|
56
|
+
In your spec_helper.rb
|
40
57
|
|
41
|
-
require 'test_xml'
|
42
58
|
require 'test_xml/spec'
|
43
59
|
|
44
|
-
in spec
|
45
|
-
|
46
|
-
it "should match_xml" do
|
47
|
-
xml = <<-XML
|
48
|
-
<root>
|
49
|
-
<one>1</one>
|
50
|
-
<two>2</two>
|
51
|
-
</root>
|
52
|
-
XML
|
53
|
-
|
54
|
-
xml.should match_xml(<<-XML)
|
55
|
-
<root>
|
56
|
-
<one>1</one>
|
57
|
-
<two>2</two>
|
58
|
-
</root>
|
59
|
-
XML
|
60
|
-
end
|
61
|
-
|
62
|
-
=== Implemented matchers
|
60
|
+
And in the actual spec, use these matchers:
|
63
61
|
|
64
|
-
*
|
65
|
-
*
|
66
|
-
*
|
67
|
-
*
|
62
|
+
* equal_xml
|
63
|
+
* contain_xml
|
64
|
+
* equal_xml_structure
|
65
|
+
* contain_xml_structure
|
68
66
|
|
69
|
-
===
|
67
|
+
=== Test::Unit
|
70
68
|
|
71
|
-
|
69
|
+
In the test_helper.rb
|
72
70
|
|
73
|
-
require 'test_xml'
|
74
71
|
require 'test_xml/test_unit'
|
75
72
|
|
76
|
-
|
73
|
+
In your test file, use these matchers:
|
77
74
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
</root>
|
83
|
-
XML
|
75
|
+
* assert_xml_equal
|
76
|
+
* assert_xml_contain
|
77
|
+
* assert_xml_structure_equal
|
78
|
+
* assert_xml_structure_contain
|
84
79
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
<one>1</one>
|
89
|
-
</root>
|
90
|
-
XML
|
91
|
-
end
|
92
|
-
end
|
80
|
+
Negative assertions are available as <tt>assert_not_*</tt>.
|
81
|
+
|
82
|
+
=== MiniTest
|
93
83
|
|
94
|
-
|
84
|
+
In the test_helper.rb
|
95
85
|
|
96
|
-
|
97
|
-
* assert_exactly_match_xml
|
98
|
-
* assert_match_xml_structure
|
99
|
-
* assert_exactly_match_xml_structure
|
86
|
+
require 'test_xml/mini_test'
|
100
87
|
|
101
|
-
|
88
|
+
Check the Test::Unit section for available assertions.
|
102
89
|
|
103
|
-
===
|
90
|
+
=== Cucumber
|
104
91
|
|
105
|
-
|
92
|
+
In the features/env.rb
|
106
93
|
|
107
94
|
require 'test_xml'
|
108
95
|
require 'test_xml/spec'
|
109
96
|
World(TestXml::Spec)
|
110
97
|
|
111
|
-
|
112
|
-
|
113
|
-
Then /^response
|
98
|
+
In your steps file e.g. features/step_definitions/xml_steps.rb add this step:
|
99
|
+
|
100
|
+
Then /^the response should match the following xml$/ do |string|
|
114
101
|
response.body.should match_xml(string)
|
115
102
|
end
|
116
103
|
|
117
104
|
== REQUIREMENTS
|
118
105
|
|
119
|
-
|
120
|
-
|
121
|
-
== INSTALL
|
122
|
-
|
123
|
-
[sudo] gem install test_xml
|
106
|
+
* nokogiri
|
data/Rakefile
CHANGED
@@ -1,22 +1,22 @@
|
|
1
|
-
require '
|
2
|
-
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
Bundler.setup
|
4
|
+
|
3
5
|
require 'rake/testtask'
|
4
|
-
require '
|
6
|
+
require 'rspec/core/rake_task'
|
5
7
|
require 'rdoc/task'
|
6
8
|
|
7
|
-
task :default => ['test
|
9
|
+
task :default => ['test', :spec]
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
t.verbose = true
|
14
|
-
end
|
11
|
+
Rake::TestTask.new(:test) do |t|
|
12
|
+
t.test_files = FileList['test/**/test_*.rb']
|
13
|
+
t.libs << "test"
|
14
|
+
t.verbose = true
|
15
15
|
end
|
16
16
|
|
17
17
|
|
18
|
-
|
19
|
-
t.libs << "spec"
|
18
|
+
RSpec::Core::RakeTask.new do |t|
|
19
|
+
#t.libs << "spec"
|
20
20
|
t.verbose = true
|
21
21
|
end
|
22
22
|
|
data/lib/test_xml.rb
CHANGED
@@ -0,0 +1,29 @@
|
|
1
|
+
module TestXml
|
2
|
+
# This module implements the actual matchers with their conditions.
|
3
|
+
module MatcherMethods
|
4
|
+
def self.xml_contain(subject, pattern)
|
5
|
+
actual, expected = parse_xml(subject, pattern)
|
6
|
+
actual.match?(expected, true)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.xml_equal(subject, pattern)
|
10
|
+
actual, expected = parse_xml(subject, pattern)
|
11
|
+
actual.match?(expected, true) && expected.match?(actual, true)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.xml_structure_contain(subject, pattern)
|
15
|
+
actual, expected = parse_xml(subject, pattern)
|
16
|
+
actual.match?(expected)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.xml_structure_equal(subject, pattern)
|
20
|
+
actual, expected = parse_xml(subject, pattern)
|
21
|
+
actual.match?(expected) && expected.match?(actual)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
def self.parse_xml(subject, pattern)
|
26
|
+
[Nokogiri::XML.parse(subject), Nokogiri::XML.parse(pattern)]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -2,23 +2,29 @@ module TestXml
|
|
2
2
|
module NokogiriExt
|
3
3
|
module Node
|
4
4
|
def match?(element, compare_value = false)
|
5
|
-
if compare_value && element.
|
6
|
-
equal_text?(element)
|
5
|
+
if compare_value && element.leaf?
|
6
|
+
comparable_attributes == element.comparable_attributes and equal_text?(element)
|
7
7
|
else
|
8
8
|
contains_elements_of?(element) &&
|
9
9
|
element.elements.all? {|el| matches_at_least_one?(el, compare_value) }
|
10
10
|
end
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
def elements
|
14
14
|
children.collect {|node| node if node.element? }.delete_if {|node| node.nil?}
|
15
15
|
end
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
|
17
|
+
# Attributes of the current node.
|
18
|
+
def comparable_attributes
|
19
|
+
attributes.collect {|k,a| [k.downcase, a.value]}.sort
|
20
|
+
end
|
21
|
+
|
22
|
+
# Check if node is either childless, self-closing, or has content text.
|
23
|
+
def leaf?
|
24
|
+
children.size == 0 or (children.size == 1 && children.first.text?)
|
19
25
|
end
|
20
26
|
|
21
|
-
|
27
|
+
private
|
22
28
|
def equal_text?(element)
|
23
29
|
content == element.content
|
24
30
|
end
|
@@ -34,7 +40,6 @@ module TestXml
|
|
34
40
|
def matches_at_least_one?(element, compare_value)
|
35
41
|
search(element.name).find { |el| el.match?(element, compare_value) }
|
36
42
|
end
|
37
|
-
|
38
43
|
end
|
39
44
|
end
|
40
45
|
end
|
data/lib/test_xml/spec.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
require 'test_xml/
|
2
|
-
require 'test_xml/spec/matchers/
|
3
|
-
require 'test_xml/spec/matchers/
|
4
|
-
require 'test_xml/spec/matchers/
|
1
|
+
require 'test_xml/matcher_methods'
|
2
|
+
require 'test_xml/spec/matchers/contain_xml'
|
3
|
+
require 'test_xml/spec/matchers/contain_xml_structure'
|
4
|
+
require 'test_xml/spec/matchers/equal_xml_structure'
|
5
|
+
require 'test_xml/spec/matchers/equal_xml'
|
@@ -1,11 +1,6 @@
|
|
1
|
-
|
1
|
+
RSpec::Matchers.define :contain_xml do |expected|
|
2
2
|
match do |actual|
|
3
|
-
|
4
|
-
pattern = Nokogiri::XML::Document.parse(expected)
|
5
|
-
|
6
|
-
compare_values = true
|
7
|
-
|
8
|
-
subject.match?(pattern, compare_values)
|
3
|
+
TestXml::MatcherMethods.xml_contain(actual, expected)
|
9
4
|
end
|
10
5
|
|
11
6
|
failure_message_for_should do |actual|
|
@@ -1,9 +1,6 @@
|
|
1
|
-
|
1
|
+
RSpec::Matchers.define :contain_xml_structure do |expected|
|
2
2
|
match do |actual|
|
3
|
-
|
4
|
-
pattern = Nokogiri::XML::Document.parse(expected)
|
5
|
-
|
6
|
-
subject.match?(pattern)
|
3
|
+
TestXml::MatcherMethods.xml_structure_contain(actual, expected)
|
7
4
|
end
|
8
5
|
|
9
6
|
failure_message_for_should do |actual|
|
@@ -1,11 +1,6 @@
|
|
1
|
-
|
1
|
+
RSpec::Matchers.define :equal_xml do |expected|
|
2
2
|
match do |actual|
|
3
|
-
|
4
|
-
pattern = Nokogiri::XML::Document.parse(expected)
|
5
|
-
|
6
|
-
compare_values = true
|
7
|
-
|
8
|
-
subject.match?(pattern, compare_values) && pattern.match?(subject, compare_values)
|
3
|
+
TestXml::MatcherMethods.xml_equal(actual, expected)
|
9
4
|
end
|
10
5
|
|
11
6
|
failure_message_for_should do |actual|
|
@@ -1,8 +1,6 @@
|
|
1
|
-
|
1
|
+
RSpec::Matchers.define :equal_xml_structure do |expected|
|
2
2
|
match do |actual|
|
3
|
-
|
4
|
-
pattern = Nokogiri::XML::Document.parse(expected)
|
5
|
-
subject.match?(pattern) && pattern.match?(subject)
|
3
|
+
TestXml::MatcherMethods.xml_structure_equal(actual, expected)
|
6
4
|
end
|
7
5
|
|
8
6
|
failure_message_for_should do |actual|
|
data/lib/test_xml/test_unit.rb
CHANGED
@@ -1,53 +1,50 @@
|
|
1
|
+
require 'test_xml/matcher_methods'
|
2
|
+
|
1
3
|
module TestXml
|
2
4
|
module TestUnit
|
3
5
|
module Assertions
|
4
|
-
def self.assertions_for(name, options)
|
5
|
-
define_method("assert_#{name}") do |subject, &block|
|
6
|
-
pattern = block.call
|
7
|
-
|
8
|
-
actual = Nokogiri::XML.parse(subject)
|
9
|
-
expected = Nokogiri::XML.parse(pattern)
|
10
6
|
|
7
|
+
def self.assertions_for(name, options)
|
8
|
+
define_method("assert_#{name}") do |subject, pattern|
|
11
9
|
full_message = options[:message_for_should].gsub(/\<pattern\>/, pattern).gsub(/\<subject\>/, subject)
|
12
10
|
|
13
|
-
|
14
|
-
options[:matcher].call(actual, expected)
|
15
|
-
end
|
11
|
+
correct_assert(MatcherMethods.send(name, subject, pattern), full_message)
|
16
12
|
end
|
17
13
|
|
18
|
-
define_method("assert_not_#{name}") do |subject,
|
19
|
-
pattern = block.call
|
20
|
-
|
21
|
-
actual = Nokogiri::XML.parse(subject)
|
22
|
-
expected = Nokogiri::XML.parse(pattern)
|
23
|
-
|
14
|
+
define_method("assert_not_#{name}") do |subject, pattern|
|
24
15
|
full_message = options[:message_for_should_not].gsub(/\<pattern\>/, pattern).gsub(/\<subject\>/, subject)
|
25
16
|
|
26
|
-
|
27
|
-
!options[:matcher].call(actual, expected)
|
28
|
-
end
|
17
|
+
correct_assert(!MatcherMethods.send(name, subject, pattern), full_message)
|
29
18
|
end
|
30
19
|
end
|
20
|
+
|
21
|
+
|
22
|
+
assertions_for :xml_contain,
|
23
|
+
:message_for_should => "the xml:\n<subject>\nshould contain xml:\n<pattern>",
|
24
|
+
:message_for_should_not => "the xml:\n<subject>\nshould not contain xml:\n<pattern> but it does"
|
31
25
|
|
32
|
-
assertions_for :
|
33
|
-
:message_for_should => "the xml:\n<subject>\nshould match xml:\n<pattern>",
|
34
|
-
:message_for_should_not => "the xml:\n<subject>\nshould not match xml:\n<pattern> but it does",
|
35
|
-
:matcher => Proc.new {|actual, expected| actual.match?(expected, true)}
|
36
|
-
|
37
|
-
assertions_for :exactly_match_xml,
|
26
|
+
assertions_for :xml_equal,
|
38
27
|
:message_for_should => "the xml:\n<subject>\nshould exactly match xml:\n<pattern>",
|
39
|
-
:message_for_should_not => "the xml:\n<subject>\nshould not exactly match xml:\n<pattern> but it does"
|
40
|
-
:matcher => Proc.new {|actual, expected| actual.match?(expected, true) && expected.match?(actual, true) }
|
28
|
+
:message_for_should_not => "the xml:\n<subject>\nshould not exactly match xml:\n<pattern> but it does"
|
41
29
|
|
42
|
-
assertions_for :
|
30
|
+
assertions_for :xml_structure_contain,
|
43
31
|
:message_for_should => "the xml:\n<subject>\nshould match xml structure:\n<pattern>",
|
44
|
-
:message_for_should_not => "the xml:\n<subject>\nshould not match xml structure:\n<pattern> but it does"
|
45
|
-
:matcher => Proc.new {|actual, expected| actual.match?(expected)}
|
32
|
+
:message_for_should_not => "the xml:\n<subject>\nshould not match xml structure:\n<pattern> but it does"
|
46
33
|
|
47
|
-
assertions_for :
|
34
|
+
assertions_for :xml_structure_equal,
|
48
35
|
:message_for_should => "the xml:\n<subject>\nshould exactly match xml structure:\n<pattern>",
|
49
|
-
:message_for_should_not => "the xml:\n<subject>\nshould not exactly match xml structure:\n<pattern> but it does"
|
50
|
-
|
36
|
+
:message_for_should_not => "the xml:\n<subject>\nshould not exactly match xml structure:\n<pattern> but it does"
|
37
|
+
|
38
|
+
private
|
39
|
+
def correct_assert(boolean, message)
|
40
|
+
if RUBY_VERSION =~ /1.9.2/ or defined?(MiniTest)
|
41
|
+
assert(boolean, message)
|
42
|
+
else
|
43
|
+
assert_block(message) do
|
44
|
+
boolean
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
51
48
|
end
|
52
49
|
end
|
53
50
|
end
|