diff options
author | Dylan Baker <baker.dylan.c@gmail.com> | 2017-02-01 10:41:41 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-02-01 10:41:41 -0800 |
commit | 567f4c2d8233e83b0489145064af662dbc010e00 (patch) | |
tree | 5ab12d4fe9093e56aec8d13b44fa3f576d3cf697 | |
parent | b29da9cdcda59b262e3df2a1fb739a33311b2165 (diff) | |
parent | a030da17b4c450440f8dd8d5a5f828a272656c5a (diff) |
Merge pull request #1019 from dcbaker/pr/more-unittests
more unittests
-rw-r--r-- | alot/commands/__init__.py | 2 | ||||
-rw-r--r-- | alot/commands/envelope.py | 14 | ||||
-rw-r--r-- | tests/commands/envelope_tests.py | 107 | ||||
-rw-r--r-- | tests/commands/init_test.py | 15 |
4 files changed, 129 insertions, 9 deletions
diff --git a/alot/commands/__init__.py b/alot/commands/__init__.py index 5df88747..6b84a50b 100644 --- a/alot/commands/__init__.py +++ b/alot/commands/__init__.py @@ -101,6 +101,8 @@ class registerCommand(object): definition is decorated to register it as handler for 'save' in mode 'thread' and add boolean and string arguments:: + .. code-block:: + @registerCommand('thread', 'save', arguments=[ (['--all'], {'action': 'store_true', 'help':'save all'}), (['path'], {'nargs':'?', 'help':'path to save to'})], diff --git a/alot/commands/envelope.py b/alot/commands/envelope.py index d0dce4be..82b87888 100644 --- a/alot/commands/envelope.py +++ b/alot/commands/envelope.py @@ -39,7 +39,7 @@ class AttachCommand(Command): """attach files to the mail""" repeatable = True - def __init__(self, path=None, **kwargs): + def __init__(self, path, **kwargs): """ :param path: files to attach (globable string) :type path: str @@ -50,14 +50,10 @@ class AttachCommand(Command): def apply(self, ui): envelope = ui.current_buffer.envelope - if self.path: # TODO: not possible, otherwise argparse error before - files = [g for g in glob.glob(os.path.expanduser(self.path)) - if os.path.isfile(g)] - if not files: - ui.notify('no matches, abort') - return - else: - ui.notify('no files specified, abort') + files = [g for g in glob.glob(os.path.expanduser(self.path)) + if os.path.isfile(g)] + if not files: + ui.notify('no matches, abort') return logging.info("attaching: %s", files) diff --git a/tests/commands/envelope_tests.py b/tests/commands/envelope_tests.py new file mode 100644 index 00000000..6d68d4d3 --- /dev/null +++ b/tests/commands/envelope_tests.py @@ -0,0 +1,107 @@ +# encoding=utf-8 +# Copyright © 2017 Dylan Baker + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +"""Tests for the alot.commands.envelope module.""" + +from __future__ import absolute_import +import os +import contextlib +import shutil +import tempfile +import unittest + +import mock + +from alot.commands import envelope + + +@contextlib.contextmanager +def temporary_directory(suffix='', prefix='', dir=None): + """Python3 interface implementation. + + Python3 provides a class that can be used as a context manager, which + creates a temporary directory and removes it when the context manager + exits. This function emulates enough of the interface of + TemporaryDirectory, for this module to use, and is designed as a drop in + replacement that can be replaced after the python3 port. + + The only user visible difference is that this does not implement the + cleanup method that TemporaryDirectory does. + """ + directory = tempfile.mkdtemp(suffix=suffix, prefix=prefix, dir=dir) + yield directory + shutil.rmtree(directory) + + +class TestAttachCommand(unittest.TestCase): + """Tests for the AttachCommaned class.""" + + def test_single_path(self): + """A test for an existing single path.""" + ui = mock.Mock() + + with temporary_directory() as d: + testfile = os.path.join(d, 'foo') + with open(testfile, 'w') as f: + f.write('foo') + + cmd = envelope.AttachCommand(path=testfile) + cmd.apply(ui) + ui.current_buffer.envelope.attach.assert_called_with(testfile) + + def test_user(self): + """A test for an existing single path prefaced with ~/.""" + ui = mock.Mock() + + with temporary_directory() as d: + # This mock replaces expanduser to replace "~/" with a path to the + # temporary directory. This is easier and more reliable than + # relying on changing an environment variable (like HOME), since it + # doesn't rely on CPython implementation details. + with mock.patch('alot.commands.os.path.expanduser', + lambda x: os.path.join(d, x[2:])): + testfile = os.path.join(d, 'foo') + with open(testfile, 'w') as f: + f.write('foo') + + cmd = envelope.AttachCommand(path='~/foo') + cmd.apply(ui) + ui.current_buffer.envelope.attach.assert_called_with(testfile) + + def test_glob(self): + """A test using a glob.""" + ui = mock.Mock() + + with temporary_directory() as d: + testfile1 = os.path.join(d, 'foo') + testfile2 = os.path.join(d, 'far') + for t in [testfile1, testfile2]: + with open(t, 'w') as f: + f.write('foo') + + cmd = envelope.AttachCommand(path=os.path.join(d, '*')) + cmd.apply(ui) + ui.current_buffer.envelope.attach.assert_has_calls( + [mock.call(testfile1), mock.call(testfile2)], any_order=True) + + def test_no_match(self): + """A test for a file that doesn't exist.""" + ui = mock.Mock() + + with temporary_directory() as d: + cmd = envelope.AttachCommand(path=os.path.join(d, 'doesnt-exist')) + cmd.apply(ui) + ui.notify.assert_called() diff --git a/tests/commands/init_test.py b/tests/commands/init_test.py index f5a37997..5caf7eb0 100644 --- a/tests/commands/init_test.py +++ b/tests/commands/init_test.py @@ -7,6 +7,8 @@ from __future__ import absolute_import import argparse import unittest +import mock + from alot import commands from alot.commands import thread @@ -28,3 +30,16 @@ class TestCommandFactory(unittest.TestCase): self.assertIsInstance(cmd, thread.SaveAttachmentCommand) self.assertTrue(cmd.all) self.assertEqual(cmd.path, u'/foo') + + +class TestRegisterCommand(unittest.TestCase): + """Tests for the registerCommand class.""" + + def test_registered(self): + """using registerCommand adds to the COMMANDS dict.""" + with mock.patch('alot.commands.COMMANDS', {'foo': {}}): + @commands.registerCommand('foo', 'test') + def foo(): + pass + + self.assertIn('test', commands.COMMANDS['foo']) |