Example #1
0
def test_profile(tmp_path, monkeypatch):
    '''Test fetching the bot profile.'''
    discard = Discard(mode="profile", token=TEST_TOKEN, output_dir=tmp_path)
    monkeypatch_discard(monkeypatch, discard)

    discard.run()

    directories = list(tmp_path.iterdir())

    assert len(directories) == 1

    run_directory = directories[0]

    with open(run_directory / 'run.meta.json') as f:
        obj = json.load(f)
        assert obj['client']['name'] == 'discard'
        assert 'version' in obj['client']
        assert 'discord.py_version' in obj['client']
        assert obj['settings']['mode'] == 'profile'
        assert obj['settings']['token'] == None
        assert obj['run']['completed'] == True
        assert obj['run']['finished'] == True
        assert obj['run']['errors'] == False
        assert obj['run']['exception'] == None
        assert obj['user']['name'] == 'DiscardTest'

    with open(run_directory / 'run.jsonl') as f:
        for line in f:
            if line.strip():
                obj = json.loads(line)
                assert obj['type'] in ['http', 'ws']
Example #2
0
    def __init__(self, nbPlayers):
        self.table = Table()
        self.players = []
        self.gameDone = False
        self.currPlayer = 0
        self.discard = Discard()
        self.stacks = {}
        for name, member in Colour.__members__.items():
            self.stacks[name] = 0

        for i in range(nbPlayers):
            self.players.append(Player(i))
            for j in range(5):
                self.players[i].draw(self.table.getTopCardFromDeck())
Example #3
0
def test_wrong_token(tmp_path, monkeypatch):
    '''Test correct exception handling when connecting with a wrong token.'''
    discard = Discard(mode="profile", token="incorrect", output_dir=tmp_path)
    monkeypatch_discard(monkeypatch, discard)

    with pytest.raises(discord.errors.LoginFailure):
        discard.run()

    run_directory = list(tmp_path.iterdir())[0]

    with open(run_directory / 'run.meta.json') as f:
        obj = json.load(f)
        assert obj['run']['completed'] == False
        assert obj['run']['finished'] == True
        assert obj['run']['errors'] == True
        assert obj['run']['exception'].startswith('LoginFailure')
Example #4
0
def test_channel(tmp_path, monkeypatch):
    '''Test archiving a single channel.'''
    discard = Discard(mode="channel",
                      channel_id=TEST_CHANNEL.id,
                      token=TEST_TOKEN,
                      output_dir=tmp_path)
    monkeypatch_discard(monkeypatch, discard)

    discard.run()

    run_directory = list(tmp_path.iterdir())[0]

    with open(run_directory / 'run.meta.json') as f:
        obj = json.load(f)
        assert obj['client']['name'] == 'discard'
        assert obj['settings']['mode'] == 'channel'
        assert obj['run']['completed'] == True
        assert obj['run']['finished'] == True
        assert obj['run']['errors'] == False
        assert obj['run']['exception'] == None

    with open(run_directory / 'run.jsonl') as f:
        for line in f:
            if line.strip():
                obj = json.loads(line)
                assert obj['type'] in ['http', 'ws']

    with open(run_directory / Path(str(TEST_GUILD.id)) /
              Path(f"{TEST_CHANNEL.id}.meta.json")) as f:
        obj = json.load(f)
        assert obj['channel']['id'] == TEST_CHANNEL.id
        assert obj['channel']['name'] == TEST_CHANNEL.name
        assert obj['summary']['num_messages'] > 0

    fetched_reactions = False

    with open(run_directory / Path(str(TEST_GUILD.id)) /
              Path(f"{TEST_CHANNEL.id}.jsonl")) as f:
        for line in f:
            if line.strip():
                obj = json.loads(line)
                assert obj['type'] in ['http', 'ws']
                if obj['type'] == 'http' and '/reactions' in obj['request'][
                        'url']:
                    fetched_reactions = True

    assert fetched_reactions
Example #5
0
def test_gzip(tmp_path, monkeypatch):
    '''Test saving gzipped files.'''
    discard = Discard(mode="profile",
                      token=TEST_TOKEN,
                      output_dir=tmp_path,
                      gzip=True)
    monkeypatch_discard(monkeypatch, discard)

    discard.run()

    run_directory = list(tmp_path.iterdir())[0]

    with open(run_directory / 'run.meta.json') as f:
        obj = json.load(f)
        assert obj['settings']['gzip'] == True

    with gzip.open(str(run_directory / 'run.jsonl.gz')) as f:
        for line in f:
            if line.strip():
                obj = json.loads(line)
                assert obj['type'] in ['http', 'ws']
