import pytest

from web_poet.pages import ItemPage, ItemWebPage, is_injectable


def test_abstract_page_object():
    with pytest.raises(TypeError) as exc:
        ItemPage()
    assert "Can't instantiate abstract class" in str(exc.value)


def test_abstract_web_page_object():
    with pytest.raises(TypeError) as exc:
        ItemWebPage()
    assert "Can't instantiate abstract class" in str(exc.value)


def test_page_object():

    class MyItemPage(ItemPage):

        def to_item(self) -> dict:
            return {
                'foo': 'bar',
            }

    page_object = MyItemPage()
    assert page_object.to_item() == {'foo': 'bar', }


def test_web_page_object(book_list_html_response):

    class MyWebPage(ItemWebPage):

        def to_item(self) -> dict:
            return {
                'url': self.url,
                'title': self.css('title::text').get().strip(),
            }

    page_object = MyWebPage(book_list_html_response)
    assert page_object.to_item() == {
        'url': 'http://books.toscrape.com/index.html',
        'title': 'All products | Books to Scrape - Sandbox',
    }


def test_is_injectable():

    class MyClass:
        pass

    class MyItemPage(ItemPage):

        def to_item(self) -> dict:
            return {
                'foo': 'bar',
            }

    assert is_injectable(None) is False
    assert is_injectable(MyClass) is False
    assert is_injectable(MyClass()) is False
    assert is_injectable(MyItemPage) is True
    assert is_injectable(MyItemPage()) is False
    assert is_injectable(ItemPage) is True
    assert is_injectable(ItemWebPage) is True
