1"""Tests for flake8.plugins.manager.PluginTypeManager.""" 2from unittest import mock 3 4import pytest 5 6from flake8 import exceptions 7from flake8.plugins import manager 8 9TEST_NAMESPACE = "testing.plugin-type-manager" 10 11 12def create_plugin_mock(raise_exception=False): 13 """Create an auto-spec'd mock of a flake8 Plugin.""" 14 plugin = mock.create_autospec(manager.Plugin, instance=True) 15 if raise_exception: 16 plugin.load_plugin.side_effect = exceptions.FailedToLoadPlugin( 17 plugin_name="T101", 18 exception=ValueError("Test failure"), 19 ) 20 return plugin 21 22 23def create_mapping_manager_mock(plugins): 24 """Create a mock for the PluginManager.""" 25 # Have a function that will actually call the method underneath 26 def fake_map(func): 27 for plugin in plugins: 28 yield func(plugin) 29 30 # Mock out the PluginManager instance 31 manager_mock = mock.Mock(spec=["map"]) 32 # Replace the map method 33 manager_mock.map = fake_map 34 return manager_mock 35 36 37class FakeTestType(manager.PluginTypeManager): 38 """Fake PluginTypeManager.""" 39 40 namespace = TEST_NAMESPACE 41 42 43@mock.patch("flake8.plugins.manager.PluginManager", autospec=True) 44def test_instantiates_a_manager(PluginManager): # noqa: N803 45 """Verify we create a PluginManager on instantiation.""" 46 FakeTestType() 47 48 PluginManager.assert_called_once_with(TEST_NAMESPACE, local_plugins=None) 49 50 51@mock.patch("flake8.plugins.manager.PluginManager", autospec=True) 52def test_proxies_names_to_manager(PluginManager): # noqa: N803 53 """Verify we proxy the names attribute.""" 54 PluginManager.return_value = mock.Mock(names=["T100", "T200", "T300"]) 55 type_mgr = FakeTestType() 56 57 assert type_mgr.names == ["T100", "T200", "T300"] 58 59 60@mock.patch("flake8.plugins.manager.PluginManager", autospec=True) 61def test_proxies_plugins_to_manager(PluginManager): # noqa: N803 62 """Verify we proxy the plugins attribute.""" 63 PluginManager.return_value = mock.Mock(plugins=["T100", "T200", "T300"]) 64 type_mgr = FakeTestType() 65 66 assert type_mgr.plugins == ["T100", "T200", "T300"] 67 68 69def test_generate_call_function(): 70 """Verify the function we generate.""" 71 optmanager = object() 72 plugin = mock.Mock(method_name=lambda x: x) 73 func = manager.PluginTypeManager._generate_call_function( 74 "method_name", 75 optmanager, 76 ) 77 78 assert callable(func) 79 assert func(plugin) is optmanager 80 81 82@mock.patch("flake8.plugins.manager.PluginManager", autospec=True) 83def test_load_plugins(PluginManager): # noqa: N803 84 """Verify load plugins loads *every* plugin.""" 85 # Create a bunch of fake plugins 86 plugins = [ 87 create_plugin_mock(), 88 create_plugin_mock(), 89 create_plugin_mock(), 90 create_plugin_mock(), 91 create_plugin_mock(), 92 create_plugin_mock(), 93 create_plugin_mock(), 94 create_plugin_mock(), 95 ] 96 # Return our PluginManager mock 97 PluginManager.return_value = create_mapping_manager_mock(plugins) 98 99 type_mgr = FakeTestType() 100 # Load the tests (do what we're actually testing) 101 assert len(type_mgr.load_plugins()) == 8 102 # Assert that our closure does what we think it does 103 for plugin in plugins: 104 plugin.load_plugin.assert_called_once_with() 105 assert type_mgr.plugins_loaded is True 106 107 108@mock.patch("flake8.plugins.manager.PluginManager") 109def test_load_plugins_fails(PluginManager): # noqa: N803 110 """Verify load plugins bubbles up exceptions.""" 111 plugins = [ 112 create_plugin_mock(), 113 create_plugin_mock(True), 114 create_plugin_mock(), 115 create_plugin_mock(), 116 create_plugin_mock(), 117 create_plugin_mock(), 118 create_plugin_mock(), 119 create_plugin_mock(), 120 ] 121 # Return our PluginManager mock 122 PluginManager.return_value = create_mapping_manager_mock(plugins) 123 124 type_mgr = FakeTestType() 125 with pytest.raises(exceptions.FailedToLoadPlugin): 126 type_mgr.load_plugins() 127 128 # Assert we didn't finish loading plugins 129 assert type_mgr.plugins_loaded is False 130 # Assert the first two plugins had their load_plugin method called 131 plugins[0].load_plugin.assert_called_once_with() 132 plugins[1].load_plugin.assert_called_once_with() 133 # Assert the rest of the plugins were not loaded 134 for plugin in plugins[2:]: 135 assert plugin.load_plugin.called is False 136 137 138@mock.patch("flake8.plugins.manager.PluginManager") 139def test_register_options(PluginManager): # noqa: N803 140 """Test that we map over every plugin to register options.""" 141 plugins = [ 142 create_plugin_mock(), 143 create_plugin_mock(), 144 create_plugin_mock(), 145 create_plugin_mock(), 146 create_plugin_mock(), 147 create_plugin_mock(), 148 create_plugin_mock(), 149 create_plugin_mock(), 150 ] 151 # Return our PluginManager mock 152 PluginManager.return_value = create_mapping_manager_mock(plugins) 153 optmanager = object() 154 155 type_mgr = FakeTestType() 156 type_mgr.register_options(optmanager) 157 158 for plugin in plugins: 159 plugin.register_options.assert_called_with(optmanager) 160 161 162@mock.patch("flake8.plugins.manager.PluginManager") 163def test_provide_options(PluginManager): # noqa: N803 164 """Test that we map over every plugin to provide parsed options.""" 165 plugins = [ 166 create_plugin_mock(), 167 create_plugin_mock(), 168 create_plugin_mock(), 169 create_plugin_mock(), 170 create_plugin_mock(), 171 create_plugin_mock(), 172 create_plugin_mock(), 173 create_plugin_mock(), 174 ] 175 # Return our PluginManager mock 176 PluginManager.return_value = create_mapping_manager_mock(plugins) 177 optmanager = object() 178 options = object() 179 180 type_mgr = FakeTestType() 181 type_mgr.provide_options(optmanager, options, []) 182 183 for plugin in plugins: 184 plugin.provide_options.assert_called_with(optmanager, options, []) 185 186 187@mock.patch("flake8.plugins.manager.PluginManager", autospec=True) 188def test_proxy_contains_to_managers_plugins_dict(PluginManager): # noqa: N803 189 """Verify that we proxy __contains__ to the manager's dictionary.""" 190 plugins = {"T10%i" % i: create_plugin_mock() for i in range(8)} 191 # Return our PluginManager mock 192 PluginManager.return_value.plugins = plugins 193 194 type_mgr = FakeTestType() 195 for i in range(8): 196 key = "T10%i" % i 197 assert key in type_mgr 198 199 200@mock.patch("flake8.plugins.manager.PluginManager") 201def test_proxies_getitem_to_managers_plugins_dict(PluginManager): # noqa: N803 202 """Verify that we can use the PluginTypeManager like a dictionary.""" 203 plugins = {"T10%i" % i: create_plugin_mock() for i in range(8)} 204 # Return our PluginManager mock 205 PluginManager.return_value.plugins = plugins 206 207 type_mgr = FakeTestType() 208 for i in range(8): 209 key = "T10%i" % i 210 assert type_mgr[key] is plugins[key] 211