rspec-sitemap-matchers 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rspec-sitemap-matchers.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2012 Attila Györffy and Unboxed Consulting
2
+ MIT License
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,67 @@
1
+ # RSpec sitemap matchers
2
+
3
+ Sitemap [protocol](http://www.sitemaps.org/protocol.html) matchers for RSpec.
4
+
5
+ Sitemaps are an easy way to inform search engines about pages on their sites that are available for crawling. In its simplest form, a Sitemap is an XML file that lists URLs for a site along with additional metadata about each URL (when it was last updated, how often it usually changes, and how important it is, relative to other URLs in the site) so that search engines can more intelligently crawl the site.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'rspec-sitemap-matchers'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install rspec-sitemap-matchers
20
+
21
+ These matchers are not loaded by default in order not to pollute the global RSpec matcher namespace and consequentially to be able to specify in which context you would want to make use of them.
22
+
23
+ You can load them globally via your `spec_helper` (not recommended):
24
+
25
+ RSpec.configure do |config|
26
+ config.include RSpec::Sitemap::Matchers
27
+ end
28
+
29
+ … or `include RSpec::Sitemap::Matchers` in an individual spec file (preferred way).
30
+
31
+ ## Usage
32
+
33
+ These matchers can be used on `File`s, `String`s and any arbitary `IO` instance that has a `:read` method:
34
+
35
+ describe "My Sitemap" do
36
+
37
+ subject { File.open(Rails.root + 'tmp' + 'sitemap.xml') }
38
+
39
+ it { should include_url("http://www.example.com") }
40
+ it { should_not include_url("http://www.a-different-example.com") }
41
+
42
+ end
43
+
44
+ The matchers also support more specific attribution matching, such as priorities as per the Sitemap protocol. These can be chained together:
45
+
46
+ it { should include_url('http://www.example.com').priority(0.5) }
47
+
48
+ ## Planned features
49
+
50
+ * More chainable attribute modifiers, such as `lastmod` and `changefreq`
51
+ * Stricter markup and structure validation
52
+ * Encoding validation matcher (Sitemaps must be UTF-8 encoded)
53
+ * `be_a_valid_sitemap` matcher
54
+
55
+ ## Contributing
56
+
57
+ 1. Fork it
58
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
59
+ 3. Write meaningful and readable tests
60
+ 4. Make the tests pass (ie implement your changes)
61
+ 5. Commit your changes (`git commit -am 'Add some feature'`)
62
+ 6. Push to the branch (`git push origin my-new-feature`)
63
+ 7. Create new Pull Request
64
+
65
+ ## Copyright
66
+
67
+ Copyright © 2012 Attila Györffy and [Unboxed Consulting](http://www.unboxedconsulting.com). See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,4 @@
1
+ require 'nokogiri'
2
+
3
+ require "rspec/sitemap/matchers/version"
4
+ require "rspec/sitemap/matchers/include_url"
@@ -0,0 +1,79 @@
1
+ module RSpec::Sitemap::Matchers
2
+ class IncludeUrl
3
+ def initialize(expected_location)
4
+ @expected_location = expected_location
5
+ end
6
+
7
+ # @api private
8
+ def matches?(actual)
9
+ @actual = Nokogiri::XML(actual) { |config| config.noblanks }
10
+ @nodes = @actual.xpath(construct_xpath)
11
+ @nodes.any? && attributes_match?
12
+ end
13
+
14
+ def failure_message
15
+ [].tap do |messages|
16
+ messages << "expected #{@actual} to include a URL to #{@expected_location}"
17
+ unmatched_attributes.each { |attribute, actual_value|
18
+ if actual_value.nil?
19
+ messages << "with a #{attribute} of #{expected_attributes[attribute]} but the #{attribute} was not set"
20
+ else
21
+ messages << "with a #{attribute} of #{expected_attributes[attribute]} but it was set to #{actual_value}"
22
+ end
23
+ }
24
+ end.join(' ')
25
+ end
26
+
27
+ def priority(expected_priority)
28
+ expected_attributes.merge!(:priority => expected_priority)
29
+ self
30
+ end
31
+
32
+ private
33
+
34
+ def expected_attributes
35
+ @expected_attributes ||= {}
36
+ end
37
+
38
+ def attributes_match?
39
+ expected_attributes.all? do |key, value|
40
+ matched_node.xpath(".//xmlns:#{key}[text()='#{value}']").any?
41
+ end
42
+ end
43
+
44
+ def matched_attributes
45
+ attributes = {}
46
+ matched_node.children.each do |node|
47
+ attributes[node.name.to_sym] = node.text
48
+ end
49
+ attributes
50
+ end
51
+
52
+ def unmatched_attributes
53
+ # First of all we remove all the attributes that match the expected values
54
+ remaining_unmatched = expected_attributes.clone.delete_if do |key, expected_value|
55
+ matched_attributes[key] == expected_value
56
+ end
57
+ # Then setting the remaining unmatched attributes to match the actual values found
58
+ remaining_unmatched.each do |key, value|
59
+ remaining_unmatched[key] = matched_attributes[key]
60
+ end
61
+ remaining_unmatched
62
+ end
63
+
64
+ def matched_node
65
+ # Using the first node matched to a specified URL as it would not
66
+ # make sense to have ultiple URL nodes with the same location.
67
+ @nodes.first
68
+ end
69
+
70
+ def construct_xpath
71
+ "//xmlns:url/xmlns:loc[text()='#{@expected_location}']/.."
72
+ end
73
+
74
+ end
75
+
76
+ def include_url(url)
77
+ IncludeUrl.new(url)
78
+ end
79
+ end
@@ -0,0 +1,7 @@
1
+ module RSpec
2
+ module Sitemap
3
+ module Matchers
4
+ VERSION = "0.0.1"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/rspec/sitemap/matchers/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Attila Györffy"]
6
+ gem.email = ["attila.gyorffy@unboxedconsulting.com"]
7
+ gem.description = %q{Sitemaps for RSpec}
8
+ gem.summary = %q{Sitemap protocol matchers for RSpec}
9
+ gem.homepage = "http://github.com/unboxed/rspec-sitemap-matchers"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "rspec-sitemap-matchers"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = RSpec::Sitemap::Matchers::VERSION
17
+
18
+ gem.add_runtime_dependency('rspec')
19
+ gem.add_runtime_dependency('nokogiri')
20
+
21
+ gem.add_development_dependency 'rake'
22
+ end
@@ -0,0 +1,74 @@
1
+ require "spec_helper"
2
+
3
+ module RSpec::Sitemap::Matchers
4
+ describe IncludeUrl do
5
+ include RSpec::Sitemap::Matchers
6
+
7
+ describe "#matches?" do
8
+
9
+ shared_examples_for "a matcher that passes or fails" do
10
+ it "passes" do
11
+ sitemap.should include_url('http://www.example.com')
12
+ end
13
+
14
+ it "fails" do
15
+ expect {
16
+ sitemap.should include_url('http://www.not-an-example.com')
17
+ }.to raise_error { |error|
18
+ error.message.should match("to include a URL to http://www.not-an-example.com")
19
+ }
20
+ end
21
+ end
22
+
23
+ context "on a File" do
24
+ it_should_behave_like "a matcher that passes or fails" do
25
+ let(:sitemap) { fixture('basic') }
26
+ end
27
+ end
28
+
29
+ context "on a String" do
30
+ it_should_behave_like "a matcher that passes or fails" do
31
+ let(:sitemap) { fixture('basic').read }
32
+ end
33
+ end
34
+
35
+ context "on any IO object that has a :read method" do
36
+ before do
37
+ sitemap.stub(:read).and_return(fixture('basic').read)
38
+ end
39
+
40
+ it_should_behave_like "a matcher that passes or fails" do
41
+ let(:sitemap) { mock('sitemap') }
42
+ end
43
+ end
44
+ end
45
+
46
+ describe "#priority" do
47
+ context "when it is set" do
48
+ let(:sitemap) { fixture('with_valid_priority') }
49
+ it "passes" do
50
+ sitemap.should include_url('http://www.example.com').priority('0.5')
51
+ end
52
+
53
+ it "fails" do
54
+ expect {
55
+ sitemap.should include_url('http://www.example.com').priority('0.8')
56
+ }.to raise_error { |error|
57
+ error.message.should match('to include a URL to http://www.example.com with a priority of 0.8 but it was set to 0.5')
58
+ }
59
+ end
60
+ end
61
+
62
+ context "when it is NOT set" do
63
+ let(:sitemap) { fixture('basic') }
64
+ it "fails" do
65
+ expect {
66
+ sitemap.should include_url('http://www.example.com').priority('0.5')
67
+ }.to raise_error { |error|
68
+ error.message.should match('to include a URL to http://www.example.com with a priority of 0.5 but the priority was not set')
69
+ }
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,22 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+
8
+ require 'rspec/sitemap/matchers'
9
+ require 'support/fixture_helper'
10
+
11
+ RSpec.configure do |config|
12
+ config.treat_symbols_as_metadata_keys_with_true_values = true
13
+ config.run_all_when_everything_filtered = true
14
+ config.filter_run :focus
15
+
16
+ # Run specs in random order to surface order dependencies. If you find an
17
+ # order dependency and want to debug it, you can fix the order by providing
18
+ # the seed, which is printed after each run.
19
+ # --seed 1234
20
+ config.order = 'random'
21
+ config.include FixtureHelper
22
+ end
@@ -0,0 +1,5 @@
1
+ module FixtureHelper
2
+ def fixture(type)
3
+ File.open(File.expand_path("../../support/fixtures/sitemaps/#{type}.xml", __FILE__))
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
3
+ <url>
4
+ <loc>http://www.example.com</loc>
5
+ </url>
6
+ </urlset>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
3
+ <url>
4
+ <loc>http://www.example.com</loc>
5
+ <priority>0.5</priority>
6
+ </url>
7
+ </urlset>
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rspec-sitemap-matchers
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Attila Györffy
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-09-03 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: nokogiri
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: Sitemaps for RSpec
63
+ email:
64
+ - attila.gyorffy@unboxedconsulting.com
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - .gitignore
70
+ - .rspec
71
+ - Gemfile
72
+ - LICENSE
73
+ - README.md
74
+ - Rakefile
75
+ - lib/rspec/sitemap/matchers.rb
76
+ - lib/rspec/sitemap/matchers/include_url.rb
77
+ - lib/rspec/sitemap/matchers/version.rb
78
+ - rspec-sitemap-matchers.gemspec
79
+ - spec/rspec/sitemap/matchers/include_url_spec.rb
80
+ - spec/spec_helper.rb
81
+ - spec/support/fixture_helper.rb
82
+ - spec/support/fixtures/sitemaps/basic.xml
83
+ - spec/support/fixtures/sitemaps/with_valid_priority.xml
84
+ homepage: http://github.com/unboxed/rspec-sitemap-matchers
85
+ licenses: []
86
+ post_install_message:
87
+ rdoc_options: []
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ segments:
97
+ - 0
98
+ hash: -4581193510046784126
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ! '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ segments:
106
+ - 0
107
+ hash: -4581193510046784126
108
+ requirements: []
109
+ rubyforge_project:
110
+ rubygems_version: 1.8.24
111
+ signing_key:
112
+ specification_version: 3
113
+ summary: Sitemap protocol matchers for RSpec
114
+ test_files:
115
+ - spec/rspec/sitemap/matchers/include_url_spec.rb
116
+ - spec/spec_helper.rb
117
+ - spec/support/fixture_helper.rb
118
+ - spec/support/fixtures/sitemaps/basic.xml
119
+ - spec/support/fixtures/sitemaps/with_valid_priority.xml