# Path: twitch/resources.py
# class Channel(TwitchObject):
#     pass
# 
# class Comment(TwitchObject):
#     pass
# 
# class Community(TwitchObject):
#     pass
# 
# class Featured(TwitchObject):
#     pass
# 
# class Follow(TwitchObject):
#     pass
# 
# class Game(TwitchObject):
#     pass
# 
# class Ingest(TwitchObject):
#     pass
# 
# class Stream(TwitchObject):
#     pass
# 
# class StreamMetadata(TwitchObject):
#     pass
# 
# class Subscription(TwitchObject):
#     pass
# 
# class Team(TwitchObject):
#     pass
# 
# class TopGame(TwitchObject):
#     pass
# 
# class TwitchObject(dict):
#     def __setattr__(self, name, value):
#         if name[0] == "_" or name in self.__dict__:
#             return super(TwitchObject, self).__setattr__(name, value)
# 
#         self[name] = value
# 
#     def __getattr__(self, name):
#         return self[name]
# 
#     def __delattr__(self, name):
#         if name[0] == "_":
#             return super(TwitchObject, self).__delattr__(name)
# 
#         del self[name]
# 
#     def __setitem__(self, key, value):
#         key = key.lstrip("_")
#         super(TwitchObject, self).__setitem__(key, value)
# 
#     @classmethod
#     def construct_from(cls, values):
#         instance = cls()
#         instance.refresh_from(values)
#         return instance
# 
#     def refresh_from(self, values):
#         for key, value in values.copy().items():
#             self.__setitem__(key, convert_to_twitch_object(key, value))
# 
# class User(TwitchObject):
#     pass
# 
# class UserBlock(TwitchObject):
#     pass
# 
# class Video(TwitchObject):
#     pass
# 
# def convert_to_twitch_object(name, data):
#     types = {
#         "channel": Channel,
#         "videos": Video,
#         "user": User,
#         "game": Game,
#         "stream": Stream,
#         "comments": Comment,
#         "owner": User,
#     }
# 
#     special_types = {
#         "created_at": _DateTime,
#         "updated_at": _DateTime,
#         "published_at": _DateTime,
#         "started_at": _DateTime,
#         "followed_at": _DateTime,
#     }
# 
#     if isinstance(data, list):
#         return [convert_to_twitch_object(name, x) for x in data]
# 
#     if name in special_types:
#         obj = special_types.get(name)
#         return obj.construct_from(data)
# 
#     if isinstance(data, dict) and name in types:
#         obj = types.get(name)
#         return obj.construct_from(data)
# 
#     return data


from datetime import datetime
from twitch.resources import (
    Channel,
    Comment,
    Community,
    Featured,
    Follow,
    Game,
    Ingest,
    Stream,
    StreamMetadata,
    Subscription,
    Team,
    TopGame,
    TwitchObject,
    User,
    UserBlock,
    Video,
    convert_to_twitch_object,
)
import pytest
def test_convert_to_twitch_object_output_returns_correct_object(
    name, data, expected_type
):
    result = convert_to_twitch_object(name, data)
    assert isinstance(result, expected_type)
    assert result == data


@pytest.mark.parametrize(
    "name,data,expected",
    [
        ("created_at", "2016-11-29T15:52:27Z", datetime(2016, 11, 29, 15, 52, 27)),
        (
            "updated_at",
            "2017-03-06T18:40:51.855Z",
            datetime(2017, 3, 6, 18, 40, 51, 855000),
        ),
        ("published_at", "2017-02-14T22:27:54Z", datetime(2017, 2, 14, 22, 27, 54)),
        ("published_at", None, None),
    ],
)
def test_datetimes_are_converted_correctly_to_datetime_objects(name, data, expected):
    result = convert_to_twitch_object(name, data)
    if result is not None:
        assert isinstance(result, datetime)
    assert result == expected


class TestTwitchObject(object):
    def test_attributes_are_stored_and_fetched_from_dict(self):

