summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorCaselIT <cfederico87@gmail.com>2021-06-15 22:32:05 +0200
committerCaselIT <cfederico87@gmail.com>2021-06-15 23:38:07 +0200
commit7756b35e23ec11b64a1ac37afcb41dda3ca29913 (patch)
treea2c46870a195f22c7489bface5a890cf90acff5c /tests
parentc0f0a3238fe1ec8029d66ad6ac518b60c78c36ed (diff)
downloadalembic-7756b35e23ec11b64a1ac37afcb41dda3ca29913.tar.gz
Revendor editor and make dateutil optional
Re-implemented the ``python-editor`` dependency as a small internal function to avoid the need for external dependencies. The implementation is based on the original version in 7b91b325ff43a0e9235e0f15b57391fa92352626. Make the ``python-dateutil`` library an optional dependency. This library is only required if the ``timezone`` option is used in the Alembic configuration. An extra require named ``tz`` is available with ``pip install alembic[tz]`` to install it. Fixes: #674 Fixes: #856 Change-Id: I07f17b2fea01e3a3d677ce95333fe3e8d8d438fd
Diffstat (limited to 'tests')
-rw-r--r--tests/test_command.py20
-rw-r--r--tests/test_editor.py106
-rw-r--r--tests/test_script_production.py16
3 files changed, 125 insertions, 17 deletions
diff --git a/tests/test_command.py b/tests/test_command.py
index 4114be0..a477a1d 100644
--- a/tests/test_command.py
+++ b/tests/test_command.py
@@ -11,12 +11,10 @@ from sqlalchemy import text
from alembic import __version__
from alembic import command
from alembic import config
-from alembic import testing
from alembic import util
from alembic.script import ScriptDirectory
from alembic.testing import assert_raises
from alembic.testing import assert_raises_message
-from alembic.testing import config as testing_config
from alembic.testing import eq_
from alembic.testing import is_false
from alembic.testing import is_true
@@ -924,7 +922,7 @@ class EditTest(TestBase):
% (EditTest.cfg.config_args["here"], EditTest.c)
)
- with mock.patch("alembic.util.edit") as edit:
+ with mock.patch("alembic.util.open_in_editor") as edit:
command.edit(self.cfg, "head")
edit.assert_called_with(expected_call_arg)
@@ -934,22 +932,10 @@ class EditTest(TestBase):
% (EditTest.cfg.config_args["here"], EditTest.b)
)
- with mock.patch("alembic.util.edit") as edit:
+ with mock.patch("alembic.util.open_in_editor") as edit:
command.edit(self.cfg, self.b[0:3])
edit.assert_called_with(expected_call_arg)
- @testing_config.requirements.editor_installed
- @testing.emits_python_deprecation_warning("the imp module is deprecated")
- def test_edit_with_missing_editor(self):
- with mock.patch("editor.edit") as edit_mock:
- edit_mock.side_effect = OSError("file not found")
- assert_raises_message(
- util.CommandError,
- "file not found",
- util.edit,
- "/not/a/file.txt",
- )
-
def test_edit_no_revs(self):
assert_raises_message(
util.CommandError,
@@ -975,7 +961,7 @@ class EditTest(TestBase):
)
command.stamp(self.cfg, self.b)
- with mock.patch("alembic.util.edit") as edit:
+ with mock.patch("alembic.util.open_in_editor") as edit:
command.edit(self.cfg, "current")
edit.assert_called_with(expected_call_arg)
diff --git a/tests/test_editor.py b/tests/test_editor.py
new file mode 100644
index 0000000..0ec6f5f
--- /dev/null
+++ b/tests/test_editor.py
@@ -0,0 +1,106 @@
+import os
+from os.path import join
+from unittest.mock import patch
+
+from alembic import util
+from alembic.testing import combinations
+from alembic.testing import expect_raises_message
+from alembic.testing.fixtures import TestBase
+
+
+class TestHelpers(TestBase):
+ def common(self, cb, is_posix=True):
+ with patch("alembic.util.editor.check_call") as check_call, patch(
+ "alembic.util.editor.exists"
+ ) as exists, patch(
+ "alembic.util.editor.is_posix",
+ new=is_posix,
+ ), patch(
+ "os.pathsep", new=":" if is_posix else ";"
+ ):
+ cb(check_call, exists)
+
+ @combinations((True,), (False,))
+ def test_edit_with_user_editor(self, posix):
+ def go(check_call, exists):
+ test_environ = {"EDITOR": "myvim", "PATH": "/usr/bin"}
+ executable = join("/usr/bin", "myvim")
+ if not posix:
+ executable += ".exe"
+
+ exists.side_effect = lambda fname: fname == executable
+ util.open_in_editor("myfile", test_environ)
+ check_call.assert_called_with([executable, "myfile"])
+
+ self.common(go, posix)
+
+ @combinations(("EDITOR",), ("VISUAL",))
+ def test_edit_with_user_editor_exists(self, key):
+ def go(check_call, exists):
+ test_environ = {key: "myvim", "PATH": "/usr/bin"}
+ exists.side_effect = lambda fname: fname == "myvim"
+ util.open_in_editor("myfile", test_environ)
+ check_call.assert_called_with(["myvim", "myfile"])
+
+ self.common(go)
+
+ @combinations((True,), (False,))
+ def test_edit_with_user_editor_precedence(self, with_path):
+ def go(check_call, exists):
+ test_environ = {
+ "EDITOR": "myvim",
+ "VISUAL": "myvisual",
+ "PATH": "/usr/bin",
+ }
+ exes = ["myvim", "myvisual"]
+ if with_path:
+ exes = [join("/usr/bin", n) for n in exes]
+ exists.side_effect = lambda fname: fname in exes
+ util.open_in_editor("myfile", test_environ)
+ check_call.assert_called_with([exes[0], "myfile"])
+
+ self.common(go)
+
+ def test_edit_with_user_editor_abs(self):
+ def go(check_call, exists):
+ test_environ = {"EDITOR": "/foo/myvim", "PATH": "/usr/bin"}
+ exists.side_effect = lambda fname: fname == "/usr/bin/foo/myvim"
+ with expect_raises_message(util.CommandError, "EDITOR"):
+ util.open_in_editor("myfile", test_environ)
+
+ self.common(go)
+
+ def test_edit_with_default_editor(self):
+ def go(check_call, exists):
+ test_environ = {"PATH": os.pathsep.join(["/usr/bin", "/bin"])}
+ executable = join("/bin", "vim")
+
+ exists.side_effect = lambda fname: fname == executable
+ util.open_in_editor("myfile", test_environ)
+ check_call.assert_called_with([executable, "myfile"])
+
+ self.common(go)
+
+ def test_edit_with_default_editor_windows(self):
+ def go(check_call, exists):
+ test_environ = {
+ "PATH": os.pathsep.join(
+ [r"C:\Windows\System32", r"C:\Users\user\bin"]
+ )
+ }
+ executable = join(r"C:\Users\user\bin", "notepad.exe")
+
+ exists.side_effect = lambda fname: fname == executable
+ util.open_in_editor("myfile", test_environ)
+ check_call.assert_called_with([executable, "myfile"])
+
+ self.common(go, False)
+
+ def test_edit_with_missing_editor(self):
+ def go(check_call, exists):
+ test_environ = {}
+ exists.return_value = False
+ with expect_raises_message(util.CommandError, "EDITOR"):
+ util.open_in_editor("myfile", test_environ)
+
+ self.common(go)
diff --git a/tests/test_script_production.py b/tests/test_script_production.py
index 15d9366..2edae26 100644
--- a/tests/test_script_production.py
+++ b/tests/test_script_production.py
@@ -15,6 +15,7 @@ from alembic.script import ScriptDirectory
from alembic.testing import assert_raises_message
from alembic.testing import assertions
from alembic.testing import eq_
+from alembic.testing import expect_raises_message
from alembic.testing import is_
from alembic.testing import mock
from alembic.testing import ne_
@@ -34,6 +35,10 @@ from alembic.testing.env import write_script
from alembic.testing.fixtures import TestBase
from alembic.util import CommandError
+try:
+ from unittest.mock import patch
+except ImportError:
+ from mock import patch # noqa
env, abc, def_ = None, None, None
@@ -250,6 +255,17 @@ class ScriptNamingTest(TestBase):
datetime.datetime(2012, 7, 25, 15, 8, 5),
)
+ def test_no_dateutil_module(self):
+ with patch("alembic.script.base.tz", new=None):
+ with expect_raises_message(
+ CommandError, "The library 'python-dateutil' is required"
+ ):
+ self._test_tz(
+ "utc",
+ datetime.datetime(2012, 7, 25, 15, 8, 5),
+ datetime.datetime(2012, 7, 25, 15, 8, 5),
+ )
+
class RevisionCommandTest(TestBase):
def setUp(self):