imap 0.4.8 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2de58b7edfcefd22cb470e09a7feb4e96ac4604d5ff0fae0d3c30d113870b956
4
- data.tar.gz: aaa7cf9c1ca0ae8f8b988d34774f83af8744c59e47df43d4a68b4ddcf251eaec
3
+ metadata.gz: 6882bdf039ee14e7959ecdd9462f2dbe73326d070f36529cfe36d7ed12b1ad59
4
+ data.tar.gz: 1895dbc808a0c8e08c9d703c6d84a3506b4ded60130b16c55e7a80f18bd06487
5
5
  SHA512:
6
- metadata.gz: dee87ae3c7717846c25f0d4bcb16274163ac43b148dcc44f5512a1d19f3095d364c0990c187f90d383a6e4d3b11f632d2a10cac6f902f9296346be32a3c84372
7
- data.tar.gz: 3aefa08e1f4a73e01cdd63d3dc3fcea30caf64dadca3b91ffa918dd535ecdaf43c6c795a7a84d6c532168c8f3dfa590defe5f6ea29e2b8680505148674e265b7
6
+ metadata.gz: 872abb99c0372e0e43cab6cb6ba239edaa8b183720754cd9505b1daa11b4d29a8931037d8329330ee4e34f4bada47ba676cfe6191bb5204b0c6cf7a858600951
7
+ data.tar.gz: fc5341b098e786bd10077f383cb1812743727a1a2395a9e3b2011796bb106f2ab56b9bec17b3fc8188f5ff38a9169e618bc44f50fc73b1cab848cd4bc7ae4728
data/CHANGELOG CHANGED
@@ -2,6 +2,26 @@
2
2
 
3
3
  ## 20260917
4
4
 
5
+ 0.5.0: + OR and NOT to the criteria, and HEADER given its field
6
+
7
+ 1. + Imap::Search#any_of: or: [{from: 'a@x'}, {to: 'b@y'}]. OR takes two keys and no more, so three or more nest, OR OR a b c, as the server reads them. Each side is a criteria hash of its own and may nest further.
8
+ 2. + Imap::Search#none_of: not: {subject: 'Payday'}. NOT takes one key, so several are negated apiece, NOT a NOT b.
9
+ 3. ~ Imap::Search#to_imap_search_keys: OR and NOT read before the operator tests, being neither general nor boolean.
10
+ 4. HEADER wanted no change: an array value already flattens to ['HEADER', field, value], which nothing said and nothing tested. It is tested now.
11
+ 5. + tests for each, and for OR mixed with the plain keys.
12
+ 6. ~ Imap::VERSION: /0.4.9/0.5.0/
13
+
14
+
15
+ 0.4.9: + imap.rb.gemspec, so that the gem resolves under both names.
16
+
17
+ 1. + imap.rb.gemspec: the same code published as imap.rb, which is how gems are named here: 21 carry the suffix and imap is one of the few which do not. rubygems has no notion of an alias, so the two are separate gems which must be kept at the same version by hand.
18
+ 2. It differs from imap.gemspec in the three lines measurand and namo differ in, the heading comment naming the file, the name, and the gemspec each lists among its own files. Neither ships the other.
19
+ 3. imap.rb is unregistered, so this is its first version. bitget, eodhd, measurand and webdav each had their second name join at whatever the first stood at rather than backfilling, and each did it as a patch of its own carrying nothing else.
20
+ 4. gem-publish builds and pushes each in turn, gem build and gem push taking one file apiece and gem build *.gemspec building only whichever the shell lists first.
21
+ 5. ~ Gemfile: gemspec name: 'imap', bundler refusing to choose between two gemspecs and stopping with "There are multiple gemspecs at ...". Every pair here which uses gemspec names one: webdav, measurand and eodhd each name the elder of their two, and namo, which carried both from its first release, names the bare one. imap is the elder here.
22
+ 6. ~ Imap::VERSION: /0.4.8/0.4.9/
23
+
24
+
5
25
  0.4.8: Rewrite the CHANGELOG in the standard form.
6
26
 
