### tests/__init__.py
# Copyright (c) 2014, Menno Smits
# Released subject to the New BSD License
# Please see http://en.wikipedia.org/wiki/BSD_licenses
### tests/imapclient_test.py
import unittest

from imapclient.testable_imapclient import TestableIMAPClient as IMAPClient


class IMAPClientTest(unittest.TestCase):
    def setUp(self):
        self.client = IMAPClient()
### tests/test_auth.py
# Copyright (c) 2016, Menno Smits
# Released subject to the New BSD License
# Please see http://en.wikipedia.org/wiki/BSD_licenses

from imapclient.exceptions import LoginError

from .imapclient_test import IMAPClientTest


class TestPlainLogin(IMAPClientTest):
    def assert_authenticate_call(self, expected_auth_string):
        authenticate = self.client._imap.authenticate
        self.assertEqual(authenticate.call_count, 1)
        auth_type, auth_func = authenticate.call_args[0]
        self.assertEqual(auth_type, "PLAIN")
        self.assertEqual(auth_func(None), expected_auth_string)

    def test_simple(self):
        self.client._imap.authenticate.return_value = ("OK", [b"Success"])
        result = self.client.plain_login("user", "secret")
        self.assertEqual(result, b"Success")
        self.assert_authenticate_call("\0user\0secret")

    def test_fail(self):
        self.client._imap.authenticate.return_value = ("NO", [b"Boom"])
        self.assertRaises(LoginError, self.client.plain_login, "user", "secret")

    def test_with_authorization_identity(self):
        self.client._imap.authenticate.return_value = ("OK", [b"Success"])
        result = self.client.plain_login("user", "secret", "authid")
        self.assertEqual(result, b"Success")
        self.assert_authenticate_call("authid\0user\0secret")
### tests/test_datetime_util.py
# Copyright (c) 2014, Menno Smits
# Released subject to the New BSD License
# Please see http://en.wikipedia.org/wiki/BSD_licenses

import unittest
from datetime import date, datetime
from unittest.mock import patch

from imapclient.datetime_util import (
    datetime_to_INTERNALDATE,
    datetime_to_native,
    format_criteria_date,
    parse_to_datetime,
)
from imapclient.fixed_offset import FixedOffset


class TestParsing(unittest.TestCase):
    def check_normalised_and_not(self, in_string, expected_datetime):
        self.assertEqual(
            parse_to_datetime(in_string), datetime_to_native(expected_datetime)
        )
        self.assertEqual(
            parse_to_datetime(in_string, normalise=False), expected_datetime
        )

    def test_rfc822_style(self):
        self.check_normalised_and_not(
            b"Sun, 24 Mar 2013 22:06:10 +0200",
            datetime(2013, 3, 24, 22, 6, 10, 0, FixedOffset(120)),
        )

    def test_internaldate_style(self):
        self.check_normalised_and_not(
            b" 9-Feb-2007 17:08:08 -0430",
            datetime(2007, 2, 9, 17, 8, 8, 0, FixedOffset(-4 * 60 - 30)),
        )
        self.check_normalised_and_not(
            b"19-Feb-2007 17:08:08 0400",
            datetime(2007, 2, 19, 17, 8, 8, 0, FixedOffset(4 * 60)),
        )

    def test_dots_for_time_separator(self):
        # As reported in issue #154.
        self.check_normalised_and_not(
            b"Sat, 8 May 2010 16.03.09 +0200",
            datetime(2010, 5, 8, 16, 3, 9, 0, FixedOffset(120)),
        )
        self.check_normalised_and_not(
            b"Tue, 18 May 2010 16.03.09 -0200",
            datetime(2010, 5, 18, 16, 3, 9, 0, FixedOffset(-120)),
        )
        self.check_normalised_and_not(
            b"Wednesday,18 August 2010 16.03.09 -0200",
            datetime(2010, 8, 18, 16, 3, 9, 0, FixedOffset(-120)),
        )

    def test_invalid(self):
        self.assertRaises(ValueError, parse_to_datetime, b"ABC")


