Skip to content

Commit

Permalink
Merge pull request #4 from artembakhanov/tests_and_documentation
Browse files Browse the repository at this point in the history
Tests and documentation + update 1.0.4
  • Loading branch information
artembakhanov authored Jan 13, 2021
2 parents d6ea017 + 449c10d commit c2f27dd
Show file tree
Hide file tree
Showing 8 changed files with 202 additions and 10 deletions.
32 changes: 32 additions & 0 deletions .github/workflows/test_library.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Tests

on: [push]

jobs:
build:

runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.6, 3.7, 3.8]

steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install flake8 pytest
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Test with pytest
run: |
pytest
26 changes: 26 additions & 0 deletions .github/workflows/upload_package.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Upload Package

on:
release:
types: [created]

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools wheel twine
- name: Build and publish
env:
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
run: |
python setup.py sdist bdist_wheel
twine upload dist/*
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

[![PyPI version](https://badge.fury.io/py/python-telegram-bot-calendar.svg)](https://badge.fury.io/py/python-telegram-bot-calendar)
[![CodeFactor](https://www.codefactor.io/repository/github/artembakhanov/python-telegram-bot-calendar/badge)](https://www.codefactor.io/repository/github/artembakhanov/python-telegram-bot-calendar)
![cock](https://github.com/artembakhanov/python-telegram-bot-calendar/workflows/Tests/badge.svg)

Very simple inline calendar for your bot.

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
setup(
name='python-telegram-bot-calendar',
packages=['telegram_bot_calendar'],
version='1.0.2',
version='1.0.4',
license='MIT',
description='Python inline calendar for telegram bots',
long_description=long_description,
Expand Down
20 changes: 19 additions & 1 deletion telegram_bot_calendar/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class TelegramCalendar:
step = None

def __init__(self, calendar_id=0, current_date=None, additional_buttons=None, locale='en', min_date=None,
max_date=None, **kwargs):
max_date=None, is_random=True, **kwargs):
"""
:param date current_date: Where calendar starts, if None the current date is used
Expand All @@ -59,6 +59,9 @@ def __init__(self, calendar_id=0, current_date=None, additional_buttons=None, lo
self.min_date = min_date
self.max_date = max_date

# whether to add random numbers to callbacks
self.is_random = True

if not additional_buttons: additional_buttons = []
self.additional_buttons = rows(additional_buttons, self.size_additional_buttons)

Expand Down Expand Up @@ -129,6 +132,10 @@ def _valid_date(self, d):
return self.min_date <= d <= self.max_date

def _get_period(self, step, start, diff, *args, **kwargs):
"""
Used for getting period of dates with a given step, start date and difference.
It allows to create empty dates if they are not in the given range.
"""
lstep = LSTEP[step] + "s"
dates = []

Expand All @@ -147,10 +154,21 @@ def _get_period(self, step, start, diff, *args, **kwargs):


def rows(buttons, row_size):
"""
Build rows for the keyboard. Divides list of buttons to list of lists of buttons.
"""
return [buttons[i:i + row_size] for i in range(0, max(len(buttons) - row_size, 0) + 1, row_size)]


def max_date(d, step):
"""
Returns the "biggest" possible date for a given step.
It is used for navigations buttons when it is needed to check if prev/next page exists.
:param d datetime
:param step current step
"""
if step == YEAR:
return d.replace(month=12, day=31)
elif step == MONTH:
Expand Down
16 changes: 8 additions & 8 deletions telegram_bot_calendar/detailed.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ class DetailedTelegramCalendar(TelegramCalendar):

def __init__(self, calendar_id=0, current_date=None, additional_buttons=None, locale='en',
min_date=None,
max_date=None, **kwargs):
max_date=None, is_random=True, **kwargs):
super(DetailedTelegramCalendar, self).__init__(calendar_id, current_date=current_date,
additional_buttons=additional_buttons, locale=locale,
min_date=min_date, max_date=max_date)
min_date=min_date, max_date=max_date, is_random=is_random)

def _build(self, step=None, **kwargs):
if not step:
Expand Down Expand Up @@ -63,7 +63,7 @@ def _build_years(self, *args, **kwargs):
years_buttons = rows(
[
self._build_button(d.year if d else self.empty_year_button, SELECT if d else NOTHING, YEAR, d,
is_random=True)
is_random=self.is_random)
for d in years
],
self.size_year
Expand All @@ -83,7 +83,7 @@ def _build_months(self, *args, **kwargs):
self._build_button(
self.months[self.locale][d.month - 1] if d else self.empty_month_button, # button text
SELECT if d else NOTHING, # action
MONTH, d, is_random=True # other parameters
MONTH, d, is_random=self.is_random # other parameters
)
for d in months
],
Expand All @@ -104,7 +104,7 @@ def _build_days(self, *args, **kwargs):
days_buttons = rows(
[
self._build_button(d.day if d else self.empty_day_button, SELECT if d else NOTHING, DAY, d,
is_random=True)
is_random=self.is_random)
for d in days
],
self.size_day
Expand Down Expand Up @@ -137,11 +137,11 @@ def _build_nav_buttons(self, step, diff, mind, maxd, *args, **kwargs):

return [[
self._build_button(text[0].format(**data) if prev_exists else self.empty_nav_button,
GOTO if prev_exists else NOTHING, step, prev_page, is_random=True),
GOTO if prev_exists else NOTHING, step, prev_page, is_random=self.is_random),
self._build_button(text[1].format(**data),
PREV_ACTIONS[step], PREV_STEPS[step], self.current_date, is_random=True),
PREV_ACTIONS[step], PREV_STEPS[step], self.current_date, is_random=self.is_random),
self._build_button(text[2].format(**data) if next_exists else self.empty_nav_button,
GOTO if next_exists else NOTHING, step, next_page, is_random=True),
GOTO if next_exists else NOTHING, step, next_page, is_random=self.is_random),
]]

def _get_period(self, step, start, diff, *args, **kwargs):
Expand Down
51 changes: 51 additions & 0 deletions tests/test_base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import pytest
import sys, os
from datetime import date
from types import SimpleNamespace

myPath = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, myPath + '/../')
from telegram_bot_calendar.base import YEAR, MONTH, DAY, max_date, min_date, TelegramCalendar, CB_CALENDAR


@pytest.mark.parametrize(('given', 'step', 'max_d'), [(date(2019, 5, 2), YEAR, date(2019, 12, 31)),
(date(1999, 12, 30), YEAR, date(1999, 12, 31)),
(date(2001, 1, 2), YEAR, date(2001, 12, 31)),
(date(2012, 5, 1), MONTH, date(2012, 5, 31)),
(date(2019, 9, 15), MONTH, date(2019, 9, 30)),
(date(2016, 2, 10), MONTH, date(2016, 2, 29)),
(date(2016, 2, 10), DAY, date(2016, 2, 10)),
])
def test_max_date(given, step, max_d):
assert max_date(given, step) == max_d


@pytest.mark.parametrize(('given', 'step', 'min_d'), [(date(2019, 5, 2), YEAR, date(2019, 1, 1)),
(date(1999, 12, 30), YEAR, date(1999, 1, 1)),
(date(2001, 1, 2), YEAR, date(2001, 1, 1)),
(date(2012, 5, 1), MONTH, date(2012, 5, 1)),
(date(2019, 9, 15), MONTH, date(2019, 9, 1)),
(date(2016, 2, 10), MONTH, date(2016, 2, 1)),
(date(2016, 2, 10), DAY, date(2016, 2, 10)),
])
def test_min_date(given, step, min_d):
assert min_date(given, step) == min_d


@pytest.mark.parametrize(('min_date', 'max_date', 'step', 'start', 'diff', 'period'),
[(date(2019, 11, 9), None, YEAR, date(2020, 1, 12), 2,
[date(2020, 1, 12), date(2021, 1, 12)])])
def test__get_period(min_date, max_date, step, start, diff, period):
telegram_calendar = TelegramCalendar(min_date=min_date, max_date=max_date)

assert telegram_calendar._get_period(step, start, diff) == period


@pytest.mark.parametrize(('calendar_id', 'callback_data', 'passed'),
[(0, 'cbcal_0_g_y_2017_1_13_238946419208856913', True),
(1, 'cbcal_0_g_y_2017_1_13_238946419208856913', False),
(1, 'cbcal_1_s_d_2016_8_25_971574741092873836', True),
(0, 'something_irrelevant', False),
(22, 'cbcal_22_n', True), ])
def test_func(calendar_id, callback_data, passed):
assert TelegramCalendar.func(calendar_id)(SimpleNamespace(data=callback_data)) == passed
64 changes: 64 additions & 0 deletions tests/test_detailed.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import json
import os
import sys
from datetime import date

import pytest
from dateutil.relativedelta import relativedelta

from telegram_bot_calendar import DAY, MONTH, YEAR
from telegram_bot_calendar.detailed import DetailedTelegramCalendar, NOTHING

myPath = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, myPath + '/../')


# todo: fix this test to properly check generated keyboard
@pytest.mark.parametrize(('callback_data', 'result', 'key', 'step'),
[('cbcal_0_s_m_2021_11_13_726706365801178150', None, None, DAY),
('cbcal_0_s_d_2021_11_13_726706365801178150', date(2021, 11, 13), None, DAY),
('cbcal_0_s_y_2020_1_1_726702345801178150', None, None, MONTH),
('cbcal_0_n_726702345801178150', None, None, None),
('cbcal_0_g_m_2022_5_7_726702345801178150', None, None, MONTH)])
def test_process(callback_data, result, key, step):
calendar = DetailedTelegramCalendar(current_date=date(2021, 1, 12))
result_, _, step_ = calendar.process(callback_data)
assert result_ == result and step_ == step


@pytest.mark.parametrize(
('step', 'start', 'diff', 'mind', 'maxd', 'min_button_date', 'max_button_date', 'result_buttons'),
[
(
MONTH, date(2021, 1, 12), relativedelta(months=12), date(2021, 1, 1), date(2021, 3, 2), date(2021, 1, 1),
date(2021, 3, 2),
[{'text': "×", "callback_data": "cbcal_0_n"},
{'text': "2021", "callback_data": "cbcal_0_g_y_2021_1_12"},
{'text': "×", "callback_data": "cbcal_0_n"}]
),
(
MONTH, date(2021, 1, 12), relativedelta(months=12), date(2021, 1, 1), date(2022, 1, 1), date(2021, 1, 1),
date(2021, 12, 1),
[{'text': "×", "callback_data": "cbcal_0_n"},
{'text': "2021", "callback_data": "cbcal_0_g_y_2021_1_12"},
{'text': ">>", "callback_data": "cbcal_0_g_m_2022_1_1"}]
),
(
YEAR, date(2021, 5, 12), relativedelta(years=4), date(2018, 5, 12), date(2023, 5, 12), date(2019, 5, 12),
date(2019, 5, 12),
[{'text': "<<", "callback_data": "cbcal_0_g_y_2017_5_12"},
{'text': " ", "callback_data": "cbcal_0_n"},
{'text': ">>", "callback_data": "cbcal_0_g_y_2025_5_12"}]
)
])
def test__build_nav_buttons(step, start, diff, mind, maxd, min_button_date, max_button_date, result_buttons):
calendar = DetailedTelegramCalendar(current_date=start, min_date=mind, max_date=maxd)
buttons = calendar._build_nav_buttons(step, diff, min_button_date, max_button_date)

result = True
print(buttons[0])
for i, button in enumerate(buttons[0]):
if button['text'] != result_buttons[i]['text'] or button['callback_data'].startswith(result_buttons[i]['text']):
result = False

assert result

0 comments on commit c2f27dd

Please sign in to comment.