html_matchers 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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