class TestDatetimeToINTERNALDATE(unittest.TestCase):
    def test_with_timezone(self):
        dt = datetime(2009, 1, 2, 3, 4, 5, 0, FixedOffset(2 * 60 + 30))
        self.assertEqual(datetime_to_INTERNALDATE(dt), "02-Jan-2009 03:04:05 +0230")

    @patch("imapclient.datetime_util.FixedOffset.for_system")
    def test_without_timezone(self, for_system):
        dt = datetime(2009, 1, 2, 3, 4, 5, 0)
        for_system.return_value = FixedOffset(-5 * 60)

        self.assertEqual(datetime_to_INTERNALDATE(dt), "02-Jan-2009 03:04:05 -0500")


class TestCriteriaDateFormatting(unittest.TestCase):
    def test_basic(self):
        self.assertEqual(format_criteria_date(date(1996, 2, 22)), b"22-Feb-1996")

    def test_single_digit_day(self):
        self.assertEqual(format_criteria_date(date(1996, 4, 4)), b"04-Apr-1996")
### tests/test_enable.py
# Copyright (c) 2017, Menno Smits
# Released subject to the New BSD License
# Please see http://en.wikipedia.org/wiki/BSD_licenses

from unittest.mock import Mock

from imapclient.exceptions import IllegalStateError

from .imapclient_test import IMAPClientTest


class TestEnable(IMAPClientTest):
    def setUp(self):
        super(TestEnable, self).setUp()
        self.command = Mock()
        self.client._raw_command_untagged = self.command
        self.client._imap.state = "AUTH"
        self.client._cached_capabilities = [b"ENABLE"]

    def test_success(self):
        self.command.return_value = b"CONDSTORE"

        resp = self.client.enable("CONDSTORE")

        self.command.assert_called_once_with(
            b"ENABLE", [b"CONDSTORE"], uid=False, response_name="ENABLED", unpack=True
        )
        self.assertEqual(resp, [b"CONDSTORE"])

    def test_failed1(self):
        # When server returns an empty ENABLED response
        self.command.return_value = b""

        resp = self.client.enable("FOO")

        self.command.assert_called_once_with(
            b"ENABLE", [b"FOO"], uid=False, response_name="ENABLED", unpack=True
        )
        self.assertEqual(resp, [])

    def test_failed2(self):
        # When server returns no ENABLED response
        self.command.return_value = None

        resp = self.client.enable("FOO")

        self.command.assert_called_once_with(
            b"ENABLE", [b"FOO"], uid=False, response_name="ENABLED", unpack=True
        )
        self.assertEqual(resp, [])

    def test_multiple(self):
        self.command.return_value = b"FOO BAR"

        resp = self.client.enable("FOO", "BAR")

        self.command.assert_called_once_with(
            b"ENABLE", [b"FOO", b"BAR"], uid=False, response_name="ENABLED", unpack=True
        )
        self.assertEqual(resp, [b"FOO", b"BAR"])

    def test_wrong_state(self):
        self.client._imap.state = "SELECTED"

        self.assertRaises(
            IllegalStateError,
            self.client.enable,
            "FOO",
        )
### tests/test_fixed_offset.py
# Copyright (c) 2014, Menno Smits
# Released subject to the New BSD License
# Please see http://en.wikipedia.org/wiki/BSD_licenses

import unittest
from datetime import timedelta
from unittest.mock import DEFAULT, Mock, patch

from imapclient.fixed_offset import FixedOffset


