Getting closer to the source of magic

The current plan is to have spell casting use effects sub-system and make Spell object a composite that has a list of effects. In order to make construction of Spells easy, I’m planning on using a factory and call it while creating the action. Following code captures this in the form of a test:

def test_spell_is_created_with_a_factory(self):
    """
    When creating a spell casting action, spell should be created
    """
    spell_factory = SpellFactoryBuilder().build()
    when(spell_factory).create_spell('healing wind').thenReturn(mock())
    spellcasting_factory = (SpellCastingFactoryBuilder()
                                        .with_spell_factory(spell_factory)
                                        .build())
    
    spellcasting_factory.get_action(
                              SpellCastingParameters(self,
                                                     direction = 1, 
                                                     spell_name = 'healing wind'))
    
    verify(spell_factory).create_spell('healing wind')

Essentially, when SpellCastingFactory is used to create a spell called “healing wind”, the SpellFactory should receive a call to make a spell called “healing wind”. I’m creating spell_factory with SpellFactoryBuilder (so I have a real instance and not just a mock object), but then I’m using mockito to tell it to return mock when create_spell – method is called. I would like to use mock, but for some reason I couldn’t get it working with the code in SpellCastingFactoryBuilder:

def with_spell_factory(self, spell_factory):
    """
    Configure spell factory to use
    """
    if spell_factory == None:
        self.use_real_spell_factory = True
    else:
        if hasattr(spell_factory, 'build'):
            self.spell_factory = spell_factory.build()
        else:
            self.spell_factory = spell_factory
    return self

When creating a SpellCastingFactory with the builder, I can supply it with a spell_factory to use. I the spell_factory has method “build”, it will be called and the result is used as a factory, otherwise the supplied object is used. For mock object, hasattr will always return True, so this approach does not work.

Following modification to code makes the test to pass:

@logged
def get_action(self, parameters):
    """
    Create a spell casting action

    :param parameters: parameters used to control creation
    :type parameters: SpellCastingParameters
    """
    spell = self.spell_factory.create_spell(parameters.spell_name)
    
    return SpellCastingAction(caster = parameters.caster, 
                                       direction = parameters.direction,
                                       spell = spell)

Again, really small step forward, but the progression is steady and the direction looks good. I’m going to leave details about finding who the spell hits and how much the mana is subtracted later (both probably ending up in the SpellCastingAction) and concentrate on getting the spell part done.

Code for the changes can be found in the following commit.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s