<commit_before>"""
The latest version of this package is available at:
<http://github.com/jantman/biweeklybudget>

################################################################################
Copyright 2016 <NAME> <<EMAIL>> <http://www.jasonantman.com>

    This file is part of biweeklybudget, also known as biweeklybudget.

    biweeklybudget is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    biweeklybudget is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with biweeklybudget.  If not, see <http://www.gnu.org/licenses/>.

The Copyright and Authors attributions contained herein may not be removed or
otherwise altered, except to add the Author attribution of a contributor to
this work. (Additional Terms pursuant to Section 7b of the AGPL v3)
################################################################################
While not legally required, I sincerely request that anyone who finds
bugs please submit them at <https://github.com/jantman/biweeklybudget> or
to me via email, and that you send any contributions or improvements
either as a pull request on GitHub, or to me via email.
################################################################################

AUTHORS:
<NAME> <<EMAIL>> <http://www.jasonantman.com>
################################################################################
"""

import sys
import pytest
from datetime import datetime, date, timedelta
from sqlalchemy.orm.session import Session
from sqlalchemy import asc
from decimal import Decimal

from biweeklybudget.biweeklypayperiod import BiweeklyPayPeriod
from biweeklybudget.models.ofx_transaction import OFXTransaction
from biweeklybudget.models.transaction import Transaction
from biweeklybudget.models.scheduled_transaction import ScheduledTransaction
from biweeklybudget.models.budget_model import Budget
from biweeklybudget.tests.unit_helpers import binexp_to_dict

# https://code.google.com/p/mock/issues/detail?id=249
# py>=3.4 should use unittest.mock not the mock package on pypi
if (
        sys.version_info[0] < 3 or
        sys.version_info[0] == 3 and sys.version_info[1] < 4
):
    from mock import Mock, patch, call, DEFAULT
else:
    from unittest.mock import Mock, patch, call, DEFAULT

pbm = 'biweeklybudget.biweeklypayperiod'
pb = '%s.BiweeklyPayPeriod' % pbm


class TestInit(object):

    def setup(self):
        self.mock_sess = Mock(spec_set=Session)
        self.cls = BiweeklyPayPeriod(date(2017, 3, 17), self.mock_sess)

    def test_init(self):
        cls = BiweeklyPayPeriod(date(2017, 3, 17), self.mock_sess)
        assert cls._start_date == date(2017, 3, 17)
        assert cls._end_date == date(2017, 3, 30)
        assert cls._db == self.mock_sess
        assert cls._data_cache == {}

    def test_init_datetime(self):
        cls = BiweeklyPayPeriod(datetime(2017, 3, 17), self.mock_sess)
        assert cls._start_date == date(2017, 3, 17)
        assert cls._end_date == date(2017, 3, 30)
        assert cls._db == self.mock_sess
        assert cls._data_cache == {}


class TestProperties(object):

    def setup(self):
        self.mock_sess = Mock(spec_set=Session)
        self.cls = BiweeklyPayPeriod(date(2017, 3, 17), self.mock_sess)

    def test_period_interval(self):
        assert self.cls.period_interval == timedelta(days=14)

    def test_period_length(self):
        assert self.cls.period_length == timedelta(days=13)

    def test_start_date(self):
        assert self.cls.start_date == date(2017, 3, 17)

    def test_end_date(self):
        assert self.cls.end_date == date(2017, 3, 30)

    def test_next(self):
        assert self.cls.next == BiweeklyPayPeriod(
            date(2017, 3, 31), self.mock_sess)

    def test_previous(self):
        assert self.cls.previous == BiweeklyPayPeriod(
            date(2017, 3, 3), self.mock_sess)


class TestMagicMethods(object):

    def setup(self):
        self.mock_sess = Mock(spec_set=Session)
        self.cls = BiweeklyPayPeriod(date(2017, 3, 17), self.mock_sess)

    def test_repr(self):
        assert str(self.cls) == '<BiweeklyPayPeriod(2017-03-17)>'

    @pytest.mark.skipif(sys.version_info[0] >= 3, reason='py2 only')
    def test_ordering_py27(self):
        assert self.cls < BiweeklyPayPeriod(date(2017, 4, 16), self.mock_sess)
        assert self.cls > BiweeklyPayPeriod(date(2017, 2, 13), self.mock_sess)
        assert self.cls == BiweeklyPayPeriod(date(2017, 3, 17), self.mock_sess)
        self.cls < 2
        self.cls.__eq__(2)

    @pytest.mark.skipif(sys.version_info[0] < 3, reason='py3 only')
    def test_ordering_py3(self):
        assert self.cls < BiweeklyPayPeriod(date(2017, 4, 16), self.mock_sess)
        assert self.cls > BiweeklyPayPeriod(date(2017, 2, 13), self.mock_sess)
        assert self.cls == BiweeklyPayPeriod(date(2017, 3, 17), self.mock_sess)
        with pytest.raises(TypeError):
            self.cls < 2
        self.cls.__eq__(2)


