diff --git a/tests/test_flask_moment.py b/tests/test_flask_moment.py index 7c6ce82..6fd301e 100644 --- a/tests/test_flask_moment.py +++ b/tests/test_flask_moment.py @@ -1,299 +1,251 @@ from datetime import datetime -from flask import render_template_string -from markupsafe import Markup -from flask_moment import _moment, Moment, default_moment_version, \ - default_moment_sri - - -# Mock Objects - -class NewDate(datetime): - """http://stackoverflow.com/questions/4481954""" - - @classmethod - def utcnow(cls): - return cls(2017, 1, 15, 22, 1, 21, 101361) - - -_datetime_mock = NewDate - - -class NewPrivateMoment(_moment): - """Mock the _moment class for predictable now timestamps""" - - def __init__(self, timestamp=None, local=False): - if timestamp is None: - timestamp = _datetime_mock.utcnow() - self.timestamp = timestamp - self.local = local - - -_moment_mock = NewPrivateMoment - - -class NewPublicMoment(Moment): - """Mock the Moment class for predictable now timestamps""" - - def init_app(self, app): - if not hasattr(app, 'extensions'): - app.extensions = {} - app.extensions['moment'] = _moment_mock - app.context_processor(self.context_processor) +import unittest +from unittest import mock +from flask import Flask, render_template_string +from markupsafe import Markup -_Moment = NewPublicMoment +from flask_moment import Moment, default_moment_version, default_moment_sri -# Testing +class TestMoment(unittest.TestCase): + def setUp(self): + self.app = Flask(__name__) + self.moment = Moment(self.app) + self.appctx = self.app.app_context() + self._moment = self.app.extensions['moment'] + self.appctx.push() -class TestFlaskAppSetup(object): + def tearDown(self): + self.appctx.pop() - def test_init_app(self, app, moment): - assert app.extensions['moment'] == _moment + def test_init(self): + assert self.app.extensions['moment'].__name__ == '_moment' + assert self.app.template_context_processors[None][1].__globals__[ + '__name__'] == 'flask_moment' - def test_app_context_processor(self, app, moment): + def test_init_app(self): + app = Flask(__name__) + moment = Moment() + moment.init_app(app) + assert app.extensions['moment'].__name__ == '_moment' assert app.template_context_processors[None][1].__globals__[ '__name__'] == 'flask_moment' - -class TestFlaskMomentIncludes(object): - def test_include_moment_directly(self): - include_moment = _moment.include_moment() - + include_moment = self._moment.include_moment() assert isinstance(include_moment, Markup) assert '' in str( include_moment) - def test_include_moment_renders_properly(self, app, moment): + def test_include_moment_renders_properly(self): ts = str(render_template_string('{{ moment.include_moment() }}')) - assert ' 0 def test__render_refresh(self): - mom = _moment_mock() - rts = mom._render(func='format', refresh=True) - + m = self._moment() + rts = m._render(func='format', refresh=True) assert isinstance(rts, Markup) assert rts.find('data-timestamp="') > 0 assert rts.find('data-function="format" data-refresh="60000"') > 0 def test_format_default(self): - mom = _moment_mock() - rts = mom.format('this-format-please') - + m = self._moment() + rts = m.format('this-format-please') assert rts.find( 'data-format="this-format-please" data-refresh="0"') > 0 def test_fromNow_default(self): - mom = _moment_mock() - rts = mom.fromNow() - + m = self._moment() + rts = m.fromNow() assert rts.find('data-function="fromNow" data-refresh="0"') > 0 def test_fromNow_no_suffix(self): - mom = _moment_mock() - rts = mom.fromNow(no_suffix=True) - + m = self._moment() + rts = m.fromNow(no_suffix=True) assert rts.find('data-function="fromNow" data-nosuffix="1" ' 'data-refresh="0"') > 0 def test_fromTime_default(self): - mom = _moment_mock() + m = self._moment() ts = datetime(2017, 1, 15, 22, 47, 6, 479898) - rts = mom.fromTime(timestamp=ts) - + rts = m.fromTime(timestamp=ts) assert rts.find('data-function="from" data-timestamp2="{}" ' 'data-refresh="0"'.format( - mom._timestamp_as_iso_8601(ts))) > 0 - assert rts.find(mom._timestamp_as_iso_8601( - timestamp=mom.timestamp)) > 0 + m._timestamp_as_iso_8601(ts))) > 0 + assert rts.find(m._timestamp_as_iso_8601( + timestamp=m.timestamp)) > 0 def test_fromTime_no_suffix(self): - mom = _moment_mock() + m = self._moment() ts = datetime(2017, 1, 15, 22, 47, 6, 479898) - rts = mom.fromTime(timestamp=ts, no_suffix=True) - + rts = m.fromTime(timestamp=ts, no_suffix=True) assert rts.find('data-function="from" data-timestamp2="{}" ' 'data-nosuffix="1" data-refresh="0"'.format( - mom._timestamp_as_iso_8601(ts))) > 0 - assert rts.find(mom._timestamp_as_iso_8601( - timestamp=mom.timestamp)) > 0 + m._timestamp_as_iso_8601(ts))) > 0 + assert rts.find(m._timestamp_as_iso_8601( + timestamp=m.timestamp)) > 0 def test_toNow_default(self): - mom = _moment_mock() - rts = mom.toNow() - + m = self._moment() + rts = m.toNow() assert rts.find('data-function="toNow" data-refresh="0"') > 0 def test_toNow_no_suffix(self): - mom = _moment_mock() + m = self._moment() no_suffix = True - rts = mom.toNow(no_suffix=no_suffix) - + rts = m.toNow(no_suffix=no_suffix) assert rts.find('data-function="toNow" data-nosuffix="1" ' 'data-refresh="0"') > 0 def test_toTime_default(self): - mom = _moment_mock() + m = self._moment() ts = datetime(2020, 1, 15, 22, 47, 6, 479898) - rts = mom.toTime(timestamp=ts) - + rts = m.toTime(timestamp=ts) assert rts.find('data-function="to" data-timestamp2="{}" ' 'data-refresh="0"'.format( - mom._timestamp_as_iso_8601(ts))) > 0 - assert rts.find(mom._timestamp_as_iso_8601( - timestamp=mom.timestamp)) > 0 + m._timestamp_as_iso_8601(ts))) > 0 + assert rts.find(m._timestamp_as_iso_8601( + timestamp=m.timestamp)) > 0 def test_toTime_no_suffix(self): - mom = _moment_mock() + m = self._moment() ts = datetime(2020, 1, 15, 22, 47, 6, 479898) no_suffix = True - rts = mom.toTime(timestamp=ts, no_suffix=no_suffix) - + rts = m.toTime(timestamp=ts, no_suffix=no_suffix) assert rts.find('data-function="to" data-timestamp2="{}" ' 'data-nosuffix="1" data-refresh="0"'.format( - mom._timestamp_as_iso_8601(ts))) > 0 - assert rts.find(mom._timestamp_as_iso_8601( - timestamp=mom.timestamp)) > 0 + m._timestamp_as_iso_8601(ts))) > 0 + assert rts.find(m._timestamp_as_iso_8601( + timestamp=m.timestamp)) > 0 def test_calendar_default(self): - mom = _moment_mock() - rts = mom.calendar() - + m = self._moment() + rts = m.calendar() assert rts.find('data-function="calendar" data-refresh="0"') > 0 def test_valueOf_default(self): - mom = _moment_mock() - rts = mom.valueOf() - + m = self._moment() + rts = m.valueOf() assert rts.find('data-function="valueOf" data-refresh="0"') > 0 def test_unix_default(self): - mom = _moment_mock() - rts = mom.unix() - + m = self._moment() + rts = m.unix() assert rts.find('data-function="unix" data-refresh="0"') > 0 def test_diff_days(self): - mom = _moment_mock() + m = self._moment() ts = datetime(2020, 1, 15, 22, 47, 6, 479898) - rts = mom.diff(ts, 'days') - + rts = m.diff(ts, 'days') assert rts.find( 'data-function="diff" data-timestamp2="{}" data-units="days" ' 'data-refresh="0"'.format( - mom._timestamp_as_iso_8601(ts))) > 0 - assert rts.find(mom._timestamp_as_iso_8601( - timestamp=mom.timestamp)) > 0 + m._timestamp_as_iso_8601(ts))) > 0 + assert rts.find(m._timestamp_as_iso_8601( + timestamp=m.timestamp)) > 0 def test_diff_hours(self): - mom = _moment_mock() + m = self._moment() ts = datetime(2020, 1, 15, 22, 47, 6, 479898) - rts = mom.diff(ts, 'hours') - + rts = m.diff(ts, 'hours') assert rts.find( 'data-function="diff" data-timestamp2="{}" data-units="hours" ' 'data-refresh="0"'.format( - mom._timestamp_as_iso_8601(ts))) > 0 - assert rts.find(mom._timestamp_as_iso_8601( - timestamp=mom.timestamp)) > 0 - - -class TestPublicMomentClass(object): - """Tests for the Moment class""" - - def test_create_default_no_timestamp(self, app): - moment = _Moment() - moment.init_app(app) - - assert moment.create().timestamp == _datetime_mock.utcnow() - - def test_create_default_with_timestamp(self, app): - moment = _Moment() - moment.init_app(app) - + m._timestamp_as_iso_8601(ts))) > 0 + assert rts.find(m._timestamp_as_iso_8601( + timestamp=m.timestamp)) > 0 + + @mock.patch('flask_moment.datetime') + def test_create_default_no_timestamp(self, dt): + ts = datetime(2017, 1, 15, 22, 1, 21, 101361) + dt.utcnow.return_value = ts + moment = Moment() + moment.init_app(self.app) + assert moment.create().timestamp == ts + + def test_create_default_with_timestamp(self): + moment = Moment() + moment.init_app(self.app) ts = datetime(2017, 1, 15, 22, 47, 6, 479898) - assert moment.create(timestamp=ts).timestamp == ts - -class TestSubresourceIntegrity(object): def test_moment_with_non_default_versions(self): include_moment = None @@ -302,18 +254,17 @@ def _check_assertions(): assert 'integrity=\"' not in include_moment assert 'crossorigin\"' not in include_moment - include_moment = _moment.include_moment(version='2.8.0') + include_moment = self._moment.include_moment(version='2.8.0') _check_assertions() - include_moment = _moment.include_moment(version='2.3.1') + include_moment = self._moment.include_moment(version='2.3.1') _check_assertions() - include_moment = _moment.include_moment(version='2.16.8') + include_moment = self._moment.include_moment(version='2.16.8') _check_assertions() - include_moment = _moment.include_moment(version='2.30.1') + include_moment = self._moment.include_moment(version='2.30.1') _check_assertions() def test_moment_with_default_version(self): - include_moment = _moment.include_moment() - + include_moment = self._moment.include_moment() assert include_moment.startswith( ''.format(default_moment_version)) - include_moment = _moment.include_moment(version='2.0.0', - sri='sha384-12345678') - + include_moment = self._moment.include_moment(version='2.0.0', + sri='sha384-12345678') assert include_moment.startswith( '') def test_moment_local(self): - include_moment = _moment.include_moment(local_js=True) - + include_moment = self._moment.include_moment(local_js=True) assert 'src=\"' in include_moment assert 'integrity=\"' not in include_moment assert 'crossorigin\"' not in include_moment def test_moment_local_with_sri(self): - include_moment = _moment.include_moment(local_js=True, - sri='sha384-87654321') - + include_moment = self._moment.include_moment(local_js=True, + sri='sha384-87654321') assert 'src=\"' in include_moment assert 'integrity=\"sha384-87654321\"' in include_moment assert 'crossorigin=\"anonymous\"' in include_moment def test_disabling_moment_default(self): - include_moment = _moment.include_moment(sri=False) - + include_moment = self._moment.include_moment(sri=False) assert 'src=\"' in include_moment assert 'integrity=\"' not in include_moment assert 'crossorigin' not in include_moment def test_disabling_moment_custom(self): - include_moment = _moment.include_moment(local_js=True, sri=False) - + include_moment = self._moment.include_moment(local_js=True, sri=False) assert 'src=\"' in include_moment assert 'integrity=\"' not in include_moment assert 'crossorigin' not in include_moment def test_disabling_moment_custom_version(self): - include_moment = _moment.include_moment(version='2.17.9', sri=False) - + include_moment = self._moment.include_moment(version='2.17.9', sri=False) assert 'src=\"' in include_moment assert 'integrity=\"' not in include_moment assert 'crossorigin' not in include_moment diff --git a/tox.ini b/tox.ini index fb47f2f..81bf652 100644 --- a/tox.ini +++ b/tox.ini @@ -1,23 +1,34 @@ [tox] -envlist=flake8,py36,py37,py38,py39,pypy3 +envlist=flake8,py36,py37,py38,py39,pypy3,docs skip_missing_interpreters=true +[gh-actions] +python = + 3.6: py36 + 3.7: py37 + 3.8: py38 + 3.9: py39 + pypy3: pypy3 + [testenv] -commands=py.test --cov-report term-missing --cov=flask_moment tests +commands= + pip install -e . + pytest -p no:logging --cov=flask_moment --cov-branch --cov-report term-missing deps= pytest pytest-cov - mock -basepython= - py36: python3.6 - py37: python3.7 - py38: python3.8 - py39: python3.9 - pypy3: pypy3 [testenv:flake8] -basepython=python3.8 commands= flake8 flask_moment.py tests example deps= flake8 + +[testenv:docs] +changedir=docs +deps= + sphinx +whitelist_externals= + make +commands= + make html