opsb-email_spec 0.6.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 (109) hide show
  1. data/History.txt +199 -0
  2. data/MIT-LICENSE.txt +19 -0
  3. data/README.rdoc +135 -0
  4. data/Rakefile +77 -0
  5. data/examples/rails_root/Rakefile +13 -0
  6. data/examples/rails_root/app/controllers/application_controller.rb +15 -0
  7. data/examples/rails_root/app/controllers/welcome_controller.rb +16 -0
  8. data/examples/rails_root/app/helpers/application_helper.rb +3 -0
  9. data/examples/rails_root/app/helpers/welcome_helper.rb +2 -0
  10. data/examples/rails_root/app/models/user.rb +2 -0
  11. data/examples/rails_root/app/models/user_mailer.rb +39 -0
  12. data/examples/rails_root/app/views/user_mailer/attachments.erb +6 -0
  13. data/examples/rails_root/app/views/user_mailer/newsletter.erb +8 -0
  14. data/examples/rails_root/app/views/user_mailer/signup.erb +3 -0
  15. data/examples/rails_root/app/views/welcome/attachments.html.erb +0 -0
  16. data/examples/rails_root/app/views/welcome/confirm.html.erb +1 -0
  17. data/examples/rails_root/app/views/welcome/index.html.erb +8 -0
  18. data/examples/rails_root/app/views/welcome/newsletter.html.erb +0 -0
  19. data/examples/rails_root/app/views/welcome/signup.html.erb +1 -0
  20. data/examples/rails_root/attachments/document.pdf +0 -0
  21. data/examples/rails_root/attachments/image.png +0 -0
  22. data/examples/rails_root/config/boot.rb +110 -0
  23. data/examples/rails_root/config/cucumber.yml +7 -0
  24. data/examples/rails_root/config/database.yml +25 -0
  25. data/examples/rails_root/config/environment.rb +28 -0
  26. data/examples/rails_root/config/environments/cucumber.rb +29 -0
  27. data/examples/rails_root/config/environments/development.rb +17 -0
  28. data/examples/rails_root/config/environments/production.rb +28 -0
  29. data/examples/rails_root/config/environments/test.rb +28 -0
  30. data/examples/rails_root/config/initializers/inflections.rb +10 -0
  31. data/examples/rails_root/config/initializers/mime_types.rb +5 -0
  32. data/examples/rails_root/config/initializers/new_rails_defaults.rb +17 -0
  33. data/examples/rails_root/config/routes.rb +45 -0
  34. data/examples/rails_root/db/migrate/20090125013728_create_users.rb +11 -0
  35. data/examples/rails_root/db/migrate/20090908054656_create_delayed_jobs.rb +20 -0
  36. data/examples/rails_root/db/schema.rb +32 -0
  37. data/examples/rails_root/doc/README_FOR_APP +5 -0
  38. data/examples/rails_root/features/attachments.feature +27 -0
  39. data/examples/rails_root/features/delayed_job.feature +13 -0
  40. data/examples/rails_root/features/errors.feature +32 -0
  41. data/examples/rails_root/features/example.feature +62 -0
  42. data/examples/rails_root/features/step_definitions/user_steps.rb +26 -0
  43. data/examples/rails_root/features/step_definitions/web_steps.rb +273 -0
  44. data/examples/rails_root/features/support/env.rb +58 -0
  45. data/examples/rails_root/features/support/env_ext.rb +6 -0
  46. data/examples/rails_root/features/support/paths.rb +33 -0
  47. data/examples/rails_root/lib/tasks/cucumber.rake +47 -0
  48. data/examples/rails_root/public/404.html +30 -0
  49. data/examples/rails_root/public/422.html +30 -0
  50. data/examples/rails_root/public/500.html +33 -0
  51. data/examples/rails_root/public/dispatch.rb +10 -0
  52. data/examples/rails_root/public/favicon.ico +0 -0
  53. data/examples/rails_root/public/images/rails.png +0 -0
  54. data/examples/rails_root/public/javascripts/application.js +2 -0
  55. data/examples/rails_root/public/javascripts/controls.js +963 -0
  56. data/examples/rails_root/public/javascripts/dragdrop.js +973 -0
  57. data/examples/rails_root/public/javascripts/effects.js +1128 -0
  58. data/examples/rails_root/public/javascripts/prototype.js +4320 -0
  59. data/examples/rails_root/public/robots.txt +5 -0
  60. data/examples/rails_root/script/about +4 -0
  61. data/examples/rails_root/script/autospec +5 -0
  62. data/examples/rails_root/script/console +3 -0
  63. data/examples/rails_root/script/cucumber +10 -0
  64. data/examples/rails_root/script/dbconsole +3 -0
  65. data/examples/rails_root/script/delayed_job +5 -0
  66. data/examples/rails_root/script/destroy +3 -0
  67. data/examples/rails_root/script/generate +3 -0
  68. data/examples/rails_root/script/performance/benchmarker +3 -0
  69. data/examples/rails_root/script/performance/profiler +3 -0
  70. data/examples/rails_root/script/performance/request +3 -0
  71. data/examples/rails_root/script/plugin +3 -0
  72. data/examples/rails_root/script/process/inspector +3 -0
  73. data/examples/rails_root/script/process/reaper +3 -0
  74. data/examples/rails_root/script/process/spawner +3 -0
  75. data/examples/rails_root/script/runner +3 -0
  76. data/examples/rails_root/script/server +3 -0
  77. data/examples/rails_root/script/spec +5 -0
  78. data/examples/rails_root/script/spec_server +125 -0
  79. data/examples/rails_root/spec/controllers/welcome_controller_spec.rb +15 -0
  80. data/examples/rails_root/spec/model_factory.rb +6 -0
  81. data/examples/rails_root/spec/models/user_mailer_spec.rb +58 -0
  82. data/examples/rails_root/spec/models/user_spec.rb +5 -0
  83. data/examples/rails_root/spec/rcov.opts +2 -0
  84. data/examples/rails_root/spec/spec.opts +4 -0
  85. data/examples/rails_root/spec/spec_helper.rb +51 -0
  86. data/examples/sinatra/app.rb +33 -0
  87. data/examples/sinatra/features/errors.feature +32 -0
  88. data/examples/sinatra/features/example.feature +62 -0
  89. data/examples/sinatra/features/step_definitions/user_steps.rb +26 -0
  90. data/examples/sinatra/features/step_definitions/web_steps.rb +273 -0
  91. data/examples/sinatra/features/support/env.rb +39 -0
  92. data/examples/sinatra/features/support/paths.rb +24 -0
  93. data/install.rb +0 -0
  94. data/lib/email-spec.rb +1 -0
  95. data/lib/email_spec.rb +15 -0
  96. data/lib/email_spec/address_converter.rb +29 -0
  97. data/lib/email_spec/background_processes.rb +45 -0
  98. data/lib/email_spec/cucumber.rb +26 -0
  99. data/lib/email_spec/deliveries.rb +87 -0
  100. data/lib/email_spec/email_viewer.rb +87 -0
  101. data/lib/email_spec/helpers.rb +160 -0
  102. data/lib/email_spec/matchers.rb +217 -0
  103. data/rails_generators/email_spec/email_spec_generator.rb +17 -0
  104. data/rails_generators/email_spec/templates/email_steps.rb +182 -0
  105. data/spec/email_spec/helpers_spec.rb +23 -0
  106. data/spec/email_spec/matchers_spec.rb +240 -0
  107. data/spec/spec.opts +4 -0
  108. data/spec/spec_helper.rb +4 -0
  109. metadata +268 -0
