Exemplo n.º 1
0
 def setUp(self):
     self.engine = Engine("sqlite:///:memory:")
     self.graphmakers = (self.engine.new_character, )
     self.tempdir = tempfile.mkdtemp(dir='.')
     for f in ('trigger.py', 'prereq.py', 'action.py', 'function.py',
               'method.py', 'strings.json'):
         if os.path.exists(f):
             os.rename(f, os.path.join(self.tempdir, f))
Exemplo n.º 2
0
def college24_premade(clean):
    if not os.path.exists("college24_premade.db"):
        print("generating test data for query")
        from LiSE.examples.college import install
        with Engine('college24_premade.db', random_seed=69105) as eng:
            install(eng)
            for i in range(24):
                print(i)
                eng.next_turn()
    eng = Engine("college24_premade.db")
    yield eng
    eng.close()
Exemplo n.º 3
0
    def setUp(self):
        """Start an engine, install the sim module, and run it a while.

        This gives us some world-state to test upon.

        """
        from logging import getLogger, FileHandler
        self.engine = Engine(":memory:")
        logger = getLogger('LiSE.engine')
        logger.setLevel('DEBUG')
        logger.addHandler(FileHandler('test.log'))
        sim.install(self.engine)
        for i in range(72):
            self.engine.next_tick()
        self.engine.commit()
Exemplo n.º 4
0
 def setUp(self):
     self.engine = Engine("sqlite:///:memory:")
     self.graphmakers = (self.engine.new_character,)
     self.tempdir = tempfile.mkdtemp(dir='.')
     for f in (
         'trigger.py', 'prereq.py', 'action.py', 'function.py',
         'method.py', 'strings.json'
     ):
         if os.path.exists(f):
             os.rename(f, os.path.join(self.tempdir, f))
Exemplo n.º 5
0
def character_updates(request):
    tempdir = tempfile.mkdtemp(dir='.')
    for f in ('trigger.py', 'prereq.py', 'action.py', 'function.py',
              'method.py', 'strings.json'):
        if os.path.exists(f):
            os.rename(f, os.path.join(tempdir, f))
    name, data, stat, nodestat, statup, nodeup, edgeup = request.param
    engine = Engine("sqlite:///:memory:")
    char = engine.new_character(name, data, **stat)
    update_char(char, node=nodestat)
    yield char, statup, nodeup, edgeup
    engine.close()
    for f in ('trigger.py', 'prereq.py', 'action.py', 'function.py',
              'method.py', 'strings.json'):
        if os.path.exists(f):
            os.remove(f)
        if os.path.exists(os.path.join(tempdir, f)):
            os.rename(os.path.join(tempdir, f), f)
    os.rmdir(tempdir)
Exemplo n.º 6
0
def test_char_creation(name, data, stat, nodestat, statup, nodeup, edgeup):
    with Engine(connect_string="sqlite:///:memory:") as eng:
        char = eng.new_character(name, data, **stat)
        assert set(char.node) == set(data)
        es = set()
        for k, v in data.items():
            for vv in v:
                es.add((k, vv))
        assert set(char.edges) == es
        assert char.stat == stat
Exemplo n.º 7
0
class CharacterTest(allegedb.tests.test_all.AllegedTest):
    def setUp(self):
        self.engine = Engine("sqlite:///:memory:")
        self.graphmakers = (self.engine.new_character, )
        self.tempdir = tempfile.mkdtemp(dir='.')
        for f in ('trigger.py', 'prereq.py', 'action.py', 'function.py',
                  'method.py', 'strings.json'):
            if os.path.exists(f):
                os.rename(f, os.path.join(self.tempdir, f))

    def tearDown(self):
        self.engine.close()
        for f in ('trigger.py', 'prereq.py', 'action.py', 'function.py',
                  'method.py', 'strings.json'):
            if os.path.exists(f):
                os.remove(f)
            if os.path.exists(os.path.join(self.tempdir, f)):
                os.rename(os.path.join(self.tempdir, f), f)
        os.rmdir(self.tempdir)
