def test_multiple(): """Test handling of multiple callbacks for a hook. """ hooks.reset() # making this an attribute of a global avoids all kinds of scoping issues test_multiple.counter = 0 def mkinc(): # can't use same callback twice def inc(): test_multiple.counter += 1 return 42 return inc hooks.add_callback("alien_invasion", mkinc()) hooks.add_callback("alien_invasion", mkinc()) hooks.add_callback("alien_invasion", mkinc()) # by default, the first successfull callback returns test_multiple.counter = 0 assert hooks.trigger("alien_invasion") == 42 assert test_multiple.counter == 1 # we can forcefully go through all callbacks (and get None back) test_multiple.counter = 0 assert hooks.trigger("alien_invasion", all=True) == None assert test_multiple.counter == 3
def test_any(): """Test the any() function. """ hooks.reset() assert hooks.any("alien_invasion") == False hooks.add_callback("alien_invasion", lambda: None) assert hooks.any("alien_invasion") == True # invalid hook names raise an error assert_raises(KeyError, hooks.any, "worldpeace")
def test_exists(): """Test the exists() function. """ hooks.reset() assert hooks.exists("alien_invasion") == True assert hooks.exists("worldpeace") == False hooks.register("worldpeace") assert hooks.exists("worldpeace") == True hooks.reset() assert hooks.exists("worldpeace") == False
def test_reset(): # reset() was already used throughout previous tests, # but for good measure, do it specifically. # callback is no longer registered after a reset hooks.add_callback("alien_invasion", lambda: 42) hooks.reset() assert hooks.trigger("alien_invasion") == None # custom hook is gone after a reset hooks.register("i_love_you") hooks.reset() assert_raises(Exception, hooks.add_callback, "i_love_you", lambda: None)
def test_priority(): # fifo: without a priority, the callback added first is called first hooks.reset() hooks.add_callback("alien_invasion", lambda: 1) hooks.add_callback("alien_invasion", lambda: 2) hooks.add_callback("alien_invasion", lambda: 3) assert hooks.trigger("alien_invasion") == 1 # but callback priorization works as well hooks.reset() hooks.add_callback("alien_invasion", lambda: "p10", priority=10) hooks.add_callback("alien_invasion", lambda: "p20", priority=20) hooks.add_callback("alien_invasion", lambda: "p5", priority=5) assert hooks.trigger("alien_invasion") == "p20"
def test_validity(): # invalid identifers result in exceptions assert_raises(KeyError, hooks.add_callback, "worldpeace", lambda: None) assert_raises(KeyError, hooks.trigger, "worldpeace") assert_raises(KeyError, hooks.any, "worldpeace") # can't register the same function twice def foo(): pass hooks.add_callback("alien_invasion", foo) assert_raises(ValueError, hooks.add_callback, "alien_invasion", foo) # valid identifers work hooks.reset() hooks.add_callback("alien_invasion", lambda x: x) assert hooks.trigger("alien_invasion", [5]) == 5
def reinstall(addins=None): """Install the addins specified by the configuration, or via ``addins`. The addin installation process consists mainly if letting each adding register it's hook callbacks, as well as rebuilding the models. Addins that were previously installed will automatically be removed. The function returns the list of addins installed. It may differ from the explicitly specified list due to dependencies, and will contain only addin instances, not classes. """ if addins is None: addins = copy(config.ADDINS) # Start by making sure all addins are available as instances, # and use a separate list that we may modify going further. # Note that by starting with an initial list of all specified # addins, dependency order is not enforced for those. E.g. if # ``b`` depends on ``a`, but the user puts ``b`` before ``a``, # then that will be accepted by this installation process. In # contrast, if he only specifies ``b``, the ``a`` dependency # would automatically be inserted before it. to_be_setup = [] for addin in addins: to_be_setup.append(_make_addin(addin)) # resolve dependencies for i in range(0, len(to_be_setup)): def resolve_dependencies(addin, index): dependencies = getattr(addin, 'depends', ()) for dependency in dependencies: exists = False # Check if the dependency is already installed. Note # that dependencies may be both classes and instances. for existing in to_be_setup: if not isinstance(dependency, type): if isinstance(existing, type(dependency)): exists = True elif isinstance(existing, dependency): exists = True # if not, insert it at the right position, and # recursively resolve it's own dependencies. if not exists: dependency = _make_addin(dependency) to_be_setup.insert(index, dependency) index = resolve_dependencies(dependency, index) index += 1 return index i = resolve_dependencies(to_be_setup[i], i) # finally, setup all the addins we determined to be installed hooks.reset() for addin in to_be_setup: addin.setup() global _ADDINS _ADDINS = to_be_setup return to_be_setup