class TestFixedOffset(unittest.TestCase):
    def _check(self, offset, expected_delta, expected_name):
        self.assertEqual(offset.utcoffset(None), expected_delta)
        self.assertEqual(offset.tzname(None), expected_name)
        self.assertEqual(offset.dst(None), timedelta(0))

    def test_GMT(self):
        self._check(FixedOffset(0), timedelta(0), "+0000")

    def test_positive(self):
        self._check(FixedOffset(30), timedelta(minutes=30), "+0030")
        self._check(FixedOffset(2 * 60), timedelta(hours=2), "+0200")
        self._check(FixedOffset(11 * 60 + 30), timedelta(hours=11, minutes=30), "+1130")

    def test_negative(self):
        self._check(FixedOffset(-30), timedelta(minutes=-30), "-0030")
        self._check(FixedOffset(-2 * 60), timedelta(hours=-2), "-0200")
        self._check(
            FixedOffset(-11 * 60 - 30), timedelta(minutes=(-11 * 60) - 30), "-1130"
        )

    @patch.multiple(
        "imapclient.fixed_offset.time",
        daylight=True,
        timezone=15 * 60 * 60,
        localtime=DEFAULT,
    )
    def test_for_system_DST_not_active(self, localtime):
        localtime_mock = Mock()
        localtime_mock.tm_isdst = False
        localtime.return_value = localtime_mock

        offset = FixedOffset.for_system()
        self.assertEqual(offset.tzname(None), "-1500")

    @patch.multiple(
        "imapclient.fixed_offset.time",
        daylight=True,
        altzone=15 * 60 * 60,
        localtime=DEFAULT,
    )
    def test_for_system_DST_active(self, localtime):
        localtime_mock = Mock()
        localtime_mock.tm_isdst = True
        localtime.return_value = localtime_mock

        offset = FixedOffset.for_system()
        self.assertEqual(offset.tzname(None), "-1500")

    @patch.multiple(
        "imapclient.fixed_offset.time", daylight=False, timezone=-15 * 60 * 60
    )
    def test_for_system_no_DST(self):
        offset = FixedOffset.for_system()
        self.assertEqual(offset.tzname(None), "+1500")


if __name__ == "__main__":
    unittest.main()
### tests/test_folder_status.py
# Copyright (c) 2015, Menno Smits
# Released subject to the New BSD License
# Please see http://en.wikipedia.org/wiki/BSD_licenses

from unittest.mock import Mock

from .imapclient_test import IMAPClientTest


class TestFolderStatus(IMAPClientTest):
    def test_basic(self):
        self.client._imap.status.return_value = (
            "OK",
            [b"foo (MESSAGES 3 RECENT 0 UIDNEXT 4 UIDVALIDITY 1435636895 UNSEEN 0)"],
        )

        out = self.client.folder_status("foo")

        self.client._imap.status.assert_called_once_with(
            b'"foo"', "(MESSAGES RECENT UIDNEXT UIDVALIDITY UNSEEN)"
        )
        self.assertDictEqual(
            out,
            {
                b"MESSAGES": 3,
                b"RECENT": 0,
                b"UIDNEXT": 4,
                b"UIDVALIDITY": 1435636895,
                b"UNSEEN": 0,
            },
        )

    def test_literal(self):
        self.client._imap.status.return_value = (
            "OK",
            [(b"{3}", b"foo"), b" (UIDNEXT 4)"],
        )

        out = self.client.folder_status("foo", ["UIDNEXT"])

        self.client._imap.status.assert_called_once_with(b'"foo"', "(UIDNEXT)")
        self.assertDictEqual(out, {b"UIDNEXT": 4})

    def test_extra_response(self):
        # In production, we've seen folder names containing spaces come back
        # like this and be broken into two components in the tuple.
        server_response = [b"My files (UIDNEXT 24369)"]
        mock = Mock(return_value=server_response)
        self.client._command_and_check = mock

        resp = self.client.folder_status("My files", ["UIDNEXT"])
        self.assertEqual(resp, {b"UIDNEXT": 24369})

        # We've also seen the response contain mailboxes we didn't
        # ask for. In all known cases, the desired mailbox is last.
        server_response = [b"sent (UIDNEXT 123)\nINBOX (UIDNEXT 24369)"]
        mock = Mock(return_value=server_response)
        self.client._command_and_check = mock

        resp = self.client.folder_status("INBOX", ["UIDNEXT"])
        self.assertEqual(resp, {b"UIDNEXT": 24369})
### tests/test_imap_utf7.py
# Copyright (c) 2014, Menno Smits
# Released subject to the New BSD License
# Please see http://en.wikipedia.org/wiki/BSD_licenses