Example #6
0
class Game(object):
    def __init__(self, nbPlayers):
        self.table = Table()
        self.players = []
        self.gameDone = False
        self.currPlayer = 0
        self.discard = Discard()
        self.stacks = {}
        for name, member in Colour.__members__.items():
            self.stacks[name] = 0

        for i in range(nbPlayers):
            self.players.append(Player(i))
            for j in range(5):
                self.players[i].draw(self.table.getTopCardFromDeck())

    def performAction(self, action):
        if isinstance(action, GiveInformationAction):
            target = action.getTarget() + self.currPlayer + 1
            if target >= 4:
                target -= 4
            if target == self.currPlayer:
                raise CheatRulesException("Cant give information to self")

            self.table.removeToken()
            try:
                self.players[target].receiveInformation(
                    action.getInformation())
            except CheatRulesException as error:
                # Give token back if move was invalid
                self.table.addToken()
                raise error

        if isinstance(action, DiscardCardAction):
            self.discardCardFromPlayer(self.currPlayer, action.getCard())
            try:
                self.players[self.currPlayer].draw(
                    self.table.getTopCardFromDeck())
            except GameOverException as error:
                # print(error)
                self.gameDone = True

        if isinstance(action, PlayCardAction):
            try:
                self.playCard(self.currPlayer, action.getCard())
            except GameOverException as error:
                # print(error)
                self.gameDone = True
            try:
                self.players[self.currPlayer].draw(
                    self.table.getTopCardFromDeck())
            except GameOverException as error:
                # print(error)
                self.gameDone = True

        if sum(self.stacks.values()) == 25:
            self.gameDone = True

        self.currPlayer += 1
        if (self.currPlayer == 4):
            self.currPlayer = 0
        # print(str(self))

    def getState(self):
        return GameState(
            self.players[self.currPlayer].getId(),
            self.players[self.currPlayer].getHand(),
            self.getOtherHands(self.players[self.currPlayer].getId()),
            self.discard, self.stacks, self.table.getTokens(),
            self.table.getFuse())

    def getScore(self):
        score = sum(self.stacks.values()) + self.table.getFuse()
        # print(score)
        return score

    def getOtherHands(self, id):
        return list(filter(lambda p: p.getId() != id, self.players))

    def discardCardFromPlayer(self, currPlayer, card):
        self.table.addToken()
        self.discard.addCard(self.players[currPlayer].removeCard(card))

    def playCard(self, currPlayer, card):
        card = self.players[currPlayer].removeCard(card)
        if self.stacks[card.getColour()] == card.getNumber() - 1:
            self.stacks[card.getColour()] += 1
            if self.stacks[card.getColour()] == 5:
                try:
                    self.table.addToken()
                except CheatRulesExceptionas as error:
                    # Dont punish ai for this
                    pass
        else:
            self.discard.addCard(card)
            self.table.removeFuse()

    def isGameDone(self):
        if self.gameDone:
            print(str(self))
        return self.gameDone

    def end(self):
        self.gameDone = True

    def informationTotal(self):
        return sum([p.getInformationValue() for p in self.players])

    def __str__(self):
        return "C:{}|I:{}|S:{}|F:{}T:{}|D:{}".format(
            str.join(",", [
                str.join("", [str(c) for c in p.getCards()])
                for p in self.players
            ]),
            str.join(",", [
                str.join("", [str(c) for c in p.getHand()])
                for p in self.players
            ]),
            str.join("", [
                str(self.stacks[name])
                for name, member in Colour.__members__.items()
            ]), self.table.getFuse(), self.table.getTokens(),
            str(self.discard))
Example #7
0
def guild(ctx, guild_id):
    require_token(ctx)
    discard = Discard(mode="guild", guild_id=guild_id, **ctx.obj)
    discard.run()
Example #8
0
def channel(ctx, channel_id):
    require_token(ctx)
    discard = Discard(mode="channel", channel_id=channel_id, **ctx.obj)
    discard.run()
Example #9
0
def profile(ctx):
    require_token(ctx)
    discard = Discard(mode="profile", **ctx.obj)
    discard.run()