Exemplo n.º 8
0
def test_facade_creation(name, data, stat, nodestat, statup, nodeup, edgeup):
    with Engine(connect_string='sqlite:///:memory:') as eng:
        char = eng.new_character(name, data, **stat)
        fac = char.facade()
        assert dict(fac.node) == dict(char.node)
        assert fac.node == char.node
        assert fac.edges == char.edges
        assert set(fac.edges) == set(char.edges)
        assert fac.stat == char.stat
        assert dict(fac.stat) == dict(char.stat)
Exemplo n.º 9
0
def college24_premade():
    codefiles = ('trigger.py', 'prereq.py', 'action.py', 'method.py', 'function.py', 'strings.json')
    tempdir = tempfile.mkdtemp(dir='.')
    for codefile in codefiles:
        if os.path.exists(codefile):
            os.rename(codefile, os.path.join(tempdir, codefile))
    if not os.path.exists("college24_premade.db"):
        print("generating test data for query")
        from LiSE.examples.college import install
        with Engine('college24_premade.db', random_seed=69105) as eng:
            install(eng)
            for i in range(24):
                print(i)
                eng.next_turn()
    eng = Engine("college24_premade.db")
    yield eng
    eng.close()
    for codefile in codefiles:
        if os.path.exists(os.path.join(tempdir, codefile)):
            os.rename(os.path.join(tempdir, codefile), codefile)
    os.rmdir(tempdir)
Exemplo n.º 10
0
def character_updates(request):
    tempdir = tempfile.mkdtemp(dir='.')
    for f in (
            'trigger.py', 'prereq.py', 'action.py', 'function.py',
            'method.py', 'strings.json'
    ):
        if os.path.exists(f):
            os.rename(f, os.path.join(tempdir, f))
    name, data, stat, nodestat, statup, nodeup, edgeup = request.param
    engine = Engine("sqlite:///:memory:")
    char = engine.new_character(name, data, **stat)
    update_char(char, node=nodestat)
    yield char, statup, nodeup, edgeup
    engine.close()
    for f in (
        'trigger.py', 'prereq.py', 'action.py', 'function.py',
        'method.py', 'strings.json'
    ):
        if os.path.exists(f):
            os.remove(f)
        if os.path.exists(os.path.join(tempdir, f)):
            os.rename(os.path.join(tempdir, f), f)
    os.rmdir(tempdir)
Exemplo n.º 11
0
class CharacterTest(allegedb.tests.test_all.AllegedTest):
    def setUp(self):
        self.engine = Engine("sqlite:///:memory:")
        self.graphmakers = (self.engine.new_character,)
        self.tempdir = tempfile.mkdtemp(dir='.')
        for f in (
            'trigger.py', 'prereq.py', 'action.py', 'function.py',
            'method.py', 'strings.json'
        ):
            if os.path.exists(f):
                os.rename(f, os.path.join(self.tempdir, f))

    def tearDown(self):
        self.engine.close()
        for f in (
            'trigger.py', 'prereq.py', 'action.py', 'function.py',
            'method.py', 'strings.json'
        ):
            if os.path.exists(f):
                os.remove(f)
            if os.path.exists(os.path.join(self.tempdir, f)):
                os.rename(os.path.join(self.tempdir, f), f)
        os.rmdir(self.tempdir)
Exemplo n.º 12
0
                if student not in student_body.stat['characters']:
                    student_body.stat['characters'].append(student)
                # Students' nodes are their brain cells.
                # They are useless if drunk or slow, but recover from both conditions a bit every hour.
                for k in range(0, 100):
                    cell = student.new_node('cell{}'.format(k),
                                            drunk=0,
                                            slow=0)
                    #  ``new_node`` is just an alias for ``new_place``;
                    #  perhaps more logical when the places don't really
                    #  represent potential locations
                    student.stat['xp'] = 0
                    student.stat['drunkard'] = eng.coinflip()
                    student.stat['lazy'] = eng.coinflip()
                # Apply these previously written rules to each student
                for rule in (drink, sloth):
                    student.rule(rule)
                # Apply these previously written rules to each brain cell
                for rule in (learn, sober_up, catch_up):
                    student.place.rule(rule)
    eng.snap_keyframe()


