Skip to content

Commit

Permalink
Merge pull request #58 from lehinevych/tests
Browse files Browse the repository at this point in the history
Increase tests and update the docs
  • Loading branch information
lehinevych authored Feb 1, 2023
2 parents 56f38b0 + c5d4f5d commit 48cf385
Show file tree
Hide file tree
Showing 13 changed files with 135 additions and 16 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,4 @@ jobs:
- name: Test with pytest
run: |
poetry run pytest --junitxml=pytest.xml --cov-report=term-missing:skip-covered --cov=mediawikiapi --cov-fail-under=78
poetry run pytest --junitxml=pytest.xml --cov-report=term-missing:skip-covered --cov=mediawikiapi --cov-fail-under=82
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,9 @@ The documentation is available [here](http://mediawikiapi.readthedocs.io/en/late
To run tests, clone the [repository on GitHub](https://github.com/lehinevych/MediaWikiAPI), then run:

```bash
pip install -r requirements.txt
python -m unittest discover tests/ '*test.py' # manual style
poetry install
poetry build
poetry run pytest --junitxml=pytest.xml --cov-report=term-missing:skip-covered --cov=mediawikiapi
```
in the root project directory.

Expand All @@ -80,9 +81,9 @@ make html
To run formatter and mypy run:

```
black --diff --check $(git ls-files '*.py')
pylint --disable=all --enable=unused-import $(git ls-files '*.py')
mypy --strict $(git ls-files '*.py')
poetry run mypy --strict .
poetry run flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
poetry run black --diff --check .
```

License
Expand Down
8 changes: 8 additions & 0 deletions docs/source/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ Contents:

changelog


Version 1.2
=============
* The `Config` allows to specify the API url. This makes the client reusable for other Mediawiki installs with the same API.
* Move to the [poetry](https://python-poetry.org/) packaing and dependencies management tool
* Add typing and mypy check
* Format the code and use the formatting checks

Version 1.1.6
=============
* Add support for Python 3.9, 3.10 and 3.11
Expand Down
6 changes: 6 additions & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ Exception handling example::
>>> except mediawikiapi.exceptions.PageError:
>>> print("Got page error, skipping")


The library can be used for other Mediawiki installs and sites except Wikipedia which onwer the same API.

>>> import mediawikiapi
>>> mediawiki = mediawikiapi.MediaWikiAPI(config=Config(mediawiki_url="https://{}.wiktionary.org/w/api.php"))

For more details and configuration option check API section.


Expand Down
16 changes: 8 additions & 8 deletions mediawikiapi/config.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from datetime import timedelta, datetime
from typing import Union, Optional
from datetime import timedelta
from typing import Union, Optional, Any
from .language import Language


Expand All @@ -8,6 +8,7 @@ class Config(object):
Contains global configuration
"""

DEFAULT_TIMEOUT = 3.0
DEFAULT_USER_AGENT = "mediawikiapi (https://github.com/lehinevych/MediaWikiAPI/)"
DONATE_URL = (
"https://donate.wikimedia.org/w/index.php?title=Special:FundraiserLandingPage"
Expand All @@ -18,6 +19,7 @@ def __init__(
self,
language: Optional[str] = None,
user_agent: Optional[str] = None,
timeout: Optional[float] = None,
rate_limit: Optional[Union[int, timedelta]] = None,
mediawiki_url: Optional[str] = None,
):
Expand All @@ -27,10 +29,10 @@ def __init__(
self.__lang = Language()
if isinstance(rate_limit, int):
rate_limit = timedelta(milliseconds=rate_limit)
self.__rate_limit = rate_limit
self.timeout = None
self.user_agent = user_agent or self.DEFAULT_USER_AGENT
self.mediawiki_url = mediawiki_url or self.API_URL
self.__rate_limit: Optional[timedelta] = rate_limit
self.timeout: float = timeout or self.DEFAULT_TIMEOUT
self.user_agent: str = user_agent or self.DEFAULT_USER_AGENT
self.mediawiki_url: str = mediawiki_url or self.API_URL

@classmethod
def donate_url(cls) -> str:
Expand Down Expand Up @@ -93,5 +95,3 @@ def rate_limit(self, rate_limit: Optional[Union[int, timedelta]] = None) -> None
self.__rate_limit = rate_limit
else:
self.__rate_limit = timedelta(milliseconds=rate_limit)

self.__rate_limit_last_call = None
4 changes: 2 additions & 2 deletions tests/request_mock_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -2279,8 +2279,8 @@
"wikibase-shortdesc": "Lettuce cultivar",
"wikibase_item": "Q574172",
},
"cyclone.revid": 1125358718,
"cyclone.parentid": 1119469655,
"cyclone.revid": 1131577210,
"cyclone.parentid": 1131577096,
"cyclone.section.seasonal_forecasts": "Noted hurricane experts Philip J. Klotzbach, William M. Gray, and their associates at Colorado State University issue forecasts of hurricane activity each year, separately from NOAA. Klotzbach's team, formerly led by Gray, determined the average number of storms per season between 1950 and 2000 to be 9.6 tropical storms, 5.9 hurricanes, and 2.3 major hurricanes (storms exceeding Category 3 on the Saffir–Simpson scale). A normal season, as defined by NOAA, has 9 to 12 named storms, of which five to seven reach hurricane strength, and one to three become major hurricanes.",
"cyclone.ru_lang": "Сезон атлантических ураганов 2007 года",
"cyclone.pageprops": {
Expand Down
16 changes: 16 additions & 0 deletions tests/test_client_configs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
import unittest

from collections import defaultdict
from decimal import Decimal
from typing import Dict, Any
from mediawikiapi import MediaWikiAPI
from mediawikiapi.config import Config

api = MediaWikiAPI(config=Config(mediawiki_url="https://{}.wiktionary.org/w/api.php"))


class TestSearchLoc(unittest.TestCase):
def test_search_in_wiktionary(self) -> None:
"""Test parsing a mediawikiapi location request result."""
self.assertIn("python", api.search("python"))
88 changes: 88 additions & 0 deletions tests/test_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# -*- coding: utf-8 -*-
import unittest
from datetime import timedelta
from mediawikiapi.config import Config
from mediawikiapi import Language


class TestConfig(unittest.TestCase):
def test_default_language_config(self) -> None:
self.assertEqual(Config().language, Language.DEFAULT_LANGUAGE)

def test_default_user_agent_config(self) -> None:
self.assertEqual(Config().user_agent, Config.DEFAULT_USER_AGENT)

def test_default_get_api_url(self) -> None:
self.assertEqual(
Config().get_api_url(), Config.API_URL.format(Language.DEFAULT_LANGUAGE)
)

def test_default_timeout(self) -> None:
self.assertEqual(Config().timeout, Config.DEFAULT_TIMEOUT)

def test_custom_timeout(self) -> None:
custom_timeout = 10
self.assertEqual(Config(timeout=custom_timeout).timeout, custom_timeout)

def test_default_get_api_url_with_custom_language(self) -> None:
fr_lang = "fr"
uk_lang = "uk"
config = Config()
self.assertEqual(
config.get_api_url(language=fr_lang), config.API_URL.format(fr_lang)
)
self.assertEqual(
config.get_api_url(language=Language(uk_lang)),
config.API_URL.format(uk_lang),
)

def test_default_rate_limit_is_None(self) -> None:
self.assertEqual(Config().rate_limit, None)

def test_default_donate_url(self) -> None:
self.assertEqual(Config().donate_url(), Config.DONATE_URL)

def test_custom_api_url_with_language_support(self) -> None:
api_url = "https://{}.wiktionary.org/w/api.php"
self.assertEqual(
Config(mediawiki_url=api_url).get_api_url(),
api_url.format(Language.DEFAULT_LANGUAGE),
)

def test_custom_api_url_without_language_support(self) -> None:
api_url = "https://wiki.archlinux.org"
self.assertEqual(Config(mediawiki_url=api_url).get_api_url(), api_url)

def test_custom_rate_limit_as_int(self) -> None:
rate_limit: int = 10
self.assertEqual(
Config(rate_limit=rate_limit).rate_limit, timedelta(milliseconds=10)
)

def test_custom_rate_limit_as_timedelta(self) -> None:
rate_limit: timedelta = timedelta(milliseconds=10)
self.assertEqual(Config(rate_limit=rate_limit).rate_limit, rate_limit)

def test_set_rate_limit(self) -> None:
rate_limit_int = 10
rate_limit: timedelta = timedelta(milliseconds=rate_limit_int)
config = Config()
config.rate_limit = None
self.assertEqual(config.rate_limit, None)
config.rate_limit = rate_limit_int # type:ignore
self.assertEqual(config.rate_limit, rate_limit)
config.rate_limit = rate_limit
self.assertEqual(config.rate_limit, rate_limit)

def test_custom_language(self) -> None:
custom_lang = "fr"
self.assertEqual(Config(language=custom_lang).language, custom_lang)

def test_set_custom_language(self) -> None:
fr_lang = "fr"
uk_lang = "uk"
config = Config()
config.language = fr_lang
self.assertEqual(config.language, fr_lang)
config.language = Language(uk_lang) # type:ignore
self.assertEqual(config.language, uk_lang)
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 comments on commit 48cf385

Please sign in to comment.