diff --git a/app/commands/phpunit_command.py b/app/commands/phpunit_command.py index 4f1f676..78d4ecd 100644 --- a/app/commands/phpunit_command.py +++ b/app/commands/phpunit_command.py @@ -44,8 +44,21 @@ def _get_run_test_command(self, view): return command.replace(' ', ' ') def _build_command(self, test_path): - return self._plugin_settings.path_to_phpunit + ' ' + ' '.join(self._plugin_settings.cl_options) + ' ' \ - + test_path + if self._plugin_settings.xml_config: + config_file_option = self._find_most_appropriate_config_by_test_path(test_path) + else: + config_file_option = ' -c phpunit.xml ' + + return self._plugin_settings.path_to_phpunit + config_file_option + ' '.join( + self._plugin_settings.cl_options) + ' ' \ + + test_path + + def _find_most_appropriate_config_by_test_path(self, test_path): + for xml_config in self._plugin_settings.xml_config: + if test_path.startswith(xml_config['path']): + config_file_option = ' -c ' + xml_config['name'] + ' ' + + return config_file_option def _get_path_builder(self): return PathBuilder() diff --git a/app/path_builder.py b/app/path_builder.py index dac6358..4fc778d 100644 --- a/app/path_builder.py +++ b/app/path_builder.py @@ -1,10 +1,10 @@ class PathBuilder(): def build(self, filepath, root, path_to_tests): """ - Takes full filepath, root folder path, and relative unit tests folder path and returns a path to - corresponding test file. + Takes full filepath, root folder path, and relative tests folder path and returns a path to corresponding test + file. - :param string filepath: full path, including the filename, of the tested file + :param string filepath: full path, including the filename, of the tested file. Can also be a test file itself. :param string root: root folder of the project :param string path_to_tests: path to test folder, relative to root :return: string path to test file diff --git a/app/remote_phpunit_settings.py b/app/remote_phpunit_settings.py index 3d9288c..c20d8b0 100644 --- a/app/remote_phpunit_settings.py +++ b/app/remote_phpunit_settings.py @@ -21,6 +21,10 @@ def path_to_phpunit(self): def tests_folder(self): return self._get('tests_folder') + @property + def xml_config(self): + return self._get('xml_config') + def _get(self, name): settings = self._sublime.load_settings(self._settings_file) diff --git a/app/sublime_facade.py b/app/sublime_facade.py index 7cbfaed..e324b42 100644 --- a/app/sublime_facade.py +++ b/app/sublime_facade.py @@ -1,4 +1,7 @@ class SublimeFacade: + """ + Offers shortcut commands for some often used sublime actions. + """ def get_word_at_caret(self, view): return view.substr(view.word(view.sel()[0])) diff --git a/remote-phpunit.sublime-settings b/remote-phpunit.sublime-settings index d0160f6..1b39d27 100644 --- a/remote-phpunit.sublime-settings +++ b/remote-phpunit.sublime-settings @@ -1,13 +1,19 @@ { - // path to root of your project, if this is empty plugin uses the current sublime project root + // Path to root of your project, if this is empty plugin uses the current sublime project root "root": "", - // path to test folder, relative and starting from root + // Path to test folder, relative and starting from root "tests_folder": "tests", - // path to phpunit, relative and starting from root + // Path to phpunit, relative and starting from root "path_to_phpunit": "vendor/bin/phpunit", - // command line options + // Path to phpunit xml configuration file, relative and starting from root. + // It is possible to define different config files for different paths. Latter paths will override previous paths. + // Any paths beside the first one will only work when creating a command on files and folders inside the test folder. + "xml_config": [ + {"name": "phpunit.xml", "path": "tests"}, + {"name": "phpunit-integration.xml", "path": "tests/integration"} + ], + // Command line options "options": [ - "-c phpunit.xml", "--colors=\"always\"" ] } \ No newline at end of file diff --git a/tests/app/commands/test_phpunit_command.py b/tests/app/commands/test_phpunit_command.py index 5e3ae16..73b75df 100644 --- a/tests/app/commands/test_phpunit_command.py +++ b/tests/app/commands/test_phpunit_command.py @@ -19,11 +19,13 @@ def setUp(self): self._settings.tests_folder = 'tests/unit' self._settings.path_to_phpunit = 'path/to/phpunit' self._settings.cl_options = [] + self._settings.xml_config = None def test_get_command_when_root_defined_in_settings(self): self._command.create_run_test_command(self._view) - self.assertEqual('path/to/phpunit tests/unit/then/path/to/fileTest.php', self._sublime.text_pasted_to_clipboard) + self.assertEqual('path/to/phpunit -c phpunit.xml tests/unit/then/path/to/fileTest.php', + self._sublime.text_pasted_to_clipboard) def test_when_root_empty_in_settings_get_it_from_project_folder(self): self._settings.root = '' @@ -31,7 +33,8 @@ def test_when_root_empty_in_settings_get_it_from_project_folder(self): self._command.create_run_test_command(self._view) - self.assertEqual('path/to/phpunit tests/unit/then/path/to/fileTest.php', self._sublime.text_pasted_to_clipboard) + self.assertEqual('path/to/phpunit -c phpunit.xml tests/unit/then/path/to/fileTest.php', + self._sublime.text_pasted_to_clipboard) def test_if_empty_root_in_settings_and_no_project_opened_show_error_message_in_status_bar(self): self._view.project_folders = [] @@ -42,36 +45,49 @@ def test_if_empty_root_in_settings_and_no_project_opened_show_error_message_in_s self.assertEqual(u"Remote PHPUnit: could not find root folder", self._sublime.status_message_string) def test_get_command_with_cl_options(self): - self._settings.cl_options = ['-c config/phpunit.xml', '--colors=\"always\"'] - + self._settings.cl_options = ['--colors=\"always\"'] self._command.create_run_test_command(self._view) - self.assertEqual( - 'path/to/phpunit -c config/phpunit.xml --colors=\"always\" tests/unit/then/path/to/fileTest.php', + 'path/to/phpunit -c phpunit.xml --colors=\"always\" tests/unit/then/path/to/fileTest.php', self._sublime.text_pasted_to_clipboard) def test_get_filtered_run_test_command(self): - self.assert_correct_filter_set_for_run_filtered_test_command('wordAtCaret') - self.assert_correct_filter_set_for_run_filtered_test_command('differentWordAtCaret') + self._assert_correct_filter_set_for_run_filtered_test_command('wordAtCaret') + self._assert_correct_filter_set_for_run_filtered_test_command('differentWordAtCaret') def test_get_command_for_folder(self): dirs = ['C:/path/to/root/then/path/to/folder'] - window = self.get_window_stub('C:/path/to/root') + window = self._get_window_stub('C:/path/to/root') self._command.create_run_test_on_folder(dirs, window) self.assertEqual( - 'path/to/phpunit tests/unit/then/path/to/folder', + 'path/to/phpunit -c phpunit.xml tests/unit/then/path/to/folder', self._sublime.text_pasted_to_clipboard) def test_get_command_for_test_folder(self): dirs = ['C:/path/to/root/tests/unit/then/path/to/folder'] - window = self.get_window_stub('C:/path/to/root') + window = self._get_window_stub('C:/path/to/root') + + self._command.create_run_test_on_folder(dirs, window) + + self.assertEqual( + 'path/to/phpunit -c phpunit.xml tests/unit/then/path/to/folder', + self._sublime.text_pasted_to_clipboard) + + def test_get_command_for_test_folder_with_different_xml_config_file(self): + self._settings.xml_config = [ + {'name': 'phpunit.xml', 'path': 'tests'}, + {'name': 'phpunit-integration.xml', 'path': 'tests/integration'}, + ] + self._settings.tests_folder = 'tests' + dirs = ['C:/path/to/root/tests/integration/then/path/to/folder'] + window = self._get_window_stub('C:/path/to/root') self._command.create_run_test_on_folder(dirs, window) self.assertEqual( - 'path/to/phpunit tests/unit/then/path/to/folder', + 'path/to/phpunit -c phpunit-integration.xml tests/integration/then/path/to/folder', self._sublime.text_pasted_to_clipboard) def test_is_current_line_php_test_function_returns_true_if_file_is_php_test_file(self): @@ -92,7 +108,7 @@ def test_is_current_line_php_test_function_returns_true_if_line_contains_words_p def test_is_current_line_php_test_function_returns_false_if_current_line_is_not_function_line(self): self._view.file_name_to_return = 'AFileTest.php' - # Property current_line does not exist in view object but is used here to assert that view was sent as a + # Property current_line does not exist in sublime view object but is used here to assert that view was sent as a # parameter to SublimeFacade.get_line_at_caret() function self._view.current_line = 'a regular line of code where words "function" and "public" are not in correct order' self._command._sublime_facade.get_line_at_caret = lambda view: view.current_line @@ -115,7 +131,31 @@ def test_is_current_line_php_test_function_returns_false_if_file_is_not_php_test self._view.file_name_to_return = None self.assertFalse(self._command.is_current_line_php_test_function(self._view)) - def assert_correct_filter_set_for_run_filtered_test_command(self, expected_filter): + def test_if_no_xml_config_option_given_assume_standard_configuration_file_is_in_root(self): + self._command.create_run_test_command(self._view) + self.assertEqual('path/to/phpunit -c phpunit.xml tests/unit/then/path/to/fileTest.php', + self._sublime.text_pasted_to_clipboard) + + def test_single_xml_config_given(self): + self._settings.xml_config = [{'name': 'config/phpunit.xml', 'path': 'tests'}] + self._command.create_run_test_command(self._view) + self.assertEqual('path/to/phpunit -c config/phpunit.xml tests/unit/then/path/to/fileTest.php', + self._sublime.text_pasted_to_clipboard) + + def test_given_multiple_xml_config_files_find_most_appropriate_config_by_test_path(self): + self._settings.tests_folder = 'tests' + self._view.file_name_to_return = 'C:/path/to/root/tests/integration/path/to/fileTest.php' + self._settings.xml_config = [ + {'name': 'phpunit.xml', 'path': 'tests'}, + {'name': 'phpunit-integration.xml', 'path': 'tests/integration'}, + ] + + self._command.create_run_test_command(self._view) + + self.assertEqual('path/to/phpunit -c phpunit-integration.xml tests/integration/path/to/fileTest.php', + self._sublime.text_pasted_to_clipboard) + + def _assert_correct_filter_set_for_run_filtered_test_command(self, expected_filter): self._view.expected_filter = expected_filter self._command._sublime_facade = SublimeFacade() self._command._sublime_facade.get_word_at_caret = lambda view: view.expected_filter @@ -123,10 +163,10 @@ def assert_correct_filter_set_for_run_filtered_test_command(self, expected_filte self._command.create_run_filtered_test_command(self._view) self.assertEqual( - 'path/to/phpunit tests/unit/then/path/to/fileTest.php --filter ' + expected_filter, + 'path/to/phpunit -c phpunit.xml tests/unit/then/path/to/fileTest.php --filter ' + expected_filter, self._sublime.text_pasted_to_clipboard) - def get_window_stub(self, path_to_root): + def _get_window_stub(self, path_to_root): window = WindowStub() window.folders = lambda: path_to_root diff --git a/tests/app/test_remote_phpunit_settings.py b/tests/app/test_remote_phpunit_settings.py index 8253b5d..025bf06 100644 --- a/tests/app/test_remote_phpunit_settings.py +++ b/tests/app/test_remote_phpunit_settings.py @@ -9,7 +9,7 @@ def setUp(self): def test_correct_settings_file_is_loaded(self): self.settings.root - self.assertThatCorrectSublimeSettingsFileIsLoaded(self.settings, self.sublime.settings_file_to_load) + self._assertThatCorrectSublimeSettingsFileIsLoaded(self.settings, self.sublime.settings_file_to_load) def test_get_root(self): self.assertEqual(SublimeSettingsStub.ROOT_SETTING, self.settings.root) @@ -23,7 +23,10 @@ def test_get_path_to_phpunit(self): def test_get_tests_folder(self): self.assertEqual(SublimeSettingsStub.TESTS_FOLDER, self.settings.tests_folder) - def assertThatCorrectSublimeSettingsFileIsLoaded(self, settings, sublime_settings_file): + def test_get_xml_config(self): + self.assertEqual(SublimeSettingsStub.XML_CONFIG, self.settings.xml_config) + + def _assertThatCorrectSublimeSettingsFileIsLoaded(self, settings, sublime_settings_file): self.assertEqual(settings._settings_file, sublime_settings_file) @@ -42,6 +45,7 @@ class SublimeSettingsStub: CL_OPTIONS_SETTING = 'a command line option list...' PATH_TO_PHPUNIT = 'path to phpunit' TESTS_FOLDER = 'path to test folder' + XML_CONFIG = [{"name": "phpunit.xml", "path": "tests"}] def get(self, setting_name): if setting_name == 'root': @@ -56,4 +60,7 @@ def get(self, setting_name): if setting_name == 'tests_folder': return self.TESTS_FOLDER + if setting_name == 'xml_config': + return self.XML_CONFIG + return None