unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
blob 56701d056de5ff6d1cda5e7fc0c53b1cdd8a6de5 6742 bytes (raw)
name: bindings/python-cffi/tests/test_message.py 	 # note: path name is non-authoritative(*)

  1
  2
  3
  4
  5
  6
  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
 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
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
 
import collections.abc
import time
import pathlib

import pytest

import notmuch2


class TestMessage:
    MaildirMsg = collections.namedtuple('MaildirMsg', ['msgid', 'path'])

    @pytest.fixture
    def maildir_msg(self, maildir):
        msgid, path = maildir.deliver()
        return self.MaildirMsg(msgid, path)

    @pytest.fixture
    def db(self, maildir):
        with notmuch2.Database.create(maildir.path) as db:
            yield db

    @pytest.fixture
    def msg(self, db, maildir_msg):
        msg, dup = db.add(maildir_msg.path, sync_flags=False)
        yield msg

    def test_type(self, msg):
        assert isinstance(msg, notmuch2.NotmuchObject)
        assert isinstance(msg, notmuch2.Message)

    def test_alive(self, msg):
        assert msg.alive

    def test_hash(self, msg):
        assert hash(msg)

    def test_eq(self, db, msg):
        copy = db.get(msg.path)
        assert msg == copy

    def test_messageid_type(self, msg):
        assert isinstance(msg.messageid, str)
        assert isinstance(msg.messageid, notmuch2.BinString)
        assert isinstance(bytes(msg.messageid), bytes)

    def test_messageid(self, msg, maildir_msg):
        assert msg.messageid == maildir_msg.msgid

    def test_messageid_find(self, db, msg):
        copy = db.find(msg.messageid)
        assert msg.messageid == copy.messageid

    def test_threadid_type(self, msg):
        assert isinstance(msg.threadid, str)
        assert isinstance(msg.threadid, notmuch2.BinString)
        assert isinstance(bytes(msg.threadid), bytes)

    def test_path_type(self, msg):
        assert isinstance(msg.path, pathlib.Path)

    def test_path(self, msg, maildir_msg):
        assert msg.path == maildir_msg.path

    def test_pathb_type(self, msg):
        assert isinstance(msg.pathb, bytes)

    def test_pathb(self, msg, maildir_msg):
        assert msg.path == maildir_msg.path

    def test_filenames_type(self, msg):
        ifn = msg.filenames()
        assert isinstance(ifn, collections.abc.Iterator)

    def test_filenames(self, msg):
        ifn = msg.filenames()
        fn = next(ifn)
        assert fn == msg.path
        assert isinstance(fn, pathlib.Path)
        with pytest.raises(StopIteration):
            next(ifn)
        assert list(msg.filenames()) == [msg.path]

    def test_filenamesb_type(self, msg):
        ifn = msg.filenamesb()
        assert isinstance(ifn, collections.abc.Iterator)

    def test_filenamesb(self, msg):
        ifn = msg.filenamesb()
        fn = next(ifn)
        assert fn == msg.pathb
        assert isinstance(fn, bytes)
        with pytest.raises(StopIteration):
            next(ifn)
        assert list(msg.filenamesb()) == [msg.pathb]

    def test_ghost_no(self, msg):
        assert not msg.ghost

    def test_matched_no(self,msg):
        assert not msg.matched

    def test_date(self, msg):
        # XXX Someone seems to treat things as local time instead of
        #     UTC or the other way around.
        now = int(time.time())
        assert abs(now - msg.date) < 3600*24

    def test_header(self, msg):
        assert msg.header('from') == 'src@example.com'

    def test_header_not_present(self, msg):
        with pytest.raises(LookupError):
            msg.header('foo')

    def test_freeze(self, msg):
        with msg.frozen():
            msg.tags.add('foo')
            msg.tags.add('bar')
            msg.tags.discard('foo')
        assert 'foo' not in msg.tags
        assert 'bar' in msg.tags

    def test_freeze_err(self, msg):
        msg.tags.add('foo')
        try:
            with msg.frozen():
                msg.tags.clear()
                raise Exception('oops')
        except Exception:
            assert 'foo' in msg.tags
        else:
            pytest.fail('Context manager did not raise')

    def test_replies_type(self, msg):
        assert isinstance(msg.replies(), collections.abc.Iterator)

    def test_replies(self, msg):
        with pytest.raises(StopIteration):
            next(msg.replies())


class TestProperties:

    @pytest.fixture
    def props(self, maildir):
        msgid, path = maildir.deliver()
        with notmuch2.Database.create(maildir.path) as db:
            msg, dup = db.add(path, sync_flags=False)
            yield msg.properties

    def test_type(self, props):
        assert isinstance(props, collections.abc.MutableMapping)

    def test_add_single(self, props):
        props['foo'] = 'bar'
        assert props['foo'] == 'bar'
        props.add('bar', 'baz')
        assert props['bar'] == 'baz'

    def test_add_dup(self, props):
        props.add('foo', 'bar')
        props.add('foo', 'baz')
        assert props['foo'] == 'bar'
        assert (set(props.getall('foo', exact=True))
                == {('foo', 'bar'), ('foo', 'baz')})

    def test_len(self, props):
        props.add('foo', 'a')
        props.add('foo', 'b')
        props.add('bar', 'a')
        assert len(props) == 3
        assert len(props.keys()) == 2
        assert len(props.values()) == 2
        assert len(props.items()) == 3

    def test_del(self, props):
        props.add('foo', 'a')
        props.add('foo', 'b')
        del props['foo']
        with pytest.raises(KeyError):
            props['foo']

    def test_remove(self, props):
        props.add('foo', 'a')
        props.add('foo', 'b')
        props.remove('foo', 'a')
        assert props['foo'] == 'b'

    def test_view_abcs(self, props):
        assert isinstance(props.keys(), collections.abc.KeysView)
        assert isinstance(props.values(), collections.abc.ValuesView)
        assert isinstance(props.items(), collections.abc.ItemsView)

    def test_pop(self, props):
        props.add('foo', 'a')
        props.add('foo', 'b')
        val = props.pop('foo')
        assert val == 'a'

    def test_pop_default(self, props):
        with pytest.raises(KeyError):
            props.pop('foo')
        assert props.pop('foo', 'default') == 'default'

    def test_popitem(self, props):
        props.add('foo', 'a')
        assert props.popitem() == ('foo', 'a')
        with pytest.raises(KeyError):
            props.popitem()

    def test_clear(self, props):
        props.add('foo', 'a')
        props.clear()
        assert len(props) == 0

    def test_getall(self, props):
        props.add('foo', 'a')
        assert set(props.getall('foo')) == {('foo', 'a')}

    def test_getall_prefix(self, props):
        props.add('foo', 'a')
        props.add('foobar', 'b')
        assert set(props.getall('foo')) == {('foo', 'a'), ('foobar', 'b')}

    def test_getall_exact(self, props):
        props.add('foo', 'a')
        props.add('foobar', 'b')
        assert set(props.getall('foo', exact=True)) == {('foo', 'a')}

debug log:

solving 56701d05 ...
found 56701d05 in https://yhetil.org/notmuch.git/

(*) Git path names are given by the tree(s) the blob belongs to.
    Blobs themselves have no identifier aside from the hash of its contents.^

Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).