diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..4c9bdaf
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 2013-2015 Sam Kingston <sam@sjkwi.com.au> and AUTHORS.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/tests.py b/tests.py
new file mode 100644
index 0000000..add5c06
--- /dev/null
+++ b/tests.py
@@ -0,0 +1,146 @@
+import os
+import random
+import shutil
+import string
+import tempfile
+from unittest import TestCase
+import unittest
+import sys
+import six
+from virtualenvapi.manage import VirtualEnvironment
+
+
+packages_for_pre_install = ['pep8', 'wheel']
+packages_for_tests = ['flask', 'git+git://github.com/sjkingo/django_auth_ldap3.git']
+
+
+def which(program):
+
+ def is_exe(fpath):
+ return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
+
+ fpath, fname = os.path.split(program)
+
+ if fpath:
+ if is_exe(program):
+ return program
+ else:
+ for path in os.environ["PATH"].split(os.pathsep):
+ path = path.strip('"')
+ exe_file = os.path.join(path, program)
+ if is_exe(exe_file):
+ return exe_file
+ return None
+
+
+class BaseTest(TestCase):
+
+ env_path = None
+
+ def setUp(self):
+ self.env_path = self.setup_env()
+ self.virtual_env_obj = VirtualEnvironment(self.env_path)
+
+ def setup_env(self):
+ env_path = self.env_path
+ if env_path is None:
+ env_path = tempfile.mkdtemp('test_env')
+ virt_env = VirtualEnvironment(env_path)
+ virt_env._create()
+ for pack in packages_for_pre_install:
+ virt_env.install(pack)
+
+ return env_path
+
+ def _install_packages(self, packages):
+ for pack in packages:
+ self.virtual_env_obj.install(pack)
+
+ def _uninstall_packages(self, packages):
+ for pack in packages:
+ self.virtual_env_obj.uninstall(pack)
+
+ def test_installed(self):
+ for pack in packages_for_pre_install:
+ self.assertTrue(self.virtual_env_obj.is_installed(pack))
+ self.assertFalse(self.virtual_env_obj.is_installed(''.join(random.sample(string.ascii_letters, 30))))
+
+ def test_install(self):
+ self._uninstall_packages(packages_for_tests)
+ for pack in packages_for_tests:
+ self.virtual_env_obj.install(pack)
+ self.assertTrue(self.virtual_env_obj.is_installed(pack))
+
+ def test_uninstall(self):
+ self._install_packages(packages_for_tests)
+ for pack in packages_for_tests:
+ if pack.endswith('.git'):
+ pack = pack.split('/')[-1].replace('.git', '')
+ self.virtual_env_obj.uninstall(pack)
+ self.assertFalse(self.virtual_env_obj.is_installed(pack))
+
+ def test_wheel(self):
+ for pack in packages_for_tests:
+ self.virtual_env_obj.wheel(pack, options=['--wheel-dir=/tmp/wheelhouse'])
+ self.virtual_env_obj.install(pack, options=['--no-index', '--find-links=/tmp/wheelhouse', '--use-wheel'])
+ self.assertTrue(self.virtual_env_obj.is_installed(pack))
+
+ def test_search(self):
+ pack = packages_for_tests[0].lower()
+ result = self.virtual_env_obj.search(pack)
+ self.assertIsInstance(result, dict)
+ self.assertTrue(bool(result))
+ if result:
+ self.assertIn(pack, [k.split(' (')[0].lower() for k in result.keys()])
+
+ def test_search_names(self):
+ pack = packages_for_tests[0].lower()
+ result = self.virtual_env_obj.search_names(pack)
+ self.assertIsInstance(result, list)
+ self.assertIn(pack, [k.split(' (')[0].lower() for k in result])
+
+ def tearDown(self):
+ if os.path.exists(self.env_path) and self.__class__.env_path is None:
+ shutil.rmtree(self.env_path)
+
+
+class Python3TestCase(BaseTest):
+
+ def setUp(self):
+ self.env_path = self.setup_env()
+ self.python = which('python')
+ self.assertIsNotNone(self.python)
+ self.virtual_env_obj = VirtualEnvironment(self.env_path, python=self.python)
+
+ def test_python_version(self):
+ self.assertEqual(self.virtual_env_obj.python, self.python)
+ self.assertEqual(
+ os.path.dirname(self.python),
+ os.path.dirname(which('pip'))
+ )
+
+
+class EnvironmentTest(BaseTest):
+
+ def setup_env(self):
+ act_filename = 'activate_this.py'
+ env_path = super(EnvironmentTest, self).setup_env()
+ act_path = os.path.join(env_path, 'bin', act_filename)
+ if six.PY2:
+ execfile(act_path, dict(__file__=act_path))
+ elif six.PY3:
+ with open(act_path, "r") as fh:
+ exec(fh.read())
+ else:
+ raise EnvironmentError('Unknown version of python')
+ return env_path
+
+
+if __name__ == '__main__':
+ # ToDo refactoring
+ if len(sys.argv) == 2 and sys.argv[1].startswith('--env='):
+ env_path = sys.argv[1].split('=', 1)[-1]
+ BaseTest.env_path = env_path
+ sys.argv = sys.argv[:1]
+
+ unittest.main()