def test_task_dependencies_with_post_definition_injections_custom_names(self): import pybuilder.reactor with patch("pybuilder.reactor.Task"): @task def task1(): pass @task @depends(task1) def task2(): pass @task("task_3") @depends(task1) @dependents(task2) def task3(): pass module1 = ModuleType("mock_module_one") module1.task1 = task1 module1.task2 = task2 module2 = ModuleType("mock_module_two") module2.task3 = task3 self.reactor.collect_tasks_and_actions_and_initializers(module1) pybuilder.reactor.Task.assert_has_calls([call("task1", task1, [], ''), call("task2", task2, [TaskDependency(task1)], '')]) self.reactor.collect_tasks_and_actions_and_initializers(module2) pybuilder.reactor.Task.assert_has_calls([call("task_3", task3, [TaskDependency(task1)], '')]) self.execution_manager.register_late_task_dependencies.assert_has_calls( [call({}), call({"task2": [TaskDependency("task_3")]})])
def test_running_plugin_cram_from_target(self, execute_mock, read_file_mock, os_mock, report_mock, find_files_mock, command_mock ): project = Project('.') project.set_property('cram_run_test_from_target', True) project.set_property('dir_dist', 'python') project.set_property('dir_dist_scripts', 'scripts') project.set_property('verbose', False) logger = Mock() command_mock.return_value = ['cram'] find_files_mock.return_value = ['test1.cram', 'test2.cram'] report_mock.return_value = 'report_file' os_mock.copy.return_value = {} read_file_mock.return_value = ['test failes for file', '# results'] execute_mock.return_value = 0 run_cram_tests(project, logger) execute_mock.assert_called_once_with( ['cram', 'test1.cram', 'test2.cram'], 'report_file', error_file_name='report_file', env={'PYTHONPATH': './python:', 'PATH': './python/scripts:'} ) expected_info_calls = [call('Running Cram command line tests'), call('Cram tests were fine'), call('results'), ] self.assertEquals(expected_info_calls, logger.info.call_args_list)
def test_should_output_happypath_test_for_teamcity(self, output): with TeamCityTestProxy().and_test_name('important-test'): pass self.assertEqual(output.call_args_list, [ call("##teamcity[testStarted name='important-test']"), call("##teamcity[testFinished name='important-test']") ])
def test_should_render_verbose_task_list_with_descriptions(self, print_text_line): self.task_1.description = ["any", "description", "for", "task", "1"] self.task_2.description = ["any", "description", "for", "task", "2"] print_list_of_tasks(self.mock_reactor, quiet=False) print_text_line.assert_has_calls([call('Tasks found for project "any-project-name":'), call(' task-1 - any description for task 1'), call(' task-2 - any description for task 2')])
def test_should_set_default_properties(self, mock_execute_tests_matching): mock_project = Mock(Project) init_test_source_directory(mock_project) self.assertEqual(mock_project.set_property_if_unset.call_args_list, [call('dir_source_unittest_python', 'src/unittest/python'), call('pyfix_unittest_module_glob', '*_pyfix_tests'), call('pyfix_unittest_file_suffix', None)])
def test_should_raise_when_verifying_project_directory_and_build_descriptor_does_not_exist( self, os_path_abspath, os_path_exists, os_path_isdir, os_path_join ): self.assertRaises(PyBuilderException, self.reactor.verify_project_directory, "spam", "eggs") os_path_abspath.assert_called_with("spam") os_path_exists.assert_has_calls([call("spam"), call("spam/eggs")]) os_path_isdir.assert_called_with("spam") os_path_join.assert_called_with("spam", "eggs")
def test_should_render_verbose_task_list_with_dependencies(self, print_text_line): self.task_1.dependencies = ["any-dependency", "any-other-dependency"] print_list_of_tasks(self.mock_reactor, quiet=False) print_text_line.assert_has_calls([call('Tasks found for project "any-project-name":'), call(' task-1 - <no description available>'), call(' depends on tasks: any-dependency any-other-dependency'), call(' task-2 - <no description available>')])
def test_should_return_directory_and_full_path_of_descriptor_when_verifying_project_directory( self, os_path_abspath, os_path_exists, os_path_isdir, os_path_join, os_path_isfile ): self.assertEquals(("/spam", "/spam/eggs"), self.reactor.verify_project_directory("spam", "eggs")) os_path_abspath.assert_called_with("spam") os_path_exists.assert_has_calls([call("/spam"), call("/spam/eggs")]) os_path_isdir.assert_called_with("/spam") os_path_join.assert_called_with("/spam", "eggs") os_path_isfile.assert_called_with("/spam/eggs")
def test_should_output_failed_test_for_teamcity(self, output): with TeamCityTestProxy().and_test_name('important-test') as test: test.fails('booom') self.assertEqual(output.call_args_list, [ call("##teamcity[testStarted name='important-test']"), call("##teamcity[testFailed name='important-test' message='See details' details='booom']"), call("##teamcity[testFinished name='important-test']") ])
def test_should_check_that_sphinx_can_be_executed(self, mock_assert_can_execute): mock_logger = Mock(Logger) assert_sphinx_is_available(mock_logger) mock_assert_can_execute.assert_has_calls( [ call(['sphinx-build', '--version'], 'sphinx', 'plugin python.sphinx'), call(['sphinx-apidoc', '--version'], 'sphinx', 'plugin python.sphinx') ] )
def test_should_discover_source_files_when_test_sources_are_included(self, discover_python_files): project = Mock() project.get_property.side_effect = lambda _property: _property discover_affected_files(True, False, project) self.assertEqual(discover_python_files.call_args_list, [call('dir_source_main_python'), call('dir_source_unittest_python'), call('dir_source_integrationtest_python')])
def test_should_set_up_project_when_directories_missing(self, mock_os): scaffolding = PythonProjectScaffolding('some-project') mock_os.path.exists.return_value = False scaffolding.set_up_project() self.assertEqual(mock_os.makedirs.call_args_list, [ call('src/main/python'), call('src/unittest/python'), call('docs'), call('src/main/scripts') ])
def test_ensure_action_registered_for_two_tasks_is_executed_two_times(self): spam = Mock(name="spam", dependencies=[]) eggs = Mock(name="eggs", dependencies=[]) self.execution_manager.register_task(spam, eggs) action = Mock(name="action", execute_before=[], execute_after=["spam", "eggs"], only_once=False) self.execution_manager.register_action(action) self.execution_manager.resolve_dependencies() self.execution_manager.execute_execution_plan([spam, eggs]) action.execute.assert_has_calls([call(ANY), call(ANY)])
def test_should_discover_source_dirs_when_script_sources_are_included(self, _): project = Mock() project.get_property.side_effect = lambda _property: ( _property if _property != 'dir_source_integrationtest_python' else None) files = discover_affected_dirs(False, True, project) self.assertEqual(project.get_property.call_args_list, [call('dir_source_main_python'), call('dir_source_main_scripts'), call('dir_source_main_scripts')]) self.assertEqual(files, ['dir_source_main_python', 'dir_source_main_scripts'])
def test_sphinx_generate(self, execute_command, mkdir, exists, rmtree, open ): execute_command.return_value = 0 exists.return_value = True sphinx_mock = Mock() sys.modules["sphinx"] = sphinx_mock try: sphinx_mock.version_info = (1, 5, 3, 4, 5) self.project.set_property("sphinx_source_dir", "sphinx_source_dir") self.project.set_property("sphinx_config_path", "sphinx_config_path") self.project.set_property("sphinx_output_dir", "sphinx_output_dir") self.project.set_property("dir_target", "dir_target") self.project.set_property("dir_source_main_python", "dir_source") self.project.set_property("sphinx_project_name", "project_name") self.project.set_property("sphinx_project_conf", {"a": 1, "b": "foo"}) self.project.set_property("sphinx_run_apidoc", True) self.project.set_property("sphinx_doc_builder", ['JSONx', 'pdf']) sphinx_generate(self.project, Mock()) finally: del sys.modules["sphinx"] exists.assert_called_with(nc("basedir/dir_target/sphinx_pyb/apidoc")) rmtree.assert_called_with(nc("basedir/dir_target/sphinx_pyb/apidoc")) mkdir.assert_called_with(nc("basedir/dir_target/sphinx_pyb/apidoc")) print(open().__enter__().write.call_args_list) open().__enter__().write.assert_has_calls([call("a = 1\n"), call("b = 'foo'\n"), call( "\nimport sys\nsys.path.insert(0, %r)\n" % nc("basedir/dir_source"))], any_order=True) execute_command.assert_has_calls([ call([sys.executable, '-m', 'sphinx.apidoc', '-H', 'project_name', '-o', nc('basedir/dir_target/sphinx_pyb/apidoc'), nc('basedir/dir_source')] if sys.version_info[:2] < (3, 3) else [sys.executable, '-m', 'sphinx.apidoc', '-H', 'project_name', '--implicit-namespaces', '-o', nc('basedir/dir_target/sphinx_pyb/apidoc'), nc('basedir/dir_source')], nc('basedir/dir_target/reports/sphinx-apidoc'), shell=False), call([sys.executable, '-m', 'sphinx', '-b', 'JSONx', nc('basedir/sphinx_config_path'), nc('basedir/sphinx_output_dir/JSONx')], nc('basedir/dir_target/reports/sphinx_JSONx'), shell=False), call([sys.executable, '-m', 'sphinx', '-b', 'pdf', nc('basedir/sphinx_config_path'), nc('basedir/sphinx_output_dir/pdf')], nc('basedir/dir_target/reports/sphinx_pdf'), shell=False)])
def test_should_write_pydev_files(self, os, mock_open): project = Project('basedir', name='pybuilder') project.set_property('dir_source_main_python', 'src/main/python') init_pydev_plugin(project) mock_open.return_value = MagicMock(spec=TYPE_FILE) os.path.join.side_effect = lambda first, second: first + '/' + second pydev_generate(project, Mock()) self.assertEqual(mock_open.call_args_list, [call('basedir/.project', 'w'), call('basedir/.pydevproject', 'w')]) metadata_file = mock_open.return_value.__enter__.return_value self.assertEqual(metadata_file.write.call_args_list, [call("""<?xml version="1.0" encoding="UTF-8"?> <!-- This file has been generated by the PyBuilder Pydev Plugin --> <projectDescription> <name>pybuilder</name> <comment></comment> <projects> </projects> <buildSpec> <buildCommand> <name>org.python.pydev.PyDevBuilder</name> <arguments> </arguments> </buildCommand> </buildSpec> <natures> <nature>org.python.pydev.pythonNature</nature> </natures> </projectDescription> """), call("""<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?eclipse-pydev version="1.0"?> <!-- This file has been generated by the PyBuilder Pydev Plugin --> <pydev_project> <pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property> <pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property> <pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH"> \t\t<path>/pybuilder/src/main/python</path> </pydev_pathproperty> </pydev_project> """)])
def test_running_plugin_fails( self, read_file_mock, report_mock, find_files_mock, command_mock, tail_mock, ): project = Project('.') project.set_property('verbose', False) project.set_property('dir_source_main_python', 'python') project.set_property('dir_source_main_scripts', 'scripts') logger = Mock() reactor = Mock() reactor.python_env_registry = {} reactor.python_env_registry["pybuilder"] = pyb_env = Mock() reactor.pybuilder_venv = pyb_env pyb_env.environ = {} pyb_env.executable = ["a/b"] execute_mock = pyb_env.execute_command = Mock() command_mock.return_value = ['cram'] find_files_mock.return_value = ['test1.cram', 'test2.cram'] report_mock.return_value = 'report_file' read_file_mock.return_value = ['test failes for file', '# results'] execute_mock.return_value = 1 tail_mock.return_value = "tail data" self.assertRaises(BuildFailedException, run_cram_tests, project, logger, reactor) execute_mock.assert_called_once_with( ['a/b', 'cram', 'test1.cram', 'test2.cram'], 'report_file', error_file_name='report_file', env={ 'PYTHONPATH': np(jp(project.basedir, 'python')) + pathsep, 'PATH': np(jp(project.basedir, 'scripts')) + pathsep }) expected_info_calls = [ call('Running Cram command line tests'), ] expected_error_calls = [ call( 'Cram tests failed! See report_file for full details:\ntail data' ), ] self.assertEqual(expected_info_calls, logger.info.call_args_list) self.assertEqual(expected_error_calls, logger.error.call_args_list)
def test_should_discover_source_dirs_when_test_sources_are_included_no_integrationtests(self, _): project = Mock() project.get_property.side_effect = lambda \ _property: _property if _property != 'dir_source_integrationtest_python' else None files = discover_affected_dirs(True, False, project) self.assertEqual(project.get_property.call_args_list, [call('dir_source_main_python'), call('dir_source_unittest_python'), call('dir_source_unittest_python'), call('dir_source_integrationtest_python')]) self.assertEquals(files, ['dir_source_main_python', 'dir_source_unittest_python'])
def test_running_plugin_failure_no_tests(self, execute_mock, read_file_mock, os_mock, report_mock, find_files_mock, command_mock ): project = Project('.') project.set_property('verbose', True) project.set_property('dir_source_main_python', 'python') project.set_property('dir_source_main_scripts', 'scripts') project.set_property("cram_fail_if_no_tests", True) logger = Mock() command_mock.return_value = ['cram'] find_files_mock.return_value = [] report_mock.return_value = 'report_file' os_mock.copy.return_value = {} read_file_mock.return_value = ['test failes for file', '# results'] execute_mock.return_value = 1 self.assertRaises( BuildFailedException, run_cram_tests, project, logger) execute_mock.assert_not_called() expected_info_calls = [call('Running Cram command line tests'), ] self.assertEquals(expected_info_calls, logger.info.call_args_list)
def test_running_plugin_failure_no_tests(self, read_file_mock, report_mock, find_files_mock, command_mock): project = Project('.') project.set_property('verbose', True) project.set_property('dir_source_main_python', 'python') project.set_property('dir_source_main_scripts', 'scripts') project.set_property("cram_fail_if_no_tests", True) project._plugin_env = {} logger = Mock() reactor = Mock() reactor.python_env_registry = {} reactor.python_env_registry["pybuilder"] = pyb_env = Mock() pyb_env.environ = {} execute_mock = pyb_env.execute_command = Mock() command_mock.return_value = ['cram'] find_files_mock.return_value = [] report_mock.return_value = 'report_file' read_file_mock.return_value = ['test failes for file', '# results'] execute_mock.return_value = 1 self.assertRaises(BuildFailedException, run_cram_tests, project, logger, reactor) execute_mock.assert_not_called() expected_info_calls = [ call('Running Cram command line tests'), ] self.assertEqual(expected_info_calls, logger.info.call_args_list)
def test_should_discover_source_files_when_test_sources_are_included_and_only_integrationtests(self, discover_python_files): project = Mock() def get_property(property): if property == 'dir_source_unittest_python': return None return property project.get_property.side_effect = get_property discover_affected_files(True, False, project) self.assertEqual(discover_python_files.call_args_list, [call('dir_source_main_python'), call('dir_source_integrationtest_python')])
def test_should_execute_external_command_and_return_execution_result(self, execution, read): execution.return_value = 0, '/tmp/reports/command-name' read.side_effect = lambda argument: { '/tmp/reports/command-name': ['Running...', 'OK all done!'], '/tmp/reports/command-name.err': ['Oh no! I am not python8 compatible!', 'I will explode now.'] }[argument] logger = Mock() result = self.command.run_on_production_source_files(logger) self.assertEqual(result.exit_code, 0) self.assertEqual(result.report_file, '/tmp/reports/command-name') self.assertEqual(read.call_args_list[0], call('/tmp/reports/command-name')) self.assertEqual(result.report_lines, ['Running...', 'OK all done!']) self.assertEqual(result.error_report_file, '/tmp/reports/command-name.err') self.assertEqual(read.call_args_list[1], call('/tmp/reports/command-name.err')) self.assertEqual(result.error_report_lines, ['Oh no! I am not python8 compatible!', 'I will explode now.'])
def test_should_prompt_user_with_defaults(self, prompt, os): os.path.basename.return_value = 'project' collect_project_information() self.assertEqual(prompt.call_args_list, [ call('Project name', 'project'), call('Source directory', 'src/main/python'), call('Docs directory', 'docs'), call('Unittest directory', 'src/unittest/python'), call('Scripts directory', 'src/main/scripts'), call('Use plugin python.flake8 (Y/n)?', 'y'), call('Use plugin python.coverage (Y/n)?', 'y'), call('Use plugin python.distutils (Y/n)?', 'y') ])
def test_running_plugin_fails_with_verbose(self, execute_mock, read_file_mock, os_mock, report_mock, find_files_mock, command_mock ): project = Project('.') project.set_property('verbose', True) project.set_property('dir_source_main_python', 'python') project.set_property('dir_source_main_scripts', 'scripts') logger = Mock() command_mock.return_value = ['cram'] find_files_mock.return_value = ['test1.cram', 'test2.cram'] report_mock.return_value = 'report_file' os_mock.copy.return_value = {} read_file_mock.return_value = ['test failes for file', '# results'] execute_mock.return_value = 1 self.assertRaises( BuildFailedException, run_cram_tests, project, logger) execute_mock.assert_called_once_with( ['cram', 'test1.cram', 'test2.cram'], 'report_file', error_file_name='report_file', env={'PYTHONPATH': './python:', 'PATH': './scripts:'} ) expected_info_calls = [call('Running Cram command line tests'), ] expected_error_calls = [call('Cram tests failed!'), call('test failes for file'), call('# results'), call("See: 'report_file' for details"), ] self.assertEquals(expected_info_calls, logger.info.call_args_list) self.assertEquals(expected_error_calls, logger.error.call_args_list)
def test_shortest_execution_plan_executed(self): one = Mock(name="one", dependencies=[]) two = Mock(name="two", dependencies=[TaskDependency("one")]) three = Mock(name="three", dependencies=[TaskDependency("two")]) self.execution_manager.register_task(one, two, three) self.execution_manager.resolve_dependencies() self.execution_manager.execute_execution_plan(self.execution_manager.build_execution_plan("two")) one.execute.assert_has_calls([call(ANY, {})]) two.execute.assert_has_calls([call(ANY, {})]) three.execute.assert_not_called() self.execution_manager.execute_execution_plan(self.execution_manager.build_shortest_execution_plan("three")) one.execute.assert_has_calls([call(ANY, {})]) two.execute.assert_has_calls([call(ANY, {})]) three.execute.assert_has_calls([call(ANY, {})]) self.execution_manager.execute_execution_plan(self.execution_manager.build_shortest_execution_plan("three")) one.execute.assert_has_calls([call(ANY, {})]) two.execute.assert_has_calls([call(ANY, {})]) three.execute.assert_has_calls([call(ANY, {}), call(ANY, {})])
def test_task_dependencies(self): import pybuilder.reactor with patch("pybuilder.reactor.Task"): @task def task1(): pass @task @depends(task1) def task2(): pass @task def task3(): pass @task @depends(optional(task3)) @dependents("task6") def task4(): pass @task @dependents("task6", optional(task3)) def task5(): pass @task @depends(task1, optional(task2)) def task6(): pass module = ModuleType("mock_module") module.task1 = task1 module.task2 = task2 module.task3 = task3 module.task4 = task4 module.task5 = task5 module.task6 = task6 self.reactor.collect_tasks_and_actions_and_initializers(module) pybuilder.reactor.Task.assert_has_calls([call("task1", task1, [], ''), call("task2", task2, [TaskDependency(task1)], ''), call("task3", task3, [TaskDependency(task5, True)], ''), call("task4", task4, [TaskDependency(task3, True)], ''), call("task5", task5, [], ''), call("task6", task6, [TaskDependency(task1), TaskDependency(task2, True), TaskDependency(task4), TaskDependency(task5)], '')])
def test_should_warn_when_report_lines_present(self): logger = Mock() log_report(logger, 'name', ['line1 ', 'line 2 ']) self.assertEqual(logger.warn.call_args_list, [call('name: line1'), call('name: line 2')])
def test_should_render_verbose_task_list_without_descriptions_and_dependencies(self, print_text_line): print_list_of_tasks(self.mock_reactor, quiet=False) print_text_line.assert_has_calls([call('Tasks found for project "any-project-name":'), call(' task-1 - <no description available>'), call(' task-2 - <no description available>')])