@@ -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,182 @@
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
+ # last_email_address
7
+ # reset_mailer
8
+ # open_last_email
9
+ # visit_in_email
10
+ # unread_emails_for
11
+ # mailbox_for
12
+ # current_email
13
+ # open_email
14
+ # read_emails_for
15
+ # find_email
16
+ #
17
+ # General form for email scenarios are:
18
+ # - clear the email queue (done automatically by email_spec)
19
+ # - execute steps that sends an email
20
+ # - check the user received an/no/[0-9] emails
21
+ # - open the email
22
+ # - inspect the email contents
23
+ # - interact with the email (e.g. click links)
24
+ #
25
+ # The Cucumber steps below are setup in this order.
26
+
27
+ module EmailHelpers
28
+ def current_email_address
29
+ # Replace with your a way to find your current email. e.g @current_user.email
30
+ # last_email_address will return the last email address used by email spec to find an email.
31
+ # Note that last_email_address will be reset after each Scenario.
32
+ last_email_address || "example@example.com"
33
+ end
34
+ end
35
+
36
+ World(EmailHelpers)
37
+
38
+ #
39
+ # Reset the e-mail queue within a scenario.
40
+ # This is done automatically before each scenario.
41
+ #
42
+
43
+ Given /^(?:a clear email queue|no emails have been sent)$/ do
44
+ reset_mailer
45
+ end
46
+
47
+ #
48
+ # Check how many emails have been sent/received
49
+ #
50
+
51
+ Then /^(?:I|they|"([^"]*?)") should receive (an|no|\d+) emails?$/ do |address, amount|
52
+ unread_emails_for(address).size.should == parse_email_count(amount)
53
+ end
54
+
55
+ Then /^(?:I|they|"([^"]*?)") should have (an|no|\d+) emails?$/ do |address, amount|
56
+ mailbox_for(address).size.should == parse_email_count(amount)
57
+ end
58
+
59
+ Then /^(?:I|they|"([^"]*?)") should receive (an|no|\d+) emails? with subject "([^"]*?)"$/ do |address, amount, subject|
60
+ unread_emails_for(address).select { |m| m.subject =~ Regexp.new(subject) }.size.should == parse_email_count(amount)
61
+ end
62
+
63
+ Then /^(?:I|they|"([^"]*?)") should receive an email with the following body:$/ do |address, expected_body|
64
+ open_email(address, :with_text => expected_body)
65
+ end
66
+
67
+ #
68
+ # Accessing emails
69
+ #
70
+
71
+ # Opens the most recently received email
72
+ When /^(?:I|they|"([^"]*?)") opens? the email$/ do |address|
73
+ open_email(address)
74
+ end
75
+
76
+ When /^(?:I|they|"([^"]*?)") opens? the email with subject "([^"]*?)"$/ do |address, subject|
77
+ open_email(address, :with_subject => subject)
78
+ end
79
+
80
+ When /^(?:I|they|"([^"]*?)") opens? the email with text "([^"]*?)"$/ do |address, text|
81
+ open_email(address, :with_text => text)
82
+ end
83
+
84
+ #
85
+ # Inspect the Email Contents
86
+ #
87
+
88
+ Then /^(?:I|they) should see "([^"]*?)" in the email subject$/ do |text|
89
+ current_email.should have_subject(text)
90
+ end
91
+
92
+ Then /^(?:I|they) should see \/([^"]*?)\/ in the email subject$/ do |text|
93
+ current_email.should have_subject(Regexp.new(text))
94
+ end
95
+
96
+ Then /^(?:I|they) should see "([^"]*?)" in the email body$/ do |text|
97
+ current_email.body.should include(text)
98
+ end
99
+
100
+ Then /^(?:I|they) should see \/([^"]*?)\/ in the email body$/ do |text|
101
+ current_email.body.should =~ Regexp.new(text)
102
+ end
103
+
104
+ Then /^(?:I|they) should see the email delivered from "([^"]*?)"$/ do |text|
105
+ current_email.should be_delivered_from(text)
106
+ end
107
+
108
+ Then /^(?:I|they) should see "([^\"]*)" in the email "([^"]*?)" header$/ do |text, name|
109
+ current_email.should have_header(name, text)
110
+ end
111
+
112
+ Then /^(?:I|they) should see \/([^\"]*)\/ in the email "([^"]*?)" header$/ do |text, name|
113
+ current_email.should have_header(name, Regexp.new(text))
114
+ end
115
+
116
+ #
117
+ # Inspect the Email Attachments
118
+ #
119
+
120
+ Then /^(?:I|they) should see (an|no|\d+) attachments? with the email$/ do |amount|
121
+ current_email_attachments.size.should == parse_email_count(amount)
122
+ end
123
+
124
+ Then /^there should be (an|no|\d+) attachments? named "([^"]*?)"$/ do |amount, filename|
125
+ current_email_attachments.select { |a| a.original_filename == filename }.size.should == parse_email_count(amount)
126
+ end
127
+
128
+ Then /^attachment (\d+) should be named "([^"]*?)"$/ do |index, filename|
129
+ current_email_attachments[(index.to_i - 1)].original_filename.should == filename
130
+ end
131
+
132
+ Then /^there should be (an|no|\d+) attachments? of type "([^"]*?)"$/ do |amount, content_type|
133
+ current_email_attachments.select { |a| a.content_type == content_type }.size.should == parse_email_count(amount)
134
+ end
135
+
136
+ Then /^attachment (\d+) should be of type "([^"]*?)"$/ do |index, content_type|
137
+ current_email_attachments[(index.to_i - 1)].content_type.should == content_type
138
+ end
139
+
140
+ Then /^all attachments should not be blank$/ do
141
+ current_email_attachments.each do |attachment|
142
+ attachment.size.should_not == 0
143
+ end
144
+ end
145
+
146
+ Then /^show me a list of email attachments$/ do
147
+ EmailSpec::EmailViewer::save_and_open_email_attachments_list(current_email)
148
+ end
149
+
150
+ #
151
+ # Interact with Email Contents
152
+ #
153
+
154
+ When /^(?:I|they) follow "([^"]*?)" in the email$/ do |link|
155
+ visit_in_email(link)
156
+ end
157
+
158
+ When /^(?:I|they) click the first link in the email$/ do
159
+ click_first_link_in_email
160
+ end
161
+
162
+ #
163
+ # Debugging
164
+ # These only work with Rails and OSx ATM since EmailViewer uses RAILS_ROOT and OSx's 'open' command.
165
+ # Patches accepted. ;)
166
+ #
167
+
168
+ Then /^save and open current email$/ do
169
+ EmailSpec::EmailViewer::save_and_open_email(current_email)
170
+ end
171
+
172
+ Then /^save and open all text emails$/ do
173
+ EmailSpec::EmailViewer::save_and_open_all_text_emails
174
+ end
175
+
176
+ Then /^save and open all html emails$/ do
177
+ EmailSpec::EmailViewer::save_and_open_all_html_emails
178
+ end
179
+
180
+ Then /^save and open all raw emails$/ do
181
+ EmailSpec::EmailViewer::save_and_open_all_raw_emails
182
+ end
@@ -0,0 +1,23 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe EmailSpec::Helpers do
4
+ include EmailSpec::Helpers
5
+ describe "#parse_email_for_link" do
6
+ it "properly finds links with text" do
7
+ email = stub(:has_body_text? => true,
8
+ :body => %(<a href="/path/to/page">Click Here</a>))
9
+ parse_email_for_link(email, "Click Here").should == "/path/to/page"
10
+ end
11
+
12
+ it "recognizes img alt properties as text" do
13
+ email = stub(:has_body_text? => true,
14
+ :body => %(<a href="/path/to/page"><img src="http://host.com/images/image.gif" alt="an image" /></a>))
15
+ parse_email_for_link(email, "an image").should == "/path/to/page"
16
+ end
17
+
18
+ it "causes a spec to fail if the body doesn't contain the text specified to click" do
19
+ email = stub(:has_body_text? => false)
20
+ lambda { parse_email_for_link(email, "non-existent text") }.should raise_error(Spec::Expectations::ExpectationNotMetError)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,240 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe EmailSpec::Matchers do
4
+ include EmailSpec::Matchers
5
+
6
+ class MatcherMatch
7
+ def initialize(object_to_test_match)
8
+ @object_to_test_match = object_to_test_match
9
+ end
10
+
11
+ def description
12
+ "match when provided #{@object_to_test_match.inspect}"
13
+ end
14
+
15
+ def matches?(matcher)
16
+ @matcher = matcher
17
+ matcher.matches?(@object_to_test_match)
18
+ end
19
+
20
+ def failure_message
21
+ "expected #{@matcher.inspect} to match when provided #{@object_to_test_match.inspect}, but it did not"
22
+ end
23
+
24
+ def negative_failure_message
25
+ "expected #{@matcher.inspect} not to match when provided #{@object_to_test_match.inspect}, but it did"
26
+ end
27
+ end
28
+
29
+ def match(object_to_test_match)
30
+ if object_to_test_match.is_a?(Regexp)
31
+ super # delegate to rspec's built in 'match' matcher
32
+ else
33
+ MatcherMatch.new(object_to_test_match)
34
+ end
35
+ end
36
+
37
+ def mock_email(stubs)
38
+ mock("email", stubs)
39
+ end
40
+
41
+ describe "#reply_to" do
42
+ it "should match when the email is set to deliver to the specified address" do
43
+ email = mock_email(:reply_to => ["test@gmail.com"])
44
+ reply_to("test@gmail.com").should match(email)
45
+ end
46
+
47
+ it "should match given a name and address" do
48
+ email = mock_email(:reply_to => ["test@gmail.com"])
49
+ reply_to("David Balatero <test@gmail.com>").should match(email)
50
+ end
51
+
52
+ it "should give correct failure message when the email is not set to deliver to the specified address" do
53
+ matcher = reply_to("jimmy_bean@yahoo.com")
54
+ matcher.matches?(mock_email(:inspect => 'email', :reply_to => ['freddy_noe@yahoo.com']))
55
+ matcher.failure_message.should == %{expected email to reply to "jimmy_bean@yahoo.com", but it replied to "freddy_noe@yahoo.com"}
56
+ end
57
+
58
+ end
59
+
60
+ describe "#deliver_to" do
61
+ it "should match when the email is set to deliver to the specidied address" do
62
+ email = mock_email(:to => "jimmy_bean@yahoo.com")
63
+
64
+ deliver_to("jimmy_bean@yahoo.com").should match(email)
65
+ end
66
+
67
+ it "should match when a list of emails is exact same as all of the email's recipients" do
68
+ email = mock_email(:to => ["james@yahoo.com", "karen@yahoo.com"])
69
+
70
+ deliver_to("karen@yahoo.com", "james@yahoo.com").should match(email)
71
+ deliver_to("karen@yahoo.com").should_not match(email)
72
+ end
73
+
74
+ it "should match when an array of emails is exact same as all of the email's recipients" do
75
+ addresses = ["james@yahoo.com", "karen@yahoo.com"]
76
+ email = mock_email(:to => addresses)
77
+ deliver_to(addresses).should match(email)
78
+ end
79
+
80
+ it "should use the passed in objects :email method if not a string" do
81
+ email = mock_email(:to => "jimmy_bean@yahoo.com")
82
+ user = mock("user", :email => "jimmy_bean@yahoo.com")
83
+
84
+ deliver_to(user).should match(email)
85
+ end
86
+
87
+ it "should give correct failure message when the email is not set to deliver to the specified address" do
88
+ matcher = deliver_to("jimmy_bean@yahoo.com")
89
+ matcher.matches?(mock_email(:inspect => 'email', :to => 'freddy_noe@yahoo.com'))
90
+ matcher.failure_message.should == %{expected email to deliver to ["jimmy_bean@yahoo.com"], but it delivered to ["freddy_noe@yahoo.com"]}
91
+ end
92
+
93
+ end
94
+
95
+ describe "#deliver_from" do
96
+ it "should match when the email is set to deliver from the specified address" do
97
+ email = mock_email(:from_addrs => [TMail::Address.parse("jimmy_bean@yahoo.com")])
98
+ deliver_from("jimmy_bean@yahoo.com").should match(email)
99
+ end
100
+
101
+ it "should match when the email is set to deliver from the specified name and address" do
102
+ email = mock_email(:from_addrs => [TMail::Address.parse("Jimmy Bean <jimmy_bean@yahoo.com>")])
103
+ deliver_from("Jimmy Bean <jimmy_bean@yahoo.com>").should match(email)
104
+ end
105
+
106
+ it "should not match when the email does not have a sender" do
107
+ email = mock_email(:from_addrs => nil)
108
+ deliver_from("jimmy_bean@yahoo.com").should_not match(email)
109
+ end
110
+
111
+ it "should not match when the email addresses match but the names do not" do
112
+ email = mock_email(:from_addrs => [TMail::Address.parse("Jimmy Bean <jimmy_bean@yahoo.com>")])
113
+ deliver_from("Freddy Noe <jimmy_bean@yahoo.com>").should_not match(email)
114
+ end
115
+
116
+ it "should not match when the names match but the email addresses do not" do
117
+ email = mock_email(:from_addrs => [TMail::Address.parse("Jimmy Bean <jimmy_bean@yahoo.com>")])
118
+ deliver_from("Jimmy Bean <freddy_noe@yahoo.com>").should_not match(email)
119
+ end
120
+
121
+ it "should not match when the email is not set to deliver from the specified address" do
122
+ email = mock_email(:from_addrs => [TMail::Address.parse("freddy_noe@yahoo.com")])
123
+ deliver_from("jimmy_bean@yahoo.com").should_not match(email)
124
+ end
125
+
126
+ it "should give correct failure message when the email is not set to deliver from the specified address" do
127
+ matcher = deliver_from("jimmy_bean@yahoo.com")
128
+ matcher.matches?(mock_email(:inspect => 'email', :from_addrs => [TMail::Address.parse("freddy_noe@yahoo.com")]))
129
+ matcher.failure_message.should == %{expected email to deliver from "jimmy_bean@yahoo.com", but it delivered from "freddy_noe@yahoo.com"}
130
+ end
131
+
132
+ end
133
+
134
+ describe "#bcc_to" do
135
+
136
+ it "should match when the email is set to deliver to the specidied address" do
137
+ email = mock_email(:bcc => "jimmy_bean@yahoo.com")
138
+
139
+ bcc_to("jimmy_bean@yahoo.com").should match(email)
140
+ end
141
+
142
+ it "should match when a list of emails is exact same as all of the email's recipients" do
143
+ email = mock_email(:bcc => ["james@yahoo.com", "karen@yahoo.com"])
144
+
145
+ bcc_to("karen@yahoo.com", "james@yahoo.com").should match(email)
146
+ bcc_to("karen@yahoo.com").should_not match(email)
147
+ end
148
+
149
+ it "should match when an array of emails is exact same as all of the email's recipients" do
150
+ addresses = ["james@yahoo.com", "karen@yahoo.com"]
151
+ email = mock_email(:bcc => addresses)
152
+ bcc_to(addresses).should match(email)
153
+ end
154
+
155
+ it "should use the passed in objects :email method if not a string" do
156
+ email = mock_email(:bcc => "jimmy_bean@yahoo.com")
157
+ user = mock("user", :email => "jimmy_bean@yahoo.com")
158
+
159
+ bcc_to(user).should match(email)
160
+ end
161
+
162
+ end
163
+
164
+ describe "#have_subject" do
165
+
166
+ describe "when regexps are used" do
167
+
168
+ it "should match when the subject mathches regexp" do
169
+ email = mock_email(:subject => ' -- The Subject --')
170
+
171
+ have_subject(/The Subject/).should match(email)
172
+ have_subject(/The Subject/).should match(email)
173
+ have_subject(/foo/).should_not match(email)
174
+ end
175
+
176
+ it "should have a helpful description" do
177
+ matcher = have_subject(/foo/)
178
+ matcher.matches?(mock_email(:subject => "bar"))
179
+
180
+ matcher.description.should == "have subject matching /foo/"
181
+ end
182
+
183
+ it "should offer helpful failing messages" do
184
+ matcher = have_subject(/foo/)
185
+ matcher.matches?(mock_email(:subject => "bar"))
186
+
187
+ matcher.failure_message.should == 'expected the subject to match /foo/, but did not. Actual subject was: "bar"'
188
+ end
189
+
190
+ it "should offer helpful negative failing messages" do
191
+ matcher = have_subject(/b/)
192
+ matcher.matches?(mock_email(:subject => "bar"))
193
+
194
+ matcher.negative_failure_message.should == 'expected the subject not to match /b/ but "bar" does match it.'
195
+ end
196
+ end
197
+
198
+ describe "when strings are used" do
199
+ it "should match when the subject equals the passed in string exactly" do
200
+ email = mock_email(:subject => 'foo')
201
+
202
+ have_subject("foo").should match(email)
203
+ have_subject(" - foo -").should_not match(email)
204
+ end
205
+
206
+ it "should have a helpful description" do
207
+ matcher = have_subject("foo")
208
+ matcher.matches?(mock_email(:subject => "bar"))
209
+
210
+ matcher.description.should == 'have subject of "foo"'
211
+ end
212
+
213
+ it "should offer helpful failing messages" do
214
+ matcher = have_subject("foo")
215
+ matcher.matches?(mock_email(:subject => "bar"))
216
+
217
+ matcher.failure_message.should == 'expected the subject to be "foo" but was "bar"'
218
+ end
219
+
220
+ it "should offer helpful negative failing messages" do
221
+ matcher = have_subject("bar")
222
+ matcher.matches?(mock_email(:subject => "bar"))
223
+
224
+ matcher.negative_failure_message.should == 'expected the subject not to be "bar" but was'
225
+ end
226
+ end
227
+ end
228
+
229
+ describe "#include_email_with_subject" do
230
+ it "should have specs!"
231
+ end
232
+
233
+ describe "#have_body_text" do
234
+ it "should have specs!"
235
+ end
236
+
237
+ describe "#have_header" do
238
+ it "should have specs!"
239
+ end
240
+ end