xml-spec 0.2.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.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rspec +1 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/Guardfile.example +36 -0
- data/LICENSE.txt +22 -0
- data/README.md +33 -0
- data/Rakefile +1 -0
- data/lib/xml-spec.rb +1 -0
- data/lib/xml_spec.rb +56 -0
- data/lib/xml_spec/configuration.rb +37 -0
- data/lib/xml_spec/errors.rb +47 -0
- data/lib/xml_spec/exclusion.rb +26 -0
- data/lib/xml_spec/helpers.rb +74 -0
- data/lib/xml_spec/matchers.rb +35 -0
- data/lib/xml_spec/matchers/be_xml_eql.rb +74 -0
- data/lib/xml_spec/messages.rb +8 -0
- data/lib/xml_spec/version.rb +3 -0
- data/spec/configuration_spec.rb +64 -0
- data/spec/helpers_spec.rb +114 -0
- data/spec/matchers_spec.rb +79 -0
- data/spec/spec_helper.rb +13 -0
- data/xml-spec.gemspec +32 -0
- metadata +198 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2460e0d0cf76e2ff9285e68c1fcc99f93d26f707
|
4
|
+
data.tar.gz: 67969a91a3db438dd5488055415417ef2e67aa9f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 752d5fb2dfe2a4a41403633c8a4984aaf277b844f9fe189b4db8da24bb41168c8ee1686654510a54843b6c45c6c6f7817574bf50fa57d05c4ae90d7cc49662e7
|
7
|
+
data.tar.gz: 1c13122c0858a66da06cc50ea371332438600335f73b27f5545e54ff57e763389355720ec268839e8b9eff8a9f5db104e7752dcc94f137a2475517e8346518ec
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
gemdev
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.1.0
|
data/Gemfile
ADDED
data/Guardfile.example
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
#guard 'rspec', cmd: 'zeus rspec',
|
2
|
+
#all_on_start: false,
|
3
|
+
#all_after_pass: false,
|
4
|
+
#failed_mode: :keep,
|
5
|
+
#spec_paths: ['spec'] do
|
6
|
+
##guard 'rspec', :all_on_start => true, :all_after_pass => false, :cli => '--color --format doc' do
|
7
|
+
#watch( %r{^spec/.+_spec\.rb$} )
|
8
|
+
#watch( %r{^lib/(.+)\.rb$} ) { |m| "spec/#{m[1]}_spec.rb" }
|
9
|
+
#watch( 'spec/spec_helper.rb' ) { "spec" }
|
10
|
+
#end
|
11
|
+
|
12
|
+
guard :rspec, #cmd: 'zeus rspec',
|
13
|
+
all_on_start: false,
|
14
|
+
all_after_pass: false,
|
15
|
+
failed_mode: :keep,
|
16
|
+
spec_paths: ['spec'] do
|
17
|
+
watch(%r{^spec/.+_spec\.rb$})
|
18
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
19
|
+
watch('spec/spec_helper.rb') { "spec" }
|
20
|
+
|
21
|
+
# Rails example
|
22
|
+
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
23
|
+
watch(%r{^app/(.*)(\.erb|\.haml|\.slim)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
|
24
|
+
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
|
25
|
+
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
26
|
+
watch('config/routes.rb') { "spec/routing" }
|
27
|
+
watch('app/controllers/application_controller.rb') { "spec/controllers" }
|
28
|
+
|
29
|
+
# Capybara features specs
|
30
|
+
watch(%r{^app/views/(.+)/.*\.(erb|haml|slim)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
|
31
|
+
|
32
|
+
# Turnip features and steps
|
33
|
+
watch(%r{^spec/acceptance/(.+)\.feature$})
|
34
|
+
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
|
35
|
+
end
|
36
|
+
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 C. Jason Harrelson
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# XmlSpec
|
2
|
+
|
3
|
+
XML matchers for RSpec and Cucumber.
|
4
|
+
|
5
|
+
#### This is alpha software and is not yet ready for primte-time.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'xml_spec'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install xml_spec
|
20
|
+
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
TODO: Write usage instructions here
|
25
|
+
|
26
|
+
|
27
|
+
## Contributing
|
28
|
+
|
29
|
+
1. Fork it ( http://github.com/<my-github-username>/xml_spec/fork )
|
30
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
31
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
32
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
33
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/lib/xml-spec.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'xml-spec'
|
data/lib/xml_spec.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
#require "json"
|
2
|
+
#require 'active_support/all'
|
3
|
+
require 'active_support/core_ext/hash/conversions'
|
4
|
+
#require 'active_support/core_ext'
|
5
|
+
require 'equivalent-xml'
|
6
|
+
require 'nokogiri'
|
7
|
+
require 'nori'
|
8
|
+
require "rspec"
|
9
|
+
require "xml_spec/errors"
|
10
|
+
require "xml_spec/exclusion"
|
11
|
+
require "xml_spec/helpers"
|
12
|
+
require "xml_spec/messages"
|
13
|
+
require "xml_spec/matchers"
|
14
|
+
|
15
|
+
module XmlSpec
|
16
|
+
|
17
|
+
autoload :Configuration, 'xml_spec/configuration'
|
18
|
+
autoload :VERSION, 'xml_spec/version'
|
19
|
+
|
20
|
+
extend Configuration
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
class Hash
|
25
|
+
def diff(other)
|
26
|
+
(self.keys + other.keys).uniq.inject({}) do |memo, key|
|
27
|
+
unless self[key] == other[key]
|
28
|
+
if self[key].kind_of?(Hash) && other[key].kind_of?(Hash)
|
29
|
+
memo[key] = self[key].diff(other[key])
|
30
|
+
else
|
31
|
+
memo[key] = [self[key], other[key]]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
memo
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def interpret_diff( memos=[], path=[] )
|
39
|
+
self.inject(memos) do |memo, key_value|
|
40
|
+
k, v = key_value.first, key_value.last
|
41
|
+
path << k
|
42
|
+
#puts '', "memo: #{memo.inspect}", "key: #{k}", "value: #{v}"
|
43
|
+
#puts "path: #{path.inspect}"
|
44
|
+
if v.kind_of?( Hash )
|
45
|
+
#debugger
|
46
|
+
v.interpret_diff( memos, path )
|
47
|
+
elsif v.kind_of?(Array)
|
48
|
+
#debugger
|
49
|
+
memo << "#{path.join( '/' )}: #{v.map { |val| val.nil? ? 'nil' : (val.respond_to?( :empty? ) && val.empty? ? "''" : "'#{val}'") }.join( ' is not ' )}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
memos
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "set"
|
2
|
+
|
3
|
+
module XmlSpec
|
4
|
+
module Configuration
|
5
|
+
|
6
|
+
DEFAULT_EXCLUDED_KEYS = %w(id created_at updated_at)
|
7
|
+
|
8
|
+
def configure(&block)
|
9
|
+
instance_eval(&block)
|
10
|
+
end
|
11
|
+
|
12
|
+
def excluded_keys
|
13
|
+
@excluded_keys ||= DEFAULT_EXCLUDED_KEYS
|
14
|
+
end
|
15
|
+
|
16
|
+
def excluded_keys=(keys)
|
17
|
+
@excluded_keys = keys.map(&:to_s).uniq
|
18
|
+
end
|
19
|
+
|
20
|
+
def exclude_keys(*keys)
|
21
|
+
self.excluded_keys = keys
|
22
|
+
end
|
23
|
+
|
24
|
+
def directory
|
25
|
+
@directory
|
26
|
+
end
|
27
|
+
|
28
|
+
def directory=(directory)
|
29
|
+
@directory = directory
|
30
|
+
end
|
31
|
+
|
32
|
+
def reset
|
33
|
+
instance_variables.each{|ivar| remove_instance_variable(ivar) }
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module XmlSpec
|
2
|
+
|
3
|
+
class Error < StandardError
|
4
|
+
end
|
5
|
+
|
6
|
+
class XmlSyntaxError < Error
|
7
|
+
def initialize( e=nil )
|
8
|
+
super e
|
9
|
+
set_backtrace e.backtrace if e
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
"Invalid XML"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class MissingPath < Error
|
18
|
+
attr_reader :path
|
19
|
+
|
20
|
+
def initialize(path)
|
21
|
+
@path = path
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_s
|
25
|
+
%(Missing JSON path "#{path}")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class MissingDirectory < Error
|
30
|
+
def to_s
|
31
|
+
"No XmlSpec.directory set"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class MissingFile < Error
|
36
|
+
attr_reader :path
|
37
|
+
|
38
|
+
def initialize(path)
|
39
|
+
@path = path
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_s
|
43
|
+
"No XML file at #{path}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module XmlSpec
|
2
|
+
module Exclusion
|
3
|
+
extend self
|
4
|
+
|
5
|
+
def exclude_keys(ruby)
|
6
|
+
case ruby
|
7
|
+
when Hash
|
8
|
+
ruby.sort.inject({}) do |hash, (key, value)|
|
9
|
+
hash[key] = exclude_keys(value) unless exclude_key?(key)
|
10
|
+
hash
|
11
|
+
end
|
12
|
+
when Array
|
13
|
+
ruby.map{|v| exclude_keys(v) }
|
14
|
+
else ruby
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def exclude_key?(key)
|
19
|
+
excluded_keys.include?(key)
|
20
|
+
end
|
21
|
+
|
22
|
+
def excluded_keys
|
23
|
+
@excluded_keys ||= Set.new(XmlSpec.excluded_keys)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
#require "multi_json"
|
2
|
+
|
3
|
+
module XmlSpec
|
4
|
+
module Helpers
|
5
|
+
|
6
|
+
extend self
|
7
|
+
|
8
|
+
def parse_xml( xml, path=nil )
|
9
|
+
Nokogiri::XML( xml ) { |config| config.options = Nokogiri::XML::ParseOptions::STRICT }
|
10
|
+
parser = Nori.new
|
11
|
+
ruby = parser.parse( xml )
|
12
|
+
value_at_json_path( ruby, path )
|
13
|
+
rescue Nokogiri::XML::SyntaxError=> e
|
14
|
+
raise XmlSpec::XmlSyntaxError.new( e )
|
15
|
+
end
|
16
|
+
|
17
|
+
def normalize_xml( xml, path=nil )
|
18
|
+
Nokogiri.XML( xml ) do |config|
|
19
|
+
config.default_xml.noblanks
|
20
|
+
end.to_xml( indent: 2 ).chomp
|
21
|
+
end
|
22
|
+
|
23
|
+
# TODO consider removing ths method as we do not need 2 levels with XML
|
24
|
+
def generate_normalized_xml( xml_or_hash )
|
25
|
+
xml = nil
|
26
|
+
if xml_or_hash.is_a?( Hash )
|
27
|
+
hash = xml_or_hash
|
28
|
+
raise 'error' if hash.keys.size != 1
|
29
|
+
root = hash.keys.first
|
30
|
+
xml = hash[root].to_xml( root: root )
|
31
|
+
end
|
32
|
+
|
33
|
+
normalize_xml( xml )
|
34
|
+
end
|
35
|
+
|
36
|
+
def load_xml(relative_path)
|
37
|
+
missing_json_directory! if XmlSpec.directory.nil?
|
38
|
+
path = File.join(XmlSpec.directory, relative_path)
|
39
|
+
missing_xml_file!(path) unless File.exist?(path)
|
40
|
+
File.read(path)
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def value_at_json_path(ruby, path)
|
46
|
+
return ruby unless path
|
47
|
+
|
48
|
+
path.split("/").inject(ruby) do |value, key|
|
49
|
+
case value
|
50
|
+
when Hash
|
51
|
+
value.fetch(key){ missing_json_path!(path) }
|
52
|
+
when Array
|
53
|
+
missing_json_path!(path) unless key =~ /^\d+$/
|
54
|
+
value.fetch(key.to_i){ missing_json_path!(path) }
|
55
|
+
else
|
56
|
+
missing_json_path!(path)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def missing_json_path!(path)
|
62
|
+
raise XmlSpec::MissingPath.new(path)
|
63
|
+
end
|
64
|
+
|
65
|
+
def missing_xml_directory!
|
66
|
+
raise XmlSpec::MissingDirectory
|
67
|
+
end
|
68
|
+
|
69
|
+
def missing_xml_file!(path)
|
70
|
+
raise XmlSpec::MissingFile.new(path)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require "xml_spec/matchers/be_xml_eql"
|
2
|
+
#require "xml_spec/matchers/include_xml"
|
3
|
+
#require "xml_spec/matchers/have_xml_path"
|
4
|
+
#require "xml_spec/matchers/have_xml_type"
|
5
|
+
#require "xml_spec/matchers/have_xml_size"
|
6
|
+
|
7
|
+
module XmlSpec
|
8
|
+
module Matchers
|
9
|
+
|
10
|
+
def be_xml_eql( xml=nil )
|
11
|
+
XmlSpec::Matchers::BeXmlEql.new( xml )
|
12
|
+
end
|
13
|
+
|
14
|
+
#def include_xml(xml = nil)
|
15
|
+
#XmlSpec::Matchers::IncludeJson.new(xml)
|
16
|
+
#end
|
17
|
+
|
18
|
+
#def have_xml_path(path)
|
19
|
+
#XmlSpec::Matchers::HaveJsonPath.new(path)
|
20
|
+
#end
|
21
|
+
|
22
|
+
#def have_xml_type(type)
|
23
|
+
#XmlSpec::Matchers::HaveJsonType.new(type)
|
24
|
+
#end
|
25
|
+
|
26
|
+
#def have_xml_size(size)
|
27
|
+
#XmlSpec::Matchers::HaveJsonSize.new(size)
|
28
|
+
#end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
RSpec.configure do |config|
|
34
|
+
config.include XmlSpec::Matchers
|
35
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module XmlSpec
|
2
|
+
module Matchers
|
3
|
+
class BeXmlEql
|
4
|
+
|
5
|
+
include XmlSpec::Helpers
|
6
|
+
include XmlSpec::Exclusion
|
7
|
+
include XmlSpec::Messages
|
8
|
+
|
9
|
+
attr_reader :expected, :actual
|
10
|
+
|
11
|
+
def diffable?
|
12
|
+
true
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize( expected_xml=nil )
|
16
|
+
@expected_xml = expected_xml
|
17
|
+
end
|
18
|
+
|
19
|
+
def matches?( actual_xml )
|
20
|
+
raise "Expected equivalent XML not provided" if @expected_xml.nil?
|
21
|
+
|
22
|
+
@actual_xml = actual_xml
|
23
|
+
@actual = parse_xml( actual_xml, @path )
|
24
|
+
@expected = parse_xml( @expected_xml, @path )
|
25
|
+
#@actual, @expected = scrub(actual_xml, @path), scrub(@expected_xml)
|
26
|
+
#@actual == @expected
|
27
|
+
EquivalentXml.equivalent?( @expected_xml, @actual_xml )
|
28
|
+
end
|
29
|
+
|
30
|
+
def at_path(path)
|
31
|
+
@path = path
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_file(path)
|
36
|
+
@expected_xml = load_xml(path)
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
def excluding(*keys)
|
41
|
+
excluded_keys.merge(keys.map(&:to_s))
|
42
|
+
self
|
43
|
+
end
|
44
|
+
|
45
|
+
def including(*keys)
|
46
|
+
excluded_keys.subtract(keys.map(&:to_s))
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
def failure_message_for_should
|
51
|
+
message_with_path( "Expected equivalent XML" ) #+ "\nReadable Diff:\n#{diff}"
|
52
|
+
end
|
53
|
+
|
54
|
+
def failure_message_for_should_not
|
55
|
+
message_with_path( "Expected inequivalent XML" )
|
56
|
+
end
|
57
|
+
|
58
|
+
def description
|
59
|
+
message_with_path("equal XML")
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def diff
|
65
|
+
' ' + expected.diff( actual ).interpret_diff.join( "\n " )
|
66
|
+
end
|
67
|
+
|
68
|
+
def scrub(xml, path = nil)
|
69
|
+
generate_normalized_xml(exclude_keys(parse_xml(xml, path))).chomp + "\n"
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe XmlSpec::Configuration do
|
4
|
+
|
5
|
+
it "excludes id and timestamps by default" do
|
6
|
+
XmlSpec.excluded_keys.should == ["id", "created_at", "updated_at"]
|
7
|
+
end
|
8
|
+
|
9
|
+
it "excludes custom keys" do
|
10
|
+
XmlSpec.exclude_keys("token")
|
11
|
+
XmlSpec.excluded_keys.should == ["token"]
|
12
|
+
end
|
13
|
+
|
14
|
+
it "excludes custom keys via setter" do
|
15
|
+
XmlSpec.excluded_keys = ["token"]
|
16
|
+
XmlSpec.excluded_keys.should == ["token"]
|
17
|
+
end
|
18
|
+
|
19
|
+
it "excludes custom keys via block" do
|
20
|
+
XmlSpec.configure{ |c| c.exclude_keys("token") }
|
21
|
+
XmlSpec.excluded_keys.should == ["token"]
|
22
|
+
end
|
23
|
+
|
24
|
+
it "excludes custom keys via block setter" do
|
25
|
+
XmlSpec.configure{ |c| c.excluded_keys = ["token"] }
|
26
|
+
XmlSpec.excluded_keys.should == ["token"]
|
27
|
+
end
|
28
|
+
|
29
|
+
it "excludes custom keys via instance-evaluated block" do
|
30
|
+
XmlSpec.configure{ exclude_keys("token") }
|
31
|
+
XmlSpec.excluded_keys.should == ["token"]
|
32
|
+
end
|
33
|
+
|
34
|
+
it "ensures its excluded keys are strings" do
|
35
|
+
XmlSpec.exclude_keys(:token)
|
36
|
+
XmlSpec.excluded_keys.should == ["token"]
|
37
|
+
end
|
38
|
+
|
39
|
+
it "ensures its excluded keys are unique" do
|
40
|
+
XmlSpec.exclude_keys("token", :token)
|
41
|
+
XmlSpec.excluded_keys.should == ["token"]
|
42
|
+
end
|
43
|
+
|
44
|
+
it "resets its excluded keys" do
|
45
|
+
original = XmlSpec.excluded_keys
|
46
|
+
|
47
|
+
XmlSpec.exclude_keys("token")
|
48
|
+
XmlSpec.excluded_keys.should_not == original
|
49
|
+
|
50
|
+
XmlSpec.reset
|
51
|
+
XmlSpec.excluded_keys.should == original
|
52
|
+
end
|
53
|
+
|
54
|
+
it "resets its directory" do
|
55
|
+
XmlSpec.directory.should be_nil
|
56
|
+
|
57
|
+
XmlSpec.directory = "/"
|
58
|
+
XmlSpec.directory.should_not be_nil
|
59
|
+
|
60
|
+
XmlSpec.reset
|
61
|
+
XmlSpec.directory.should be_nil
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe XmlSpec::Helpers do
|
4
|
+
|
5
|
+
include described_class
|
6
|
+
|
7
|
+
let :xml do
|
8
|
+
%(<xml><specs type="array"><spec type="integer">1</spec><spec type="integer">2</spec></specs></xml>)
|
9
|
+
end
|
10
|
+
|
11
|
+
let :normalized do
|
12
|
+
<<-XML
|
13
|
+
<?xml version="1.0"?>
|
14
|
+
<xml>
|
15
|
+
<specs type="array">
|
16
|
+
<spec type="integer">1</spec>
|
17
|
+
<spec type="integer">2</spec>
|
18
|
+
</specs>
|
19
|
+
</xml>
|
20
|
+
XML
|
21
|
+
end
|
22
|
+
|
23
|
+
let :hash do
|
24
|
+
{"xml" => {"specs" => [1, 2]}}
|
25
|
+
end
|
26
|
+
|
27
|
+
context "parse_xml" do
|
28
|
+
|
29
|
+
it "parses XML documents" do
|
30
|
+
parse_xml( xml ).should == hash
|
31
|
+
end
|
32
|
+
|
33
|
+
it "raises a parser error for invalid XML" do
|
34
|
+
expect{ parse_xml("xml_spec") }.to raise_error( XmlSpec::XmlSyntaxError )
|
35
|
+
end
|
36
|
+
|
37
|
+
it "parses at a path if given" do
|
38
|
+
parse_xml( xml, "xml/specs" ).should == [1, 2]
|
39
|
+
parse_xml( xml, "xml/specs/0" ).should == 1
|
40
|
+
end
|
41
|
+
|
42
|
+
it "raises an error for a missing path" do
|
43
|
+
%w(spec spec/1).each do |path|
|
44
|
+
expect{ parse_xml( xml, path ) }.to raise_error( XmlSpec::MissingPath )
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
context "normalize_xml" do
|
51
|
+
|
52
|
+
it "normalizes a XML document" do
|
53
|
+
normalize_xml( xml ).should == normalized.chomp
|
54
|
+
end
|
55
|
+
|
56
|
+
#it "normalizes at a path" do
|
57
|
+
#normalize_xml(%({"xml":["spec"]}), "xml/0").should == %("spec")
|
58
|
+
#end
|
59
|
+
|
60
|
+
#it "accepts a XML value" do
|
61
|
+
#normalize_xml(%("xml_spec")).should == %("xml_spec")
|
62
|
+
#end
|
63
|
+
|
64
|
+
#it "normalizes XML values" do
|
65
|
+
#normalize_xml(%(1e+1)).should == %(10.0)
|
66
|
+
#end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
context "generate_normalized_xml" do
|
71
|
+
|
72
|
+
it "generates a normalized XML document" do
|
73
|
+
generate_normalized_xml( hash ).should == normalized.chomp
|
74
|
+
end
|
75
|
+
|
76
|
+
it "generates a normalized XML value" do
|
77
|
+
generate_normalized_xml( nil ).should == %(<?xml version=\"1.0\"?>)
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
#context "load_xml_file" do
|
83
|
+
#it "raises an error when no directory is set" do
|
84
|
+
#expect{ load_xml("one.xml") }.to raise_error(XmlSpec::MissingDirectory)
|
85
|
+
#end
|
86
|
+
|
87
|
+
#it "returns JSON when the file exists" do
|
88
|
+
#XmlSpec.directory = files_path
|
89
|
+
#load_xml("one.xml").should == %({"value":"from_file"})
|
90
|
+
#end
|
91
|
+
|
92
|
+
#it "ignores extra slashes" do
|
93
|
+
#XmlSpec.directory = "/#{files_path}/"
|
94
|
+
#load_xml("one.xml").should == %({"value":"from_file"})
|
95
|
+
#end
|
96
|
+
|
97
|
+
#it "raises an error when the file doesn't exist" do
|
98
|
+
#XmlSpec.directory = files_path
|
99
|
+
#expect{ load_xml("bogus.xml") }.to raise_error(XmlSpec::MissingFile)
|
100
|
+
#end
|
101
|
+
|
102
|
+
#it "raises an error when the directory doesn't exist" do
|
103
|
+
#XmlSpec.directory = "#{files_path}_bogus"
|
104
|
+
#expect{ load_xml("one.xml") }.to raise_error(XmlSpec::MissingFile)
|
105
|
+
#end
|
106
|
+
|
107
|
+
#it "finds nested files" do
|
108
|
+
#XmlSpec.directory = files_path
|
109
|
+
#load_xml("project/one.xml").should == %({"nested":"inside_folder"})
|
110
|
+
#load_xml("project/version/one.xml").should == %({"nested":"deeply"})
|
111
|
+
#end
|
112
|
+
#end
|
113
|
+
|
114
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe XmlSpec::Matchers do
|
4
|
+
|
5
|
+
let(:environment) do
|
6
|
+
klass = Class.new
|
7
|
+
klass.send(:include, XmlSpec::Matchers)
|
8
|
+
klass.new
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:json){ %({"json":"spec"}) }
|
12
|
+
|
13
|
+
#context "be_json_eql" do
|
14
|
+
#it "instantiates its matcher" do
|
15
|
+
#XmlSpec::Matchers::BeJsonEql.should_receive(:new).with(json)
|
16
|
+
#environment.be_json_eql(json)
|
17
|
+
#end
|
18
|
+
|
19
|
+
#it "returns its matcher" do
|
20
|
+
#matcher = environment.be_json_eql(json)
|
21
|
+
#matcher.should be_a(XmlSpec::Matchers::BeJsonEql)
|
22
|
+
#end
|
23
|
+
#end
|
24
|
+
|
25
|
+
#context "include_json" do
|
26
|
+
#it "instantiates its matcher" do
|
27
|
+
#XmlSpec::Matchers::IncludeJson.should_receive(:new).with(json)
|
28
|
+
#environment.include_json(json)
|
29
|
+
#end
|
30
|
+
|
31
|
+
#it "returns its matcher" do
|
32
|
+
#matcher = environment.include_json(json)
|
33
|
+
#matcher.should be_a(XmlSpec::Matchers::IncludeJson)
|
34
|
+
#end
|
35
|
+
#end
|
36
|
+
|
37
|
+
#context "have_json_path" do
|
38
|
+
#let(:path){ "json" }
|
39
|
+
|
40
|
+
#it "instantiates its matcher" do
|
41
|
+
#XmlSpec::Matchers::HaveJsonPath.should_receive(:new).with(path)
|
42
|
+
#environment.have_json_path(path)
|
43
|
+
#end
|
44
|
+
|
45
|
+
#it "returns its matcher" do
|
46
|
+
#matcher = environment.have_json_path(path)
|
47
|
+
#matcher.should be_a(XmlSpec::Matchers::HaveJsonPath)
|
48
|
+
#end
|
49
|
+
#end
|
50
|
+
|
51
|
+
#context "have_json_type" do
|
52
|
+
#let(:type){ Hash }
|
53
|
+
|
54
|
+
#it "instantiates its matcher" do
|
55
|
+
#XmlSpec::Matchers::HaveJsonType.should_receive(:new).with(type)
|
56
|
+
#environment.have_json_type(type)
|
57
|
+
#end
|
58
|
+
|
59
|
+
#it "returns its matcher" do
|
60
|
+
#matcher = environment.have_json_type(type)
|
61
|
+
#matcher.should be_a(XmlSpec::Matchers::HaveJsonType)
|
62
|
+
#end
|
63
|
+
#end
|
64
|
+
|
65
|
+
#context "have_json_size" do
|
66
|
+
#let(:size){ 1 }
|
67
|
+
|
68
|
+
#it "instantiates its matcher" do
|
69
|
+
#XmlSpec::Matchers::HaveJsonSize.should_receive(:new).with(size)
|
70
|
+
#environment.have_json_size(size)
|
71
|
+
#end
|
72
|
+
|
73
|
+
#it "returns its matcher" do
|
74
|
+
#matcher = environment.have_json_size(size)
|
75
|
+
#matcher.should be_a(XmlSpec::Matchers::HaveJsonSize)
|
76
|
+
#end
|
77
|
+
#end
|
78
|
+
|
79
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/xml-spec.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'xml_spec/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "xml-spec"
|
8
|
+
spec.version = XmlSpec::VERSION
|
9
|
+
spec.authors = ["C. Jason Harrelson"]
|
10
|
+
spec.email = ["jason@lookforwardenterprises.com"]
|
11
|
+
spec.summary = %q{XML matchers for specs.}
|
12
|
+
spec.description = %q{XML matchers for specs. See README for more info.}
|
13
|
+
spec.homepage = "https://github.com/midas/xml_spec"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
#spec.add_dependency "multi_json", "~> 1.0"
|
22
|
+
spec.add_dependency "activesupport", ">= 3"
|
23
|
+
spec.add_dependency "builder", ">= 3"
|
24
|
+
spec.add_dependency "equivalent-xml"
|
25
|
+
spec.add_dependency "nokogiri", "~> 1"
|
26
|
+
spec.add_dependency "nori", "~> 2"
|
27
|
+
spec.add_dependency "rspec", "~> 2"
|
28
|
+
|
29
|
+
spec.add_development_dependency "bundler", "~> 1"
|
30
|
+
spec.add_development_dependency "guard-rspec"
|
31
|
+
spec.add_development_dependency "rake"
|
32
|
+
end
|
metadata
ADDED
@@ -0,0 +1,198 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: xml-spec
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- C. Jason Harrelson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-01-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: builder
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: equivalent-xml
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: nokogiri
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: nori
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '2'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '2'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '2'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ~>
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '2'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: bundler
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ~>
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '1'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ~>
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '1'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: guard-rspec
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - '>='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rake
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - '>='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - '>='
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
description: XML matchers for specs. See README for more info.
|
140
|
+
email:
|
141
|
+
- jason@lookforwardenterprises.com
|
142
|
+
executables: []
|
143
|
+
extensions: []
|
144
|
+
extra_rdoc_files: []
|
145
|
+
files:
|
146
|
+
- .gitignore
|
147
|
+
- .rspec
|
148
|
+
- .ruby-gemset
|
149
|
+
- .ruby-version
|
150
|
+
- Gemfile
|
151
|
+
- Guardfile.example
|
152
|
+
- LICENSE.txt
|
153
|
+
- README.md
|
154
|
+
- Rakefile
|
155
|
+
- lib/xml-spec.rb
|
156
|
+
- lib/xml_spec.rb
|
157
|
+
- lib/xml_spec/configuration.rb
|
158
|
+
- lib/xml_spec/errors.rb
|
159
|
+
- lib/xml_spec/exclusion.rb
|
160
|
+
- lib/xml_spec/helpers.rb
|
161
|
+
- lib/xml_spec/matchers.rb
|
162
|
+
- lib/xml_spec/matchers/be_xml_eql.rb
|
163
|
+
- lib/xml_spec/messages.rb
|
164
|
+
- lib/xml_spec/version.rb
|
165
|
+
- spec/configuration_spec.rb
|
166
|
+
- spec/helpers_spec.rb
|
167
|
+
- spec/matchers_spec.rb
|
168
|
+
- spec/spec_helper.rb
|
169
|
+
- xml-spec.gemspec
|
170
|
+
homepage: https://github.com/midas/xml_spec
|
171
|
+
licenses:
|
172
|
+
- MIT
|
173
|
+
metadata: {}
|
174
|
+
post_install_message:
|
175
|
+
rdoc_options: []
|
176
|
+
require_paths:
|
177
|
+
- lib
|
178
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
179
|
+
requirements:
|
180
|
+
- - '>='
|
181
|
+
- !ruby/object:Gem::Version
|
182
|
+
version: '0'
|
183
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - '>='
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0'
|
188
|
+
requirements: []
|
189
|
+
rubyforge_project:
|
190
|
+
rubygems_version: 2.0.3
|
191
|
+
signing_key:
|
192
|
+
specification_version: 4
|
193
|
+
summary: XML matchers for specs.
|
194
|
+
test_files:
|
195
|
+
- spec/configuration_spec.rb
|
196
|
+
- spec/helpers_spec.rb
|
197
|
+
- spec/matchers_spec.rb
|
198
|
+
- spec/spec_helper.rb
|