import unittest

from imapclient.imap_utf7 import decode, encode


class IMAP4UTF7TestCase(unittest.TestCase):
    tests = [
        ["Foo", b"Foo"],
        ["Foo Bar", b"Foo Bar"],
        ["Stuff & Things", b"Stuff &- Things"],
        ["Hello world", b"Hello world"],
        ["Hello & world", b"Hello &- world"],
        ["Hello\xffworld", b"Hello&AP8-world"],
        ["\xff\xfe\xfd\xfc", b"&AP8A,gD9APw-"],
        [
            "~peter/mail/\u65e5\u672c\u8a9e/\u53f0\u5317",
            b"~peter/mail/&ZeVnLIqe-/&U,BTFw-",
        ],  # example from RFC 2060
        ["\x00foo", b"&AAA-foo"],
        ["foo\r\n\nbar\n", b"foo&AA0ACgAK-bar&AAo-"],  # see imapclient/#187 issue
    ]

    def test_encode(self):
        for input, output in self.tests:
            encoded = encode(input)
            self.assertIsInstance(encoded, bytes)
            self.assertEqual(encoded, output)

    def test_decode(self):
        for input, output in self.tests:
            decoded = decode(output)
            self.assertIsInstance(decoded, str)
            self.assertEqual(input, decoded)

    def test_printable_singletons(self):
        """
        The IMAP4 modified UTF-7 implementation encodes all printable
        characters which are in ASCII using the corresponding ASCII byte.
        """
        # All printables represent themselves
        for o in list(range(0x20, 0x26)) + list(range(0x27, 0x7F)):
            self.assertEqual(bytes((o,)), encode(chr(o)))
            self.assertEqual(chr(o), decode(bytes((o,))))
        self.assertEqual(encode("&"), b"&-")
        self.assertEqual(encode("&"), b"&-")
        self.assertEqual(decode(b"&-"), "&")
### tests/test_imapclient.py
# Copyright (c) 2014, Menno Smits
# Released subject to the New BSD License
# Please see http://en.wikipedia.org/wiki/BSD_licenses

import io
import itertools
import logging
import socket
import sys
import warnings
from datetime import datetime
from select import POLLIN
from unittest.mock import Mock, patch, sentinel

from imapclient.exceptions import CapabilityError, IMAPClientError, ProtocolError
from imapclient.fixed_offset import FixedOffset
from imapclient.imapclient import (
    _literal,
    _parse_quota,
    IMAPlibLoggerAdapter,
    MailboxQuotaRoots,
    Quota,
    require_capability,
)
from imapclient.testable_imapclient import TestableIMAPClient as IMAPClient

from .imapclient_test import IMAPClientTest


class TestListFolders(IMAPClientTest):
    def test_list_folders(self):
        self.client._imap._simple_command.return_value = ("OK", [b"something"])
        self.client._imap._untagged_response.return_value = (
            "LIST",
            sentinel.folder_data,
        )
        self.client._proc_folder_list = Mock(return_value=sentinel.folder_list)

        folders = self.client.list_folders("foo", "bar")

        self.client._imap._simple_command.assert_called_once_with(
            "LIST", b'"foo"', b'"bar"'
        )
        self.assertEqual(
            self.client._proc_folder_list.call_args, ((sentinel.folder_data,), {})
        )
        self.assertTrue(folders is sentinel.folder_list)

    def test_list_sub_folders(self):
        self.client._imap._simple_command.return_value = ("OK", [b"something"])
        self.client._imap._untagged_response.return_value = (
            "LSUB",
            sentinel.folder_data,
        )
        self.client._proc_folder_list = Mock(return_value=sentinel.folder_list)

        folders = self.client.list_sub_folders("foo", "bar")

        self.client._imap._simple_command.assert_called_once_with(
            "LSUB", b'"foo"', b'"bar"'
        )
    <response clipped><NOTE>Due to the max output limit, only part of the full response has been shown to you.</NOTE>untagged = Mock()
        self.client._raw_command_untagged.return_value = b"9 8 7"

    def check_call(self, expected_args):
        self.client._raw_command_untagged.assert_called_once_with(
            b"SORT", expected_args, unpack=True
        )

    def test_no_support(self):
        self.client._cached_capabilities = (b"BLAH",)
        self.assertRaises(CapabilityError, self.client.sort, "ARRIVAL")

    def test_single_criteria(self):
        ids = self.client.sort("arrival")

        self.check_call([b"(ARRIVAL)", b"UTF-8", b"ALL"])
        self.assertSequenceEqual(ids, [9, 8, 7])

    def test_multiple_criteria(self):
        self.client.sort(["arrival", b"SUBJECT"])

        self.check_call([b"(ARRIVAL SUBJECT)", b"UTF-8", b"ALL"])

    def test_all_args(self):
        self.client.sort("arrival", ["TEXT", "\u261e"], "UTF-7")

        self.check_call([b"(ARRIVAL)", b"UTF-7", b"TEXT", b"+Jh4-"])
