summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDylan Baker <baker.dylan.c@gmail.com>2017-02-01 10:41:41 -0800
committerGitHub <noreply@github.com>2017-02-01 10:41:41 -0800
commit567f4c2d8233e83b0489145064af662dbc010e00 (patch)
tree5ab12d4fe9093e56aec8d13b44fa3f576d3cf697
parentb29da9cdcda59b262e3df2a1fb739a33311b2165 (diff)
parenta030da17b4c450440f8dd8d5a5f828a272656c5a (diff)
Merge pull request #1019 from dcbaker/pr/more-unittests
more unittests
-rw-r--r--alot/commands/__init__.py2
-rw-r--r--alot/commands/envelope.py14
-rw-r--r--tests/commands/envelope_tests.py107
-rw-r--r--tests/commands/init_test.py15
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'])