#!/usr/bin/env python

"""Unit tests for cacher_mod."""

import unittest

import cacher_mod
import dohdbm
import helpers


class test_cacher_mod(unittest.TestCase):
    # pylint: disable=R0904
    # R0904: We're a module inheriting from unittest.TestCase; of course we have lots of public methods
    """Unit tests for cacher_mod."""

    b_a = b'a'
    b_b = b'b'
    b_c = b'c'
    b_key = b'key'
    b_key2 = b'key2'
    b_key3 = b'key3'
    b_value = b'value'
    b_value2 = b'value2'
    b_value3 = b'value3'
    b_a_doh = b'a.doh'
    b_b_doh = b'b.doh'
    b_c_doh = b'c.doh'

    def test_open_and_close(self):
        """Test a single file."""
        helpers.make_used(self)
        cacher = cacher_mod.Database_cacher(max_entries=2)
        cacher[test_cacher_mod.b_a] = dohdbm.open(test_cacher_mod.b_a_doh, 'w')
        cacher[test_cacher_mod.b_a].close()

    def test_open_value_close(self):
        """Test a single file with a single value."""
        helpers.make_used(self)
        cacher = cacher_mod.Database_cacher(max_entries=2)
        cacher[test_cacher_mod.b_a] = dohdbm.open(test_cacher_mod.b_a_doh, 'n')
        cacher[test_cacher_mod.b_a][test_cacher_mod.b_key] = test_cacher_mod.b_value
        cacher[test_cacher_mod.b_a].close()

    def test_2_open_value_close(self):
        """Test 2 files with values."""
        helpers.make_used(self)
        cacher = cacher_mod.Database_cacher(max_entries=2)
        cacher[test_cacher_mod.b_a] = dohdbm.open(test_cacher_mod.b_a_doh, 'n')
        cacher[test_cacher_mod.b_b] = dohdbm.open(test_cacher_mod.b_b_doh, 'n')
        cacher[test_cacher_mod.b_a][test_cacher_mod.b_key] = test_cacher_mod.b_value
        cacher[test_cacher_mod.b_b][test_cacher_mod.b_key2] = test_cacher_mod.b_value2
        cacher[test_cacher_mod.b_a].close()
        cacher[test_cacher_mod.b_b].close()

    def test_3_open_value_close(self):
        """Test 3 files with values in a cacher that'll only hold 2 - close the remaining two, one at a time."""
        helpers.make_used(self)
        cacher = cacher_mod.Database_cacher(max_entries=2)
        assert len(cacher) == 0, len(cacher)  # pylint: disable=len-as-condition
        cacher[test_cacher_mod.b_a] = dohdbm.open(test_cacher_mod.b_a_doh, 'n')
        assert len(cacher) == 1, len(cacher)
        cacher[test_cacher_mod.b_b] = dohdbm.open(test_cacher_mod.b_b_doh, 'n')
        assert len(cacher) == 2, len(cacher)
        cacher[test_cacher_mod.b_c] = dohdbm.open(test_cacher_mod.b_c_doh, 'n')
        assert len(cacher) == 2, len(cacher)
        try:
            cacher[test_cacher_mod.b_a][test_cacher_mod.b_key] = test_cacher_mod.b_value
        except KeyError:
            pass
        else:
            raise AssertionError
        cacher[test_cacher_mod.b_b][test_cacher_mod.b_key2] = test_cacher_mod.b_value2
        cacher[test_cacher_mod.b_c][test_cacher_mod.b_key3] = test_cacher_mod.b_value3
        cacher[test_cacher_mod.b_b].close()
        cacher[test_cacher_mod.b_c].close()

    def test_3_open_value_agg_close(self):
        """Test 3 files with values in a cacher that'll only hold 2 - close en masse."""
        helpers.make_used(self)
        cacher = cacher_mod.Database_cacher(max_entries=2)
        assert len(cacher) == 0, len(cacher)  # pylint: disable=len-as-condition
        cacher[test_cacher_mod.b_a] = dohdbm.open(test_cacher_mod.b_a_doh, 'n')
        assert len(cacher) == 1, len(cacher)
        cacher[test_cacher_mod.b_b] = dohdbm.open(test_cacher_mod.b_b_doh, 'n')
        assert len(cacher) == 2, len(cacher)
        cacher[test_cacher_mod.b_c] = dohdbm.open(test_cacher_mod.b_c_doh, 'n')
        assert len(cacher) == 2, len(cacher)
        try:
            cacher[test_cacher_mod.b_a][test_cacher_mod.b_key] = test_cacher_mod.b_value
        except KeyError:
            pass
        else:
            raise AssertionError
        cacher[test_cacher_mod.b_b][test_cacher_mod.b_key2] = test_cacher_mod.b_value2
        cacher[test_cacher_mod.b_c][test_cacher_mod.b_key3] = test_cacher_mod.b_value3
        cacher.close()

    def test_3_open_part_then_agg_close(self):
        """3 files, two values, close en masse."""
        helpers.make_used(self)
        cacher = cacher_mod.Database_cacher(max_entries=2)
        assert len(cacher) == 0, len(cacher)  # pylint: disable=len-as-condition
        cacher[test_cacher_mod.b_a] = dohdbm.open(test_cacher_mod.b_a_doh, 'n')
        assert len(cacher) == 1, len(cacher)
        cacher[test_cacher_mod.b_b] = dohdbm.open(test_cacher_mod.b_b_doh, 'n')
        assert len(cacher) == 2, len(cacher)
        cacher[test_cacher_mod.b_c] = dohdbm.open(test_cacher_mod.b_c_doh, 'n')
        assert len(cacher) == 2, len(cacher)
        try:
            cacher[test_cacher_mod.b_a][test_cacher_mod.b_key] = test_cacher_mod.b_value
        except KeyError:
            pass
        else:
            raise AssertionError
        cacher[test_cacher_mod.b_b][test_cacher_mod.b_key2] = test_cacher_mod.b_value2
        cacher.close()


unittest.main()