7
27
  1. ~ CHANGELOG: ## before each date rather than ## [version] - date, the version and its summary beneath, a blank line between that and the first item, and the items numbered rather than dashed. No item is reworded, dropped or reordered.
data/Gemfile CHANGED
@@ -1,3 +1,3 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gemspec
3
+ gemspec name: 'imap'
data/lib/Imap/Search.rb CHANGED
@@ -123,6 +123,10 @@ class Imap
123
123
  criteria.inject([]) do |m, kv|
124
124
  key, value = kv.first.to_s.upcase, kv.last
125
125
  case
126
+ when key == 'OR'
127
+ m << any_of(value)
128
+ when key == 'NOT'
129
+ m << none_of(value)
126
130
  when general_operator?(key)
127
131
  m << general_to_imap_search_key(key, value)
128
132
  when boolean_operator?(key)
@@ -133,6 +137,17 @@ class Imap
133
137
  end.flatten
134
138
  end
135
139
 
140
+ # OR takes two keys and no more, so three criteria nest: OR OR a b c. Each
141
+ # is a criteria hash of its own, so either side may nest further.
142
+ def any_of(criteria_hashes)
143
+ criteria_hashes.collect{|criteria_hash| Search.new(nil, criteria_hash).to_imap_search_keys}.inject{|m, keys| ['OR'] + m + keys}
144
+ end
145
+
146
+ # NOT takes one key, so each criterion is negated on its own: NOT a NOT b.
147
+ def none_of(criteria_hash)
148
+ criteria_hash.inject([]){|m, kv| m + ['NOT'] + Search.new(nil, Hash[*kv]).to_imap_search_keys}
149
+ end
150
+
136
151
  def general_to_imap_search_key(key, value)
137
152
  value.is_a?(Negated) ? ['NOT', key, value.value] : [key, value]
138
153
  end
data/lib/Imap/VERSION.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class Imap
2
- VERSION = '0.4.8'
2
+ VERSION = '0.5.0'
3
3
  end
@@ -44,6 +44,34 @@ describe Imap::Search do
44
44
  end
45
45
  end
46
46
 
47
+ describe 'OR, NOT and HEADER' do
48
+ def keys(criteria) = Imap::Search.new(client, criteria).to_imap_search_keys
49
+
50
+ it 'takes two criteria hashes for OR' do
51
+ _(keys(or: [{from: 'a@x'}, {to: 'b@y'}])).must_equal ['OR', 'FROM', 'a@x', 'TO', 'b@y']
52
+ end
53
+
54
+ it 'nests OR where there are more than two, it taking only two' do
55
+ _(keys(or: [{from: 'a@x'}, {to: 'b@y'}, {cc: 'c@z'}])).must_equal ['OR', 'OR', 'FROM', 'a@x', 'TO', 'b@y', 'CC', 'c@z']
56
+ end
57
+
58
+ it 'negates a criterion for NOT' do
59
+ _(keys(not: {subject: 'Payday'})).must_equal ['NOT', 'SUBJECT', 'Payday']
60
+ end
61
+
62
+ it 'negates each on its own where NOT carries more than one, it taking only one' do
63
+ _(keys(not: {subject: 'Payday', seen: true})).must_equal ['NOT', 'SUBJECT', 'Payday', 'NOT', 'SEEN']
64
+ end
65
+
66
+ it 'takes a field and a value for HEADER' do
67
+ _(keys(header: ['List-Id', 'announce'])).must_equal ['HEADER', 'List-Id', 'announce']
68
+ end
69
+
70
+ it 'mixes with the plain keys' do
71
+ _(keys(since: '1-Sep-2026', or: [{from: 'a@x'}, {to: 'b@y'}])).must_equal ['SINCE', '1-Sep-2026', 'OR', 'FROM', 'a@x', 'TO', 'b@y']
72
+ end
73
+ end
74
+
47
75
  describe 'the chaining interface' do
48
76
  it 'names the keys in lower case' do
49
77
  _(Imap::Search.new(client).from('x@y.com').criteria).must_equal({FROM: 'x@y.com'})
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: imap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.8
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - thoran