html_matchers 0.0.1

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 ADDED
@@ -0,0 +1 @@
1
+ .svn
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 [name of plugin creator]
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,25 @@
1
+ HtmlMatchers
2
+ ============
3
+
4
+ This Rails plugin provides a layer of abstraction on top of Rspec for testing
5
+ HTML contents.
6
+
7
+ It depends on Rspec and Hpricot: rspec, and rspec-rails because enhancing them
8
+ is the whole point of this plugin, and Hpricot because I find it so much more
9
+ capable, and faster than the assert_select that is built into Rails.
10
+
11
+ Using from Cucumber
12
+ ===================
13
+
14
+ Add require 'cucumber/rails/rspec' to features/support/env.rb.
15
+
16
+ This is important, so that rspec matchers are in play.
17
+
18
+
19
+ Example
20
+ =======
21
+
22
+ Example goes here.
23
+
24
+
25
+ Copyright (c) 2008 [name of plugin creator], released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,42 @@
1
+ require 'rake'
2
+ require 'spec/rake/spectask'
3
+ # require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+
6
+ desc 'Default: run spec tests.'
7
+ task :default => :spec
8
+
9
+ desc "Run all specs"
10
+ Spec::Rake::SpecTask.new do |t|
11
+ t.spec_files = FileList['spec/**/*_spec.rb']
12
+ t.spec_opts = ['--options', 'spec/spec.opts']
13
+ # unless ENV['NO_RCOV']
14
+ # t.rcov = true
15
+ # t.rcov_dir = 'coverage'
16
+ # t.rcov_opts = ['--exclude', 'lib/spec.rb,lib/spec/runner.rb,spec\/spec,bin\/spec,examples,\/var\/lib\/gems,\/Library\/Ruby,\.autotest']
17
+ # end
18
+ end
19
+
20
+ desc 'Generate documentation for the html_matchers plugin.'
21
+ Rake::RDocTask.new(:rdoc) do |rdoc|
22
+ rdoc.rdoc_dir = 'rdoc'
23
+ rdoc.title = 'HtmlMatchers'
24
+ rdoc.options << '--line-numbers' << '--inline-source'
25
+ rdoc.rdoc_files.include('README')
26
+ rdoc.rdoc_files.include('lib/**/*.rb')
27
+ end
28
+
29
+ begin
30
+ require 'jeweler'
31
+ Jeweler::Tasks.new do |gemspec|
32
+ gemspec.name = "html_matchers"
33
+ gemspec.summary = "HTML entity matchers for RSpec"
34
+ gemspec.description = "HTML entity matchers for RSpec"
35
+ gemspec.email = "stephen@bendyworks.com"
36
+ gemspec.homepage = "http://github.com/bendyworks/html_matchers"
37
+ gemspec.authors = ["bendycode, helabed, listrophy"]
38
+ end
39
+ Jeweler::GemcutterTasks.new
40
+ rescue LoadError
41
+ puts "Jeweler not available. Install it with: gem install jeweler"
42
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
data/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ # Include hook code here
2
+ require File.join(File.dirname(__FILE__), 'lib', 'html_matchers')
data/install.rb ADDED
@@ -0,0 +1 @@
1
+ # Install hook code here
data/lib/.gitignore ADDED
@@ -0,0 +1 @@
1
+ .svn
@@ -0,0 +1,60 @@
1
+ require 'hpricot'
2
+
3
+ # %w(check_box_group drop_down radio_group span_text table_body table_header td_link).each do |element|
4
+ # require File.join(File.dirname(__FILE__), 'matchers', "#{element}_matcher")
5
+ # end
6
+
7
+ Dir.glob(File.dirname(__FILE__) + '/matchers/*.rb').each do |rb|
8
+ require rb
9
+ end
10
+
11
+ module Spec # :nodoc:
12
+ module Rails
13
+ module Matchers
14
+
15
+ def have_button expected
16
+ ButtonMatcher.new expected
17
+ end
18
+
19
+ def have_check_box_group target_name, expected
20
+ CheckBoxGroupMatcher.new target_name, expected
21
+ end
22
+
23
+ def have_dropdown target_id, expected_options
24
+ DropDownMatcher.new target_id, expected_options
25
+ end
26
+
27
+ def have_image expected_path
28
+ ImageMatcher.new expected_path
29
+ end
30
+
31
+ def have_options expected_options
32
+ OptionsMatcher.new expected_options
33
+ end
34
+
35
+ def have_radio_group target_name, expected_radio_choices
36
+ RadioGroupMatcher.new target_name, expected_radio_choices
37
+ end
38
+
39
+ def have_span_text target_id, expected_text
40
+ SpanTextMatcher.new target_id, expected_text
41
+ end
42
+
43
+ def have_table table_id_or_expected, expected = nil
44
+ TableMatcher.new table_id_or_expected, expected
45
+ end
46
+
47
+ def have_table_header table_id_or_expected, expected = nil
48
+ TableHeaderMatcher.new table_id_or_expected, expected
49
+ end
50
+
51
+ def have_table_body table_id_or_expected, expected = nil
52
+ TableBodyMatcher.new table_id_or_expected, expected
53
+ end
54
+
55
+ def have_td_link target_id, expected_link, expected_text
56
+ TdLinkMatcher.new target_id, expected_link, expected_text
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1 @@
1
+ .svn
@@ -0,0 +1,33 @@
1
+ module Spec # :nodoc:
2
+ module Rails
3
+ module Matchers
4
+ class ButtonMatcher
5
+ def initialize expected_value
6
+ # @target_id = target_id
7
+ @expected = expected_value
8
+ end
9
+
10
+ def matches? response
11
+ @actual = extract_html_content response.body
12
+ @actual == @expected
13
+ end
14
+
15
+ def failure_message
16
+ "\nWrong button value.\nexpected: #{@expected.inspect}\n found: #{@actual.inspect}\n\n"
17
+ end
18
+
19
+ def negative_failure_message
20
+ "\nShould not have matched button: #{@target_id}, with text: '#{@expected}'\n\n"
21
+ end
22
+
23
+ def extract_html_content html
24
+ doc = Hpricot.XML(html)
25
+ # elements = doc.search("//input[@value='#{@expected}' & @type='button|submit']")
26
+ # elements = doc.search("input[@value~='#{@expected}'][@type]")
27
+ elements = doc.search("//input[@value='#{@expected}']").select{|e| ['submit', 'button'].include?(e['type'])}
28
+ elements.map{|n| n['value']}.first
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,42 @@
1
+ module Spec # :nodoc:
2
+ module Rails
3
+ module Matchers
4
+ class CheckBoxGroupMatcher
5
+
6
+ def initialize target_name, expected
7
+ @expected = expected
8
+ @target_name = target_name
9
+ end
10
+
11
+ def matches? response
12
+ @actual = extract_html_content response.body
13
+ @actual == @expected
14
+ end
15
+
16
+ def failure_message
17
+ "\nWrong check box group contents.\nexpected: #{@expected.inspect}\n found: #{@actual.inspect}\n\n"
18
+ end
19
+
20
+ def negative_failure_message
21
+ "\nShould not have matched check box group: name: #{@target_name}, with: #{@expected.inspect}\n\n"
22
+ end
23
+
24
+ def extract_html_content html
25
+ doc = Hpricot.XML(html)
26
+ # elements = doc.search('div input[type="checkbox"]')
27
+ elements = doc.search('div/input')
28
+ elements = elements.select{|n| n.elem? && n.get_attribute('type') == 'checkbox' && n.get_attribute('name') == @target_name}
29
+ elements.map{|n| value = n.get_attribute('value'); [value, find_label(n)]}
30
+ end
31
+
32
+ private
33
+
34
+ def find_label node
35
+ label_node = node.next_sibling
36
+ label_node.inner_text
37
+ end
38
+
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,43 @@
1
+ module Spec # :nodoc:
2
+ module Rails
3
+ module Matchers
4
+ class DropDownMatcher
5
+
6
+ def initialize target_id, expected
7
+ @target_id = target_id
8
+ @expected = expected
9
+ end
10
+
11
+ def matches? response
12
+ @actual = extract_html_content response.body
13
+ @actual == @expected
14
+ end
15
+
16
+ def failure_message
17
+ if @found_select
18
+ "\nWrong '#{@target_id}' drop down contents.\nexpected: #{@expected.inspect}\n found: #{@actual.inspect}\n\n"
19
+ else
20
+ "\nCould not find a select element with id: '#{@target_id}'\n\n"
21
+ end
22
+ end
23
+
24
+ def negative_failure_message
25
+ "\nShould not have matched dropdown with id: #{@target_id}\n\tand contents: #{@expected.inspect}\n\n"
26
+ end
27
+
28
+ def extract_html_content html
29
+ doc = Hpricot.XML(html)
30
+ select = doc.search("select##{@target_id}")
31
+ @found_select = ! select.empty?
32
+
33
+ if @found_select
34
+ select.search("/option").map{|n| n.inner_text.strip}
35
+ else
36
+ []
37
+ end
38
+ end
39
+
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,32 @@
1
+ module Spec # :nodoc:
2
+ module Rails
3
+ module Matchers
4
+ class ImageMatcher
5
+ def initialize expected_path
6
+ @expected = expected_path
7
+ end
8
+
9
+ def matches? response
10
+ @actual = extract_html_content response.body
11
+ @actual =~ /#{@expected}/
12
+ end
13
+
14
+ def failure_message
15
+ "\nWrong image path.\nexpected: #{@expected.inspect}\n found: #{@actual.inspect}\n\n"
16
+ end
17
+
18
+ def negative_failure_message
19
+ "\nShould not have matched image with path: '#{@expected}'\n\n"
20
+ end
21
+
22
+ def extract_html_content html
23
+ doc = Hpricot.XML(html)
24
+ elements = doc.search("img[@src*=\"#{@expected}\"]")
25
+ # elements.each {|e| puts e.inspect}
26
+ # elements.first.to_html
27
+ elements.map{|n| n.to_html}.first
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,29 @@
1
+ module Spec # :nodoc:
2
+ module Rails
3
+ module Matchers
4
+ class OptionsMatcher
5
+ def initialize expected
6
+ @expected = expected
7
+ end
8
+
9
+ def matches? response
10
+ @actual = extract_html_content response.body
11
+ @actual == @expected
12
+ end
13
+
14
+ def failure_message
15
+ "\nWrong option contents.\nexpected: #{@expected.inspect}\n found: #{@actual.inspect}\n\n"
16
+ end
17
+
18
+ def negative_failure_message
19
+ "\nShould not have matched contents: #{@expected.inspect}\n\n"
20
+ end
21
+
22
+ def extract_html_content html
23
+ doc = Hpricot.XML(html)
24
+ doc.search("/option").map{|n| n.inner_text.strip}
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,32 @@
1
+ module Spec # :nodoc:
2
+ module Rails
3
+ module Matchers
4
+ class RadioGroupMatcher
5
+ def initialize target_name, expected
6
+ @expected = expected
7
+ @target_name = target_name
8
+ end
9
+
10
+ def matches? response
11
+ @actual = extract_html_content response.body
12
+ @actual == @expected
13
+ end
14
+
15
+ def failure_message
16
+ "\nWrong radio group contents.\nexpected: #{@expected.inspect}\n found: #{@actual.inspect}\n\n"
17
+ end
18
+
19
+ def negative_failure_message
20
+ "\nShould not have matched radio group: name: #{@target_name}, with: #{@expected.inspect}\n\n"
21
+ end
22
+
23
+ def extract_html_content html
24
+ doc = Hpricot.XML(html)
25
+ elements = doc.search('input')
26
+ elements = elements.select{|n| n.elem? && n.get_attribute('name') == @target_name}
27
+ elements.map{|n| n.get_attribute('value')}
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,31 @@
1
+ module Spec # :nodoc:
2
+ module Rails
3
+ module Matchers
4
+ class SpanTextMatcher
5
+ def initialize target_id, expected_text
6
+ @target_id = target_id
7
+ @expected = expected_text
8
+ end
9
+
10
+ def matches? response
11
+ @actual = extract_html_content response.body
12
+ @actual == @expected
13
+ end
14
+
15
+ def failure_message
16
+ "\nWrong span text contents.\nexpected: #{@expected.inspect}\n found: #{@actual.inspect}\n\n"
17
+ end
18
+
19
+ def negative_failure_message
20
+ "\nShould not have matched span: #{@target_id}, with text: '#{@expected}'\n\n"
21
+ end
22
+
23
+ def extract_html_content html
24
+ doc = Hpricot.XML(html)
25
+ elements = doc.search("p span##{@target_id}")
26
+ elements.map{|n| n.inner_text.strip}.first
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,39 @@
1
+ module Spec # :nodoc:
2
+ module Rails
3
+ module Matchers
4
+ class TableBodyMatcher
5
+
6
+ def initialize table_id_or_expected, expected
7
+ case table_id_or_expected
8
+ when String
9
+ @table_id = table_id_or_expected
10
+ @expected = expected
11
+ when Array
12
+ @expected = table_id_or_expected
13
+ end
14
+ raise 'Invalid "expected" argument' if @expected.nil?
15
+ end
16
+
17
+ def matches? response
18
+ @actual = extract_html_content response.body
19
+ @actual == @expected
20
+ end
21
+
22
+ def failure_message
23
+ "\nWrong table body contents.\nexpected: #{@expected.inspect}\n found: #{@actual.inspect}\n\n"
24
+ end
25
+
26
+ def negative_failure_message
27
+ "\nTable body should not have matched: #{@expected.inspect}\n"
28
+ end
29
+
30
+ def extract_html_content html
31
+ doc = Hpricot.XML(html)
32
+ elements = doc.search("table#{"##{@table_id}" if @table_id} tr").reject{|e| e.search('td').empty? }
33
+ elements.map{|n| n.search('/td').map{|n| n.inner_text.strip.gsub(/[ \t]*\n[\n \t]*/, "\n")}}
34
+ end
35
+
36
+ end
37
+ end
38
+ end
39
+ end