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.
@@ -0,0 +1,43 @@
1
+ module Spec # :nodoc:
2
+ module Rails
3
+ module Matchers
4
+ class TableHeaderMatcher
5
+ def initialize table_id_or_expected, expected
6
+ case table_id_or_expected
7
+ when String
8
+ @table_id = table_id_or_expected
9
+ @expected = expected
10
+ when Array
11
+ @expected = table_id_or_expected
12
+ end
13
+ raise 'Invalid "expected" argument' if @expected.nil?
14
+ end
15
+
16
+ def matches? response
17
+ @actual = extract_html_content response.body
18
+ @actual == @expected
19
+ end
20
+
21
+ def failure_message
22
+ "\nWrong table header contents.\nexpected: #{@expected.inspect}\n found: #{@actual.inspect}\n\n"
23
+ end
24
+
25
+ def negative_failure_message
26
+ "\nTable header should not have matched: #{@expected.inspect}\n"
27
+ end
28
+
29
+ def extract_html_content html
30
+ html = html.gsub(/[ \t]*<br *\/>[ \t]*/, "\n")
31
+ doc = Hpricot.XML(html)
32
+ elements = doc.search("table#{"##{@table_id}" if @table_id} tr")
33
+ elements = elements.reject{|e| e.search('th').empty? }
34
+ elements.map do |node|
35
+ node.search('/th').map do |n|
36
+ n.inner_text.strip.gsub(/[ \t]*\n[\n \t]*/, "\n")
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,57 @@
1
+ module Spec # :nodoc:
2
+ module Rails
3
+ module Matchers
4
+ class TableMatcher
5
+
6
+ def initialize table_selector_or_expected, expected
7
+ case table_selector_or_expected
8
+ when String
9
+ @table_selector = table_selector_or_expected
10
+ @expected = expected
11
+ when Array
12
+ @expected = table_selector_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 contents.\nexpected: #{@expected.inspect.gsub('], [', "],\n[")}\n found: #{@actual.inspect.gsub('], [', "],\n[")}\n\n"
24
+ end
25
+
26
+ def negative_failure_message
27
+ "\nTable should not have matched: #{@expected.inspect}\n"
28
+ end
29
+
30
+ def extract_html_content html
31
+ doc = Hpricot.XML(html)
32
+
33
+ rows = doc.search("table#{"#{@table_selector}" if @table_selector} tr")
34
+ header_elements = rows.reject{|e| e.search('th').empty? }
35
+ header_content = header_elements.map do |header_element|
36
+ header_element.search('/th').map do |n|
37
+ stripped = n.inner_html.gsub(/<script.*<\/script>/m, '')
38
+ temp_node = Hpricot.XML("<temp-node>#{stripped}</temp-node>")
39
+ temp_node.inner_text.strip.gsub(/[ \t]*\n[\n \t]*/, "\n")
40
+ end
41
+ end
42
+
43
+ body_elements = rows.reject{|e| e.search('td').empty? }
44
+ body_content = body_elements.map do |body_element|
45
+ body_element.search('/td').map do |n|
46
+ stripped = n.inner_html.gsub(/<script.*<\/script>/m, '')
47
+ temp_node = Hpricot.XML("<temp-node>#{stripped}</temp-node>")
48
+ temp_node.inner_text.strip.gsub(/[ \t]*\n[\n \t]*/, "\n")
49
+ end
50
+ end
51
+
52
+ header_content + body_content
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,30 @@
1
+ module Spec # :nodoc:
2
+ module Rails
3
+ module Matchers
4
+ class TdLinkMatcher
5
+
6
+ def initialize target_id, expected_text, expected_link
7
+ @xpath = "td##{target_id}"
8
+ @expected_link = expected_link
9
+ @expected_text = expected_text
10
+ end
11
+
12
+ def matches? response
13
+ @actual_text = extract_html_content response.body
14
+ @actual_text == @expected_text
15
+ end
16
+
17
+ def failure_message
18
+ "\nWrong #{@element_name} contents.\nexpected: #{@expected_text.inspect}\n found: #{@actual_text.inspect}\n\n"
19
+ end
20
+
21
+ def extract_html_content html
22
+ doc = Hpricot.XML(html)
23
+ elements = doc.search(@xpath)
24
+ elements.map{|n| n.inner_text.strip}.first
25
+ end
26
+
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,59 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe 'span_text_matcher' do
4
+ FORM_WITH_SUBMIT_INPUT = %Q{<form><div><input value="Approve" type="submit"></div></form>}
5
+ FORM_WITH_BUTTON_INPUT = %Q{<form><div><input value="Approve" type="button"></div></form>}
6
+ FORM_WITH_RADIO_INPUT = %Q{<form><div><input value="Approve" type="radio"></div></form>}
7
+ FORM_WITH_BUTTON_INPUT_WITH_SPACES = %Q{<form><div><input value="Mark as spam" type="button"></div></form>}
8
+
9
+ it 'should find matching submit input' do
10
+ response = mock_model(Object, :body => FORM_WITH_SUBMIT_INPUT)
11
+ response.should have_button('Approve')
12
+ end
13
+
14
+ it 'should find matching button input' do
15
+ response = mock_model(Object, :body => FORM_WITH_BUTTON_INPUT)
16
+ response.should have_button('Approve')
17
+ end
18
+
19
+ it 'should find matching button input with spaces' do
20
+ response = mock_model(Object, :body => FORM_WITH_BUTTON_INPUT_WITH_SPACES)
21
+ response.should have_button('Mark as spam')
22
+ end
23
+
24
+ it 'should not find matching radio input' do
25
+ response = mock_model(Object, :body => FORM_WITH_RADIO_INPUT)
26
+ response.should_not have_button('Approve')
27
+ end
28
+
29
+ # describe 'passed wrong id' do
30
+ # it 'should not match' do
31
+ # response = mock_model(Object, :body => '<p><span id="span_id">My Text</span></p>')
32
+ # response.should_not have_span_text('wrong_id', 'My Text')
33
+ # end
34
+ # end
35
+ #
36
+ # describe 'with non-matching expected' do
37
+ # it 'should not match' do
38
+ # response = mock_model(Object, :body => '<p><span id="span_id">My Text</span></p>')
39
+ # response.should_not have_span_text('span_id', 'Some Other Text')
40
+ # end
41
+ # end
42
+ #
43
+ # describe 'with normal failure' do
44
+ # it 'should raise ExpectationNotMetError with correct message' do
45
+ # response = mock_model Object, :body => 'Some non-matching HTML'
46
+ # lambda do
47
+ # response.should have_span_text('span_id', 'My Text')
48
+ # end.should raise_error(Spec::Expectations::ExpectationNotMetError, "\nWrong span text contents.\nexpected: \"My Text\"\n found: nil\n\n")
49
+ # end
50
+ # end
51
+ #
52
+ # describe 'with negative failure' do
53
+ # it 'should raise ExpectationNotMetError' do
54
+ # response = mock_model Object, :body => '<p><span id="span_id">My Text</span></p>'
55
+ # lambda{response.should_not have_span_text('span_id', 'My Text')}.should raise_error(Spec::Expectations::ExpectationNotMetError,
56
+ # "\nShould not have matched span: span_id, with text: 'My Text'\n\n")
57
+ # end
58
+ # end
59
+ end
@@ -0,0 +1,58 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe 'check_box_group_matcher' do
4
+ it 'should find matching check box group' do
5
+ response = mock_model(Object, :body => check_box_html)
6
+ response.should have_check_box_group('user[genre_ids][]', [['1', 'Rock/Pop General'], ['2', 'Modern "Alternative"'], ['4', 'Metal']])
7
+ end
8
+
9
+ describe 'passed wrong target name' do
10
+ it 'should not match' do
11
+ response = mock_model(Object, :body => check_box_html)
12
+ response.should_not have_check_box_group('wrong name', [['1', 'Rock/Pop General'], ['2', 'Modern "Alternative"'], ['4', 'Metal']])
13
+ end
14
+ end
15
+
16
+ describe 'passed non-matching expected' do
17
+ it 'should not match' do
18
+ response = mock_model(Object, :body => check_box_html)
19
+ response.should_not have_check_box_group('user[genre_ids][]', [['1', 'Rock/Pop New Wave'], ['2', 'Modern "Alternative"'], ['4', 'Metal']])
20
+ end
21
+ end
22
+
23
+ describe 'with normal failure' do
24
+ it 'should raise ExpectationNotMetError with correct message' do
25
+ response = mock_model Object, :body => 'Some non-matching HTML'
26
+ lambda do
27
+ response.should have_check_box_group('user[genre_ids][]', [['1', 'Rock/Pop General'], ['2', 'Modern "Alternative"'], ['4', 'Metal']])
28
+ end.should raise_error(Spec::Expectations::ExpectationNotMetError, "\nWrong check box group contents.\nexpected: [[\"1\", \"Rock/Pop General\"], [\"2\", \"Modern \\\"Alternative\\\"\"], [\"4\", \"Metal\"]]\n found: []\n\n")
29
+ end
30
+ end
31
+
32
+ describe 'with negative failure' do
33
+ it 'should raise ExpectationNotMetError' do
34
+ response = mock_model Object, :body => check_box_html
35
+ lambda{response.should_not have_check_box_group('user[genre_ids][]', [['1', 'Rock/Pop General'], ['2', 'Modern "Alternative"'], ['4', 'Metal']])}.should raise_error(Spec::Expectations::ExpectationNotMetError,
36
+ "\nShould not have matched check box group: name: user[genre_ids][], with: [[\"1\", \"Rock/Pop General\"], [\"2\", \"Modern \\\"Alternative\\\"\"], [\"4\", \"Metal\"]]\n\n")
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def check_box_html
43
+ %{<div>
44
+ <input id="genre_1" name="user[genre_ids][]" type="checkbox" value="1" />
45
+ <label for="genre_1">Rock/Pop General</label>
46
+ </div>
47
+
48
+ <div>
49
+ <input id="genre_2" name="user[genre_ids][]" type="checkbox" value="2" />
50
+ <label for="genre_2">Modern "Alternative"</label>
51
+ </div>
52
+
53
+ <div>
54
+ <input id="genre_4" name="user[genre_ids][]" type="checkbox" value="4" />
55
+ <label for="genre_4">Metal</label>
56
+ </div>}
57
+ end
58
+ end
@@ -0,0 +1,48 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe 'drop_down_matcher' do
4
+ it 'should find matching dropdown' do
5
+ response = mock_model(Object, :body => '<select id="choice"><option value="val1">Choice 1</option><option value="val2">Choice 2</option></select>')
6
+ response.should have_dropdown('choice', ['Choice 1', 'Choice 2'])
7
+ end
8
+
9
+ describe 'passed wrong id' do
10
+ it 'should not match' do
11
+ response = mock_model(Object, :body => '<select id="choice"><option value="val1">Choice 1</option><option value="val2">Choice 2</option></select>')
12
+ response.should_not have_dropdown('wrong_id', ['Choice 1', 'Choice 2'])
13
+ end
14
+ end
15
+
16
+ describe 'with non-matching expected' do
17
+ it 'should not match' do
18
+ response = mock_model(Object, :body => '<select id="choice"><option value="val1">Choice 1</option><option value="val2">Choice 2</option></select>')
19
+ response.should_not have_dropdown('choice', ['Not A Match 1', 'Not A Match 2'])
20
+ end
21
+ end
22
+
23
+ describe 'without matching select element' do
24
+ it 'should raise ExpectationNotMetError with correct message' do
25
+ response = mock_model Object, :body => 'Some non-matching HTML'
26
+ lambda do
27
+ response.should have_dropdown('choice', [['Choice 1', 'Choice 2']])
28
+ end.should raise_error(Spec::Expectations::ExpectationNotMetError, "\nCould not find a select element with id: 'choice'\n\n")
29
+ end
30
+ end
31
+
32
+ describe 'with wrong contents in correct select element' do
33
+ it 'should raise ExpectationNotMetError with correct message' do
34
+ response = mock_model Object, :body => '<select id="choice"><option value="no_match">No Match</option></select>'
35
+ lambda do
36
+ response.should have_dropdown('choice', [['Choice 1', 'Choice 2']])
37
+ end.should raise_error(Spec::Expectations::ExpectationNotMetError, "\nWrong 'choice' drop down contents.\nexpected: [[\"Choice 1\", \"Choice 2\"]]\n found: [\"No Match\"]\n\n")
38
+ end
39
+ end
40
+
41
+ describe 'with negative failure' do
42
+ it 'should raise ExpectationNotMetError' do
43
+ response = mock_model Object, :body => '<select id="choice"><option value="val1">Choice 1</option><option value="val2">Choice 2</option></select>'
44
+ lambda{response.should_not have_dropdown('choice', ['Choice 1', 'Choice 2'])}.should raise_error(Spec::Expectations::ExpectationNotMetError,
45
+ "\nShould not have matched dropdown with id: choice\n\tand contents: [\"Choice 1\", \"Choice 2\"]\n\n")
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,34 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe 'image_matcher' do
4
+ it 'should find matching image' do
5
+ response = mock_model(Object, :body => '<p><img id="image_id" src="/images/my_photo.jpg?1233455"/></p>')
6
+ response.should have_image('my_photo.jpg')
7
+ end
8
+
9
+ describe 'with non-matching expected' do
10
+ it 'should not match' do
11
+ response = mock_model(Object, :body => '<p><img id="image_id" src="/images/my_photo.jpg?1233455"/></p>')
12
+ response.should_not have_image('my_other_photo.gif')
13
+ end
14
+ end
15
+
16
+ describe 'with normal failure' do
17
+ it 'should raise ExpectationNotMetError with correct message' do
18
+ response = mock_model Object, :body => 'Some non-matching HTML'
19
+ lambda do
20
+ response.should have_image('my_photo.jpg')
21
+ end.should raise_error(Spec::Expectations::ExpectationNotMetError, "\nWrong image path.\nexpected: \"my_photo.jpg\"\n found: nil\n\n")
22
+ end
23
+ end
24
+
25
+ describe 'with negative failure' do
26
+ it 'should raise ExpectationNotMetError' do
27
+ response = mock_model Object, :body => '<p><img id="image_id" src="/images/my_photo.jpg?1233455"/></p>'
28
+ lambda do
29
+ response.should_not have_image('my_photo.jpg')
30
+ end.should raise_error(Spec::Expectations::ExpectationNotMetError,
31
+ "\nShould not have matched image with path: 'my_photo.jpg'\n\n")
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,39 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe 'radio_group_matcher' do
4
+ it 'should find matching radio group' do
5
+ response = mock_model(Object, :body => '<p><b>Gender</b><br/>M <input id="athlete_gender_m" name="athlete[gender]" type="radio" value="M" /><br/>F <input id="athlete_gender_f" name="athlete[gender]" type="radio" value="F" /></p>')
6
+ response.should have_radio_group('athlete[gender]', ['M', 'F'])
7
+ end
8
+
9
+ describe 'passed wrong id' do
10
+ it 'should not match' do
11
+ response = mock_model(Object, :body => '<p><b>Gender</b><br/>M <input id="athlete_gender_m" name="athlete[gender]" type="radio" value="M" /><br/>F <input id="athlete_gender_f" name="athlete[gender]" type="radio" value="F" /></p>')
12
+ response.should_not have_radio_group('wrong_id', ['M', 'F'])
13
+ end
14
+ end
15
+
16
+ describe 'with non-matching expected' do
17
+ it 'should not match' do
18
+ response = mock_model(Object, :body => '<p><b>Gender</b><br/>M <input id="athlete_gender_m" name="athlete[gender]" type="radio" value="M" /><br/>F <input id="athlete_gender_f" name="athlete[gender]" type="radio" value="F" /></p>')
19
+ response.should_not have_radio_group('athlete[gender]', ['M', 'O'])
20
+ end
21
+ end
22
+
23
+ describe 'with normal failure' do
24
+ it 'should raise ExpectationNotMetError with correct message' do
25
+ response = mock_model Object, :body => 'Some non-matching HTML'
26
+ lambda do
27
+ response.should have_radio_group('athlete[gender]', ['M', 'F'])
28
+ end.should raise_error(Spec::Expectations::ExpectationNotMetError, "\nWrong radio group contents.\nexpected: [\"M\", \"F\"]\n found: []\n\n")
29
+ end
30
+ end
31
+
32
+ describe 'with negative failure' do
33
+ it 'should raise ExpectationNotMetError' do
34
+ response = mock_model Object, :body => '<p><b>Gender</b><br/>M <input id="athlete_gender_m" name="athlete[gender]" type="radio" value="M" /><br/>F <input id="athlete_gender_f" name="athlete[gender]" type="radio" value="F" /></p>'
35
+ lambda{response.should_not have_radio_group('athlete[gender]', ['M', 'F'])}.should raise_error(Spec::Expectations::ExpectationNotMetError,
36
+ "\nShould not have matched radio group: name: athlete[gender], with: [\"M\", \"F\"]\n\n")
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,39 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe 'span_text_matcher' do
4
+ it 'should find matching span' do
5
+ response = mock_model(Object, :body => '<p><span id="span_id">My Text</span></p>')
6
+ response.should have_span_text('span_id', 'My Text')
7
+ end
8
+
9
+ describe 'passed wrong id' do
10
+ it 'should not match' do
11
+ response = mock_model(Object, :body => '<p><span id="span_id">My Text</span></p>')
12
+ response.should_not have_span_text('wrong_id', 'My Text')
13
+ end
14
+ end
15
+
16
+ describe 'with non-matching expected' do
17
+ it 'should not match' do
18
+ response = mock_model(Object, :body => '<p><span id="span_id">My Text</span></p>')
19
+ response.should_not have_span_text('span_id', 'Some Other Text')
20
+ end
21
+ end
22
+
23
+ describe 'with normal failure' do
24
+ it 'should raise ExpectationNotMetError with correct message' do
25
+ response = mock_model Object, :body => 'Some non-matching HTML'
26
+ lambda do
27
+ response.should have_span_text('span_id', 'My Text')
28
+ end.should raise_error(Spec::Expectations::ExpectationNotMetError, "\nWrong span text contents.\nexpected: \"My Text\"\n found: nil\n\n")
29
+ end
30
+ end
31
+
32
+ describe 'with negative failure' do
33
+ it 'should raise ExpectationNotMetError' do
34
+ response = mock_model Object, :body => '<p><span id="span_id">My Text</span></p>'
35
+ lambda{response.should_not have_span_text('span_id', 'My Text')}.should raise_error(Spec::Expectations::ExpectationNotMetError,
36
+ "\nShould not have matched span: span_id, with text: 'My Text'\n\n")
37
+ end
38
+ end
39
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,3 @@
1
+ --colour
2
+ --format progress
3
+ --timeout 20
@@ -0,0 +1,46 @@
1
+ # This file is copied from the spec Rails plugin
2
+ ENV["RAILS_ENV"] = "test"
3
+ require File.expand_path(File.dirname(__FILE__) + "/../../../../config/environment")
4
+ require 'spec'
5
+ require 'spec/rails'
6
+
7
+ Spec::Runner.configure do |config|
8
+ # If you're not using ActiveRecord you should remove these
9
+ # lines, delete config/database.yml and disable :active_record
10
+ # in your config/boot.rb
11
+ config.use_transactional_fixtures = true
12
+ config.use_instantiated_fixtures = false
13
+ config.fixture_path = RAILS_ROOT + '/spec/fixtures/'
14
+
15
+ # == Fixtures
16
+ #
17
+ # You can declare fixtures for each example_group like this:
18
+ # describe "...." do
19
+ # fixtures :table_a, :table_b
20
+ #
21
+ # Alternatively, if you prefer to declare them only once, you can
22
+ # do so right here. Just uncomment the next line and replace the fixture
23
+ # names with your fixtures.
24
+ #
25
+ # config.global_fixtures = :table_a, :table_b
26
+ #
27
+ # If you declare global fixtures, be aware that they will be declared
28
+ # for all of your examples, even those that don't use them.
29
+ #
30
+ # You can also declare which fixtures to use (for example fixtures for test/fixtures):
31
+ #
32
+ # config.fixture_path = RAILS_ROOT + '/spec/fixtures/'
33
+ #
34
+ # == Mock Framework
35
+ #
36
+ # RSpec uses it's own mocking framework by default. If you prefer to
37
+ # use mocha, flexmock or RR, uncomment the appropriate line:
38
+ #
39
+ # config.mock_with :mocha
40
+ # config.mock_with :flexmock
41
+ # config.mock_with :rr
42
+ #
43
+ # == Notes
44
+ #
45
+ # For more information take a look at Spec::Example::Configuration and Spec::Runner
46
+ end