class TestForDate(object):

    def setup(self):
        self.mock_sess = Mock(spec_set=Session)
        self.cls = BiweeklyPayPeriod(date(2017, 3, 17), self.mock_sess)

    def test_period_for_date(self):
        assert BiweeklyPayPeriod.period_for_date(
            date(2017, 3, 16), self.mock_sess) == BiweeklyPayPeriod(
            date(2017, 3, 3), self.mock_sess)
        assert BiweeklyPayPeriod.period_for_date(
            date(2017, 3, 17), self.mock_sess) == BiweeklyPayPeriod(
            date(2017, 3, 17), self.mock_sess)
        assert BiweeklyPayPeriod.period_for_date(
            date(2017, 3, 18), self.mock_sess) == BiweeklyPayPeriod(
            date(2017, 3, 17), self.mock_sess)
        assert BiweeklyPayPeriod.period_for_date(
            date(2017, 3, 30), self.mock_sess) == BiweeklyPayPeriod(
            date(2017, 3, 17), self.mock_sess)
        assert BiweeklyPayPeriod.period_for_date(
            date(2017, 3, 31), self.mock_sess) == BiweeklyPayPeriod(
            date(2017, 3, 31), self.mock_sess)
        assert BiweeklyPayPeriod.period_for_date(
            date(2017, 1, 21), self.mock_sess) == BiweeklyPayPeriod(
            date(2017, 1, 20), self.mock_sess)
        assert BiweeklyPayPeriod.period_for_date(
            date(2017, 5, 2), self.mock_sess) == BiweeklyPayPeriod(<commit_msg>fix test that started failing when tox was switched to the test_settings module<commit_after>"""
The latest version of this package is available at:
<http://github.com/jantman/biweeklybudget>

################################################################################
Copyright 2016 <NAME> <<EMAIL>> <http://www.jasonantman.com>

    This file is part of biweeklybudget, also known as biweeklybudget.

    biweeklybudget is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    biweeklybudget is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with biweeklybudget.  If not, see <http://www.gnu.org/licenses/>.

The Copyright and Authors attributions contained herein may not be removed or
otherwise altered, except to add the Author attribution of a contributor to
this work. (Additional Terms pursuant to Section 7b of the AGPL v3)
################################################################################
While not legally required, I sincerely request that anyone who finds
bugs please submit them at <https://github.com/jantman/biweeklybudget> or
to me via email, and that you send any contributions or improvements
either as a pull request on GitHub, or to me via email.
################################################################################

AUTHORS:
<NAME> <<EMAIL>> <http://www.jasonantman.com>
################################################################################
"""

import sys
import pytest
from datetime import datetime, date, timedelta
from sqlalchemy.orm.session import Session
from sqlalchemy import asc
from decimal import Decimal

from biweeklybudget.biweeklypayperiod import BiweeklyPayPeriod
from biweeklybudget.models.ofx_transaction import OFXTransaction
from biweeklybudget.models.transaction import Transaction
from biweeklybudget.models.scheduled_transaction import ScheduledTransaction
from biweeklybudget.models.budget_model import Budget
from biweeklybudget.tests.unit_helpers import binexp_to_dict

# https://code.google.com/p/mock/issues/detail?id=249
# py>=3.4 should use unittest.mock not the mock package on pypi
if (
        sys.version_info[0] < 3 or
        sys.version_info[0] == 3 and sys.version_info[1] < 4
):
    from mock import Mock, patch, call, DEFAULT
else:
    from unittest.mock import Mock, patch, call, DEFAULT

pbm = 'biweeklybudget.biweeklypayperiod'
pb = '%s.BiweeklyPayPeriod' % pbm


class TestInit(object):

    def setup(self):
        self.mock_sess = Mock(spec_set=Session)
        self.cls = BiweeklyPayPeriod(date(2017, 3, 17), self.mock_sess)

    def test_init(self):
        cls = BiweeklyPayPeriod(date(2017, 3, 17), self.mock_sess)
        assert cls._start_date == date(2017, 3, 17)
        assert cls._end_date == date(2017, 3, 30)
        assert cls._db == self.mock_sess
        assert cls._data_cache == {}

    def test_init_datetime(self):
        cls = BiweeklyPayPeriod(datetime(2017, 3, 17), self.mock_sess)
        assert cls._start_date == date(2017, 3, 17)
        assert cls._end_date == date(2017, 3, 30)
        assert cls._db == self.mock_sess
        assert cls._data_cache == {}


class TestProperties(object):

    def setup(self):
        self.mock_sess = Mock(spec_set=Session)
        self.cls = BiweeklyPayPeriod(date(2017, 3, 17), self.mock_sess)

    def test_period_interval(self):
        assert self.cls.period_interval == timedelta(days=14)

    def test_period_length(self):
        assert self.cls.period_length == timedelta(days=13)

    def test_start_date(self):
        assert self.cls.start_date == date(2017, 3, 17)

    def test_end_date(self):
        assert self.cls.end_date == date(2017, 3, 30)

    def test_next(self):
        assert self.cls.next == BiweeklyPayPeriod(
            date(2017, 3, 31), self.mock_sess)

    def test_previous(self):
        assert self.cls.previous == BiweeklyPayPeriod(
            date(2017, 3, 3), self.mock_sess)


class TestMagicMethods(object):

    def setup(self):
        self.mock_sess = Mock(spec_set=Session)
        self.cls = BiweeklyPayPeriod(date(2017, 3, 17), self.mock_sess)

    def test_repr(self):
        assert str(self.cls) == '<BiweeklyPayPeriod(2017-03-17)>'

    @pytest.mark.skipif(sys.version_info[0] >= 3, reason='py2 only')
    def test_ordering_py27(self):
        assert self.cls < BiweeklyPayPeriod(date(2017, 4, 16), self.mock_sess)
        assert self.cls > BiweeklyPayPeriod(date(2017, 2, 13), self.mock_sess)
        assert self.cls == BiweeklyPayPeriod(date(2017, 3, 17), self.mock_sess)
        self.cls < 2
        self.cls.__eq__(2)

    @pytest.mark.skipif(sys.version_info[0] < 3, reason='py3 only')
    def test_ordering_py3(self):
        assert self.cls < BiweeklyPayPeriod(date(2017, 4, 16), self.mock_sess)
        assert self.cls > BiweeklyPayPeriod(date(2017, 2, 13), self.mock_sess)
        assert self.cls == BiweeklyPayPeriod(date(2017, 3, 17), self.mock_sess)
        with pytest.raises(TypeError):
            self.cls < 2
        self.cls.__eq__(2)


class TestForDate(object):

    def setup(self):
        self.mock_sess = Mock(spec_set=Session)
        self.cls = BiweeklyPayPeriod(date(2017, 3, 17), self.mock_sess)

    @patch('%s.settings.PAY_PERIOD_START_DATE' % pbm, date(2017, 3, 17))
    def test_period_for_date(self):
        assert BiweeklyPayPeriod.period_for_date(
            date(2017, 3, 16), self.mock_sess) == BiweeklyPayPeriod(
            date(2017, 3, 3), self.mock_sess)
        assert BiweeklyPayPeriod.period_for_date(
            date(2017, 3, 17), self.mock_sess) == BiweeklyPayPeriod(
            date(2017, 3, 17), self.mock_sess)
        assert BiweeklyPayPeriod.period_for_date(
            date(2017, 3, 18), self.mock_sess) == BiweeklyPayPeriod(
            date(2017, 3, 17), self.mock_sess)
        assert BiweeklyPayPeriod.period_for_date(
            date(2017, 3, 30), self.mock_sess) == BiweeklyPayPeriod(
            date(2017, 3, 17), self.mock_sess)
        assert BiweeklyPayPeriod.period_for_date(
            date(2017, 3, 31), self.mock_sess) == BiweeklyPayPeriod(
            date(2017, 3, 31), self.mock_sess)
        assert BiweeklyPayPeriod.period_for_date(
            date(2017, 1, 21), self.mock_sess) == BiweeklyPayPeriod(
            date(2017, 1, 20), self.mock_sess)
        assert BiweeklyPayPeriod.period_for_date(
            date(2017, 5, 2), self.mock_sess) == BiweeklyPayPeriod(
{'fraction_non_alphanumeric': 0.14181362060060504, 'fraction_numerical': 0.04050763668560466, 'mean_word_length': 3.5713322091062394, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 35, 'https://': 4, 'lorem ipsum': 0, 'www.': 6, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '130055', 'n_tokens_mistral': 4663, 'n_tokens_neox': 4140, 'n_words': 1134}