### tests/test_starttls.py
# Copyright (c) 2015, Menno Smits
# Released subject to the New BSD License
# Please see http://en.wikipedia.org/wiki/BSD_licenses

from unittest.mock import Mock, patch, sentinel

from imapclient.exceptions import IMAPClientError
from imapclient.imapclient import IMAPClient

from .imapclient_test import IMAPClientTest


class TestStarttls(IMAPClientTest):
    def setUp(self):
        super(TestStarttls, self).setUp()

        patcher = patch("imapclient.imapclient.tls")
        self.tls = patcher.start()
        self.addCleanup(patcher.stop)

        self.client._imap.sock = sentinel.old_sock

        self.new_sock = Mock()
        self.new_sock.makefile.return_value = sentinel.file
        self.tls.wrap_socket.return_value = self.new_sock

        self.client.host = sentinel.host
        self.client.ssl = False
        self.client._starttls_done = False
        self.client._imap._simple_command.return_value = "OK", [
            b"start TLS negotiation"
        ]
        self.client._cached_capabilities = [b"STARTTLS"]

    def test_works(self):
        resp = self.client.starttls(sentinel.ssl_context)

        self.tls.wrap_socket.assert_called_once_with(
            sentinel.old_sock,
            sentinel.ssl_context,
            sentinel.host,
        )
        self.new_sock.makefile.assert_called_once_with("rb")
        self.assertEqual(self.client._imap.file, sentinel.file)
        self.assertEqual(resp, b"start TLS negotiation")

    def test_command_fails(self):
        self.client._imap._simple_command.return_value = "NO", [b"sorry"]

        with self.assertRaises(IMAPClientError) as raised:
            self.client.starttls(sentinel.ssl_context)
        self.assertEqual(str(raised.exception), "starttls failed: sorry")

    def test_fails_if_called_twice(self):
        self.client.starttls(sentinel.ssl_context)
        self.assert_tls_already_established()

    def test_fails_if_ssl_true(self):
        self.client.ssl = True
        self.assert_tls_already_established()

    def assert_tls_already_established(self):
        with self.assertRaises(IMAPClient.AbortError) as raised:
            self.client.starttls(sentinel.ssl_context)
        self.assertEqual(str(raised.exception), "TLS session already established")
### tests/test_store.py
# -*- coding: utf-8 -*-
# Copyright (c) 2016, Menno Smits
# Released subject to the New BSD License
# Please see http://en.wikipedia.org/wiki/BSD_licenses

from unittest.mock import Mock, patch, sentinel

from imapclient.imapclient import ANSWERED, DELETED, DRAFT, FLAGGED, RECENT, SEEN

from .imapclient_test import IMAPClientTest


class TestFlagsConsts(IMAPClientTest):
    def test_flags_are_bytes(self):
        for flag in DELETED, SEEN, ANSWERED, FLAGGED, DRAFT, RECENT:
            if not isinstance(flag, bytes):
                self.fail("%r flag is not bytes" % flag)