# Path: twitch/resources.py
# class Channel(TwitchObject):
#     pass
# 
# class Comment(TwitchObject):
#     pass
# 
# class Community(TwitchObject):
#     pass
# 
# class Featured(TwitchObject):
#     pass
# 
# class Follow(TwitchObject):
#     pass
# 
# class Game(TwitchObject):
#     pass
# 
# class Ingest(TwitchObject):
#     pass
# 
# class Stream(TwitchObject):
#     pass
# 
# class StreamMetadata(TwitchObject):
#     pass
# 
# class Subscription(TwitchObject):
#     pass
# 
# class Team(TwitchObject):
#     pass
# 
# class TopGame(TwitchObject):
#     pass
# 
# class TwitchObject(dict):
#     def __setattr__(self, name, value):
#         if name[0] == "_" or name in self.__dict__:
#             return super(TwitchObject, self).__setattr__(name, value)
# 
#         self[name] = value
# 
#     def __getattr__(self, name):
#         return self[name]
# 
#     def __delattr__(self, name):
#         if name[0] == "_":
#             return super(TwitchObject, self).__delattr__(name)
# 
#         del self[name]
# 
#     def __setitem__(self, key, value):
#         key = key.lstrip("_")
#         super(TwitchObject, self).__setitem__(key, value)
# 
#     @classmethod
#     def construct_from(cls, values):
#         instance = cls()
#         instance.refresh_from(values)
#         return instance
# 
#     def refresh_from(self, values):
#         for key, value in values.copy().items():
#             self.__setitem__(key, convert_to_twitch_object(key, value))
# 
# class User(TwitchObject):
#     pass
# 
# class UserBlock(TwitchObject):
#     pass
# 
# class Video(TwitchObject):
#     pass
# 
# def convert_to_twitch_object(name, data):
#     types = {
#         "channel": Channel,
#         "videos": Video,
#         "user": User,
#         "game": Game,
#         "stream": Stream,
#         "comments": Comment,
#         "owner": User,
#     }
# 
#     special_types = {
#         "created_at": _DateTime,
#         "updated_at": _DateTime,
#         "published_at": _DateTime,
#         "started_at": _DateTime,
#         "followed_at": _DateTime,
#     }
# 
#     if isinstance(data, list):
#         return [convert_to_twitch_object(name, x) for x in data]
# 
#     if name in special_types:
#         obj = special_types.get(name)
#         return obj.construct_from(data)
# 
#     if isinstance(data, dict) and name in types:
#         obj = types.get(name)
#         return obj.construct_from(data)
# 
#     return data


# Path: tests/test_resources.py
from datetime import datetime
from twitch.resources import (
    Channel,
    Comment,
    Community,
    Featured,
    Follow,
    Game,
    Ingest,
    Stream,
    StreamMetadata,
    Subscription,
    Team,
    TopGame,
    TwitchObject,
    User,
    UserBlock,
    Video,
    convert_to_twitch_object,
)
import pytest

def test_convert_to_twitch_object_output_returns_correct_object(
    name, data, expected_type
):
    result = convert_to_twitch_object(name, data)
    assert isinstance(result, expected_type)
    assert result == data


@pytest.mark.parametrize(
    "name,data,expected",
    [
        ("created_at", "2016-11-29T15:52:27Z", datetime(2016, 11, 29, 15, 52, 27)),
        (
            "updated_at",
            "2017-03-06T18:40:51.855Z",
            datetime(2017, 3, 6, 18, 40, 51, 855000),
        ),
        ("published_at", "2017-02-14T22:27:54Z", datetime(2017, 2, 14, 22, 27, 54)),
        ("published_at", None, None),
    ],
)
def test_datetimes_are_converted_correctly_to_datetime_objects(name, data, expected):
    result = convert_to_twitch_object(name, data)
    if result is not None:
        assert isinstance(result, datetime)
    assert result == expected


class TestTwitchObject(object):
    def test_attributes_are_stored_and_fetched_from_dict(self):

        obj = TwitchObject()