Skip to content

Commit e36fd90

Browse files
authored
Merge pull request #690 from TotallyNotRobots/expand-coverage
Add more tests for db access
2 parents a38d7d4 + 8a02f78 commit e36fd90

File tree

18 files changed

+1437
-50
lines changed

18 files changed

+1437
-50
lines changed

.devcontainer/devcontainer.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
],
3838
"settings": {
3939
"python.pythonPath": "/usr/local/bin/python",
40-
"python.testing.pytestArgs": ["--no-cov"],
4140
"terminal.integrated.profiles.linux": {
4241
"zsh": {
4342
"path": "/usr/bin/zsh"

.vscode/settings.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
],
55
"python.testing.unittestEnabled": false,
66
"python.testing.pytestEnabled": true,
7-
"coverage-gutters.showLineCoverage": true,
8-
"coverage-gutters.showRulerCoverage": true
7+
"python.analysis.enablePytestSupport": true,
8+
"[python]": {
9+
"diffEditor.ignoreTrimWhitespace": false,
10+
"editor.formatOnType": true,
11+
"editor.wordBasedSuggestions": "off",
12+
"editor.defaultFormatter": "ms-python.black-formatter"
13+
}
914
}

cloudbot/bot.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,25 +29,28 @@
2929
logger = logging.getLogger("cloudbot")
3030

3131

32+
class AbstractBot:
33+
def __init__(self, *, config: Config) -> None:
34+
self.config = config
35+
36+
3237
class BotInstanceHolder:
33-
def __init__(self):
34-
self._instance = None
38+
def __init__(self) -> None:
39+
self._instance: Optional[AbstractBot] = None
3540

36-
def get(self):
37-
# type: () -> CloudBot
41+
def get(self) -> Optional[AbstractBot]:
3842
return self._instance
3943

40-
def set(self, value):
41-
# type: (CloudBot) -> None
44+
def set(self, value: Optional[AbstractBot]) -> None:
4245
self._instance = value
4346

4447
@property
45-
def config(self):
46-
# type: () -> Config
47-
if not self.get():
48+
def config(self) -> Config:
49+
instance = self.get()
50+
if not instance:
4851
raise ValueError("No bot instance available")
4952

50-
return self.get().config
53+
return instance.config
5154

5255

5356
# Store a global instance of the bot to allow easier access to global data
@@ -88,7 +91,7 @@ def get_cmd_regex(event):
8891
return cmd_re
8992

9093

91-
class CloudBot:
94+
class CloudBot(AbstractBot):
9295
def __init__(
9396
self,
9497
*,
@@ -127,7 +130,7 @@ def __init__(
127130
self.data_path.mkdir(parents=True)
128131

129132
# set up config
130-
self.config = Config(self)
133+
super().__init__(config=Config(self))
131134
logger.debug("Config system initialised.")
132135

133136
self.executor = ThreadPoolExecutor(

plugins/librefm.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def librefm(text, nick, db, event):
8484

8585
if (
8686
"track" not in response["recenttracks"]
87-
or response["recenttracks"]["track"]
87+
or not response["recenttracks"]["track"]
8888
):
8989
return f'No recent tracks for user "{user}" found.'
9090

@@ -243,7 +243,7 @@ def toptrack(text, nick):
243243
return "Error: {}.".format(data["message"])
244244

245245
out = f"{username}'s favorite songs: "
246-
for r in range(5):
246+
for r in range(min(5, len(data["toptracks"]["track"]))):
247247
track_name = data["toptracks"]["track"][r]["name"]
248248
artist_name = data["toptracks"]["track"][r]["artist"]["name"]
249249
play_count = data["toptracks"]["track"][r]["playcount"]

plugins/quote.py

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
String,
1010
Table,
1111
func,
12+
inspect,
1213
not_,
1314
select,
1415
)
@@ -44,8 +45,9 @@ def migrate_table(db, logger):
4445
Column("deleted", String(5), default=0),
4546
PrimaryKeyConstraint("chan", "nick", "time"),
4647
)
48+
inspector = inspect(db.bind)
4749

48-
if not old_table.exists():
50+
if not inspector.has_table(old_table.name):
4951
database.metadata.remove(old_table)
5052
return
5153

@@ -106,19 +108,6 @@ def add_quote(db, chan, target, sender, message):
106108
return "Quote added."
107109

108110

109-
def del_quote(db, nick, msg):
110-
"""Deletes a quote from a nick"""
111-
query = (
112-
qtable.update()
113-
.where(qtable.c.chan == 1)
114-
.where(qtable.c.nick == nick.lower())
115-
.where(qtable.c.msg == msg)
116-
.values(deleted=True)
117-
)
118-
db.execute(query)
119-
db.commit()
120-
121-
122111
def get_quote_num(num, count, name):
123112
"""Returns the quote number to fetch from the DB"""
124113
if num: # Make sure num is a number if it isn't false

tests/conftest.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,14 @@ def mock_db(tmp_path):
5959

6060

6161
@pytest.fixture()
62-
def mock_bot_factory(event_loop, tmp_path):
62+
def mock_bot_factory(event_loop, tmp_path, unset_bot):
6363
instances: List[MockBot] = []
6464

6565
def _factory(*args, **kwargs):
6666
kwargs.setdefault("loop", event_loop)
6767
kwargs.setdefault("base_dir", tmp_path)
6868
_bot = MockBot(*args, **kwargs)
69+
bot.set(_bot)
6970
instances.append(_bot)
7071
return _bot
7172

tests/core_tests/test_bot.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import pytest
55
from sqlalchemy import Column, String, Table
66

7+
import cloudbot.bot
78
from cloudbot import hook
89
from cloudbot.bot import CloudBot, clean_name, get_cmd_regex
910
from cloudbot.event import Event, EventType
@@ -15,6 +16,12 @@
1516
from tests.util.mock_db import MockDB
1617

1718

19+
def test_no_instance_config(unset_bot):
20+
cloudbot.bot.bot.set(None)
21+
with pytest.raises(ValueError):
22+
_ = cloudbot.bot.bot.config
23+
24+
1825
@pytest.mark.asyncio()
1926
async def test_migrate_db(
2027
mock_db, mock_bot_factory, event_loop, mock_requests, tmp_path

0 commit comments

Comments
 (0)