pipreqs/tests/test_pipreqs.py
2021-03-26 14:19:07 -03:00

307 lines
11 KiB
Python
Executable File

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
test_pipreqs
----------------------------------
Tests for `pipreqs` module.
"""
import unittest
import os
import requests
from pipreqs import pipreqs
class TestPipreqs(unittest.TestCase):
def setUp(self):
self.modules = [
'flask', 'requests', 'sqlalchemy', 'docopt', 'boto', 'ipython',
'pyflakes', 'nose', 'analytics', 'flask_seasurf', 'peewee',
'ujson', 'nonexistendmodule', 'bs4',
'after_method_is_valid_even_if_not_pep8'
]
self.modules2 = ['beautifulsoup4']
self.local = ["docopt", "requests", "nose", 'pyflakes']
self.project = os.path.join(os.path.dirname(__file__), "_data")
self.project_clean = os.path.join(
os.path.dirname(__file__),
"_data_clean"
)
self.project_invalid = os.path.join(
os.path.dirname(__file__),
"_invalid_data"
)
self.project_with_ignore_directory = os.path.join(
os.path.dirname(__file__),
"_data_ignore"
)
self.project_with_duplicated_deps = os.path.join(
os.path.dirname(__file__),
"_data_duplicated_deps"
)
self.requirements_path = os.path.join(self.project, "requirements.txt")
self.alt_requirement_path = os.path.join(
self.project,
"requirements2.txt"
)
def test_get_all_imports(self):
imports = pipreqs.get_all_imports(self.project)
self.assertEqual(len(imports), 15)
for item in imports:
self.assertTrue(
item.lower() in self.modules, "Import is missing: " + item)
self.assertFalse("time" in imports)
self.assertFalse("logging" in imports)
self.assertFalse("curses" in imports)
self.assertFalse("__future__" in imports)
self.assertFalse("django" in imports)
self.assertFalse("models" in imports)
def test_deduplicate_dependencies(self):
imports = pipreqs.get_all_imports(self.project_with_duplicated_deps)
pkgs = pipreqs.get_pkg_names(imports)
self.assertEqual(len(pkgs), 1)
self.assertTrue("pymongo" in pkgs)
def test_invalid_python(self):
"""
Test that invalid python files cannot be imported.
"""
self.assertRaises(
SyntaxError, pipreqs.get_all_imports, self.project_invalid)
def test_get_imports_info(self):
"""
Test to see that the right number of packages were found on PyPI
"""
imports = pipreqs.get_all_imports(self.project)
with_info = pipreqs.get_imports_info(imports)
# Should contain 10 items without the "nonexistendmodule" and
# "after_method_is_valid_even_if_not_pep8"
self.assertEqual(len(with_info), 13)
for item in with_info:
self.assertTrue(
item['name'].lower() in self.modules,
"Import item appears to be missing " + item['name'])
def test_get_pkg_names(self):
pkgs = ['jury', 'Japan', 'camel', 'Caroline']
actual_output = pipreqs.get_pkg_names(pkgs)
expected_output = ['camel', 'Caroline', 'Japan', 'jury']
self.assertEqual(actual_output, expected_output)
def test_get_use_local_only(self):
"""
Test without checking PyPI, check to see if names of local
imports matches what we expect
- Note even though pyflakes isn't in requirements.txt,
It's added to locals since it is a development dependency
for testing
"""
# should find only docopt and requests
imports_with_info = pipreqs.get_import_local(self.modules)
for item in imports_with_info:
self.assertTrue(item['name'].lower() in self.local)
def test_init(self):
"""
Test that all modules we will test upon are in requirements file
"""
pipreqs.init(
{'<path>': self.project, '--savepath': None, '--print': False,
'--use-local': None, '--force': True, '--proxy': None,
'--pypi-server': None, '--diff': None, '--clean': None}
)
assert os.path.exists(self.requirements_path) == 1
with open(self.requirements_path, "r") as f:
data = f.read().lower()
for item in self.modules[:-3]:
self.assertTrue(item.lower() in data)
# It should be sorted based on names.
data = data.strip().split('\n')
self.assertEqual(data, sorted(data))
def test_init_local_only(self):
"""
Test that items listed in requirements.text are the same
as locals expected
"""
pipreqs.init(
{'<path>': self.project, '--savepath': None, '--print': False,
'--use-local': True, '--force': True, '--proxy': None,
'--pypi-server': None, '--diff': None, '--clean': None}
)
assert os.path.exists(self.requirements_path) == 1
with open(self.requirements_path, "r") as f:
data = f.readlines()
for item in data:
item = item.strip().split("==")
self.assertTrue(item[0].lower() in self.local)
def test_init_savepath(self):
"""
Test that we can save requirements.txt correctly
to a different path
"""
pipreqs.init(
{'<path>': self.project, '--savepath': self.alt_requirement_path,
'--use-local': None, '--proxy': None, '--pypi-server': None,
'--print': False, "--diff": None, "--clean": None}
)
assert os.path.exists(self.alt_requirement_path) == 1
with open(self.alt_requirement_path, "r") as f:
data = f.read().lower()
for item in self.modules[:-3]:
self.assertTrue(item.lower() in data)
for item in self.modules2:
self.assertTrue(item.lower() in data)
def test_init_overwrite(self):
"""
Test that if requiremnts.txt exists, it will not be
automatically overwritten
"""
with open(self.requirements_path, "w") as f:
f.write("should_not_be_overwritten")
pipreqs.init(
{'<path>': self.project, '--savepath': None, '--use-local': None,
'--force': None, '--proxy': None, '--pypi-server': None,
'--print': False, '--diff': None, '--clean': None}
)
assert os.path.exists(self.requirements_path) == 1
with open(self.requirements_path, "r") as f:
data = f.read().lower()
self.assertEqual(data, "should_not_be_overwritten")
def test_get_import_name_without_alias(self):
"""
Test that function get_name_without_alias()
will work on a string.
- Note: This isn't truly needed when pipreqs is walking
the AST to find imports
"""
import_name_with_alias = "requests as R"
expected_import_name_without_alias = "requests"
import_name_without_aliases = pipreqs.get_name_without_alias(
import_name_with_alias)
self.assertEqual(
import_name_without_aliases,
expected_import_name_without_alias
)
def test_custom_pypi_server(self):
"""
Test that trying to get a custom pypi sever fails correctly
"""
self.assertRaises(
requests.exceptions.MissingSchema, pipreqs.init,
{'<path>': self.project, '--savepath': None, '--print': False,
'--use-local': None, '--force': True, '--proxy': None,
'--pypi-server': 'nonexistent'}
)
def test_ignored_directory(self):
"""
Test --ignore parameter
"""
pipreqs.init(
{'<path>': self.project_with_ignore_directory, '--savepath': None,
'--print': False, '--use-local': None, '--force': True,
'--proxy': None, '--pypi-server': None,
'--ignore': '.ignored_dir,.ignore_second', '--diff': None,
'--clean': None}
)
with open(
os.path.join(
self.project_with_ignore_directory,
"requirements.txt"
), "r"
) as f:
data = f.read().lower()
for item in ['click', 'getpass']:
self.assertFalse(item.lower() in data)
def test_omit_version(self):
"""
Test --no-pin parameter
"""
pipreqs.init(
{'<path>': self.project_with_ignore_directory, '--savepath': None,
'--print': False, '--use-local': None, '--force': True,
'--proxy': None, '--pypi-server': None, '--diff': None,
'--clean': None, '--no-pin': True}
)
with open(os.path.join(
self.project_with_ignore_directory,
"requirements.txt"), "r"
) as f:
data = f.read().lower()
for item in ['beautifulsoup4==4.8.1', 'boto==2.49.0']:
self.assertFalse(item.lower() in data)
def test_clean(self):
"""
Test --clean parameter
"""
pipreqs.init(
{'<path>': self.project, '--savepath': None, '--print': False,
'--use-local': None, '--force': True, '--proxy': None,
'--pypi-server': None, '--diff': None, '--clean': None}
)
assert os.path.exists(self.requirements_path) == 1
pipreqs.init(
{'<path>': self.project, '--savepath': None, '--print': False,
'--use-local': None, '--force': None, '--proxy': None,
'--pypi-server': None, '--diff': None,
'--clean': self.requirements_path, '--no-pin': True}
)
with open(self.requirements_path, "r") as f:
data = f.read().lower()
for item in self.modules[:-3]:
self.assertTrue(item.lower() in data)
def test_clean_with_imports_to_clean(self):
"""
Test --clean parameter when there are imports to clean
"""
cleaned_module = 'sqlalchemy'
pipreqs.init(
{'<path>': self.project, '--savepath': None, '--print': False,
'--use-local': None, '--force': True, '--proxy': None,
'--pypi-server': None, '--diff': None, '--clean': None}
)
assert os.path.exists(self.requirements_path) == 1
modules_clean = [m for m in self.modules if m != cleaned_module]
pipreqs.init(
{'<path>': self.project_clean, '--savepath': None,
'--print': False, '--use-local': None, '--force': None,
'--proxy': None, '--pypi-server': None, '--diff': None,
'--clean': self.requirements_path, '--no-pin': True}
)
with open(self.requirements_path, "r") as f:
data = f.read().lower()
self.assertTrue(cleaned_module not in data)
def tearDown(self):
"""
Remove requiremnts.txt files that were written
"""
try:
os.remove(self.requirements_path)
except OSError:
pass
try:
os.remove(self.alt_requirement_path)
except OSError:
pass
if __name__ == '__main__':
unittest.main()