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