Beispiel #1
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()
Beispiel #2
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()
Beispiel #3
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)
Beispiel #4
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)
Beispiel #5
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)
Beispiel #6
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)
Beispiel #7
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)
Beispiel #8
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))