11 MaildirMsg = collections.namedtuple('MaildirMsg', ['msgid', 'path'])
14 def maildir_msg(self, maildir):
15 msgid, path = maildir.deliver()
16 return self.MaildirMsg(msgid, path)
19 def db(self, maildir):
20 with notmuch2.Database.create(maildir.path) as db:
24 def msg(self, db, maildir_msg):
25 msg, dup = db.add(maildir_msg.path, sync_flags=False)
28 def test_type(self, msg):
29 assert isinstance(msg, notmuch2.NotmuchObject)
30 assert isinstance(msg, notmuch2.Message)
32 def test_alive(self, msg):
35 def test_hash(self, msg):
38 def test_eq(self, db, msg):
39 copy = db.get(msg.path)
42 def test_messageid_type(self, msg):
43 assert isinstance(msg.messageid, str)
44 assert isinstance(msg.messageid, notmuch2.BinString)
45 assert isinstance(bytes(msg.messageid), bytes)
47 def test_messageid(self, msg, maildir_msg):
48 assert msg.messageid == maildir_msg.msgid
50 def test_messageid_find(self, db, msg):
51 copy = db.find(msg.messageid)
52 assert msg.messageid == copy.messageid
54 def test_threadid_type(self, msg):
55 assert isinstance(msg.threadid, str)
56 assert isinstance(msg.threadid, notmuch2.BinString)
57 assert isinstance(bytes(msg.threadid), bytes)
59 def test_path_type(self, msg):
60 assert isinstance(msg.path, pathlib.Path)
62 def test_path(self, msg, maildir_msg):
63 assert msg.path == maildir_msg.path
65 def test_pathb_type(self, msg):
66 assert isinstance(msg.pathb, bytes)
68 def test_pathb(self, msg, maildir_msg):
69 assert msg.path == maildir_msg.path
71 def test_filenames_type(self, msg):
73 assert isinstance(ifn, collections.abc.Iterator)
75 def test_filenames(self, msg):
79 assert isinstance(fn, pathlib.Path)
80 with pytest.raises(StopIteration):
82 assert list(msg.filenames()) == [msg.path]
84 def test_filenamesb_type(self, msg):
85 ifn = msg.filenamesb()
86 assert isinstance(ifn, collections.abc.Iterator)
88 def test_filenamesb(self, msg):
89 ifn = msg.filenamesb()
91 assert fn == msg.pathb
92 assert isinstance(fn, bytes)
93 with pytest.raises(StopIteration):
95 assert list(msg.filenamesb()) == [msg.pathb]
97 def test_ghost_no(self, msg):
100 def test_matched_no(self,msg):
101 assert not msg.matched
103 def test_date(self, msg):
104 # XXX Someone seems to treat things as local time instead of
105 # UTC or the other way around.
106 now = int(time.time())
107 assert abs(now - msg.date) < 3600*24
109 def test_header(self, msg):
110 assert msg.header('from') == 'src@example.com'
112 def test_header_not_present(self, msg):
113 with pytest.raises(LookupError):
116 def test_freeze(self, msg):
120 msg.tags.discard('foo')
121 assert 'foo' not in msg.tags
122 assert 'bar' in msg.tags
124 def test_freeze_err(self, msg):
129 raise Exception('oops')
131 assert 'foo' in msg.tags
133 pytest.fail('Context manager did not raise')
135 def test_replies_type(self, msg):
136 assert isinstance(msg.replies(), collections.abc.Iterator)
138 def test_replies(self, msg):
139 with pytest.raises(StopIteration):
143 class TestProperties:
146 def props(self, maildir):
147 msgid, path = maildir.deliver()
148 with notmuch2.Database.create(maildir.path) as db:
149 msg, dup = db.add(path, sync_flags=False)
152 def test_type(self, props):
153 assert isinstance(props, collections.abc.MutableMapping)
155 def test_add_single(self, props):
157 assert props['foo'] == 'bar'
158 props.add('bar', 'baz')
159 assert props['bar'] == 'baz'
161 def test_add_dup(self, props):
162 props.add('foo', 'bar')
163 props.add('foo', 'baz')
164 assert props['foo'] == 'bar'
165 assert (set(props.getall('foo', exact=True))
166 == {('foo', 'bar'), ('foo', 'baz')})
168 def test_len(self, props):
169 props.add('foo', 'a')
170 props.add('foo', 'b')
171 props.add('bar', 'a')
172 assert len(props) == 3
173 assert len(props.keys()) == 2
174 assert len(props.values()) == 2
175 assert len(props.items()) == 3
177 def test_del(self, props):
178 props.add('foo', 'a')
179 props.add('foo', 'b')
181 with pytest.raises(KeyError):
184 def test_remove(self, props):
185 props.add('foo', 'a')
186 props.add('foo', 'b')
187 props.remove('foo', 'a')
188 assert props['foo'] == 'b'
190 def test_view_abcs(self, props):
191 assert isinstance(props.keys(), collections.abc.KeysView)
192 assert isinstance(props.values(), collections.abc.ValuesView)
193 assert isinstance(props.items(), collections.abc.ItemsView)
195 def test_pop(self, props):
196 props.add('foo', 'a')
197 props.add('foo', 'b')
198 val = props.pop('foo')
201 def test_pop_default(self, props):
202 with pytest.raises(KeyError):
204 assert props.pop('foo', 'default') == 'default'
206 def test_popitem(self, props):
207 props.add('foo', 'a')
208 assert props.popitem() == ('foo', 'a')
209 with pytest.raises(KeyError):
212 def test_clear(self, props):
213 props.add('foo', 'a')
215 assert len(props) == 0
217 def test_getall(self, props):
218 props.add('foo', 'a')
219 assert set(props.getall('foo')) == {('foo', 'a')}
221 def test_getall_prefix(self, props):
222 props.add('foo', 'a')
223 props.add('foobar', 'b')
224 assert set(props.getall('foo')) == {('foo', 'a'), ('foobar', 'b')}
226 def test_getall_exact(self, props):
227 props.add('foo', 'a')
228 props.add('foobar', 'b')
229 assert set(props.getall('foo', exact=True)) == {('foo', 'a')}