if __name__ == "__main__":
    from LiSE.engine import Engine
    with Engine(connect_string=":memory:") as eng:
        install(eng)
        for i in range(72):
            eng.next_turn()
            print(i)
Exemplo n.º 13
0
    go2kobold.prereqs = ['kobold_alive']

    @go2kobold.prereq
    def kobold_not_here(thing):
        return 'kobold' not in thing.location.content

    @dwarf.rule
    def wander(thing):
        dests = sorted(list(thing.character.place.keys()))
        dests.remove(thing['location'])
        thing.travel_to(thing.engine.choice(dests))

    @wander.trigger
    def standing_still(thing):
        return thing.next_location is None


if __name__ == '__main__':
    from LiSE.engine import Engine
    from os import remove
    try:
        remove('LiSEworld.db')
    except FileNotFoundError:
        pass
    with Engine('LiSEworld.db', random_seed=69105) as engine:
        inittest(engine, shrubberies=20, kobold_sprint_chance=.9)
        engine.commit()
        print('shrub_places beginning: {}'.format(
            engine.character['physical'].thing['kobold']['shrub_places']
        ))
Exemplo n.º 14
0
            for student in (student0, student1):
                if student not in student_body.stat['characters']:
                    student_body.stat['characters'].append(student)
                # Students' nodes are their brain cells.
                # They are useless if drunk or slow, but recover from both conditions a bit every hour.
                for k in range(0, 100):
                    cell = student.new_node('cell{}'.format(k),
                                            drunk=0,
                                            slow=0)
                    #  ``new_node`` is just an alias for ``new_place``;
                    #  perhaps more logical when the places don't really
                    #  represent potential locations
                    student.stat['xp'] = 0
                    student.stat['drunkard'] = eng.coinflip()
                    student.stat['lazy'] = eng.coinflip()
                # Apply these previously written rules to each student
                for rule in (drink, sloth):
                    student.rule(rule)
                # Apply these previously written rules to each brain cell
                for rule in (learn, sober_up, catch_up):
                    student.place.rule(rule)


if __name__ == "__main__":
    from LiSE.engine import Engine
    with Engine(":memory:") as eng:
        install(eng)
        for i in range(72):
            eng.next_turn()
            print(i)
Exemplo n.º 15
0
def test_keyframe_load_init(tempdir):
    """Can load a keyframe at start of branch, including locations"""
    eng = Engine(tempdir)
    inittest(eng)
    eng.branch = 'new'
    eng.snap_keyframe()
    eng.close()
    eng = Engine(tempdir)
    assert eng._things_cache.keyframe['physical', 'kobold'][
        eng.branch][eng.turn][eng.tick]
    assert 'kobold' in eng.character['physical'].thing
    assert (0, 0) in eng.character['physical'].place
    assert (0, 1) in eng.character['physical'].portal[0, 0]
    eng.close()
Exemplo n.º 16
0
def mkengine(w='sqlite:///LiSEworld.db', *args, **kwargs):
    return Engine(worlddb=w, codedb='LiSEcode.db', *args, **kwargs)
Exemplo n.º 17
0
def college24_premade():
    directory = tempfile.mkdtemp('.')
    shutil.unpack_archive(os.path.join(os.path.abspath(os.path.dirname(__file__)), 'college24_premade.tar.xz'), directory)
    with Engine(directory) as eng:
        yield eng
    shutil.rmtree(directory)
Exemplo n.º 18
0
def test():
    eng = Engine(":memory:")
    install(eng)
    for i in range(24):
        eng.next_tick()
