hectoregm-email_spec 0.1.2

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.
Files changed (89) hide show
  1. data/History.txt +65 -0
  2. data/MIT-LICENSE.txt +19 -0
  3. data/README.rdoc +126 -0
  4. data/Rakefile +51 -0
  5. data/examples/rails_root/app/controllers/application.rb +15 -0
  6. data/examples/rails_root/app/controllers/welcome_controller.rb +9 -0
  7. data/examples/rails_root/app/helpers/application_helper.rb +3 -0
  8. data/examples/rails_root/app/helpers/welcome_helper.rb +2 -0
  9. data/examples/rails_root/app/models/user.rb +2 -0
  10. data/examples/rails_root/app/models/user_mailer.rb +12 -0
  11. data/examples/rails_root/app/views/user_mailer/signup.erb +3 -0
  12. data/examples/rails_root/app/views/welcome/confirm.html.erb +1 -0
  13. data/examples/rails_root/app/views/welcome/index.html.erb +8 -0
  14. data/examples/rails_root/app/views/welcome/signup.html.erb +1 -0
  15. data/examples/rails_root/config/boot.rb +109 -0
  16. data/examples/rails_root/config/database.yml +22 -0
  17. data/examples/rails_root/config/environment.rb +22 -0
  18. data/examples/rails_root/config/environments/development.rb +17 -0
  19. data/examples/rails_root/config/environments/production.rb +24 -0
  20. data/examples/rails_root/config/environments/test.rb +33 -0
  21. data/examples/rails_root/config/initializers/inflections.rb +10 -0
  22. data/examples/rails_root/config/initializers/mime_types.rb +5 -0
  23. data/examples/rails_root/config/initializers/new_rails_defaults.rb +17 -0
  24. data/examples/rails_root/config/routes.rb +43 -0
  25. data/examples/rails_root/cucumber.yml +1 -0
  26. data/examples/rails_root/db/migrate/20090125013728_create_users.rb +11 -0
  27. data/examples/rails_root/db/schema.rb +19 -0
  28. data/examples/rails_root/doc/README_FOR_APP +5 -0
  29. data/examples/rails_root/features/errors.feature +42 -0
  30. data/examples/rails_root/features/example.feature +59 -0
  31. data/examples/rails_root/features/step_definitions/email_steps.rb +74 -0
  32. data/examples/rails_root/features/step_definitions/user_steps.rb +23 -0
  33. data/examples/rails_root/features/step_definitions/webrat_steps.rb +104 -0
  34. data/examples/rails_root/features/support/env.rb +21 -0
  35. data/examples/rails_root/public/404.html +30 -0
  36. data/examples/rails_root/public/422.html +30 -0
  37. data/examples/rails_root/public/500.html +33 -0
  38. data/examples/rails_root/public/dispatch.rb +10 -0
  39. data/examples/rails_root/public/favicon.ico +0 -0
  40. data/examples/rails_root/public/images/rails.png +0 -0
  41. data/examples/rails_root/public/javascripts/application.js +2 -0
  42. data/examples/rails_root/public/javascripts/controls.js +963 -0
  43. data/examples/rails_root/public/javascripts/dragdrop.js +973 -0
  44. data/examples/rails_root/public/javascripts/effects.js +1128 -0
  45. data/examples/rails_root/public/javascripts/prototype.js +4320 -0
  46. data/examples/rails_root/public/robots.txt +5 -0
  47. data/examples/rails_root/script/about +4 -0
  48. data/examples/rails_root/script/autospec +5 -0
  49. data/examples/rails_root/script/console +3 -0
  50. data/examples/rails_root/script/cucumber +7 -0
  51. data/examples/rails_root/script/dbconsole +3 -0
  52. data/examples/rails_root/script/destroy +3 -0
  53. data/examples/rails_root/script/generate +3 -0
  54. data/examples/rails_root/script/performance/benchmarker +3 -0
  55. data/examples/rails_root/script/performance/profiler +3 -0
  56. data/examples/rails_root/script/performance/request +3 -0
  57. data/examples/rails_root/script/plugin +3 -0
  58. data/examples/rails_root/script/process/inspector +3 -0
  59. data/examples/rails_root/script/process/reaper +3 -0
  60. data/examples/rails_root/script/process/spawner +3 -0
  61. data/examples/rails_root/script/runner +3 -0
  62. data/examples/rails_root/script/server +3 -0
  63. data/examples/rails_root/script/spec +5 -0
  64. data/examples/rails_root/script/spec_server +125 -0
  65. data/examples/rails_root/spec/controllers/welcome_controller_spec.rb +15 -0
  66. data/examples/rails_root/spec/model_factory.rb +6 -0
  67. data/examples/rails_root/spec/models/user_mailer_spec.rb +58 -0
  68. data/examples/rails_root/spec/models/user_spec.rb +5 -0
  69. data/examples/rails_root/spec/rcov.opts +2 -0
  70. data/examples/rails_root/spec/spec.opts +4 -0
  71. data/examples/rails_root/spec/spec_helper.rb +51 -0
  72. data/examples/rails_root/stories/all.rb +4 -0
  73. data/examples/rails_root/stories/helper.rb +3 -0
  74. data/examples/rails_root/vendor/plugins/email_spec/rails_generators/email_spec/email_spec_generator.rb +17 -0
  75. data/examples/rails_root/vendor/plugins/email_spec/rails_generators/email_spec/templates/email_steps.rb +74 -0
  76. data/install.rb +0 -0
  77. data/lib/email_spec/address_converter.rb +27 -0
  78. data/lib/email_spec/cucumber.rb +19 -0
  79. data/lib/email_spec/deliveries.rb +55 -0
  80. data/lib/email_spec/email_viewer.rb +70 -0
  81. data/lib/email_spec/helpers.rb +128 -0
  82. data/lib/email_spec/matchers.rb +122 -0
  83. data/lib/email_spec.rb +14 -0
  84. data/rails_generators/email_spec/email_spec_generator.rb +17 -0
  85. data/rails_generators/email_spec/templates/email_steps.rb +74 -0
  86. data/spec/email_spec/matchers_spec.rb +159 -0
  87. data/spec/spec.opts +4 -0
  88. data/spec/spec_helper.rb +4 -0
  89. metadata +187 -0