class TestFlags(IMAPClientTest):
    def setUp(self):
        super(TestFlags, self).setUp()
        self.client._command_and_check = Mock()

    def test_get(self):
        with patch.object(
            self.client,
            "fetch",
            autospec=True,
            return_value={123: {b"FLAGS": [b"foo", b"bar"]}, 444: {b"FLAGS": [b"foo"]}},
        ):
            out = self.client.get_flags(sentinel.messages)
            self.client.fetch.assert_called_with(sentinel.messages, ["FLAGS"])
            self.assertEqual(out, {123: [b"foo", b"bar"], 444: [b"foo"]})

    def test_set(self):
        self.check(self.client.set_flags, b"FLAGS")

    def test_add(self):
        self.check(self.client.add_flags, b"+FLAGS")

    def test_remove(self):
        self.check(self.client.remove_flags, b"-FLAGS")

    def check(self, meth, expected_command):
        self._check(meth, expected_command)
        self._check(meth, expected_command, silent=True)

    def _check(self, meth, expected_command, silent=False):
        if silent:
            expected_command += b".SILENT"

        cc = self.client._command_and_check
        cc.return_value = [
            b"11 (FLAGS (blah foo) UID 1)",
            b"11 (UID 1 OTHER (dont))",
            b"22 (FLAGS (foo) UID 2)",
            b"22 (UID 2 OTHER (care))",
        ]
        resp = meth([1, 2], "foo", silent=silent)
        cc.assert_called_once_with("store", b"1,2", expected_command, "(foo)", uid=True)
        if silent:
            self.assertIsNone(resp)
        else:
            self.assertEqual(
                resp,
                {
                    1: (b"blah", b"foo"),
                    2: (b"foo",),
                },
            )

        cc.reset_mock()


class TestGmailLabels(IMAPClientTest):
    def setUp(self):
        super(TestGmailLabels, self).setUp()
        self.client._command_and_check = Mock()

    def test_get(self):
        with patch.object(
            self.client,
            "fetch",
            autospec=True,
            return_value={
                123: {b"X-GM-LABELS": [b"foo", b"&AUE-abel"]},
                444: {b"X-GM-LABELS": [b"foo"]},
            },
        ):
            out = self.client.get_gmail_labels(sentinel.messages)
            self.client.fetch.assert_called_with(sentinel.messages, [b"X-GM-LABELS"])
            self.assertEqual(out, {123: ["foo", "Łabel"], 444: ["foo"]})

    def test_set(self):
        self.check(self.client.set_gmail_labels, b"X-GM-LABELS")

    def test_add(self):
        self.check(self.client.add_gmail_labels, b"+X-GM-LABELS")

    def test_remove(self):
        self.check(self.client.remove_gmail_labels, b"-X-GM-LABELS")

    def check(self, meth, expected_command):
        self._check(meth, expected_command)
        self._check(meth, expected_command, silent=True)

    def _check(self, meth, expected_command, silent=False):
        if silent:
            expected_command += b".SILENT"

        cc = self.client._command_and_check
        cc.return_value = [
            b'11 (X-GM-LABELS (&AUE-abel "f\\"o\\"o") UID 1)',
            b'22 (X-GM-LABELS ("f\\"o\\"o") UID 2)',
            b"11 (UID 1 FLAGS (dont))",
            b"22 (UID 2 FLAGS (care))",
        ]
        resp = meth([1, 2], 'f"o"o', silent=silent)
        cc.assert_called_once_with(
            "store", b"1,2", expected_command, '("f\\"o\\"o")', uid=True
        )
        if silent:
            self.assertIsNone(resp)
        else:
            self.assertEqual(
                resp,
                {
                    1: ["Łabel", 'f"o"o'],
                    2: [
                        'f"o"o',
                    ],
                },
            )

        cc.reset_mock()
### tests/test_thread.py
# Copyright (c) 2015, Menno Smits
# Released subject to the New BSD License
# Please see http://en.wikipedia.org/wiki/BSD_licenses

from unittest.mock import Mock

