import pytest
from typing import Optional

from sqlmodel import Field, Session, SQLModel, create_engine
from sqlalchemy.exc import IntegrityError


def test_should_allow_duplicate_row_if_unique_constraint_is_not_passed(clear_sqlmodel):
    class Hero(SQLModel, table=True):
        id: Optional[int] = Field(default=None, primary_key=True)
        name: str
        secret_name: str
        age: Optional[int] = None

    hero_1 = Hero(name="Deadpond", secret_name="<NAME>")
    hero_2 = Hero(name="Deadpond", secret_name="<NAME>")

    engine = create_engine("sqlite://")

    SQLModel.metadata.create_all(engine)

    with Session(engine) as session:
        session.add(hero_1)
        session.commit()
        session.refresh(hero_1)

    with Session(engine) as session:
        session.add(hero_2)
        session.commit()
        session.refresh(hero_2)

    with Session(engine) as session:
        heroes = session.query(Hero).all()
        assert len(heroes) == 2
        assert heroes[0].name == heroes[1].name


def test_should_allow_duplicate_row_if_unique_constraint_is_false(clear_sqlmodel):
    class Hero(SQLModel, table=True):
        id: Optional[int] = Field(default=None, primary_key=True)
        name: str
        secret_name: str = Field(unique=False)
        age: Optional[int] = None

    hero_1 = Hero(name="Deadpond", secret_name="<NAME>")
    hero_2 = Hero(name="Deadpond", secret_name="<NAME>")

    engine = create_engine("sqlite://")

    SQLModel.metadata.create_all(engine)

    with Session(engine) as session:
        session.add(hero_1)
        session.commit()
        session.refresh(hero_1)

    with Session(engine) as session:
        session.add(hero_2)
        session.commit()
        session.refresh(hero_2)

    with Session(engine) as session:
        heroes = session.query(Hero).all()
        assert len(heroes) == 2
        assert heroes[0].name == heroes[1].name


def test_should_raise_exception_when_try_to_duplicate_row_if_unique_constraint_is_true(clear_sqlmodel):
    class Hero(SQLModel, table=True):
        id: Optional[int] = Field(default=None, primary_key=True)
        name: str
        secret_name: str = Field(unique=True)
        age: Optional[int] = None

    hero_1 = Hero(name="Deadpond", secret_name="<NAME>")
    hero_2 = Hero(name="Deadpond", secret_name="<NAME>")

    engine = create_engine("sqlite://")

    SQLModel.metadata.create_all(engine)

    with Session(engine) as session:
        session.add(hero_1)
        session.commit()
        session.refresh(hero_1)

    with pytest.raises(IntegrityError):
        with Session(engine) as session:
            session.add(hero_2)
            session.commit()
            session.refresh(hero_2)

sqlmodel.create_engine sqlmodel.Session sqlmodel.SQLModel.metadata.create_all sqlmodel.Field pytest.raises
[((563, 589), 'sqlmodel.create_engine', 'create_engine', (['"""sqlite://"""'], {}), "('sqlite://')\n", (576, 589), False, 'from sqlmodel import Field, Session, SQLModel, create_engine\n'), ((597, 633), 'sqlmodel.SQLModel.metadata.create_all', 'SQLModel.metadata.create_all', (['engine'], {}), '(engine)\n', (625, 633), False, 'from sqlmodel import Field, Session, SQLModel, create_engine\n'), ((1486, 1512), 'sqlmodel.create_engine', 'create_engine', (['"""sqlite://"""'], {}), "('sqlite://')\n", (1499, 1512), False, 'from sqlmodel import Field, Session, SQLModel, create_engine\n'), ((1520, 1556), 'sqlmodel.SQLModel.metadata.create_all', 'SQLModel.metadata.create_all', (['engine'], {}), '(engine)\n', (1548, 1556), False, 'from sqlmodel import Field, Session, SQLModel, create_engine\n'), ((2429, 2455), 'sqlmodel.create_engine', 'create_engine', (['"""sqlite://"""'], {}), "('sqlite://')\n", (2442, 2455), False, 'from sqlmodel import Field, Session, SQLModel, create_engine\n'), ((2463, 2499), 'sqlmodel.SQLModel.metadata.create_all', 'SQLModel.metadata.create_all', (['engine'], {}), '(engine)\n', (2491, 2499), False, 'from sqlmodel import Field, Session, SQLModel, create_engine\n'), ((311, 348), 'sqlmodel.Field', 'Field', ([], {'default': 'None', 'primary_key': '(True)'}), '(default=None, primary_key=True)\n', (316, 348), False, 'from sqlmodel import Field, Session, SQLModel, create_engine\n'), ((646, 661), 'sqlmodel.Session', 'Session', (['engine'], {}), '(engine)\n', (653, 661), False, 'from sqlmodel import Field, Session, SQLModel, create_engine\n'), ((774, 789), 'sqlmodel.Session', 'Session', (['engine'], {}), '(engine)\n', (781, 789), False, 'from sqlmodel import Field, Session, SQLModel, create_engine\n'), ((902, 917), 'sqlmodel.Session', 'Session', (['engine'], {}), '(engine)\n', (909, 917), False, 'from sqlmodel import Field, Session, SQLModel, create_engine\n'), ((1212, 1249), 'sqlmodel.Field', 'Field', ([], {'default': 'None', 'primary_key': '(True)'}), '(default=None, primary_key=True)\n', (1217, 1249), False, 'from sqlmodel import Field, Session, SQLModel, create_engine\n'), ((1297, 1316), 'sqlmodel.Field', 'Field', ([], {'unique': '(False)'}), '(unique=False)\n', (1302, 1316), False, 'from sqlmodel import Field, Session, SQLModel, create_engine\n'), ((1569, 1584), 'sqlmodel.Session', 'Session', (['engine'], {}), '(engine)\n', (1576, 1584), False, 'from sqlmodel import Field, Session, SQLModel, create_engine\n'), ((1697, 1712), 'sqlmodel.Session', 'Session', (['engine'], {}), '(engine)\n', (1704, 1712), False, 'from sqlmodel import Field, Session, SQLModel, create_engine\n'), ((1825, 1840), 'sqlmodel.Session', 'Session', (['engine'], {}), '(engine)\n', (1832, 1840), False, 'from sqlmodel import Field, Session, SQLModel, create_engine\n'), ((2156, 2193), 'sqlmodel.Field', 'Field', ([], {'default': 'None', 'primary_key': '(True)'}), '(default=None, primary_key=True)\n', (2161, 2193), False, 'from sqlmodel import Field, Session, SQLModel, create_engine\n'), ((2241, 2259), 'sqlmodel.Field', 'Field', ([], {'unique': '(True)'}), '(unique=True)\n', (2246, 2259), False, 'from sqlmodel import Field, Session, SQLModel, create_engine\n'), ((2512, 2527), 'sqlmodel.Session', 'Session', (['engine'], {}), '(engine)\n', (2519, 2527), False, 'from sqlmodel import Field, Session, SQLModel, create_engine\n'), ((2640, 2669), 'pytest.raises', 'pytest.raises', (['IntegrityError'], {}), '(IntegrityError)\n', (2653, 2669), False, 'import pytest\n'), ((2685, 2700), 'sqlmodel.Session', 'Session', (['engine'], {}), '(engine)\n', (2692, 2700), False, 'from sqlmodel import Field, Session, SQLModel, create_engine\n')]