def test_initialize_widget(self): handler = SettingsHandler() handler.defaults = {'default': 42, 'setting': 1} handler.provider = provider = Mock() handler.widget_class = SimpleWidget provider.get_provider.return_value = provider widget = SimpleWidget() def reset_provider(): provider.get_provider.return_value = None provider.reset_mock() provider.get_provider.return_value = provider # No data handler.initialize(widget) provider.initialize.assert_called_once_with(widget, { 'default': 42, 'setting': 1 }) # Dictionary data reset_provider() handler.initialize(widget, {'setting': 5}) provider.initialize.assert_called_once_with(widget, { 'default': 42, 'setting': 5 }) # Pickled data reset_provider() handler.initialize(widget, pickle.dumps({'setting': 5})) provider.initialize.assert_called_once_with(widget, { 'default': 42, 'setting': 5 })
def test_schema_only_settings(self): handler = SettingsHandler() with self.override_default_settings(SimpleWidget): handler.bind(SimpleWidget) # fast_save should not update defaults widget = SimpleWidget() handler.fast_save(widget, 'schema_only_setting', 5) self.assertEqual( handler.known_settings['schema_only_setting'].default, None) handler.fast_save(widget, 'component.schema_only_setting', 5) self.assertEqual( handler.known_settings['component.schema_only_setting'].default, "only") # update_defaults should not update defaults widget.schema_only_setting = 5 handler.update_defaults(widget) self.assertEqual( handler.known_settings['schema_only_setting'].default, None) widget.component.schema_only_setting = 5 self.assertEqual( handler.known_settings['component.schema_only_setting'].default, "only") # pack_data should pack setting widget.schema_only_setting = 5 widget.component.schema_only_setting = 5 data = handler.pack_data(widget) self.assertEqual(data['schema_only_setting'], 5) self.assertEqual(data['component']['schema_only_setting'], 5)
def test_pack_settings_stores_version(self): handler = SettingsHandler() handler.bind(SimpleWidget) widget = SimpleWidget() settings = handler.pack_data(widget) self.assertIn(VERSION_KEY, settings)
def test_read_defaults(self): handler = SettingsHandler() handler.widget_class = SimpleWidget defaults = {'a': 5, 'b': {1: 5}} with self.override_default_settings(SimpleWidget, defaults): handler.read_defaults() self.assertEqual(handler.defaults, defaults)
def test_write_defaults_handles_permission_error(self): handler = SettingsHandler() with named_file("") as f: handler._get_settings_filename = lambda: f with patch('Orange.widgets.settings.open', create=True) as mocked_open: mocked_open.side_effect = PermissionError() handler.write_defaults()
def test_initialize_widget(self): handler = SettingsHandler() handler.defaults = {'default': 42, 'setting': 1} handler.provider = provider = Mock() handler.widget_class = SimpleWidget provider.get_provider.return_value = provider widget = SimpleWidget() def reset_provider(): provider.get_provider.return_value = None provider.reset_mock() provider.get_provider.return_value = provider # No data handler.initialize(widget) provider.initialize.assert_called_once_with(widget, {'default': 42, 'setting': 1}) # Dictionary data reset_provider() handler.initialize(widget, {'setting': 5}) provider.initialize.assert_called_once_with(widget, {'default': 42, 'setting': 5}) # Pickled data reset_provider() handler.initialize(widget, pickle.dumps({'setting': 5})) provider.initialize.assert_called_once_with(widget, {'default': 42, 'setting': 5})
def test_write_defaults_handles_permission_error(self): handler = SettingsHandler() with named_file("") as f: handler._get_settings_filename = lambda: f with patch("Orange.widgets.settings.log.error") as log, \ patch('Orange.widgets.settings.open', create=True, side_effect=PermissionError): handler.write_defaults() log.assert_called()
def test_about_pack_settings_signal(self): handler = SettingsHandler() handler.bind(SimpleWidget) widget = SimpleWidget() handler.initialize(widget) fn = Mock() widget.settingsAboutToBePacked.connect(fn) handler.pack_data(widget) self.assertEqual(1, fn.call_count) handler.update_defaults(widget) self.assertEqual(2, fn.call_count)
def test_create_uses_template_if_provided(self): template = SettingsHandler() template.a = 'a' template.b = 'b' with self.override_default_settings(SimpleWidget): handler = SettingsHandler.create(SimpleWidget, template) self.assertEqual(handler.a, 'a') self.assertEqual(handler.b, 'b') # create should copy the template handler.b = 'B' self.assertEqual(template.b, 'b')
def test_create_uses_template_if_provided(self): template = SettingsHandler() template.read_defaults = lambda: None template.a = 'a' template.b = 'b' handler = SettingsHandler.create(SimpleWidget, template) self.assertEqual(handler.a, 'a') self.assertEqual(handler.b, 'b') # create should copy the template handler.b = 'B' self.assertEqual(template.b, 'b')
def test_create_uses_template_if_provided(self): template = SettingsHandler() template.a = "a" template.b = "b" with self.override_default_settings(SimpleWidget): handler = SettingsHandler.create(SimpleWidget, template) self.assertEqual(handler.a, "a") self.assertEqual(handler.b, "b") # create should copy the template handler.b = "B" self.assertEqual(template.b, "b")
def test_read_defaults(self): default_settings = {'a': 5, 'b': {1: 5}} f, settings_file = mkstemp(suffix='.ini') with open(settings_file, 'wb') as f: pickle.dump(default_settings, f) handler = SettingsHandler() handler._get_settings_filename = lambda: settings_file handler.read_defaults() self.assertEqual(handler.defaults, default_settings) os.remove(settings_file)
def override_default_settings(self, widget, defaults=None): if defaults is None: defaults = {} h = SettingsHandler() h.widget_class = widget filename = h._get_settings_filename() with open(filename, "wb") as f: pickle.dump(defaults, f) yield if os.path.isfile(filename): os.remove(filename)
def test_fast_save(self): handler = SettingsHandler() handler.read_defaults = lambda: None handler.bind(SimpleWidget) widget = SimpleWidget() handler.fast_save(widget, 'component.int_setting', 5) self.assertEqual(Component.int_setting.default, 5) handler.fast_save(widget, 'non_setting', 4)
def test_write_defaults_handles_writing_errors(self): handler = SettingsHandler() for error in (EOFError, IOError, pickle.PicklingError): f = NamedTemporaryFile("wt", delete=False) f.close() # so it can be opened on windows handler._get_settings_filename = lambda x=f: x.name with patch.object(handler, "write_defaults_file") as mocked_write: mocked_write.side_effect = error() handler.write_defaults() # Corrupt setting files should be removed self.assertFalse(os.path.exists(f.name))
def test_initialize_copies_mutables(self): handler = SettingsHandler() handler.bind(SimpleWidget) handler.defaults = dict(list_setting=[]) widget = SimpleWidget() handler.initialize(widget) widget2 = SimpleWidget() handler.initialize(widget2) self.assertNotEqual(id(widget.list_setting), id(widget2.list_setting))
def __new__(mcs, name, bases, kwargs): cls = super().__new__(mcs, name, bases, kwargs) if not cls.name: # not a widget return cls cls.convert_signals() cls.settingsHandler = SettingsHandler.create(cls, template=cls.settingsHandler) return cls
def test_initialize_with_no_provider(self, SettingProvider): """:type SettingProvider: unittest.mock.Mock""" handler = SettingsHandler() handler.provider = Mock(get_provider=Mock(return_value=None)) provider = Mock() SettingProvider.return_value = provider widget = SimpleWidget() # initializing an undeclared provider should display a warning with warnings.catch_warnings(record=True) as w: handler.initialize(widget) self.assertEqual(1, len(w)) SettingProvider.assert_called_once_with(SimpleWidget) provider.initialize.assert_called_once_with(widget, None)
def __new__(mcs, name, bases, dict): from Orange.canvas.registry.description import ( input_channel_from_args, output_channel_from_args) cls = type.__new__(mcs, name, bases, dict) if not cls.name: # not a widget return cls cls.inputs = [input_channel_from_args(inp) for inp in cls.inputs] cls.outputs = [output_channel_from_args(outp) for outp in cls.outputs] for inp in cls.inputs: if not hasattr(cls, inp.handler): raise AttributeError( "missing input signal handler '{}' in {}".format( inp.handler, cls.name)) # TODO Remove this when all widgets are migrated to Orange 3.0 if (hasattr(cls, "settingsToWidgetCallback") or hasattr(cls, "settingsFromWidgetCallback")): raise TypeError("Reimplement settingsToWidgetCallback and " "settingsFromWidgetCallback") cls.settingsHandler = SettingsHandler.create( cls, template=cls.settingsHandler) return cls
def __new__(mcs, name, bases, kwargs): from Orange.canvas.registry.description import ( input_channel_from_args, output_channel_from_args) cls = type.__new__(mcs, name, bases, kwargs) if not cls.name: # not a widget return cls cls.inputs = [input_channel_from_args(inp) for inp in cls.inputs] cls.outputs = [output_channel_from_args(outp) for outp in cls.outputs] for inp in cls.inputs: if not hasattr(cls, inp.handler): raise AttributeError("missing input signal handler '{}' in {}". format(inp.handler, cls.name)) # TODO Remove this when all widgets are migrated to Orange 3.0 if (hasattr(cls, "settingsToWidgetCallback") or hasattr(cls, "settingsFromWidgetCallback")): raise TypeError("Reimplement settingsToWidgetCallback and " "settingsFromWidgetCallback") cls.settingsHandler = SettingsHandler.create(cls, template=cls.settingsHandler) return cls
def __new__(mcs, name, bases, kwargs): cls = super().__new__(mcs, name, bases, kwargs) if not cls.name: # not a widget return cls cls.convert_signals() cls.settingsHandler = \ SettingsHandler.create(cls, template=cls.settingsHandler) return cls
def test_initialization_of_not_declared_provider(self): widget = WidgetWithNoProviderDeclared() handler = SettingsHandler.create(WidgetWithNoProviderDeclared) with warnings.catch_warnings(): warnings.simplefilter("ignore") handler.initialize(widget) handler.initialize(widget.undeclared_component) self.assertIsInstance(widget.undeclared_component.int_setting, int)
def test_initialize_component(self): handler = SettingsHandler() handler.defaults = {'default': 42} provider = Mock() handler.provider = Mock(get_provider=Mock(return_value=provider)) widget = SimpleWidget() # No data handler.initialize(widget) provider.initialize.assert_called_once_with(widget, None) # Dictionary data provider.reset_mock() handler.initialize(widget, {'setting': 5}) provider.initialize.assert_called_once_with(widget, {'setting': 5}) # Pickled data provider.reset_mock() handler.initialize(widget, pickle.dumps({'setting': 5})) provider.initialize.assert_called_once_with(widget, {'setting': 5})
def test_create(self, SettingProvider): """:type SettingProvider: unittest.mock.Mock""" with patch.object(SettingsHandler, 'read_defaults'): handler = SettingsHandler.create(SimpleWidget) self.assertEqual(handler.widget_class, SimpleWidget) # create needs to create a SettingProvider which traverses # the widget definition and collects all settings and read # all settings and for widget class SettingProvider.assert_called_once_with(SimpleWidget) SettingsHandler.read_defaults.assert_called_once_with()
def test_schema_only_settings(self): handler = SettingsHandler() handler.read_defaults = lambda: None handler.bind(SimpleWidget) # fast_save should not update defaults widget = SimpleWidget() handler.fast_save(widget, 'schema_only_setting', 5) self.assertEqual(handler.known_settings['schema_only_setting'].default, None) # update_defaults should not update defaults widget.schema_only_setting = 5 handler.update_defaults(widget) self.assertEqual(handler.known_settings['schema_only_setting'].default, None) # pack_data should pack setting widget.schema_only_setting = 5 data = handler.pack_data(widget) self.assertEqual(data['schema_only_setting'], 5)
def test_initialize_component(self): handler = SettingsHandler() handler.defaults = {'default': 42} provider = Mock() handler.widget_class = SimpleWidget handler.provider = Mock(get_provider=Mock(return_value=provider)) widget = SimpleWidget() # No data handler.initialize(widget) provider.initialize.assert_called_once_with(widget, None) # Dictionary data provider.reset_mock() handler.initialize(widget, {'setting': 5}) provider.initialize.assert_called_once_with(widget, {'setting': 5}) # Pickled data provider.reset_mock() handler.initialize(widget, pickle.dumps({'setting': 5})) provider.initialize.assert_called_once_with(widget, {'setting': 5})
def test_fast_save(self): handler = SettingsHandler() with self.override_default_settings(SimpleWidget): handler.bind(SimpleWidget) widget = SimpleWidget() handler.fast_save(widget, 'component.int_setting', 5) self.assertEqual( handler.known_settings['component.int_setting'].default, 5) self.assertEqual(Component.int_setting.default, 42) handler.fast_save(widget, 'non_setting', 4)
def test_schema_only_settings(self): handler = SettingsHandler() handler.read_defaults = lambda: None handler.bind(SimpleWidget) # fast_save should not update defaults widget = SimpleWidget() handler.fast_save(widget, 'schema_only_setting', 5) self.assertEqual( handler.known_settings['schema_only_setting'].default, None) # update_defaults should not update defaults widget.schema_only_setting = 5 handler.update_defaults(widget) self.assertEqual( handler.known_settings['schema_only_setting'].default, None) # pack_data should pack setting widget.schema_only_setting = 5 data = handler.pack_data(widget) self.assertEqual(data['schema_only_setting'], 5)
def override_default_settings(self, widget, defaults=None): if defaults is None: defaults = {} h = SettingsHandler() h.widget_class = widget h.defaults = defaults filename = h._get_settings_filename() h.write_defaults() yield if os.path.isfile(filename): os.remove(filename)
def __new__(mcs, name, bases, dict): from Orange.canvas.registry.description import input_channel_from_args, output_channel_from_args cls = type.__new__(mcs, name, bases, dict) if not cls.name: # not a widget return cls cls.inputs = list(map(input_channel_from_args, cls.inputs)) cls.outputs = list(map(output_channel_from_args, cls.outputs)) # TODO Remove this when all widgets are migrated to Orange 3.0 if hasattr(cls, "settingsToWidgetCallback") or hasattr(cls, "settingsFromWidgetCallback"): raise SystemError("Reimplement settingsToWidgetCallback and " "settingsFromWidgetCallback") cls.settingsHandler = SettingsHandler.create(cls, template=cls.settingsHandler) return cls
def test_write_defaults(self): f, settings_file = mkstemp(suffix='.ini') handler = SettingsHandler() handler.defaults = {'a': 5, 'b': {1: 5}} handler._get_settings_filename = lambda: settings_file handler.write_defaults() with open(settings_file, 'rb') as f: default_settings = pickle.load(f) self.assertEqual(handler.defaults, default_settings) os.remove(settings_file)
def test_initialize_migrates_settings(self): handler = SettingsHandler() with self.override_default_settings(SimpleWidget): handler.bind(SimpleWidget) widget = SimpleWidget() migrate_settings = Mock() with patch.object(SimpleWidget, "migrate_settings", migrate_settings): # Old settings without version settings = {"value": 5} handler.initialize(widget, settings) migrate_settings.assert_called_with(settings, 0) migrate_settings.reset_mock() # Settings with version settings_with_version = dict(settings) settings_with_version[VERSION_KEY] = 1 handler.initialize(widget, settings_with_version) migrate_settings.assert_called_with(settings, 1)
def __new__(mcs, name, bases, dict): from Orange.canvas.registry.description import ( input_channel_from_args, output_channel_from_args) cls = type.__new__(mcs, name, bases, dict) if not cls.name: # not a widget return cls cls.inputs = list(map(input_channel_from_args, cls.inputs)) cls.outputs = list(map(output_channel_from_args, cls.outputs)) # TODO Remove this when all widgets are migrated to Orange 3.0 if (hasattr(cls, "settingsToWidgetCallback") or hasattr(cls, "settingsFromWidgetCallback")): raise TypeError("Reimplement settingsToWidgetCallback and " "settingsFromWidgetCallback") cls.settingsHandler = SettingsHandler.create( cls, template=cls.settingsHandler) return cls
def test_read_defaults_migrates_settings(self): handler = SettingsHandler() handler.widget_class = SimpleWidget migrate_settings = Mock() with patch.object(SimpleWidget, "migrate_settings", migrate_settings): # Old settings without version settings = {"value": 5} with self.override_default_settings(SimpleWidget, settings): handler.read_defaults() migrate_settings.assert_called_with(settings, 0) migrate_settings.reset() # Settings with version settings_with_version = dict(settings) settings_with_version[VERSION_KEY] = 1 with self.override_default_settings(SimpleWidget, settings_with_version): handler.read_defaults() migrate_settings.assert_called_with(settings, 1)
def test_write_defaults(self): fd, settings_file = mkstemp(suffix='.ini') handler = SettingsHandler() handler.widget_class = SimpleWidget handler.defaults = {'a': 5, 'b': {1: 5}} handler._get_settings_filename = lambda: settings_file handler.write_defaults() with open(settings_file, 'rb') as f: default_settings = pickle.load(f) os.close(fd) self.assertEqual( default_settings.pop(VERSION_KEY, -0xBAD), handler.widget_class.settings_version, ) self.assertEqual(default_settings, handler.defaults) os.remove(settings_file)
def test_write_defaults(self): fd, settings_file = mkstemp(suffix='.ini') handler = SettingsHandler() handler.widget_class = SimpleWidget handler.defaults = {'a': 5, 'b': {1: 5}} handler._get_settings_filename = lambda: settings_file handler.write_defaults() with open(settings_file, 'rb') as f: default_settings = pickle.load(f) os.close(fd) self.assertEqual(default_settings.pop(VERSION_KEY, -0xBAD), handler.widget_class.settings_version,) self.assertEqual(default_settings, handler.defaults) os.remove(settings_file)
def test_fast_save_siblings_spill(self): handler_mk1 = SettingsHandler() with self.override_default_settings(SimpleWidgetMk1): handler_mk1.bind(SimpleWidgetMk1) widget_mk1 = SimpleWidgetMk1() handler_mk1.fast_save(widget_mk1, "setting", -1) handler_mk1.fast_save(widget_mk1, "component.int_setting", 1) self.assertEqual( handler_mk1.known_settings['setting'].default, -1) self.assertEqual( handler_mk1.known_settings['component.int_setting'].default, 1) handler_mk1.initialize(widget_mk1, data=None) handler_mk1.provider.providers["component"].initialize( widget_mk1.component, data=None) self.assertEqual(widget_mk1.setting, -1) self.assertEqual(widget_mk1.component.int_setting, 1) handler_mk2 = SettingsHandler() with self.override_default_settings(SimpleWidgetMk2): handler_mk2.bind(SimpleWidgetMk2) widget_mk2 = SimpleWidgetMk2() handler_mk2.initialize(widget_mk2, data=None) handler_mk2.provider.providers["component"].initialize( widget_mk2.component, data=None) self.assertEqual(widget_mk2.setting, 42, "spils defaults into sibling classes") self.assertEqual(Component.int_setting.default, 42) self.assertEqual(widget_mk2.component.int_setting, 42, "spils defaults into sibling classes")
def test_fast_save_siblings_spill(self): handler_mk1 = SettingsHandler() with self.override_default_settings(SimpleWidgetMk1): handler_mk1.bind(SimpleWidgetMk1) widget_mk1 = SimpleWidgetMk1() handler_mk1.fast_save(widget_mk1, "setting", -1) handler_mk1.fast_save(widget_mk1, "component.int_setting", 1) self.assertEqual(handler_mk1.known_settings['setting'].default, -1) self.assertEqual( handler_mk1.known_settings['component.int_setting'].default, 1) handler_mk1.initialize(widget_mk1, data=None) handler_mk1.provider.providers["component"].initialize( widget_mk1.component, data=None) self.assertEqual(widget_mk1.setting, -1) self.assertEqual(widget_mk1.component.int_setting, 1) handler_mk2 = SettingsHandler() with self.override_default_settings(SimpleWidgetMk2): handler_mk2.bind(SimpleWidgetMk2) widget_mk2 = SimpleWidgetMk2() handler_mk2.initialize(widget_mk2, data=None) handler_mk2.provider.providers["component"].initialize( widget_mk2.component, data=None) self.assertEqual(widget_mk2.setting, 42, "spils defaults into sibling classes") self.assertEqual(Component.int_setting.default, 42) self.assertEqual(widget_mk2.component.int_setting, 42, "spils defaults into sibling classes")
def test_schema_only_settings(self): handler = SettingsHandler() with self.override_default_settings(SimpleWidget): handler.bind(SimpleWidget) # fast_save should not update defaults widget = SimpleWidget() handler.fast_save(widget, 'schema_only_setting', 5) self.assertEqual(handler.known_settings['schema_only_setting'].default, None) handler.fast_save(widget, 'component.schema_only_setting', 5) self.assertEqual( handler.known_settings['component.schema_only_setting'].default, "only") # update_defaults should not update defaults widget.schema_only_setting = 5 handler.update_defaults(widget) self.assertEqual(handler.known_settings['schema_only_setting'].default, None) widget.component.schema_only_setting = 5 self.assertEqual( handler.known_settings['component.schema_only_setting'].default, "only") # pack_data should pack setting widget.schema_only_setting = 5 widget.component.schema_only_setting = 5 data = handler.pack_data(widget) self.assertEqual(data['schema_only_setting'], 5) self.assertEqual(data['component']['schema_only_setting'], 5)