unittest_devctl.py 6.07 KB
Newer Older
1
# copyright 2003-2016 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
2
# contact https://www.logilab.fr/ -- mailto:contact@logilab.fr
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#
# This file is part of CubicWeb.
#
# CubicWeb is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 2.1 of the License, or (at your option)
# any later version.
#
# CubicWeb 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 Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License along
17
# with CubicWeb.  If not, see <https://www.gnu.org/licenses/>.
18
19
"""unit tests for cubicweb-ctl commands from devtools"""

20
21
import os
import os.path as osp
22
import sys
23
from subprocess import Popen, PIPE, STDOUT
Denis Laxalde's avatar
Denis Laxalde committed
24
from tempfile import TemporaryDirectory
25
26
27
from unittest import TestCase


28
def newcube(directory, name):
29
30
31
32
33
34
35
36
37
    cmd = [
        "cubicweb-ctl",
        "newcube",
        "--directory",
        directory,
        "--short-description",
        "short_desc",
        name,
    ]
38
    proc = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=STDOUT)
39
40
    returncode = proc.wait()
    return returncode, proc.stdout.read()
41
42


43
def to_unicode(msg):
44
    return msg.decode(sys.getdefaultencoding(), errors="replace")
45
46
47
48


class DevCtlTC(TestCase):
    """Test case for devtools commands"""
49
50

    def test_newcube(self):
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
        expected_project_content = [
            "setup.py",
            "test",
            "MANIFEST.in",
            "cubicweb_foo",
            "README",
            "tox.ini",
            ".gitlab-ci.yml",
            ".yamllint",
            ".hgignore",
        ]
        expected_package_content = [
            "i18n",
            "hooks.py",
            "views.py",
            "migration",
            "entities.py",
            "schema.py",
            "__init__.py",
            "data",
            "__pkginfo__.py",
        ]
73
        with TemporaryDirectory(prefix="temp-cwctl-newcube") as tmpdir:
74
            retcode, stdout = newcube(tmpdir, "foo")
75
            self.assertEqual(retcode, 0, msg=to_unicode(stdout))
76
            project_dir = osp.join(tmpdir, "cubicweb-foo")
77
            project_content = os.listdir(project_dir)
78
            package_dir = osp.join(project_dir, "cubicweb_foo")
79
            package_content = os.listdir(package_dir)
80
81
            self.assertCountEqual(project_content, expected_project_content)
            self.assertCountEqual(package_content, expected_package_content)
82
83
84

    def test_flake8(self):
        """Ensure newcube built from skeleton is flake8-compliant"""
85
        with TemporaryDirectory(prefix="temp-cwctl-newcube-flake8") as tmpdir:
86
87
88
89
90
91
92
            newcube(tmpdir, "foo")
            cmd = [
                sys.executable,
                "-m",
                "flake8",
                osp.join(tmpdir, "cubicweb-foo", "cubicweb_foo"),
            ]
93
94
            proc = Popen(cmd, stdout=PIPE, stderr=STDOUT)
            retcode = proc.wait()
95
        self.assertEqual(retcode, 0, msg=to_unicode(proc.stdout.read()))
96

97
98
    def test_newcube_sdist(self):
        """Ensure sdist can be built from a new cube"""
99
        with TemporaryDirectory(prefix="temp-cwctl-newcube-sdist") as tmpdir:
100
101
102
            newcube(tmpdir, "foo")
            projectdir = osp.join(tmpdir, "cubicweb-foo")
            cmd = [sys.executable, "setup.py", "sdist"]
103
104
105
106
            proc = Popen(cmd, stdout=PIPE, stderr=STDOUT, cwd=projectdir)
            retcode = proc.wait()
            stdout = to_unicode(proc.stdout.read())
            self.assertEqual(retcode, 0, stdout)
107
            distfpath = osp.join(projectdir, "dist", "cubicweb-foo-0.1.0.tar.gz")
108
109
            self.assertTrue(osp.isfile(distfpath))

110
111
    def test_newcube_install(self):
        """Ensure a new cube can be installed"""
112
        with TemporaryDirectory(prefix="temp-cwctl-newcube-install") as tmpdir:
113
114
            newcube(tmpdir, "foo")
            projectdir = osp.join(tmpdir, "cubicweb-foo")
115
            env = os.environ.copy()
116
            env["HOME"] = tmpdir
117
            # Retrieve user-site first to later set the PYTHONPATH.
118
119
120
121
122
123
124
            proc = Popen(
                [sys.executable, "-m", "site", "--user-site"],
                stdout=PIPE,
                stderr=PIPE,
                env=env,
                cwd=tmpdir,
            )
125
126
127
128
129
130
131
132
            retcode = proc.wait()
            # Exit codes below 2 are not errors and are ok for us (see
            # 'python3 -m site --help' for details).
            self.assertFalse(retcode > 2, to_unicode(proc.stderr.read()))
            user_site = proc.stdout.read().strip()
            # We need this otherwise setuptools will complain that the
            # installation target is not in PYTHONPATH (probably because we
            # use a fake HOME).
133
134
135
            env["PYTHONPATH"] = user_site
            cmd = [sys.executable, "setup.py", "install", "--user"]
            proc = Popen(cmd, stdout=PIPE, stderr=STDOUT, cwd=projectdir, env=env)
136
137
138
            retcode = proc.wait()
            stdout = to_unicode(proc.stdout.read())
            self.assertEqual(retcode, 0, stdout)
139
            target_egg = "cubicweb_foo-0.1.0-py{}.egg".format(sys.version[:3]).encode()
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
            self.assertTrue(
                osp.isdir(osp.join(user_site, target_egg)),
                "target directory content: %s" % os.listdir(user_site),
            )
            pkgdir = osp.join(user_site, target_egg, b"cubicweb_foo")
            self.assertTrue(
                osp.isdir(pkgdir), os.listdir(osp.join(user_site, target_egg))
            )
            pkgcontent = [f for f in os.listdir(pkgdir) if f.endswith(b".py")]
            self.assertCountEqual(
                pkgcontent,
                [
                    b"schema.py",
                    b"entities.py",
                    b"hooks.py",
                    b"__init__.py",
                    b"__pkginfo__.py",
                    b"views.py",
                ],
            )
160

161

162
if __name__ == "__main__":
163
    from unittest import main
164

165
    main()