from imapclient.exceptions import CapabilityError

from .imapclient_test import IMAPClientTest


class TestThread(IMAPClientTest):
    def setUp(self):
        super(TestThread, self).setUp()
        self.client._cached_capabilities = (b"THREAD=REFERENCES",)
        self.client._raw_command_untagged = Mock()
        self.client._raw_command_untagged.return_value = [b"(1 2)(3)(4 5 6)"]

    def check_call(self, expected_args):
        self.client._raw_command_untagged.assert_called_once_with(
            b"THREAD", expected_args
        )

    def test_no_thread_support(self):
        self.client._cached_capabilities = (b"NOT-THREAD",)
        self.assertRaises(CapabilityError, self.client.thread)

    def test_unsupported_algorithm(self):
        self.client._cached_capabilities = (b"THREAD=FOO",)
        self.assertRaises(CapabilityError, self.client.thread)

    def test_defaults(self):
        threads = self.client.thread()

        self.check_call([b"REFERENCES", b"UTF-8", b"ALL"])
        self.assertSequenceEqual(threads, ((1, 2), (3,), (4, 5, 6)))

    def test_all_args(self):
        self.client._cached_capabilities = (b"THREAD=COTTON",)

        self.client.thread("COTTON", ["TEXT", "\u261e"], "UTF-7")

        self.check_call([b"COTTON", b"UTF-7", b"TEXT", b"+Jh4-"])
### tests/test_util_functions.py
# Copyright (c) 2014, Menno Smits
# Released subject to the New BSD License
# Please see http://en.wikipedia.org/wiki/BSD_licenses

import unittest

from imapclient.exceptions import InvalidCriteriaError, ProtocolError
from imapclient.imapclient import (
    _normalise_search_criteria,
    _quoted,
    join_message_ids,
    normalise_text_list,
    seq_to_parenstr,
    seq_to_parenstr_upper,
)
from imapclient.util import assert_imap_protocol


class Test_normalise_text_list(unittest.TestCase):
    def check(self, items, expected):
        self.assertEqual(normalise_text_list(items), expected)

    def test_unicode(self):
        self.check("Foo", ["Foo"])

    def test_binary(self):
        self.check(b"FOO", ["FOO"])

    def test_tuple(self):
        self.check(("FOO", "BAR"), ["FOO", "BAR"])

    def test_list(self):
        self.check(["FOO", "BAR"], ["FOO", "BAR"])

    def test_iter(self):
        self.check(iter(["FOO", "BAR"]), ["FOO", "BAR"])

    def test_mixed_list(self):
        self.check(["FOO", b"Bar"], ["FOO", "Bar"])


class Test_seq_to_parenstr(unittest.TestCase):
    def check(self, items, expected):
        self.assertEqual(seq_to_parenstr(items), expected)

    def test_unicode(self):
        self.check("foO", "(foO)")

    def test_binary(self):
        self.check(b"Foo", "(Foo)")

    def test_tuple(self):
        self.check(("FOO", "BAR"), "(FOO BAR)")

    def test_list(self):
        self.check(["FOO", "BAR"], "(FOO BAR)")

    def test_iter(self):
        self.check(iter(["FOO", "BAR"]), "(FOO BAR)")

    def test_mixed_list(self):
        self.check(["foo", b"BAR"], "(foo BAR)")


class Test_seq_to_parenstr_upper(unittest.TestCase):
    def check(self, items, expected):
        self.assertEqual(seq_to_parenstr_upper(items), expected)

    def test_unicode(self):
        self.check("foO", "(FOO)")

    def test_binary(self):
        self.check(b"Foo", "(FOO)")

    def test_tuple(self):
        self.check(("foo", "BAR"), "(FOO BAR)")

    def test_list(self):
        self.check(["FOO", "bar"], "(FOO BAR)")

    def test_iter(self):
        self.check(iter(["FOO", "BaR"]), "(FOO BAR)")

    def test_mixed_list(self):
        self.check(["foo", b"BAR"], "(FOO BAR)")


