gmail 0.6.0 → 0.7.0
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.
- checksums.yaml +4 -4
- data/.coveralls.yml +1 -0
- data/.gitignore +27 -27
- data/.rspec +1 -1
- data/.rubocop.yml +53 -13
- data/.rubocop_todo.yml +299 -239
- data/.travis.yml +19 -19
- data/CHANGELOG.md +152 -145
- data/Gemfile +5 -3
- data/LICENSE +21 -21
- data/README.md +380 -355
- data/Rakefile +44 -46
- data/gmail.gemspec +32 -34
- data/lib/gmail.rb +72 -78
- data/lib/gmail/client.rb +35 -34
- data/lib/gmail/client/base.rb +244 -229
- data/lib/gmail/client/plain.rb +24 -24
- data/lib/gmail/client/xoauth.rb +67 -68
- data/lib/gmail/client/xoauth2.rb +39 -39
- data/lib/gmail/imap_extensions.rb +156 -159
- data/lib/gmail/labels.rb +80 -79
- data/lib/gmail/mailbox.rb +178 -175
- data/lib/gmail/message.rb +212 -207
- data/lib/gmail/version.rb +3 -3
- data/spec/account.yml.example +1 -1
- data/spec/account.yml.obfus +2 -2
- data/spec/gmail/client/base_spec.rb +5 -5
- data/spec/gmail/client/plain_spec.rb +169 -169
- data/spec/gmail/client/xoauth2_spec.rb +186 -186
- data/spec/gmail/client/xoauth_spec.rb +5 -5
- data/spec/gmail/client_spec.rb +5 -5
- data/spec/gmail/imap_extensions_spec.rb +47 -47
- data/spec/gmail/labels_spec.rb +27 -27
- data/spec/gmail/mailbox_spec.rb +84 -84
- data/spec/gmail/message_spec.rb +181 -181
- data/spec/gmail_spec.rb +40 -39
- data/spec/recordings/gmail/_new_connects_with_client_and_give_it_context_when_block_given.yml +61 -28
- data/spec/recordings/gmail/_new_connects_with_gmail_service_and_return_valid_connection_object.yml +43 -28
- data/spec/recordings/gmail/_new_does_not_raise_error_when_couldn_t_connect_with_given_account.yml +21 -13
- data/spec/recordings/gmail/_new_raises_error_when_couldn_t_connect_with_given_account.yml +21 -13
- data/spec/recordings/gmail_client_plain/instance/delivers_inline_composed_email.yml +61 -42
- data/spec/recordings/gmail_client_plain/instance/does_not_log_in_when_given_gmail_account_is_invalid.yml +21 -13
- data/spec/recordings/gmail_client_plain/instance/does_not_raise_error_even_though_gmail_account_is_invalid.yml +21 -13
- data/spec/recordings/gmail_client_plain/instance/labels/checks_if_there_is_given_label_defined.yml +409 -196
- data/spec/recordings/gmail_client_plain/instance/labels/creates_given_label.yml +280 -151
- data/spec/recordings/gmail_client_plain/instance/labels/removes_existing_label.yml +271 -146
- data/spec/recordings/gmail_client_plain/instance/labels/returns_list_of_all_available_labels.yml +227 -113
- data/spec/recordings/gmail_client_plain/instance/properly_logs_in_to_valid_gmail_account.yml +61 -42
- data/spec/recordings/gmail_client_plain/instance/properly_logs_out_from_gmail.yml +61 -42
- data/spec/recordings/gmail_client_plain/instance/properly_switches_to_given_mailbox.yml +164 -109
- data/spec/recordings/gmail_client_plain/instance/properly_switches_to_given_mailbox_using_block_style.yml +164 -109
- data/spec/recordings/gmail_client_plain/instance/raises_error_when_given_gmail_account_is_invalid_and_errors_enabled.yml +21 -13
- data/spec/recordings/gmail_client_xo_auth2/instance/does_not_log_in_when_given_gmail_account_is_invalid.yml +24 -13
- data/spec/recordings/gmail_client_xo_auth2/instance/labels/checks_if_there_is_given_label_defined.yml +39 -27
- data/spec/recordings/gmail_client_xo_auth2/instance/labels/creates_given_label.yml +52 -39
- data/spec/recordings/gmail_client_xo_auth2/instance/labels/removes_existing_label.yml +52 -39
- data/spec/recordings/gmail_client_xo_auth2/instance/labels/returns_list_of_all_available_labels.yml +39 -27
- data/spec/recordings/gmail_client_xo_auth2/instance/properly_logs_in_to_valid_gmail_account.yml +26 -15
- data/spec/recordings/gmail_client_xo_auth2/instance/properly_logs_out_from_gmail.yml +26 -15
- data/spec/recordings/gmail_client_xo_auth2/instance/properly_switches_to_given_mailbox.yml +63 -40
- data/spec/recordings/gmail_client_xo_auth2/instance/properly_switches_to_given_mailbox_using_block_style.yml +63 -40
- data/spec/recordings/gmail_client_xo_auth2/instance/raises_error_when_given_gmail_account_is_invalid_and_errors_enabled.yml +24 -13
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/all/localizes_into_the_appropriate_label.yml +229 -116
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/and_the_mailbox_does_not_exist/returns_the_mailbox_name_as_a_string.yml +229 -110
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/drafts/localizes_into_the_appropriate_label.yml +229 -116
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/flagged/localizes_into_the_appropriate_label.yml +229 -116
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/important/localizes_into_the_appropriate_label.yml +229 -116
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/inbox/localizes_into_the_appropriate_label.yml +61 -42
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/junk/localizes_into_the_appropriate_label.yml +229 -116
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/sent/localizes_into_the_appropriate_label.yml +229 -116
- data/spec/recordings/gmail_labels/localize/when_given_the_xl_is_tflag/trash/localizes_into_the_appropriate_label.yml +229 -116
- data/spec/recordings/gmail_mailbox/instance/counts_all_emails.yml +595 -277
- data/spec/recordings/gmail_mailbox/instance/finds_messages.yml +1049 -586
- data/spec/recordings/gmail_mailbox/instance/waits_once.yml +191 -136
- data/spec/recordings/gmail_mailbox/instance/waits_repeatedly.yml +217 -141
- data/spec/recordings/gmail_mailbox/instance/waits_with_29-minute_re-issue.yml +188 -136
- data/spec/recordings/gmail_mailbox/instance/waits_with_an_unblocked_connection.yml +644 -207
- data/spec/recordings/gmail_mailbox/on_initialize/sets_client_and_name.yml +61 -42
- data/spec/recordings/gmail_mailbox/on_initialize/works_in_inbox_by_default.yml +61 -42
- data/spec/recordings/gmail_message/initialize/sets_prefetch_attrs.yml +1068 -578
- data/spec/recordings/gmail_message/initialize/sets_uid_and_mailbox.yml +1068 -580
- data/spec/recordings/gmail_message/instance_methods/deletes_itself.yml +1084 -637
- data/spec/recordings/gmail_message/instance_methods/marks_itself_read.yml +1137 -682
- data/spec/recordings/gmail_message/instance_methods/marks_itself_unread.yml +1153 -686
- data/spec/recordings/gmail_message/instance_methods/moves_from_one_tag_to_other.yml +1447 -862
- data/spec/recordings/gmail_message/instance_methods/removes_a_given_label.yml +1288 -776
- data/spec/recordings/gmail_message/instance_methods/removes_a_given_label_with_old_method.yml +1288 -776
- data/spec/recordings/gmail_message/instance_methods/sets_given_label.yml +1165 -690
- data/spec/recordings/gmail_message/instance_methods/sets_given_label_with_old_method.yml +1157 -691
- data/spec/spec_helper.rb +56 -53
- data/spec/support/imap_mock.rb +181 -181
- data/spec/support/obfuscation.rb +49 -52
- metadata +21 -90
- data/spec/recordings/gmail_client_plain/instance/_connection_automatically_logs_in_to_gmail_account_when_it_s_called.yml +0 -42
data/spec/spec_helper.rb
CHANGED
@@ -1,53 +1,56 @@
|
|
1
|
-
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
-
|
3
|
-
require 'rubygems'
|
4
|
-
require 'rspec'
|
5
|
-
require 'yaml'
|
6
|
-
require 'gmail'
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'rspec'
|
5
|
+
require 'yaml'
|
6
|
+
require 'gmail'
|
7
|
+
require 'coveralls'
|
8
|
+
|
9
|
+
Coveralls.wear!
|
10
|
+
|
11
|
+
# require_support_files
|
12
|
+
Dir[File.join(File.dirname(__FILE__), 'support', '*.rb')].each { |f| require f }
|
13
|
+
|
14
|
+
RSpec.configure do |config|
|
15
|
+
Spec::ImapMock.configure_rspec!(config)
|
16
|
+
end
|
17
|
+
|
18
|
+
def within_gmail(&block)
|
19
|
+
Gmail.connect!(*TEST_ACCOUNT) do |gmail|
|
20
|
+
yield(gmail)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def mock_client(&block)
|
25
|
+
client = Gmail::Client::Plain.new(*TEST_ACCOUNT)
|
26
|
+
client.connect
|
27
|
+
|
28
|
+
if block_given?
|
29
|
+
client.login
|
30
|
+
yield client
|
31
|
+
client.logout
|
32
|
+
end
|
33
|
+
|
34
|
+
client
|
35
|
+
end
|
36
|
+
|
37
|
+
def mock_mailbox(box = "INBOX", &block)
|
38
|
+
within_gmail do |gmail|
|
39
|
+
mailbox = gmail.mailbox(box)
|
40
|
+
yield(mailbox) if block_given?
|
41
|
+
mailbox
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# TODO: move this to it's own dir; get rid of global variable
|
46
|
+
# Run test by creating your own test account with credentials in account.yml
|
47
|
+
# Otherwise default credentials from an obfuscated file are used.
|
48
|
+
clear_file = File.join(File.dirname(__FILE__), 'account.yml')
|
49
|
+
obfus_file = File.join(File.dirname(__FILE__), 'account.yml.obfus')
|
50
|
+
if File.exist?(clear_file)
|
51
|
+
TEST_ACCOUNT = YAML.load_file(clear_file)
|
52
|
+
elsif File.exist?(obfus_file)
|
53
|
+
TEST_ACCOUNT = Spec::Obfuscation.decrypt_file(obfus_file)
|
54
|
+
else
|
55
|
+
raise 'account.yml file not found'
|
56
|
+
end
|
data/spec/support/imap_mock.rb
CHANGED
@@ -1,181 +1,181 @@
|
|
1
|
-
module Net
|
2
|
-
class IMAP
|
3
|
-
class << self
|
4
|
-
def recordings=(value)
|
5
|
-
@replaying = !value.nil?
|
6
|
-
@recordings = value
|
7
|
-
end
|
8
|
-
|
9
|
-
def recordings
|
10
|
-
@recordings ||= {}
|
11
|
-
end
|
12
|
-
|
13
|
-
def replaying?
|
14
|
-
@replaying
|
15
|
-
end
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
def send_command(cmd, *args, &block)
|
72
|
-
mock_command(:_send_command, cmd, *args, &block)
|
73
|
-
end
|
74
|
-
|
75
|
-
def mock_command(method, cmd, *args, &block)
|
76
|
-
# In Ruby 1.9.x, strings default to binary which causes the digest to be
|
77
|
-
# different.
|
78
|
-
clean_args = args.dup.each do |s|
|
79
|
-
Net::IMAP.force_utf8(s)
|
80
|
-
end
|
81
|
-
|
82
|
-
yaml_dump = YAML.dump([cmd] + clean_args)
|
83
|
-
|
84
|
-
if RUBY_VERSION =~ /^(1.9|2.0)/
|
85
|
-
# From 1.9 to 2.0 to 2.1, the way YAML encodes special characters changed.
|
86
|
-
# Here's what each returns for: YAML.dump(["", "%"])
|
87
|
-
# 1.9.x: "---\n- ''\n- ! '%'\n"
|
88
|
-
# 2.0.x: "---\n- ''\n- '%'\n"
|
89
|
-
# 2.1.x: "---\n- ''\n- \"%\"\n"
|
90
|
-
# The `gsub` here converts the older format into the 2.1.x.
|
91
|
-
yaml_dump.gsub!(/(?:! )?'(.+)'/, '"\1"')
|
92
|
-
|
93
|
-
# In 1.9 and 2.0 strings starting with `+` or `-` are not escaped in quotes, but
|
94
|
-
# they are in 2.1+. This addresses that.
|
95
|
-
yaml_dump.gsub!(/ ([+-](?:X-GM-\w+|FLAGS))/, ' "\1"')
|
96
|
-
|
97
|
-
# In 1.9 and 2.0 strings starting with `\` are not escaped in quotes, but
|
98
|
-
# they are in 2.1+. This addresses that. Yes we need all those backslashes :|
|
99
|
-
yaml_dump.gsub!(/ \\(\w+)/, ' "\\\\\\\\\1"')
|
100
|
-
end
|
101
|
-
|
102
|
-
digest = "#{cmd}-#{Digest::MD5.hexdigest(yaml_dump)}"
|
103
|
-
|
104
|
-
if Net::IMAP.replaying?
|
105
|
-
recordings = Net::IMAP.recordings[digest] || []
|
106
|
-
if recordings.empty?
|
107
|
-
# Be lenient if LOGOUT is called but wasn't explicitly recorded. This
|
108
|
-
# comes up often when called from `at_exit`.
|
109
|
-
cmd == 'LOGOUT' ? return : raise('Could not find recording')
|
110
|
-
end
|
111
|
-
|
112
|
-
action, response, @responses, all_responses = recordings.shift
|
113
|
-
|
114
|
-
if block && all_responses
|
115
|
-
all_responses.each do |resp|
|
116
|
-
|
117
|
-
end
|
118
|
-
end
|
119
|
-
else
|
120
|
-
action = :return
|
121
|
-
all_responses = []
|
122
|
-
begin
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
#
|
134
|
-
Net::IMAP.
|
135
|
-
Net::IMAP.recordings[digest]
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
end
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
#
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
end
|
180
|
-
end
|
181
|
-
end
|
1
|
+
module Net
|
2
|
+
class IMAP
|
3
|
+
class << self
|
4
|
+
def recordings=(value)
|
5
|
+
@replaying = !value.nil?
|
6
|
+
@recordings = value
|
7
|
+
end
|
8
|
+
|
9
|
+
def recordings
|
10
|
+
@recordings ||= {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def replaying?
|
14
|
+
@replaying
|
15
|
+
end
|
16
|
+
|
17
|
+
def force_utf8(data)
|
18
|
+
case data.class.to_s
|
19
|
+
when /String/
|
20
|
+
data.force_encoding('utf-8')
|
21
|
+
when /Hash/
|
22
|
+
data.each { |k, v| data[k] = force_utf8(v) }
|
23
|
+
when /Array/
|
24
|
+
data.map { |s| force_utf8(s) }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
alias_method :_idle, :idle
|
30
|
+
alias_method :_idle_done, :idle_done
|
31
|
+
|
32
|
+
def idle(&response_handler)
|
33
|
+
if Net::IMAP.replaying?
|
34
|
+
@idle_done_cond = new_cond
|
35
|
+
@idle_done = false
|
36
|
+
end
|
37
|
+
|
38
|
+
response = mock_command(:_idle, 'IDLE', &response_handler)
|
39
|
+
|
40
|
+
if Net::IMAP.replaying?
|
41
|
+
synchronize do
|
42
|
+
unless @idle_done
|
43
|
+
@idle_done_cond.wait(0.1)
|
44
|
+
raise('The IDLE has not done') unless @idle_done
|
45
|
+
end
|
46
|
+
@idle_done_cond = nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
response
|
51
|
+
end
|
52
|
+
|
53
|
+
def idle_done
|
54
|
+
if Net::IMAP.replaying?
|
55
|
+
synchronize do
|
56
|
+
if @idle_done_cond.nil?
|
57
|
+
raise Net::IMAP::Error, 'not during IDLE'
|
58
|
+
end
|
59
|
+
@idle_done = true
|
60
|
+
idle_done_cond.signal
|
61
|
+
end
|
62
|
+
else
|
63
|
+
_idle_done
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
alias_method :_send_command, :send_command
|
70
|
+
|
71
|
+
def send_command(cmd, *args, &block)
|
72
|
+
mock_command(:_send_command, cmd, *args, &block)
|
73
|
+
end
|
74
|
+
|
75
|
+
def mock_command(method, cmd, *args, &block)
|
76
|
+
# In Ruby 1.9.x, strings default to binary which causes the digest to be
|
77
|
+
# different.
|
78
|
+
clean_args = args.dup.each do |s|
|
79
|
+
Net::IMAP.force_utf8(s)
|
80
|
+
end
|
81
|
+
|
82
|
+
yaml_dump = YAML.dump([cmd] + clean_args)
|
83
|
+
|
84
|
+
if RUBY_VERSION =~ /^(1.9|2.0)/
|
85
|
+
# From 1.9 to 2.0 to 2.1, the way YAML encodes special characters changed.
|
86
|
+
# Here's what each returns for: YAML.dump(["", "%"])
|
87
|
+
# 1.9.x: "---\n- ''\n- ! '%'\n"
|
88
|
+
# 2.0.x: "---\n- ''\n- '%'\n"
|
89
|
+
# 2.1.x: "---\n- ''\n- \"%\"\n"
|
90
|
+
# The `gsub` here converts the older format into the 2.1.x.
|
91
|
+
yaml_dump.gsub!(/(?:! )?'(.+)'/, '"\1"')
|
92
|
+
|
93
|
+
# In 1.9 and 2.0 strings starting with `+` or `-` are not escaped in quotes, but
|
94
|
+
# they are in 2.1+. This addresses that.
|
95
|
+
yaml_dump.gsub!(/ ([+-](?:X-GM-\w+|FLAGS))/, ' "\1"')
|
96
|
+
|
97
|
+
# In 1.9 and 2.0 strings starting with `\` are not escaped in quotes, but
|
98
|
+
# they are in 2.1+. This addresses that. Yes we need all those backslashes :|
|
99
|
+
yaml_dump.gsub!(/ \\(\w+)/, ' "\\\\\\\\\1"')
|
100
|
+
end
|
101
|
+
|
102
|
+
digest = "#{cmd}-#{Digest::MD5.hexdigest(yaml_dump)}"
|
103
|
+
|
104
|
+
if Net::IMAP.replaying?
|
105
|
+
recordings = Net::IMAP.recordings[digest] || []
|
106
|
+
if recordings.empty?
|
107
|
+
# Be lenient if LOGOUT is called but wasn't explicitly recorded. This
|
108
|
+
# comes up often when called from `at_exit`.
|
109
|
+
cmd == 'LOGOUT' ? return : raise('Could not find recording')
|
110
|
+
end
|
111
|
+
|
112
|
+
action, response, @responses, all_responses = recordings.shift
|
113
|
+
|
114
|
+
if block && all_responses
|
115
|
+
all_responses.each do |resp|
|
116
|
+
yield(resp)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
else
|
120
|
+
action = :return
|
121
|
+
all_responses = []
|
122
|
+
begin
|
123
|
+
args.unshift(cmd) if method==:_send_command
|
124
|
+
response = send(method, *args) do |resp|
|
125
|
+
all_responses << resp
|
126
|
+
yield(resp)
|
127
|
+
end
|
128
|
+
rescue StandardError => e
|
129
|
+
action = :raise
|
130
|
+
response = e
|
131
|
+
end
|
132
|
+
|
133
|
+
# @responses (the third argument here) contains untagged responses captured
|
134
|
+
# via the Net::IMAP#record_response method.
|
135
|
+
Net::IMAP.recordings[digest] ||= []
|
136
|
+
Net::IMAP.recordings[digest] << [action, response.dup, @responses ? @responses.dup : nil, all_responses]
|
137
|
+
end
|
138
|
+
|
139
|
+
raise(response) if action == :raise
|
140
|
+
|
141
|
+
response
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
module Spec
|
147
|
+
module ImapMock
|
148
|
+
# Configures RSpec with an around(:each) block to use IMAP mocks
|
149
|
+
def self.configure_rspec!(config)
|
150
|
+
config.around(:each) do |example|
|
151
|
+
Spec::ImapMock.run_rspec_example(example)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
# Run an RSpec example using IMAP mocks
|
156
|
+
def self.run_rspec_example(example)
|
157
|
+
# The path is determined by the rspec `describe`s and `context`s
|
158
|
+
mock_path = example.example_group.to_s
|
159
|
+
.gsub(/RSpec::ExampleGroups::/, '')
|
160
|
+
.gsub(/(\w)([A-Z])/, '\1_\2')
|
161
|
+
.gsub(/::/, '/')
|
162
|
+
.downcase
|
163
|
+
|
164
|
+
# The name is determined by the description of the example.
|
165
|
+
mock_name = example.description.gsub(/[^\w\-\/]+/, '_').downcase
|
166
|
+
|
167
|
+
filename = File.join('spec/recordings/', mock_path, "#{mock_name}.yml")
|
168
|
+
|
169
|
+
# If we've already recorded this spec load the recordings
|
170
|
+
Net::IMAP.recordings = File.exist?(filename) ? YAML.load_file(filename) : nil
|
171
|
+
|
172
|
+
example.run
|
173
|
+
|
174
|
+
# If we haven't yet recorded the spec and there were some recordings,
|
175
|
+
# write them to a file.
|
176
|
+
return if File.exist?(filename) or Net::IMAP.recordings.empty?
|
177
|
+
FileUtils.mkdir_p(File.dirname(filename))
|
178
|
+
File.open(filename, 'w') { |f| YAML.dump(Net::IMAP.recordings, f) }
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|