# Tai Sakuma <tai.sakuma@gmail.com>
import pytest

try:
    import unittest.mock as mock
except ImportError:
    import mock

from alphatwirl.selection.modules import All, Any, Not
from alphatwirl.selection.modules import AllwCount, AnywCount, NotwCount

##__________________________________________________________________||
all_classes = [All, AllwCount]
all_classe_ids = [c.__name__ for c in all_classes]

any_classes = [Any, AnywCount]
any_classe_ids = [c.__name__ for c in any_classes]

not_classes = [Not, NotwCount]
not_classe_ids = [c.__name__ for c in not_classes]

##__________________________________________________________________||
allany_classes = all_classes + any_classes
allany_classe_ids = all_classe_ids + any_classe_ids

##__________________________________________________________________||
@pytest.mark.parametrize('Class', allany_classes, ids=allany_classe_ids)
def test_allany_init(Class):
    obj = Class()
    assert obj.name is not None
    obj = Class(name='name_of_object')
    assert obj.name is not None
    obj = Class(name=None)
    assert obj.name is not None

@pytest.mark.parametrize('Class', not_classes, ids=not_classe_ids)
def test_not_init(Class):
    sel1 = mock.Mock()
    obj = Class(sel1)
    assert obj.name is not None
    obj = Class(sel1, name='name_of_object')
    assert obj.name is not None
    obj = Class(sel1, name=None)
    assert obj.name is not None

##__________________________________________________________________||
@pytest.mark.parametrize('Class', allany_classes, ids=allany_classe_ids)
def test_allany_repr(Class):
    obj = Class()
    repr(obj)
    obj = Class(name='name_of_object')
    repr(obj)

@pytest.mark.parametrize('Class', not_classes, ids=not_classe_ids)
def test_not_repr(Class):
    sel1 = mock.Mock()
    obj = Class(sel1)
    repr(obj)
    obj = Class(sel1, name='name_of_object')
    repr(obj)

##__________________________________________________________________||
@pytest.mark.parametrize('Class', all_classes, ids=all_classe_ids)
def test_all(Class):
    sel1 = mock.Mock()
    sel2 = mock.Mock()
    sel1.side_effect = [True, True, False, False]
    sel2.side_effect = [True, False, True, False]

    obj = Class()
    obj.add(sel1)
    obj.add(sel2)

    event = mock.Mock()

    obj.begin(event)

    assert obj(event)
    assert not obj(event)
    assert not obj(event)
    assert not obj(event)

    obj.end()

@pytest.mark.parametrize('Class', any_classes, ids=any_classe_ids)
def test_any(Class):
    sel1 = mock.Mock()
    sel2 = mock.Mock()
    sel1.side_effect = [True, True, False, False]
    sel2.side_effect = [True, False, True, False]

    obj = Class()
    obj.add(sel1)
    obj.add(sel2)

    event = mock.Mock()

    obj.begin(event)

    assert obj(event)
    assert obj(event)
    assert obj(event)
    assert not obj(event)

    obj.end()

##__________________________________________________________________||
@pytest.mark.parametrize('Class', all_classes, ids=all_classe_ids)
def test_all_empty(Class):
    obj = Class()
    event = mock.Mock()
    obj.begin(event)
    assert obj(event)
    obj.end()

@pytest.mark.parametrize('Class', any_classes, ids=any_classe_ids)
def test_any_empty(Class):
    obj = Class()
    event = mock.Mock()
    obj.begin(event)
    assert not obj(event)
    obj.end()

##__________________________________________________________________||
@pytest.mark.parametrize('Class', not_classes, ids=not_classe_ids)
def test_not(Class):
    sel1 = mock.Mock()
    sel1.side_effect = [True, False]

    obj = Class(sel1)

    event = mock.Mock()

    obj.begin(event)

    assert not obj(event)
    assert obj(event)

    obj.end()

##__________________________________________________________________||

@@ -2023,16 +2023,21 @@
 test_all
+_call
 (Class):
@@ -2029,32 +2029,32 @@
 ll_call(Class):%0A
-
     sel1 = mock.
@@ -2481,16 +2481,21 @@
 test_any
+_call
 (Class):
@@ -3003,16 +3003,21 @@
 est_all_
+call_
 empty(Cl
@@ -3202,16 +3202,21 @@
 est_any_
+call_
 empty(Cl
@@ -3455,32 +3455,32 @@
 not_classe_ids)%0A
-
 def test_not(Cla
@@ -3475,16 +3475,21 @@
 test_not
+_call
 (Class):

rename tests in test_selection.py