class Test_join_message_ids(unittest.TestCase):
    def check(self, items, expected):
        self.assertEqual(join_message_ids(items), expected)

    def test_int(self):
        self.check(123, b"123")

    def test_unicode(self):
        self.check("123", b"123")

    def test_unicode_non_numeric(self):
        self.check("2:*", b"2:*")

    def test_binary(self):
        self.check(b"123", b"123")

    def test_binary_non_numeric(self):
        self.check(b"2:*", b"2:*")

    def test_tuple(self):
        self.check((123, 99), b"123,99")

    def test_mixed_list(self):
        self.check(["2:3", 123, b"44"], b"2:3,123,44")

    def test_iter(self):
        self.check(iter([123, 99]), b"123,99")


class Test_normalise_search_criteria(unittest.TestCase):
    def check(self, criteria, charset, expected):
        actual = _normalise_search_criteria(criteria, charset)
        self.assertEqual(actual, expected)
        # Go further and check exact types
        for a, e in zip(actual, expected):
            self.assertEqual(
                type(a),
                type(e),
                "type mismatch: %s (%r) != %s (%r) in %r"
                % (type(a), a, type(e), e, actual),
            )

    def test_list(self):
        self.check(["FOO", "\u263a"], "utf-8", [b"FOO", b"\xe2\x98\xba"])

    def test_tuple(self):
        self.check(("FOO", "BAR"), None, [b"FOO", b"BAR"])

    def test_mixed_list(self):
        self.check(["FOO", b"BAR"], None, [b"FOO", b"BAR"])

    def test_quoting(self):
        self.check(["foo bar"], None, [_quoted(b'"foo bar"')])

    def test_ints(self):
        self.check(["modseq", 500], None, [b"modseq", b"500"])

    def test_unicode(self):
        self.check("Foo", None, [b"Foo"])

    def test_binary(self):
        self.check(b"FOO", None, [b"FOO"])

    def test_unicode_with_charset(self):
        self.check("\u263a", "UTF-8", [b"\xe2\x98\xba"])

    def test_binary_with_charset(self):
        # charset is unused when criteria is binary.
        self.check(b"FOO", "UTF-9", [b"FOO"])

    def test_no_quoting_when_criteria_given_as_string(self):
        self.check("foo bar", None, [b"foo bar"])

    def test_None(self):
        self.assertRaises(InvalidCriteriaError, _normalise_search_criteria, None, None)

    def test_empty(self):
        self.assertRaises(InvalidCriteriaError, _normalise_search_criteria, "", None)


class TestAssertIMAPProtocol(unittest.TestCase):
    def test_assert_imap_protocol(self):
        assert_imap_protocol(True)
        with self.assertRaises(ProtocolError):
            assert_imap_protocol(False)

    def test_assert_imap_protocol_with_message(self):
        assert_imap_protocol(True, b"foo")
        with self.assertRaises(ProtocolError):
            assert_imap_protocol(False, b"foo")
### tests/test_version.py
# Copyright (c) 2015, Menno Smits
# Released subject to the New BSD License
# Please see http://en.wikipedia.org/wiki/BSD_licenses

import unittest

from imapclient.version import _imapclient_version_string


class TestVersionString(unittest.TestCase):
    def test_dot_oh(self):
        self.assertEqual(_imapclient_version_string((1, 0, 0, "final")), "1.0.0")

    def test_minor(self):
        self.assertEqual(_imapclient_version_string((2, 1, 0, "final")), "2.1.0")

    def test_point_release(self):
        self.assertEqual(_imapclient_version_string((1, 2, 3, "final")), "1.2.3")

    def test_alpha(self):
        self.assertEqual(_imapclient_version_string((2, 1, 0, "alpha")), "2.1.0-alpha")

    def test_beta_point(self):
        self.assertEqual(_imapclient_version_string((2, 1, 3, "beta")), "2.1.3-beta")
[The command completed with exit code 0.]
[Current working directory: /workspace/imapclient]
[Python interpreter: /usr/bin/python]
[Command finished with exit code 0]