def should_detect_git_repo(self, mock_tmp_dir, mock_clone, mock_tempfile, mock_stdout): t = Template(self.config) assert not t.vcs_cls self.config.template = '[email protected]:repo.git' t = Template(self.config) self.assertEquals(t.vcs_cls.__class__.__name__, 'Git')
def should_clone_git_repo(self, mock_working_dir): # Create a fake temp repo w/ commit git_dir = tempfile.mkdtemp(prefix='git') git_repo = Repo.init(git_dir) try: f = open(os.path.join(git_dir, 'foo.txt'), 'w') f.write('blah') except IOError: assert False finally: f.close() cwd = os.getcwd() os.chdir(git_dir) git_repo.index.add(['foo.txt']) git_repo.index.commit("Added foo.txt") os.chdir(cwd) # Fake Template Path mock_working_dir.return_value = tempfile.gettempdir() # Now attempt to clone but patch for Exception throw self.config.template = 'git+' + git_dir t = Template(self.config) t.copy_template() # Clean up rmtree(t.project_root) self.assertFalse(os.path.isdir(t.config.template)) self.assertFalse(self.config.cli_opts.error.called)
def test_update_copy_ignore_globs_empty_wrong_type(self): instance = Template('/foo/bar') del(instance.copy_ignore_globs) instance.update_copy_ignore_globs({'foo': 'bar'}) self.assertEqual(instance.copy_ignore_globs, [])
def test_directory_not_renamed_if_not_in_placeholders(self, mock_working_dir): mock_working_dir.return_value = tempfile.gettempdir() t = Template(self.config) t.copy_template() self.assertTrue(os.path.isdir(os.path.join(t.project_root, '__NOT_IN_PLACEHOLDERS__'))) rmtree(t.project_root)
def test_get_render_ignore_files(self): instance = Template('/foo/bar') instance.update_copy_ignore_globs(['*.ico', ]) files = ['setup.py', 'foo.png', 'bar.jpeg', 'index.html'] ignores = instance.get_render_ignore_files(files) self.assertEqual(ignores, ['foo.png', 'bar.jpeg'])
def test_excluded_dirs_are_not_copied(self, mock_working_dir): mock_working_dir.return_value = tempfile.gettempdir() t = Template(self.config) t.exclude_dirs.append('.exclude_this') t.copy_template() self.assertFalse(os.path.isdir(os.path.join(t.project_root, '.exclude_this'))) rmtree(t.project_root)
def ensure_excluded_dirs_are_not_copied(self, mock_working_dir): mock_working_dir.return_value = tempfile.gettempdir() t = Template(self.config) t.exclude_dirs.append('.exclude_this') t.copy_template() self.assertFalse( os.path.isdir(os.path.join(t.project_root, '.exclude_this'))) rmtree(t.project_root)
def test_rename_files_in_placeholders(self, mock_working_dir): mock_working_dir.return_value = tempfile.gettempdir() t = Template(self.config) t.copy_template() self.assertTrue(os.path.isfile(os.path.join( t.project_root, '__NOT_IN_PLACEHOLDERS__', '%s.txt' % self.config.project_name))) rmtree(t.project_root)
def should_copy_directory_tree_if_is_dir(self, mock_working_dir): mock_working_dir.return_value = tempfile.gettempdir() t = Template(self.config) t.exclude_dirs.append('.exclude_this') t.copy_template() self.assertTrue( os.path.isdir(os.path.join(t.project_root, 'should_copy_this'))) rmtree(t.project_root)
def test_copy_directory_tree_if_is_dir(self, mock_working_dir): mock_working_dir.return_value = tempfile.gettempdir() t = Template(self.config) t.exclude_dirs.append('.exclude_this') t.copy_template() self.assertTrue(os.path.isdir(os.path.join(t.project_root, 'should_copy_this'))) rmtree(t.project_root)
def test_copy_callback_call(self, mock_copy_tree, mock_pwd): from facio.state import state instance = Template('/foo/bar') callback = MagicMock() self.assertTrue(instance.copy(callback=callback)) callback.assert_called_once_with( origin=instance.origin, destination=state.get_project_root())
def test_exception_setting_copy_ignore_globs_not_iterable(self, mock_exit): instance = Template('/foo/bar') with self.assertRaises(FacioException): instance.update_copy_ignore_globs(1) self.mocked_facio_exceptions_puts.assert_any_call( 'Error: Failed to add 1 to ignore globs list') self.assertTrue(mock_exit.called)
def should_rename_files_in_placeholders(self, mock_working_dir): mock_working_dir.return_value = tempfile.gettempdir() t = Template(self.config) t.copy_template() self.assertTrue( os.path.isfile( os.path.join(t.project_root, '__NOT_IN_PLACEHOLDERS__', '%s.txt' % self.config.project_name))) rmtree(t.project_root)
def ensure_directory_not_renamed_if_not_in_placeholders( self, mock_working_dir): mock_working_dir.return_value = tempfile.gettempdir() t = Template(self.config) t.copy_template() self.assertTrue( os.path.isdir( os.path.join(t.project_root, '__NOT_IN_PLACEHOLDERS__'))) rmtree(t.project_root)
def test_copy_template_failes_if_dir_does_not_exist( self, mock_working_dir, mock_error, mock_isdir): mock_working_dir.return_value = tempfile.gettempdir() tmp_dir = tempfile.mkdtemp(suffix=self.config.project_name, prefix='') tmp_dir_name = list(os.path.split(tmp_dir))[-1:][0] self.config.project_name = tmp_dir_name t = Template(self.config) t.copy_template() self.config._error.assert_called_with( 'Unable to copy template, directory does not exist')
def test_dir_cannot_be_created_if_already_exists(self, mock_working_dir, mock_error, mock_isdir): mock_working_dir.return_value = tempfile.gettempdir() tmp_dir = tempfile.mkdtemp(suffix=self.config.project_name, prefix='') tmp_dir_name = list(os.path.split(tmp_dir))[-1:][0] self.config.project_name = tmp_dir_name t = Template(self.config) t.copy_template() rmtree(tmp_dir) self.config._error.assert_called_with('%s already exists' % (tmp_dir))
def test_rename_directories(self, mock_move, mock_walk): mock_walk.return_value = [ ('/foo', ['bar', '{{UNKNOWN}}', '{{PROJECT_NAME}}', 'baz'], []) ] instance = Template('/foo/bar') for index, value in enumerate(instance.rename_direcories()): old, new = value mock_move.assert_called_with(old, new) self.assertEqual(old, '/foo/{{PROJECT_NAME}}') self.assertEqual(new, '/foo/foo')
def test_get_render_ignore_globs(self): instance = Template('/foo/bar') instance.update_render_ignore_globs(['*.psd', '*.ico']) self.assertEqual(instance.get_render_ignore_globs(), [ '*.png', '*.gif', '*.jpeg', '*.jpg', '*.psd', '*.ico', ])
def test_rename_files(self, mock_move, mock_walk): mock_walk.return_value = [ ('/foo', [], ['bar.py', '{{UNKNOWN}}.png', '{{PROJECT_NAME}}.html', 'baz.gif']) ] instance = Template('/foo/bar') for index, value in enumerate(instance.rename_files()): old, new = value mock_move.assert_called_with(old, new) self.assertEqual(old, '/foo/{{PROJECT_NAME}}.html') self.assertEqual(new, '/foo/foo.html')
def test_copy_oserror_vcs_path_recursion_limit( self, mock_copy_tree, mock_isdir, mock_gitvcs, mock_exit): instance = Template('git+/foo/bar') with self.assertRaises(FacioException): instance.copy() self.assertTrue(mock_exit.called) self.mocked_facio_exceptions_puts.assert_any_call( 'Error: Failed to copy template after 6 attempts')
def test_copy_oserror_vcs_path( self, mock_copy_tree, mock_isdir, mock_gitvcs, mock_exit): instance = Template('git+/foo/bar') instance.COPY_ATTEMPT_LIMIT = 0 # Block the next copy call with self.assertRaises(FacioException): instance.copy() mock_gitvcs.assert_called_with('git+/foo/bar')
def ensure_exception_if_directory_creation_fails(self, mock_os_mkdir): try: t = Template(self.config) t.copy_template() except Exception: assert True else: assert False self.config.cli_opts.error.assert_called_with( 'Error creating project directory') mock_os_mkdir.assert_called_with( os.path.join(t.working_dir, self.config.project_name))
def ensure_exception_if_directory_creation_fails(self, mock_os_mkdir): try: t = Template(self.config) t.copy_template() except Exception: assert True else: assert False self.config.cli_opts.error.assert_called_with( 'Error creating project directory') mock_os_mkdir.assert_called_with(os.path.join( t.working_dir, self.config.project_name))
def test_copy_shutil_error_raise_exception( self, mock_copy_tree, mock_pwd, mock_exit): instance = Template('/foo/bar') with self.assertRaises(FacioException): instance.copy() self.assertTrue(mock_exit.called) self.mocked_facio_exceptions_puts.assert_any_call( 'Error: Failed to copy /foo/bar to /tmp/foo')
def test_get_copy_ignore_globs(self): instance = Template('/foo/bar') instance.update_copy_ignore_globs(['*.png', '*.gif']) self.assertEqual(instance.get_copy_ignore_globs(), [ '.git', '.hg', '.svn', '.DS_Store', 'Thumbs.db', '*.png', '*.gif' ])
def test_exception_if_directory_creation_fails(self, mock_working_dir, mock_error, mock_os_mkdir): mock_working_dir.return_value = tempfile.gettempdir() tmp_dir = tempfile.mkdtemp(suffix=self.config.project_name, prefix='') tmp_dir_name = list(os.path.split(tmp_dir))[-1:][0] self.config.project_name = tmp_dir_name t = Template(self.config) t.copy_template() self.config._error.assert_called_with( 'Error creating project directory') mock_os_mkdir.assert_called_with( os.path.join(t.working_dir, self.config.project_name))
def test_exception_if_directory_creation_fails(self, mock_working_dir, mock_error, mock_os_mkdir): mock_working_dir.return_value = tempfile.gettempdir() tmp_dir = tempfile.mkdtemp(suffix=self.config.project_name, prefix='') tmp_dir_name = list(os.path.split(tmp_dir))[-1:][0] self.config.project_name = tmp_dir_name t = Template(self.config) t.copy_template() self.config._error.assert_called_with( 'Error creating project directory') mock_os_mkdir.assert_called_with(os.path.join( t.working_dir, self.config.project_name))
def test_copy_oserror_vcs_clone_returns_not_path( self, mock_copy_tree, mock_isdir, mock_gitvcs, mock_exit): instance = Template('git+/foo/bar') instance.COPY_ATTEMPT_LIMIT = 0 # Block the next copy call with self.assertRaises(FacioException): instance.copy() self.mocked_facio_exceptions_puts.assert_any_call( 'Error: New path to template not returned by GitVCS.clone()')
def ensure_copy_template_failes_if_dir_does_not_exist( self, mock_working_dir, mock_isdir): mock_working_dir.return_value = tempfile.gettempdir() tmp_dir = tempfile.mkdtemp(suffix=self.config.project_name, prefix='') tmp_dir_name = list(os.path.split(tmp_dir))[-1:][0] self.config.project_name = tmp_dir_name try: t = Template(self.config) t.copy_template() except: self.config.cli_opts.error.assert_called_with( 'Unable to copy template, directory does not exist') assert True else: assert False
def test_copy_shutil_oserror_raise_exception( self, mock_copy_tree, mock_isdir, mock_pwd, mock_exit): instance = Template('/foo/bar') with self.assertRaises(FacioException): instance.copy() mock_isdir.assert_called_with('/tmp/foo') self.assertTrue(mock_exit.called) self.mocked_facio_exceptions_puts.assert_any_call( 'Error: /tmp/foo already exists')
def test_copy_oserror_not_vcs_path_exception( self, mock_copy_tree, mock_isdir, mock_pwd, mock_exit): instance = Template('/foo/bar') with self.assertRaises(FacioException): instance.copy() mock_isdir.assert_called_with('/tmp/foo') self.assertTrue(mock_exit.called) self.mocked_facio_exceptions_puts.assert_any_call( 'Error: /foo/bar does not exist')
def test_rename(self, mock_move, mock_walk): mock_walk.return_value = [( '/foo', # Root ['{{PROJECT_NAME}}', 'baz'], # Dirs ['bar.py', '{{PROJECT_NAME}}.png', 'baz.gif'], # Files )] instance = Template('/foo/bar') instance.rename() self.assertEqual(self.mocked_facio_template_Template_out.call_count, 2) self.mocked_facio_template_Template_out.has_any_call( 'Renaming /foo/{{PROJECT_NAME}} to /foo/foo') self.mocked_facio_template_Template_out.has_any_call( 'Renaming /foo/{{PROJECT_NAME}}.png to /foo/foo.png')
def ensure_dir_cannot_be_created_if_already_exists(self, mock_working_dir): mock_working_dir.return_value = tempfile.gettempdir() tmp_dir = tempfile.mkdtemp(suffix=self.config.project_name, prefix='') tmp_dir_name = list(os.path.split(tmp_dir))[-1:][0] self.config.project_name = tmp_dir_name try: t = Template(self.config) t.copy_template() rmtree(tmp_dir) except Exception: assert True else: assert False self.config.cli_opts.error.assert_called_with('%s already exists' % ( tmp_dir))
def ensure_dir_cannot_be_created_if_already_exists(self, mock_working_dir): mock_working_dir.return_value = tempfile.gettempdir() tmp_dir = tempfile.mkdtemp(suffix=self.config.project_name, prefix='') tmp_dir_name = list(os.path.split(tmp_dir))[-1:][0] self.config.project_name = tmp_dir_name try: t = Template(self.config) t.copy_template() rmtree(tmp_dir) except Exception: assert True else: assert False self.config.cli_opts.error.assert_called_with('%s already exists' % (tmp_dir))
def test_render(self, mock_get_source, mock_walk): # Mock Setups - Fake file contents and open renderer files_map = { 'bar.py': '{{PROJECT_NAME}}', 'foo.bah': 'PNGIHDRÄIDATxÚcøûýhúÌIEND®B`', 'baz.html': '<h1>{{UNKNOWN|default(\'Hello World\')}}</h1>', 'baz.gif': 'I am a gif' } def get_source(environmet, template): """ Overriding Jinja2 FileSystemLoader get_source function so we can return our own source. """ if template == 'foo.bah': raise Exception('\'utf8\' codec can\'t decode byte ' '0x89 in position 0: invalid start ' 'byte') contents = files_map[template] return contents, template, True mock_get_source.side_effect = get_source mock_walk.return_value = [ ('/foo', [], [k for k, v in six.iteritems(files_map)]) ] open_mock = mock_open() open_patcher = patch('facio.template.open', open_mock, create=True) open_patcher.start() # Call the renderer method on facio.Template instance = Template('/foo/bar') instance.update_render_ignore_globs(['*.gif', ]) instance.render() # Assertions handle = open_mock() self.assertEqual(handle.write.call_count, 2) handle.write.assert_any_call('foo') handle.write.assert_any_call('<h1>Hello World</h1>') self.mocked_facio_template_Template_warning.assert_called_with( 'Failed to render /foo/foo.bah: \'utf8\' codec can\'t ' 'decode byte 0x89 in position 0: invalid start byte') # Stop the open patch open_patcher.stop()
def ensure_custom_variables_added_to_placeholders(self): self.config.variables = 'foo=bar,baz=1' t = Template(self.config) self.assertTrue('foo' in t.place_holders) self.assertEquals(t.place_holders['foo'], 'bar') self.assertTrue('baz' in t.place_holders) self.assertEquals(t.place_holders['baz'], '1')
def ensure_error_on_clone_exception(self, mock_repo_init): self.config.template = 'git+this/wont/work' try: Template(self.config) except: assert True else: assert False
def test_clone_git_repo(self, mock_working_dir): # Create a fake temp repo w/ commit git_dir = tempfile.mkdtemp(prefix='git') git.init(git_dir) try: f = open(os.path.join(git_dir, 'foo.txt'), 'w') f.write('blah') except IOError: assert False finally: f.close() cwd = os.getcwd() os.chdir(git_dir) git.add('foo.txt') if os.environ.get('TRAVIS_CI') == 'true': git.config('--global', 'user.email', '"*****@*****.**"') git.config('--global', 'user.name', '"Testing on Travis CI"') git.commit('-m "Added foo.txt"') os.chdir(cwd) # Fake Template Path mock_working_dir.return_value = tempfile.gettempdir() # Now attempt to clone but patch for Exception throw self.config.template = 'git+' + git_dir self.config._tpl = git_dir t = Template(self.config) t.copy_template() # Clean up rmtree(t.project_root) self.assertFalse(os.path.isdir(t.config.template)) self.assertFalse(self.config.cli_opts.error.called)
def run(self): """ Run the Facio processes. """ interface = CommandLineInterface() interface.start() config = ConfigurationFile() parsed = config.read() settings = Settings(interface, parsed) state.update_context_variables(settings.get_variables()) template = Template(settings.get_template_path()) template.update_copy_ignore_globs(settings.copy_ignore_globs()) template.update_render_ignore_globs(settings.render_ignore_globs()) template.copy() pipeline = Hook() pipeline.load(os.path.join(state.get_project_root(), HOOKS_FILE_NAME)) if pipeline.has_before(): pipeline.run_before() template.rename() template.render() if pipeline.has_after(): pipeline.run_after() self.success('Done')
def test_get_render_ignore_globs_empty_list(self): instance = Template('/foo/bar') del(instance.render_ignore_globs) self.assertEqual(instance.get_render_ignore_globs(), [])
def run(self): """ Run the Facio processes. """ interface = CommandLineInterface() interface.start() config = ConfigurationFile() parsed = config.read() settings = Settings(interface, parsed) state.update_context_variables(settings.get_variables()) template = Template(settings.get_template_path()) template.update_copy_ignore_globs(settings.copy_ignore_globs()) template.update_render_ignore_globs(settings.render_ignore_globs()) template.copy() pipeline = Hook() pipeline.load(os.path.join( state.get_project_root(), HOOKS_FILE_NAME)) if pipeline.has_before(): pipeline.run_before() template.rename() template.render() if pipeline.has_after(): pipeline.run_after() self.success('Done')
def should_handle_malformed_variables_gracefully(self): self.config.variables = 'this,is.wrong' t = Template(self.config) self.assertEquals(len(t.place_holders), 3)