@@ -0,0 +1,128 @@
1
+ require 'uri'
2
+
3
+ module EmailSpec
4
+
5
+ module Helpers
6
+ include Deliveries
7
+
8
+ def visit_in_email(link_text)
9
+ visit(parse_email_for_link(current_email, link_text))
10
+ end
11
+
12
+ def click_email_link_matching(regex, email = current_email)
13
+ url = links_in_email(email).detect { |link| link =~ regex }
14
+ raise "No link found matching #{regex.inspect} in #{email.body}" unless url
15
+ request_uri = URI::parse(url).request_uri
16
+ visit request_uri
17
+ end
18
+
19
+ def click_first_link_in_email(email = current_email)
20
+ link = links_in_email(email).first
21
+ request_uri = URI::parse(link).request_uri
22
+ visit request_uri
23
+ end
24
+
25
+ def open_email(address, opts={})
26
+ address = convert_address(address)
27
+ set_current_email(find_email!(address, opts))
28
+ end
29
+
30
+ alias_method :open_email_for, :open_email
31
+
32
+ def open_last_email
33
+ set_current_email(last_email_sent)
34
+ end
35
+
36
+ def open_last_email_for(address)
37
+ address = convert_address(address)
38
+ set_current_email(mailbox_for(address).last)
39
+ end
40
+
41
+ def current_email(address=nil)
42
+ address = convert_address(address)
43
+ email = address ? email_spec_hash[:current_emails][address] : email_spec_hash[:current_email]
44
+ raise Spec::Expectations::ExpectationNotMetError, "Expected an open email but none was found. Did you forget to call open_email?" unless email
45
+ email
46
+ end
47
+
48
+ def unread_emails_for(address)
49
+ address = convert_address(address)
50
+ mailbox_for(address) - read_emails_for(address)
51
+ end
52
+
53
+ def read_emails_for(address)
54
+ address = convert_address(address)
55
+ email_spec_hash[:read_emails][address] ||= []
56
+ end
57
+
58
+ def find_email(address, opts={})
59
+ address = convert_address(address)
60
+ if opts[:with_subject]
61
+ email = mailbox_for(address).find { |m| m.subject =~ Regexp.new(opts[:with_subject]) }
62
+ elsif opts[:with_text]
63
+ email = mailbox_for(address).find { |m| m.body =~ Regexp.new(opts[:with_text]) }
64
+ else
65
+ email = mailbox_for(address).first
66
+ end
67
+ end
68
+
69
+ def links_in_email(email)
70
+ URI.extract(email.body, ['http', 'https'])
71
+ end
72
+
73
+ private
74
+
75
+ def email_spec_hash
76
+ @email_spec_hash ||= {:read_emails => {}, :unread_emails => {}, :current_emails => {}, :current_email => nil}
77
+ end
78
+
79
+ def find_email!(address, opts={})
80
+ address = convert_address(address)
81
+ email = find_email(address, opts)
82
+ if email.nil?
83
+ error = "#{opts.keys.first.to_s.humanize unless opts.empty?} #{('"' + opts.values.first.to_s.humanize + '"') unless opts.empty?}"
84
+ raise Spec::Expectations::ExpectationNotMetError, "Could not find email #{error}. \n Found the following emails:\n\n #{all_emails.to_s}"
85
+ end
86
+ email
87
+ end
88
+
89
+ def set_current_email(email)
90
+ return unless email
91
+ email.to.each do |to|
92
+ read_emails_for(to) << email
93
+ email_spec_hash[:current_emails][to] = email
94
+ end
95
+ email_spec_hash[:current_email] = email
96
+ end
97
+
98
+ def parse_email_for_link(email, text_or_regex)
99
+ email.should have_body_text(text_or_regex)
100
+
101
+ url = parse_email_for_explicit_link(email, text_or_regex)
102
+ url ||= parse_email_for_anchor_text_link(email, text_or_regex)
103
+
104
+ raise "No link found matching #{text_or_regex.inspect} in #{email}" unless url
105
+ url
106
+ end
107
+
108
+ # e.g. confirm in http://confirm
109
+ def parse_email_for_explicit_link(email, regex)
110
+ regex = /#{Regexp.escape(regex)}/ unless regex.is_a?(Regexp)
111
+ url = links_in_email(email).detect { |link| link =~ regex }
112
+ URI::parse(url).request_uri if url
113
+ end
114
+
115
+ # e.g. Click here in <a href="http://confirm">Click here</a>
116
+ def parse_email_for_anchor_text_link(email, link_text)
117
+ email.body =~ %r{<a[^>]*href=['"]?([^'"]*)['"]?[^>]*?>[^<]*?#{link_text}[^<]*?</a>}
118
+ URI.split($~[1])[5..-1].compact!.join("?").gsub("&amp;", "&")
119
+ # sub correct ampersand after rails switches it (http://dev.rubyonrails.org/ticket/4002)
120
+ end
121
+
122
+
123
+ def convert_address(address)
124
+ AddressConverter.instance.convert(address)
125
+ end
126
+ end
127
+ end
128
+
@@ -0,0 +1,122 @@
1
+ module EmailSpec
2
+
3
+ module Matchers
4
+
5
+ class DeliverTo
6
+
7
+ def initialize(expected_email_addresses_or_objects_that_respond_to_email)
8
+ emails = expected_email_addresses_or_objects_that_respond_to_email.map do |email_or_object|
9
+ email_or_object.kind_of?(String) ? email_or_object : email_or_object.email
10
+ end
11
+
12
+ @expected_email_addresses = emails.sort
13
+ end
14
+
15
+ def description
16
+ "be delivered to #{@expected_email_addresses.inspect}"
17
+ end
18
+
19
+ def matches?(email)
20
+ @email = email
21
+ @actual_recipients = (email.to || []).sort
22
+ @actual_recipients == @expected_email_addresses
23
+ end
24
+
25
+ def failure_message
26
+ "expected #{@email.inspect} to deliver to #{@expected_email_addresses.inspect}, but it delievered to #{@actual_recipients.inspect}"
27
+ end
28
+
29
+ def negative_failure_message
30
+ "expected #{@email.inspect} not to deliver to #{@expected_email_addresses.inspect}, but it did"
31
+ end
32
+ end
33
+
34
+ def deliver_to(*expected_email_addresses_or_objects_that_respond_to_email)
35
+ DeliverTo.new(expected_email_addresses_or_objects_that_respond_to_email.flatten)
36
+ end
37
+
38
+ alias :be_delivered_to :deliver_to
39
+
40
+ def have_subject(expected)
41
+ simple_matcher do |given, matcher|
42
+ given_subject = given.subject
43
+
44
+ if expected.is_a?(String)
45
+ matcher.description = "have subject of #{expected.inspect}"
46
+ matcher.failure_message = "expected the subject to be #{expected.inspect} but was #{given_subject.inspect}"
47
+ matcher.negative_failure_message = "expected the subject not to be #{expected.inspect} but was"
48
+
49
+ given_subject == expected
50
+ else
51
+ matcher.description = "have subject matching #{expected.inspect}"
52
+ matcher.failure_message = "expected the subject to match #{expected.inspect}, but did not. Actual subject was: #{given_subject.inspect}"
53
+ matcher.negative_failure_message = "expected the subject not to match #{expected.inspect} but #{given_subject.inspect} does match it."
54
+
55
+ !!(given_subject =~ expected)
56
+ end
57
+ end
58
+ end
59
+
60
+ def include_email_with_subject(expected)
61
+ simple_matcher do |given_emails, matcher|
62
+
63
+ if expected.is_a?(String)
64
+ matcher.description = "include email with subject of #{expected.inspect}"
65
+ matcher.failure_message = "expected at least one email to have the subject #{expected.inspect} but none did. Subjects were #{given_emails.map(&:subject).inspect}"
66
+ matcher.negative_failure_message = "expected no email with the subject #{expected.inspect} but found at least one. Subjects were #{given_emails.map(&:subject).inspect}"
67
+
68
+ given_emails.map(&:subject).include?(expected)
69
+ else
70
+ matcher.description = "include email with subject matching #{expected.inspect}"
71
+ matcher.failure_message = "expected at least one email to have a subject matching #{expected.inspect}, but none did. Subjects were #{given_emails.map(&:subject).inspect}"
72
+ matcher.negative_failure_message = "expected no email to have a subject matching #{expected.inspect} but found at least one. Subjects were #{given_emails.map(&:subject).inspect}"
73
+
74
+ !!(given_emails.any?{ |mail| mail.subject =~ expected })
75
+ end
76
+ end
77
+ end
78
+
79
+ def have_body_text(expected)
80
+ simple_matcher do |given, matcher|
81
+
82
+ if expected.is_a?(String)
83
+ normalized_body = given.body.gsub(/\s+/, " ")
84
+ normalized_expected = expected.gsub(/\s+/, " ")
85
+ matcher.description = "have body including #{normalized_expected.inspect}"
86
+ matcher.failure_message = "expected the body to contain #{normalized_expected.inspect} but was #{normalized_body.inspect}"
87
+ matcher.negative_failure_message = "expected the body not to contain #{normalized_expected.inspect} but was #{normalized_body.inspect}"
88
+
89
+ normalized_body.include?(normalized_expected)
90
+ else
91
+ given_body = given.body
92
+ matcher.description = "have body matching #{expected.inspect}"
93
+ matcher.failure_message = "expected the body to match #{expected.inspect}, but did not. Actual body was: #{given_body.inspect}"
94
+ matcher.negative_failure_message = "expected the body not to match #{expected.inspect} but #{given_body.inspect} does match it."
95
+
96
+ !!(given_body =~ expected)
97
+ end
98
+ end
99
+ end
100
+
101
+ def have_header(expected_name, expected_value)
102
+ simple_matcher do |given, matcher|
103
+ given_header = given.header
104
+
105
+ if expected_value.is_a?(String)
106
+ matcher.description = "have header #{expected_name}: #{expected_value}"
107
+ matcher.failure_message = "expected the headers to include '#{expected_name}: #{expected_value}' but they were #{given_header.inspect}"
108
+ matcher.negative_failure_message = "expected the headers not to include '#{expected_name}: #{expected_value}' but they were #{given_header.inspect}"
109
+
110
+ given_header[expected_name].to_s == expected_value
111
+ else
112
+ matcher.description = "have header #{expected_name} with value matching #{expected_value.inspect}"
113
+ matcher.failure_message = "expected the headers to include '#{expected_name}' with a value matching #{expected_value.inspect} but they were #{given_header.inspect}"
114
+ matcher.negative_failure_message = "expected the headers not to include '#{expected_name}' with a value matching #{expected_value.inspect} but they were #{given_header.inspect}"
115
+
116
+ given_header[expected_name].to_s =~ expected_value
117
+ end
118
+ end
119
+ end
120
+
121
+ end
122
+ end
data/lib/email_spec.rb ADDED
@@ -0,0 +1,14 @@
1
+ unless defined?(ActionMailer)
2
+ Kernel.warn("ActionMailer did not appear to be loaded so email-spec is requiring it.")
3
+ require 'actionmailer'
4
+ end
5
+
6
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))
7
+
8
+ require 'email_spec/deliveries'
9
+ require 'email_spec/address_converter'
10
+ require 'email_spec/email_viewer'
11
+ require 'email_spec/helpers'
12
+ require 'email_spec/matchers'
13
+
14
+
@@ -0,0 +1,17 @@
1
+ # This generator adds email steps to the step definitions directory
2
+ generator_base = defined?(Rails) ? Rails::Generator::Base : RubiGen::Base
3
+ class EmailSpecGenerator < generator_base
4
+ def manifest
5
+ record do |m|
6
+ m.directory 'features/step_definitions'
7
+ m.file 'email_steps.rb', 'features/step_definitions/email_steps.rb'
8
+ end
9
+ end
10
+
11
+ protected
12
+
13
+ def banner
14
+ "Usage: #{$0} email_spec"
15
+ end
16
+
17
+ end
@@ -0,0 +1,74 @@
1
+ #Commonly used email steps
2
+ #
3
+ # To add your own steps make a custom_email_steps.rb
4
+ # The provided methods are:
5
+ #
6
+ # reset_mailer
7
+ # open_last_email
8
+ # visit_in_email
9
+ # unread_emails_for
10
+ # mailbox_for
11
+ # current_email
12
+ # open_email
13
+ # read_emails_for
14
+ # find_email
15
+
16
+ module EmailHelpers
17
+ def current_email_address
18
+ "quentin@example.com" # Replace with your a way to find your current_email. e.g current_user.email
19
+ end
20
+ end
21
+ World(EmailHelpers)
22
+
23
+ # Use this step to reset the e-mail queue within a scenario.
24
+ # This is done automatically before each scenario.
25
+ Given /^(?:a clear email queue|no emails have been sent)$/ do
26
+ reset_mailer
27
+ end
28
+
29
+ # Use this step to open the most recently sent e-mail.
30
+ When /^I open the email$/ do
31
+ open_email(current_email_address)
32
+ end
33
+
34
+ When /^I follow "(.*)" in the email$/ do |link|
35
+ visit_in_email(link)
36
+ end
37
+
38
+ Then /^I should receive (an|\d+) emails?$/ do |amount|
39
+ amount = 1 if amount == "an"
40
+ unread_emails_for(current_email_address).size.should == amount.to_i
41
+ end
42
+
43
+ Then /^"([^']*?)" should receive (\d+) emails?$/ do |address, n|
44
+ unread_emails_for(address).size.should == n.to_i
45
+ end
46
+
47
+ Then /^"([^']*?)" should have (\d+) emails?$/ do |address, n|
48
+ mailbox_for(address).size.should == n.to_i
49
+ end
50
+
51
+ Then /^"([^']*?)" should not receive an email$/ do |address|
52
+ find_email(address).should be_nil
53
+ end
54
+
55
+ Then /^I should see "(.*)" in the subject$/ do |text|
56
+ current_email.should have_subject(Regexp.new(text))
57
+ end
58
+
59
+ Then /^I should see "(.*)" in the email$/ do |text|
60
+ current_email.body.should =~ Regexp.new(text)
61
+ end
62
+
63
+ When %r{^"([^']*?)" opens? the email with subject "([^']*?)"$} do |address, subject|
64
+ open_email(address, :with_subject => subject)
65
+ end
66
+
67
+ When %r{^"([^']*?)" opens? the email with text "([^']*?)"$} do |address, text|
68
+ open_email(address, :with_text => text)
69
+ end
70
+
71
+ When /^I click the first link in the email$/ do
72
+ click_first_link_in_email
73
+ end
74
+
@@ -0,0 +1,159 @@
1
+
2
+ require File.dirname(__FILE__) + '/../spec_helper'
3
+
4
+
5
+
6
+ describe EmailSpec::Matchers do
7
+
8
+
9
+ class MatcherMatch
10
+
11
+ def initialize(object_to_test_match)
12
+ @object_to_test_match = object_to_test_match
13
+ end
14
+
15
+ def description
16
+ "match when provided #{@object_to_test_match.inspect}"
17
+ end
18
+
19
+ def matches?(matcher)
20
+ @matcher = matcher
21
+ matcher.matches?(@object_to_test_match)
22
+ end
23
+
24
+ def failure_message
25
+ "expected #{@matcher.inspect} to match when provided #{@object_to_test_match.inspect}, but it did not"
26
+ end
27
+
28
+ def negative_failure_message
29
+ "expected #{@matcher.inspect} not to match when provided #{@object_to_test_match.inspect}, but it did"
30
+ end
31
+ end
32
+
33
+ def match(object_to_test_match)
34
+ if object_to_test_match.is_a?(Regexp)
35
+ super # delegate to rspec's built in 'match' matcher
36
+ else
37
+ MatcherMatch.new(object_to_test_match)
38
+ end
39
+ end
40
+
41
+ include EmailSpec::Matchers
42
+
43
+ def mock_email(stubs)
44
+ mock("email", stubs)
45
+ end
46
+
47
+ describe "#deliver_to" do
48
+
49
+ it "should match when the email is set to deliver to the specidied address" do
50
+ email = mock_email(:to => "jimmy_bean@yahoo.com")
51
+
52
+ deliver_to("jimmy_bean@yahoo.com").should match(email)
53
+ end
54
+
55
+ it "should match when a list of emails is exact same as all of the email's recipients" do
56
+ email = mock_email(:to => ["james@yahoo.com", "karen@yahoo.com"])
57
+
58
+ deliver_to("karen@yahoo.com", "james@yahoo.com").should match(email)
59
+ deliver_to("karen@yahoo.com").should_not match(email)
60
+ end
61
+
62
+ it "should match when an array of emails is exact same as all of the email's recipients" do
63
+ addresses = ["james@yahoo.com", "karen@yahoo.com"]
64
+ email = mock_email(:to => addresses)
65
+ deliver_to(addresses).should match(email)
66
+ end
67
+
68
+ it "should use the passed in objects :email method if not a string" do
69
+ email = mock_email(:to => "jimmy_bean@yahoo.com")
70
+ user = mock("user", :email => "jimmy_bean@yahoo.com")
71
+
72
+ deliver_to(user).should match(email)
73
+ end
74
+
75
+ end
76
+
77
+ describe "#have_subject" do
78
+
79
+ describe "when regexps are used" do
80
+
81
+ it "should match when the subject mathches regexp" do
82
+ email = mock_email(:subject => ' -- The Subject --')
83
+
84
+ have_subject(/The Subject/).should match(email)
85
+ have_subject(/The Subject/).should match(email)
86
+ have_subject(/foo/).should_not match(email)
87
+ end
88
+
89
+ it "should have a helpful description" do
90
+ matcher = have_subject(/foo/)
91
+ matcher.matches?(mock_email(:subject => "bar"))
92
+
93
+ matcher.description.should == "have subject matching /foo/"
94
+ end
95
+
96
+ it "should offer helpful failing messages" do
97
+ matcher = have_subject(/foo/)
98
+ matcher.matches?(mock_email(:subject => "bar"))
99
+
100
+ matcher.failure_message.should == 'expected the subject to match /foo/, but did not. Actual subject was: "bar"'
101
+ end
102
+
103
+ it "should offer helpful negative failing messages" do
104
+ matcher = have_subject(/b/)
105
+ matcher.matches?(mock_email(:subject => "bar"))
106
+
107
+ matcher.negative_failure_message.should == 'expected the subject not to match /b/ but "bar" does match it.'
108
+ end
109
+
110
+ end
111
+
112
+ describe "when strings are used" do
113
+
114
+ it "should match when the subject equals the passed in string exactly" do
115
+ email = mock_email(:subject => 'foo')
116
+
117
+ have_subject("foo").should match(email)
118
+ have_subject(" - foo -").should_not match(email)
119
+ end
120
+
121
+ it "should have a helpful description" do
122
+ matcher = have_subject("foo")
123
+ matcher.matches?(mock_email(:subject => "bar"))
124
+
125
+ matcher.description.should == 'have subject of "foo"'
126
+ end
127
+
128
+ it "should offer helpful failing messages" do
129
+ matcher = have_subject("foo")
130
+ matcher.matches?(mock_email(:subject => "bar"))
131
+
132
+ matcher.failure_message.should == 'expected the subject to be "foo" but was "bar"'
133
+ end
134
+
135
+
136
+ it "should offer helpful negative failing messages" do
137
+ matcher = have_subject("bar")
138
+ matcher.matches?(mock_email(:subject => "bar"))
139
+
140
+ matcher.negative_failure_message.should == 'expected the subject not to be "bar" but was'
141
+ end
142
+
143
+ end
144
+
145
+
146
+ end
147
+
148
+ describe "#include_email_with_subject" do
149
+ it "should have specs!"
150
+ end
151
+
152
+ describe "#have_body_text" do
153
+ it "should have specs!"
154
+ end
155
+
156
+ describe "#have_header" do
157
+ it "should have specs!"
158
+ end
159
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,4 @@
1
+ --colour
2
+ --format s
3
+ --loadby mtime
4
+ --reverse
@@ -0,0 +1,4 @@
1
+ require 'rubygems'
2
+ require 'actionmailer'
3
+ require 'spec'
4
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/email_spec.rb')