Exemplo n.º 19
0
    def go2kobold(thing):
        thing.travel_to(thing.character.thing['kobold']['location'])

    go2kobold.trigger(aware)

    go2kobold.prereqs = ['kobold_alive']

    @go2kobold.prereq
    def kobold_not_here(thing):
        return 'kobold' not in thing.location.content

    @dwarf.rule
    def wander(thing):
        dests = sorted(list(thing.character.place.keys()))
        dests.remove(thing['location'])
        thing.travel_to(thing.engine.choice(dests))

    @wander.trigger
    def standing_still(thing):
        return thing.next_location is None


if __name__ == '__main__':
    from LiSE.engine import Engine
    from os import remove
    with Engine(random_seed=69105, clear=True) as engine:
        inittest(engine, shrubberies=20, kobold_sprint_chance=.9)
        engine.commit()
        print('shrub_places beginning: {}'.format(
            engine.character['physical'].thing['kobold']['shrub_places']))
Exemplo n.º 20
0
def test():
    eng = Engine(":memory:")
    install(eng)
    for i in range(24):
        eng.next_tick()
Exemplo n.º 21
0
class SimTest(TestCase):
    maxDiff = None

    def setUp(self):
        """Start an engine, install the sim module, and run it a while.

        This gives us some world-state to test upon.

        """
        from logging import getLogger, FileHandler
        self.engine = Engine(":memory:")
        logger = getLogger('LiSE.engine')
        logger.setLevel('DEBUG')
        logger.addHandler(FileHandler('test.log'))
        sim.install(self.engine)
        for i in range(72):
            self.engine.next_tick()
        self.engine.commit()

    def tearDown(self):
        """Close my engine."""
        self.engine.close()

    def testRulebooksCache(self):
        rulebooks = defaultdict(list)
        for (rulebook, rule) in self.engine.rule.query.rulebooks_rules():
            rulebooks[rulebook].append(rule)
        # Ignoring empty rulebooks because those only exist
        # implicitly, they don't have database records
        oldrulebooks = {}
        for (k, v) in self.engine._rulebooks_cache._data.items():
            if v:
                oldrulebooks[k] = [rule.name for rule in v]
        self.assertDictEqual(oldrulebooks, rulebooks)

    def testCharRulebooksCaches(self):
        charrb = {}
        for (character, character_rulebook, avatar_rulebook,
             character_thing_rulebook, character_place_rulebook,
             character_node_rulebook, character_portal_rulebook
             ) in self.engine.query.characters_rulebooks():
            charrb[character] = {
                'character': character_rulebook,
                'avatar': avatar_rulebook,
                'character_thing': character_thing_rulebook,
                'character_place': character_place_rulebook,
                'character_node': character_node_rulebook,
                'character_portal': character_portal_rulebook
            }
        self.assertDictEqual(charrb,
                             self.engine._characters_rulebooks_cache._data)

    def testNodeRulebooksCache(self):
        noderb = defaultdict(dict)
        for (character, node, rulebook) in self.engine.query.nodes_rulebooks():
            noderb[character][node] = rulebook
        self.assertDictEqual(noderb, self.engine._nodes_rulebooks_cache._data)

    def testPortalRulebooksCache(self):
        portrb = StructuredDefaultDict(1, dict)
        for (character, nodeA, nodeB,
             rulebook) in self.engine.query.portals_rulebooks():
            portrb[character][nodeA][nodeB] = rulebook
        self.assertDictEqual(portrb,
                             self.engine._portals_rulebooks_cache._data)

    def testAvatarnessCaches(self):
        user_avatarness = StructuredDefaultDict(3, WindowDict)
        for (character, graph, node, branch, tick,
             is_avatar) in self.engine.query.avatarness_dump():
            user_avatarness[graph][node][character][branch][tick] = is_avatar
        new_user_avatarness = StructuredDefaultDict(3, WindowDict)
        usr = self.engine._avatarness_cache.user_order
        for graph in usr:
            for node in usr[graph]:
                for char in usr[graph][node]:
                    if usr[graph][node][char]:
                        for branch in usr[graph][node][char]:
                            for tick, is_avatar in usr[graph][node][char][
                                    branch].items():
                                new_user_avatarness[graph][node][char][branch][
                                    tick] = is_avatar
        self.assertDictEqual(user_avatarness, new_user_avatarness)

    def testNodeRulesHandledCache(self):
        node_rules_handled_ticks = defaultdict(  # character:
            lambda: defaultdict(  # node:
                lambda: defaultdict(  # rulebook:
                    lambda: defaultdict(  # rule:
                        lambda: defaultdict(  # branch:
                            set  # ticks handled
                        )))))
        new_node_rules_handled_ticks = defaultdict(  # character:
            lambda: defaultdict(  # node:
                lambda: defaultdict(  # rulebook:
                    lambda: defaultdict(  # rule:
                        dict))))
        cache = self.engine._node_rules_handled_cache._data
        for char in cache:
            for node in cache[char]:
                for rulebook in cache[char][node]:
                    for rule in cache[char][node][rulebook]:
                        if cache[char][node][rulebook][rule]:
                            new_node_rules_handled_ticks[
                                char][node][rulebook][rule] \
                                = cache[char][node][rulebook][rule]
        for character, node, rulebook, rule, branch, tick in \
                self.engine.query.dump_node_rules_handled():
            node_rules_handled_ticks[character][node][rulebook][rule][
                branch].add(tick)
        self.assertDictEqual(node_rules_handled_ticks,
                             new_node_rules_handled_ticks)

    def testPortalRulesHandledCache(self):
        portal_rules_handled_ticks = defaultdict(  # character:
            lambda: defaultdict(  # nodeA:
                lambda: defaultdict(  # nodeB:
                    lambda: defaultdict(  # rulebook:
                        lambda: defaultdict(  # rule:
                            lambda: defaultdict(  # branch:
                                set  # ticks handled
                            ))))))
        new_portal_rules_handled_ticks = defaultdict(  # character:
            lambda: defaultdict(  # nodeA:
                lambda: defaultdict(  # nodeB:
                    lambda: defaultdict(  # rulebook:
                        lambda: defaultdict(  # rule:
                            dict)))))
        cache = self.engine._portal_rules_handled_cache._data
        for character in cache:
            for nodeA in cache[character]:
                for nodeB in cache[character][nodeA]:
                    for rulebook in cache[character][nodeA][nodeB]:
                        for rule in cache[character][nodeA][nodeB][rulebook]:
                            if cache[character][nodeA][nodeB][rulebook][rule]:
                                new_portal_rules_handled_ticks[
                                    character][nodeA][nodeB][rulebook][rule] \
                                    = cache[character][nodeA][nodeB][
                                        rulebook][rule]
        for (character, nodeA, nodeB, idx, rulebook, rule, branch, tick) \
                in self.engine.query.dump_portal_rules_handled():
            portal_rules_handled_ticks[character][nodeA][nodeB][rulebook][
                rule][branch].add(tick)
        self.assertDictEqual(portal_rules_handled_ticks,
                             new_portal_rules_handled_ticks)

    def testCharRulesHandledCaches(self):
        live = self.engine._character_rules_handled_cache._data
        for rulemap in [
                'character', 'avatar', 'character_thing', 'character_place',
                'character_portal'
        ]:
            handled_ticks = StructuredDefaultDict(2, set)
            for character, rulebook, rule, branch, tick in getattr(
                    self.engine.query, 'handled_{}_rules'.format(rulemap))():
                handled_ticks[character][rule][branch].add(tick)
            old_handled_ticks = StructuredDefaultDict(2, set)
            for character in live:
                if live[character][rulemap]:
                    for rule in live[character][rulemap]:
                        for branch, ticks in live[character][rulemap][
                                rule].items():
                            self.assertIsInstance(ticks, set)
                            old_handled_ticks[character][rule][branch] = ticks
            self.assertDictEqual(old_handled_ticks, handled_ticks,
                                 "\n{} cache differs from DB".format(rulemap))

    def testThingsCache(self):
        things = StructuredDefaultDict(3, tuple)
        for (character, thing, branch, tick, loc, nextloc) in \
                self.engine.query.things_dump():
            things[(character, )][thing][branch][tick] = (loc, nextloc)
        self.assertDictEqual(things, self.engine._things_cache.keys)

    def testRoommateCollisions(self):
        """Test queries' ability to tell that all of the students that share
        rooms have been in the same place.

        """
        done = set()
        for chara in self.engine.character.values():
            if chara.name in done:
                continue
            match = re.match('dorm(\d)room(\d)student(\d)', chara.name)
            if not match:
                continue
            dorm, room, student = match.groups()
            other_student = 1 if student == 0 else 0
            student = chara
            other_student = self.engine.character[
                'dorm{}room{}student{}'.format(dorm, room, other_student)]

            same_loc_ticks = list(
                self.engine.ticks_when(
                    student.avatar.only.historical('location') ==
                    other_student.avatar.only.historical('location')))
            self.assertTrue(
                same_loc_ticks, "{} and {} don't seem to share a room".format(
                    student.name, other_student.name))
            self.assertGreater(
                len(same_loc_ticks), 6,
                "{} and {} share their room for less than 6 ticks".format(
                    student.name, other_student.name))
            done.add(student.name)
            done.add(other_student.name)

    def testSoberCollisions(self):
        """Students that are neither lazy nor drunkards should all have been
        in class together at least once.

        """
        students = [
            stu
            for stu in self.engine.character['student_body'].stat['characters']
            if not (stu.stat['drunkard'] or stu.stat['lazy'])
        ]

        assert students

        def sameClasstime(stu0, stu1):
            self.assertTrue(
                self.engine.ticks_when(
                    stu0.avatar.only.historical('location') == stu1.avatar.only
                    .historical('location') == self.engine.alias('classroom')),
                "{stu0} seems not to have been in the classroom "
                "at the same time as {stu1}.\n"
                "{stu0} was there at ticks {ticks0}\n"
                "{stu1} was there at ticks {ticks1}".format(
                    stu0=stu0.name,
                    stu1=stu1.name,
                    ticks0=list(
                        self.engine.ticks_when(
                            stu0.avatar.only.historical('location') ==
                            self.engine.alias('classroom'))),
                    ticks1=list(
                        self.engine.ticks_when(
                            stu1.avatar.only.historical('location') ==
                            self.engine.alias('classroom')))))
            return stu1

        reduce(sameClasstime, students)

    def testNoncollision(self):
        """Make sure students *not* from the same room never go there together"""
        dorm = defaultdict(lambda: defaultdict(dict))
        for character in self.engine.character.values():
            match = re.match('dorm(\d)room(\d)student(\d)', character.name)
            if not match:
                continue
            d, r, s = match.groups()
            dorm[d][r][s] = character
        for d in dorm:
            other_dorms = [dd for dd in dorm if dd != d]
            for r in dorm[d]:
                other_rooms = [rr for rr in dorm[d] if rr != r]
                for stu0 in dorm[d][r].values():
                    for rr in other_rooms:
                        for stu1 in dorm[d][rr].values():
                            self.assertFalse(
                                self.engine.ticks_when(
                                    stu0.avatar.only.historical('location') ==
                                    stu1.avatar.only.historical('location') ==
                                    self.engine.alias('dorm{}room{}'.format(
                                        d, r))),
                                "{} seems to share a room with {}".format(
                                    stu0.name, stu1.name))
                    common = 'common{}'.format(d)
                    for dd in other_dorms:
                        for rr in dorm[dd]:
                            for stu1 in dorm[dd][rr].values():
                                self.assertFalse(
                                    self.engine.ticks_when(
                                        stu0.avatar.only.historical('location')
                                        == stu1.avatar.only.historical(
                                            'location') == self.engine.alias(
                                                common)),
                                    "{} seems to have been in the same"
                                    "common room  as {}".format(
                                        stu0.name, stu1.name))