imap 0.4.4 → 0.4.6
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/CHANGELOG +16 -0
- data/Gemfile +3 -0
- data/imap.gemspec +26 -5
- data/lib/Imap/Message.rb +2 -2
- data/lib/Imap/Search.rb +4 -0
- data/lib/Imap/VERSION.rb +1 -1
- data/test/Imap/Message_test.rb +9 -0
- data/test/Imap/Search_test.rb +4 -0
- data/test/test_helper.rb +5 -2
- metadata +9 -4
- /data/test/{imap_test.rb → Imap_test.rb} +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 26d3a42b29eb3be8775fc3ec60f3559b0834e8ef106e2e3458cd2b93bdee7364
|
|
4
|
+
data.tar.gz: 85aebe82c105a2d7db62c581ca61bd2c0630fcd7054dc777a02a86e84fd620ba
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bb36b35b0cd5f9ddc6895aa0bfe9c0d644cd5386f13f4b26a66324d767560c3af41a8741be6a4fecf4f69fbbf6028dc823e1207e9aba50ab63a382b0a9750c50
|
|
7
|
+
data.tar.gz: 79add07e74eb8acc3105b3791be56d020cc50c89e80d47d3e47f8b46cf997b6e9c7fdd44e536292435f5560f380bd1bdac2d966c4bfc53bd548a010e77b93432
|
data/CHANGELOG
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## [0.4.6] - 2026-09-17, ~ Imap::Message#body: BODY.PEEK[TEXT]; ~ Imap::Search#to_imap_search_keys: raise upon a key which is neither
|
|
4
|
+
- ~ Imap::Message#body: BODY.PEEK[TEXT] for BODY[TEXT]. Reading a body set \Seen, so anything which looked at one marked it read; PEEK is the whole of the difference and the response still answers to BODY[TEXT].
|
|
5
|
+
- ~ Imap::Search#to_imap_search_keys: + UnknownSearchKey where the case matched neither operator. An unrecognised key was dropped and the search ran wider than it was asked for, saying nothing.
|
|
6
|
+
- ~ Imap::Message#to: [] where the envelope carries no to, which raised NoMethodError upon nil.
|
|
7
|
+
- ~ test/test_helper.rb: MockIMAP answers BODY.PEEK[TEXT] with BODY[TEXT] as a server does, records the attrs fetched, and gives message 99 an envelope with no to.
|
|
8
|
+
- + a test apiece: that #body peeks, that #to is empty where there is no to, and that an unknown key raises.
|
|
9
|
+
- ~ Imap::VERSION: /0.4.5/0.4.6/
|
|
10
|
+
|
|
11
|
+
## [0.4.5] - 2026-09-17, + Gemfile; ~ imap.gemspec: dependencies=, - spec.date, + metadata
|
|
12
|
+
- + Gemfile: source and gemspec, as switches, eodhd and moby have it, so that the dependencies are declared once in the gemspec rather than restated here to drift. bitget and coinmarketcap restate theirs and are the minority. This was the only gem here with no Gemfile at all.
|
|
13
|
+
- ~ imap.gemspec: + 'Gemfile' to spec.files, which every other gem here ships.
|
|
14
|
+
- ~ imap.gemspec: dependencies= and development_dependencies= through the Gem::Specification extension, as switches, eodhd and moby have it and as bitget, coinmarketcap and this did not. The constraints survive: the splat takes a bare string or a [name, constraint] pair alike.
|
|
15
|
+
- ~ imap.gemspec: - spec.date = '2025-12-20', nine months and two versions stale, and the last one left in the estate. RubyGems answers 1980-01-02 in its place, the reproducible-build epoch, which is what coinmarketcap has carried since dropping its own at 0.6.0.
|
|
16
|
+
- ~ imap.gemspec: + metadata, the four uris switches and moby declare, so that the RubyGems page links to the issues, the changelog, the source and the README. master here where moby says main, each by the branch it is on.
|
|
17
|
+
- ~ Imap::VERSION: /0.4.4/0.4.5/
|
|
18
|
+
|
|
3
19
|
## [0.4.4] - 2026-09-17, + Rakefile, - test/test_all.rb
|
|
4
20
|
- + Rakefile: Rake::TestTask over FileList['test/**/*_test.rb'], with libs for lib and test, and warning = true. The minimal form nine of the gems here use rather than the fuller one five use: the :spec alias and the :version task belong to the minority, and a :version task reading VERSION.rb would not have caught 0.4.1, where require 'imap' left Imap::VERSION undefined while VERSION.rb sat there defining it. rake has been a development dependency since 0.4.0 with nothing here to run.
|
|
5
21
|
- - test/test_all.rb: a second entry point which the Rakefile's FileList makes redundant, and which had drifted from the files on disk in two ways: it never loaded test/Imap/VERSION_test.rb, added in 0.4.2, so it ran 42 tests where there are 44; and it required './Imap_test' for a file named imap_test.rb, which resolved only because the filesystem is case insensitive and would not have on Linux. A glob cannot drift. 14 of the 16 gems here with a Rakefile carry no such file; switches keeps spec/all.rb because its Rakefile targets it, and bitget carries the same redundancy this removes.
|
data/Gemfile
ADDED
data/imap.gemspec
CHANGED
|
@@ -2,11 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
require_relative './lib/Imap/VERSION'
|
|
4
4
|
|
|
5
|
+
class Gem::Specification
|
|
6
|
+
def dependencies=(gems)
|
|
7
|
+
gems.each{|gem| add_dependency(*gem)}
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def development_dependencies=(gems)
|
|
11
|
+
gems.each{|gem| add_development_dependency(*gem)}
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
5
15
|
Gem::Specification.new do |spec|
|
|
6
16
|
spec.name = 'imap'
|
|
7
17
|
|
|
8
18
|
spec.version = Imap::VERSION
|
|
9
|
-
spec.date = '2025-12-20'
|
|
10
19
|
|
|
11
20
|
spec.summary = "IMAP for Ruby made easy."
|
|
12
21
|
spec.description = "A Ruby wrapper around Net::IMAP with an elegant DSL for searching, reading, and managing email."
|
|
@@ -18,20 +27,32 @@ Gem::Specification.new do |spec|
|
|
|
18
27
|
|
|
19
28
|
spec.required_ruby_version = '>= 2.7'
|
|
20
29
|
|
|
21
|
-
spec.
|
|
30
|
+
spec.dependencies = [
|
|
31
|
+
['net-imap', '~> 0.4']
|
|
32
|
+
]
|
|
22
33
|
|
|
23
|
-
spec.
|
|
24
|
-
|
|
25
|
-
|
|
34
|
+
spec.development_dependencies = [
|
|
35
|
+
['minitest', '~> 5.0'],
|
|
36
|
+
'minitest-mock',
|
|
37
|
+
['rake', '~> 13.0']
|
|
38
|
+
]
|
|
26
39
|
|
|
27
40
|
spec.files = [
|
|
28
41
|
'imap.gemspec',
|
|
29
42
|
Dir['lib/**/*.rb'],
|
|
30
43
|
Dir['test/**/*.rb'],
|
|
31
44
|
'CHANGELOG',
|
|
45
|
+
'Gemfile',
|
|
32
46
|
'Rakefile',
|
|
33
47
|
'LICENSE',
|
|
34
48
|
'README.md',
|
|
35
49
|
].flatten
|
|
36
50
|
spec.require_paths = ['lib']
|
|
51
|
+
|
|
52
|
+
spec.metadata = {
|
|
53
|
+
"bug_tracker_uri" => "https://github.com/thoran/imap/issues",
|
|
54
|
+
"changelog_uri" => "https://github.com/thoran/imap/blob/master/CHANGELOG",
|
|
55
|
+
"source_code_uri" => "https://github.com/thoran/imap",
|
|
56
|
+
"documentation_uri" => "https://github.com/thoran/imap/blob/master/README.md"
|
|
57
|
+
}
|
|
37
58
|
end
|
data/lib/Imap/Message.rb
CHANGED
|
@@ -29,7 +29,7 @@ class Imap
|
|
|
29
29
|
attr_accessor :message_id
|
|
30
30
|
|
|
31
31
|
def body
|
|
32
|
-
@body ||= fetch_data('BODY[TEXT]').first.attr['BODY[TEXT]']
|
|
32
|
+
@body ||= fetch_data('BODY.PEEK[TEXT]').first.attr['BODY[TEXT]']
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def subject
|
|
@@ -41,7 +41,7 @@ class Imap
|
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
def to
|
|
44
|
-
@to ||= fetch_data('ENVELOPE').first.attr['ENVELOPE'].to.map{|addr| addr.mailbox + '@' + addr.host}
|
|
44
|
+
@to ||= (fetch_data('ENVELOPE').first.attr['ENVELOPE'].to || []).map{|addr| addr.mailbox + '@' + addr.host}
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
def urls
|
data/lib/Imap/Search.rb
CHANGED
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
class Imap
|
|
12
12
|
class Search
|
|
13
13
|
|
|
14
|
+
class UnknownSearchKey < ArgumentError; end
|
|
15
|
+
|
|
14
16
|
ALL_SEARCH_KEYS = %w{
|
|
15
17
|
ALL
|
|
16
18
|
ANSWERED
|
|
@@ -112,6 +114,8 @@ class Imap
|
|
|
112
114
|
m << general_to_imap_search_key(key, value)
|
|
113
115
|
when boolean_operator?(key)
|
|
114
116
|
m << boolean_to_imap_search_key(key, value)
|
|
117
|
+
else
|
|
118
|
+
raise UnknownSearchKey, "no such search key: #{key}"
|
|
115
119
|
end
|
|
116
120
|
end.flatten
|
|
117
121
|
end
|
data/lib/Imap/VERSION.rb
CHANGED
data/test/Imap/Message_test.rb
CHANGED
|
@@ -40,6 +40,11 @@ describe Imap::Message do
|
|
|
40
40
|
second_call = imap_message.body
|
|
41
41
|
_(first_call.object_id).must_equal second_call.object_id
|
|
42
42
|
end
|
|
43
|
+
|
|
44
|
+
it 'peeks, so that reading a body does not mark it seen' do
|
|
45
|
+
imap_message.body
|
|
46
|
+
_(client.imap.fetched_attrs).must_include 'BODY.PEEK[TEXT]'
|
|
47
|
+
end
|
|
43
48
|
end
|
|
44
49
|
|
|
45
50
|
describe '#subject' do
|
|
@@ -74,6 +79,10 @@ describe Imap::Message do
|
|
|
74
79
|
addresses = imap_message.to
|
|
75
80
|
_(addresses.first).must_equal('user@example.com')
|
|
76
81
|
end
|
|
82
|
+
|
|
83
|
+
it 'is empty where the envelope carries no to' do
|
|
84
|
+
_(Imap::Message.new(99, client).to).must_equal []
|
|
85
|
+
end
|
|
77
86
|
end
|
|
78
87
|
|
|
79
88
|
describe '#urls' do
|
data/test/Imap/Search_test.rb
CHANGED
|
@@ -33,6 +33,10 @@ describe Imap::Search do
|
|
|
33
33
|
_(keys).must_include 'SEEN'
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
+
it 'raises upon a key which is neither' do
|
|
37
|
+
_{Imap::Search.new(client, bogus: 'x').to_imap_search_keys}.must_raise Imap::Search::UnknownSearchKey
|
|
38
|
+
end
|
|
39
|
+
|
|
36
40
|
it 'handles multiple criteria' do
|
|
37
41
|
test_search = Imap::Search.new(client, from: 'test@example.com', seen: true)
|
|
38
42
|
keys = test_search.to_imap_search_keys
|
data/test/test_helper.rb
CHANGED
|
@@ -31,7 +31,10 @@ class MockIMAP
|
|
|
31
31
|
[1, 2, 3]
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
+
attr_reader :fetched_attrs
|
|
35
|
+
|
|
34
36
|
def fetch(message_id, attrs)
|
|
37
|
+
@fetched_attrs = attrs
|
|
35
38
|
[OpenStruct.new(attr: mock_fetch_attrs(message_id, attrs))]
|
|
36
39
|
end
|
|
37
40
|
|
|
@@ -58,7 +61,7 @@ class MockIMAP
|
|
|
58
61
|
result = {}
|
|
59
62
|
attrs.each do |attr|
|
|
60
63
|
case attr
|
|
61
|
-
when 'BODY[TEXT]'
|
|
64
|
+
when 'BODY[TEXT]', 'BODY.PEEK[TEXT]'
|
|
62
65
|
result['BODY[TEXT]'] = "Mock body for message #{message_id}"
|
|
63
66
|
when 'BODY[HEADER.FIELDS (SUBJECT)]'
|
|
64
67
|
result['BODY[HEADER.FIELDS (SUBJECT)]'] = "Subject: Mock Subject #{message_id}\r\n"
|
|
@@ -66,7 +69,7 @@ class MockIMAP
|
|
|
66
69
|
result['BODY[HEADER.FIELDS (FROM)]'] = "From: sender@example.com\r\n"
|
|
67
70
|
when 'ENVELOPE'
|
|
68
71
|
result['ENVELOPE'] = OpenStruct.new(
|
|
69
|
-
to: [OpenStruct.new(mailbox: 'user', host: 'example.com')]
|
|
72
|
+
to: message_id == 99 ? nil : [OpenStruct.new(mailbox: 'user', host: 'example.com')]
|
|
70
73
|
)
|
|
71
74
|
end
|
|
72
75
|
end
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: imap
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- thoran
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: net-imap
|
|
@@ -73,6 +73,7 @@ extensions: []
|
|
|
73
73
|
extra_rdoc_files: []
|
|
74
74
|
files:
|
|
75
75
|
- CHANGELOG
|
|
76
|
+
- Gemfile
|
|
76
77
|
- LICENSE
|
|
77
78
|
- README.md
|
|
78
79
|
- Rakefile
|
|
@@ -84,12 +85,16 @@ files:
|
|
|
84
85
|
- test/Imap/Message_test.rb
|
|
85
86
|
- test/Imap/Search_test.rb
|
|
86
87
|
- test/Imap/VERSION_test.rb
|
|
87
|
-
- test/
|
|
88
|
+
- test/Imap_test.rb
|
|
88
89
|
- test/test_helper.rb
|
|
89
90
|
homepage: https://github.com/thoran/imap
|
|
90
91
|
licenses:
|
|
91
92
|
- MIT
|
|
92
|
-
metadata:
|
|
93
|
+
metadata:
|
|
94
|
+
bug_tracker_uri: https://github.com/thoran/imap/issues
|
|
95
|
+
changelog_uri: https://github.com/thoran/imap/blob/master/CHANGELOG
|
|
96
|
+
source_code_uri: https://github.com/thoran/imap
|
|
97
|
+
documentation_uri: https://github.com/thoran/imap/blob/master/README.md
|
|
93
98
|
rdoc_options: []
|
|
94
99
|
require_paths:
|
|
95
100
|
- lib
|
|
File without changes
|