def _create_language_module(language: str, tasks: Optional[Sequence[Task]] = None ) -> Language: result = Language({}, language) if tasks is not None: result.tasks = tasks return result
def test_handle_project_resolution(self, tmpdir): directory = Path(str(tmpdir)) name = 'name.txt' path = directory / name mock_project = MagicMock() mock_project.get_config.return_value = None mock_cache = MagicMock() mock_cache.names = ['a name'] mock_cache.get_project.return_value = mock_project language = Language({}, 'lang') language.project_as_dist_path = MagicMock(return_value=None) context = DependencyContext([], language, Configuration({}, [], mock_cache)) assert context._handle_project_resolution('', name) is None language.project_as_dist_path = MagicMock(return_value=directory) assert context._handle_project_resolution('', name) is None path.write_text("") assert context._handle_project_resolution('', name) == path
def test_resolve_no_dependencies(self): language = Language({}, 'lang') context = DependencyContext([], language, Configuration({}, [], None)) language.resolver = MagicMock() assert context.resolve() == []
def test_resolve_duplicates(self): dep = _make_dep() path = Path('/path/to/file.txt') language = Language({}, 'lang') path_set = DependencyPathSet(dep, path) context = DependencyContext([dep, dep], language, Configuration({}, [], None)) language.resolver = MagicMock(return_value=path_set) assert context.resolve() == [path_set] language.resolver.assert_called_once_with(context, dep)
def test_resolve_to_nothing(self): dep = _make_dep(name='resolve-to-nothing') language = Language({}, 'lang') context = DependencyContext([dep], language, Configuration({}, [], None)) language.resolver = MagicMock(return_value=None) with pytest.raises(ValueError) as info: context.resolve() assert info.value.args[0] == 'Dependency path:\nresolve-to-nothing:resolve-to-nothing:1.2.3\nThe dependency, ' \ 'resolve-to-nothing:resolve-to-nothing:1.2.3, could not be resolved.' language.resolver.assert_called_once_with(context, dep)
def test_format_args_task_config(self): config = {'lib_target': 'library'} project = Project.from_dir(Path('/path/to/project')) engine = Engine(project) module = Language(None, 'java') task = Task('myTask', func_task_config) mock_get_config = MagicMock() mock_get_config.return_value = config project.get_config = mock_get_config # noinspection PyProtectedMember args, kwargs = engine._format_args(module, task) assert args == [config] assert kwargs == {} task.function = func_named_task_config # noinspection PyProtectedMember args, kwargs = engine._format_args(module, task) assert args == [] assert kwargs == {'task_config': config}
def test_fetch_file(self): remote_dep = _make_dep(location='remote') local_dep = _make_dep(location='local') project_dep = _make_dep(location='project') p1 = Path('path1') p2 = Path('path2') p3 = Path('path3') context = DependencyContext([], Language({}, 'lang'), Configuration({}, [], None)) context._handle_remote_resolution = MagicMock(return_value=p1) context._handle_local_resolution = MagicMock(return_value=p2) context._handle_project_resolution = MagicMock(return_value=p3) r1 = context._fetch_file(remote_dep, 'remote.name') r2 = context._fetch_file(local_dep, 'local.name') r3 = context._fetch_file(project_dep, 'project.name') context._handle_remote_resolution.assert_called_once_with( 'remote.name') context._handle_local_resolution.assert_called_once_with('local.name') context._handle_project_resolution.assert_called_once_with( 'dep', 'project.name') assert r1 is p1 assert r2 is p2 assert r3 is p3
def add_task(containing_module: Language, new_task: Task): if new_task.name not in task_names: for required_task_name in new_task.require: add_task(containing_module, containing_module.get_task(required_task_name)) task_names.append(new_task.name) full_task_list.append((containing_module, new_task))
def test_read_pom_for_dependencies_no_dependencies(self): """Make sure we generate no dependencies when none exist.""" pom_path = get_test_path('java/junit-2.pom.xml') context = DependencyContext([], Language({}, 'lang'), Configuration({}, [], None)) read_pom_for_dependencies(pom_path, context, self._parent_dependency()) assert context.is_empty()
def test_resolve_no_resolver(self): context = DependencyContext([], Language({}, 'lang'), Configuration({}, [], None)) with pytest.raises(ValueError) as info: context.resolve() assert info.value.args[ 0] == 'The language, lang, does not provide a means of resolving dependencies.'
def test_resolve_version_mismatch(self): dep1 = _make_dep(version='1.2.3') dep2 = _make_dep(version='4.5.6') path = Path('/path/to/file.txt') language = Language({}, 'lang') path_set = DependencyPathSet(dep1, path) context = DependencyContext([dep1, dep2], language, Configuration({}, [], None)) language.resolver = MagicMock(return_value=path_set) with pytest.raises(ValueError) as info: context.resolve() assert info.value.args[0] == 'The same library, name:name, is required at two different versions, 1.2.3 vs. ' \ '4.5.6.' language.resolver.assert_called_once_with(context, dep1)
def test_handle_project_resolution_missing_function(self): context = DependencyContext([], Language({}, 'lang'), Configuration({}, [], None)) with pytest.raises(ValueError) as info: context._handle_project_resolution('', 'name.txt') assert info.value.args[0] == 'The language, lang, does not provide a means of resolving project-based ' \ 'dependencies.'
def test_construction(self): deps = [] language = Language({}, 'lang') context = DependencyContext(deps, language, Configuration({}, [], None)) assert context._dependencies == deps assert context._dependencies is not deps assert context._language is language
def test_format_args_no_args(self): project = Project.from_dir(Path('/path/to/project')) engine = Engine(project) module = Language(None, 'java') task = Task('myTask', func_no_args) # noinspection PyProtectedMember args, kwargs = engine._format_args(module, task) assert args == [] assert kwargs == {}
def test_to_local_file_no_path(self): mock_fetch = MagicMock(return_value=None) dep = _make_dep() context = DependencyContext([], Language({}, 'lang'), Configuration({}, [], None)) context._fetch_file = mock_fetch assert context.to_local_path(dep, 'file.txt') is None mock_fetch.assert_called_once_with(dep, 'file.txt')
def test_add_dependency(self): dep = _make_dep() context = DependencyContext([], Language({}, 'lang'), Configuration({}, [], None)) context._resolve = MagicMock() assert dep.transient is False assert len(context._dependencies) == 0 context.add_dependency(dep) assert dep.transient is True
def test_format_args_dependencies(self): project = Project.from_dir(Path('/path/to/project')) engine = Engine(project) module = Language(None, 'java') task = Task('myTask', func_dependencies) module.resolver = MagicMock(return_value=None) # noinspection PyProtectedMember args, kwargs = engine._format_args(module, task) assert args == [[]] assert kwargs == {} task.function = func_named_dependencies # noinspection PyProtectedMember args, kwargs = engine._format_args(module, task) assert args == [] assert kwargs == {'dependencies': []}
def test_to_local_file_empty_signatures(self): path = 'file.txt' mock_fetch = MagicMock(return_value=path) dep = _make_dep() context = DependencyContext([], Language({}, 'lang'), Configuration({}, [], None)) context._fetch_file = mock_fetch assert context.to_local_path(dep, 'file.txt', {}) is path mock_fetch.assert_called_once_with(dep, 'file.txt')
def test_with_function(self): class FakeModule(object): @staticmethod def define_language(lang: Language): lang.tasks = [Task('task', None)] module = FakeModule() language = Language(module, 'lang') assert language.language == 'lang' assert len(language.tasks) == 1 assert language.tasks[0].name == 'task'
def test_create_dependency_context_for(self): dep_set = DependencySet(_set_test_data) context = dep_set.create_dependency_context_for( 'bogus', Language(None, 'fake'), Configuration({}, [], None)) assert context.is_empty() is True context = dep_set.create_dependency_context_for( 'task', Language(None, 'fake'), Configuration({}, [], None)) assert context.is_empty() is False assert len(context._dependencies) == 2 dep1 = context._dependencies[0] dep2 = context._dependencies[1] # Make sure order is correct for consistent testing. if dep1.name == 'dep2': dep1, dep2 = dep2, dep1 _assert_dep(dep1, 'remote', 'dep1', 'dep1', '1.2.3', False, ['task']) _assert_dep(dep2, 'local', 'dep2', 'dep2', '4.5.6', False, ['task'])
def test_handle_local_resolution(self, tmpdir): directory = Path(str(tmpdir)) good_name = 'file.txt' bad_name = 'no-such-file.txt' existing_file = directory / good_name existing_file.write_text("") context = DependencyContext([], Language({}, 'lang'), Configuration({}, [directory], None)) assert context._handle_local_resolution(bad_name) is None assert context._handle_local_resolution(good_name) == existing_file
def test_get_language_config(self): config = {'lib_target': 'library'} project = Project.from_dir(Path('/path/to/project')) engine = Engine(project) module = Language(None, 'java') mock_get_config = MagicMock() mock_get_config.return_value = config project.get_config = mock_get_config # noinspection PyProtectedMember assert engine._get_language_config(module) == config assert mock_get_config.mock_calls == [call('java', None, None)]
def test_to_local_file_good_passed_signatures(self, tmpdir): directory = Path(str(tmpdir)) path = directory / 'file.txt' mock_fetch = MagicMock(return_value=path) dep = _make_dep() context = DependencyContext([], Language({}, 'lang'), Configuration({}, [], None)) context._fetch_file = mock_fetch path.write_text("file content.\n") signatures = sign_path(path) assert context.to_local_path(dep, 'file.txt', signatures) is path assert mock_fetch.mock_calls == [call(dep, 'file.txt')]
def get_language_module(language: str) -> Optional[Language]: """ A function for loading the support module for a language. This isn't considered fatal since a task error will likely occur. This gives the end user the most information. Especially since this is most likely to occur when a language is added via the ``--language`` command line option. If a support module cannot be loaded, a warning is printed and ``None`` is returned. :param language: the language to load the support module for. :return: the loaded task module or ``None``. """ try: return Language(_import_module(f'builder.{language}'), language) except ModuleNotFoundError as exception: warn(f'Exception loading module for {language}: {str(exception)}') return None
def test_remote_info(self): path = Path('.') context = DependencyContext([], Language({}, 'lang'), Configuration({}, [], None)) resolver = RemoteResolver('the url', path) assert context._remote_resolver is None context.set_remote_resolver(resolver) assert context._remote_resolver is resolver resolver = RemoteResolver('http://server/path/', path) context.set_remote_resolver(resolver) assert context._remote_resolver is resolver
def test_to_local_file_bad_passed_signatures(self, tmpdir): directory = Path(str(tmpdir)) path = directory / 'file.txt' mock_fetch = MagicMock(return_value=path) dep = _make_dep() context = DependencyContext([], Language({}, 'lang'), Configuration({}, [], None)) context._fetch_file = mock_fetch path.write_text("file content.\n") with pytest.raises(ValueError) as info: context.to_local_path(dep, 'file.txt', {'sha512': 'bad-signature'}) assert info.value.args[ 0] == 'Dependency path:\n\nCould not verify the signature of the file file.txt.' assert mock_fetch.mock_calls == [call(dep, 'file.txt')]
def test_handle_remote_resolution(self): name = 'file.txt' parent_url = 'http://server/path/to' url = parent_url + '/' + name parent_path = Path('path/to') file = parent_path / name return_value = Path('/resolved/path/to/' + name) context = DependencyContext([], Language({}, 'lang'), Configuration({}, [], None)) resolver = RemoteResolver(parent_url, parent_path) resolver._resolve_remotely = MagicMock(return_value=return_value) context.set_remote_resolver(resolver) rv = context._handle_remote_resolution(name) resolver._resolve_remotely.assert_called_once_with(url, file) assert rv is return_value
def test_format_args_dependencies_not_accepted(self): project = Project.from_dir(Path('/path/to/project')) dependency = Dependency('name', { 'location': 'remote', 'version': '1.2.3', 'scope': 'myTask' }) project.get_dependencies()._dependencies = {'name': dependency} engine = Engine(project) module = Language(None, 'java') task = Task('myTask', func_no_args) with patch('builder.engine.end') as mock_end: # noinspection PyProtectedMember _, _ = engine._format_args(module, task) assert mock_end.mock_calls == [ call( 'Dependencies were specified for task myTask but it does not accept dependencies.' ) ]
def test_execute_tasks(self): project = Project.from_dir(Path('/path/to/project')) engine = Engine(project) module = Language(None, 'java') et = MagicMock() task1 = Task('task1', MagicMock()) task2 = Task('task2', None) task3 = Task('task3', MagicMock()) tasks = [(module, task1), (module, task2), (module, task3)] engine._execute_task = et with patch('builder.engine.out') as mock_out: # noinspection PyProtectedMember engine._execute_tasks(tasks) assert et.mock_calls == [call(module, task1), call(module, task3)] assert mock_out.mock_calls == [ call('--> task1', fg='bright_green'), call('--> task2', fg='bright_green'), call('--> task3', fg='bright_green') ]
def test_to_local_file_good_file_signatures(self, tmpdir): directory = Path(str(tmpdir)) path = directory / 'file.txt' file_names = ['file.txt'] file_names.extend([f'file.txt.{sn}' for sn in supported_signatures]) mock_fetch = MagicMock( side_effect=[directory / name for name in file_names]) dep = _make_dep() context = DependencyContext([], Language({}, 'lang'), Configuration({}, [], None)) context._fetch_file = mock_fetch file_names = ['file.txt'] file_names.extend([f'file.txt.{sn}' for sn in supported_signatures]) path.write_text("file content.\n") sign_path_to_files(path) assert context.to_local_path(dep, 'file.txt') == path assert mock_fetch.mock_calls == [ call(dep, 'file.txt'), call(dep, f'file.txt.{supported_signatures[0]}') ]