Skip to content

Commit

Permalink
Merge pull request #53 from yassun7010/fix_ci
Browse files Browse the repository at this point in the history
fix: ci.
  • Loading branch information
yassun7010 authored Jan 29, 2024
2 parents bbf84d8 + 27387dd commit b1e0f5d
Show file tree
Hide file tree
Showing 12 changed files with 124 additions and 101 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/test-suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ jobs:
- turu-snowflake
- turu-bigquery
- .
install-flags:
- ""
- "--all-extras"
defaults:
run:
working-directory: ${{ matrix.package }}
Expand All @@ -44,7 +47,7 @@ jobs:
poetry --version
- name: Poetry Install Dependencies
run: |
poetry install --no-interaction --all-extras
poetry install --no-interaction ${{ matrix.install-flags }}
- name: Lint
run: |
poetry run task format --diff
Expand Down
17 changes: 11 additions & 6 deletions turu-core/src/turu/core/cursor.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
Type,
TypeVar,
Union,
cast,
)

from turu.core.exception import TuruRowTypeMismatchError
Expand Down Expand Up @@ -140,13 +141,17 @@ def map_row(row_type: Optional[Type[GenericRowType]], row: Any) -> GenericRowTyp
}
) # type: ignore

if issubclass(row_type, tuple):
elif issubclass(row_type, tuple):
return row_type._make(row) # type: ignore

if USE_PYDANTIC:
if issubclass(row_type, PydanticModel):
return row_type(
**{key: data for key, data in zip(row_type.model_fields.keys(), row)}
)
elif USE_PYDANTIC and issubclass(row_type, PydanticModel):
return row_type(
**{
key: data
for key, data in zip(
cast(PydanticModel, row_type).model_fields.keys(), row
)
}
) # type: ignore

raise TuruRowTypeMismatchError(row_type, row.__class__)
9 changes: 6 additions & 3 deletions turu-core/src/turu/core/features.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
from typing_extensions import TypeAlias


class _NotSupportFeature:
pass


try:
import pydantic # noqa: F401
import pydantic # type: ignore[import]

USE_PYDANTIC = True
PydanticModel = pydantic.BaseModel
PydanticModel: TypeAlias = pydantic.BaseModel # type: ignore

except ImportError:
USE_PYDANTIC = False

PydanticModel = _NotSupportFeature
PydanticModel: TypeAlias = _NotSupportFeature # type: ignore
89 changes: 49 additions & 40 deletions turu-core/tests/turu/core/test_mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import pytest
import turu.core.mock
from pydantic import BaseModel
from turu.core.features import USE_PYDANTIC
from turu.core.mock.exception import (
TuruMockStoreDataNotFoundError,
TuruMockUnexpectedFetchError,
Expand All @@ -21,8 +21,16 @@ class RowDataclass:
id: int


class RowPydantic(BaseModel):
id: int
if USE_PYDANTIC:
from pydantic import BaseModel # type: ignore[import]

class RowPydantic(BaseModel):
id: int

ROW_TYPE_LIST = [RowNamedTuple, RowDataclass, RowPydantic]

else:
ROW_TYPE_LIST = [RowNamedTuple, RowDataclass]


class TestTuruMock:
Expand Down Expand Up @@ -57,10 +65,10 @@ def test_execute(self, mock_connection: turu.core.mock.MockConnection):
def test_mock_execute_map_fetchone(
self, mock_connection: turu.core.mock.MockConnection, rowsize: int
):
expected = [RowPydantic(id=i) for i in range(rowsize)]
mock_connection.inject_response(RowPydantic, expected)
expected = [RowDataclass(id=i) for i in range(rowsize)]
mock_connection.inject_response(RowDataclass, expected)

cursor = mock_connection.cursor().execute_map(RowPydantic, "SELECT 1")
cursor = mock_connection.cursor().execute_map(RowDataclass, "SELECT 1")
for i in range(rowsize):
assert cursor.fetchone() == expected[i]

Expand All @@ -72,10 +80,10 @@ def test_mock_execute_map_fetchmany(
mock_connection: turu.core.mock.MockConnection,
rowsize: int,
):
expected = [RowPydantic(id=i) for i in range(rowsize)]
mock_connection.inject_response(RowPydantic, expected)
expected = [RowDataclass(id=i) for i in range(rowsize)]
mock_connection.inject_response(RowDataclass, expected)

cursor = mock_connection.cursor().execute_map(RowPydantic, "SELECT 1")
cursor = mock_connection.cursor().execute_map(RowDataclass, "SELECT 1")

assert list(cursor.fetchmany(rowsize)) == expected
assert cursor.fetchone() is None
Expand All @@ -84,17 +92,15 @@ def test_mock_execute_map_fetchmany(
def test_mock_execute_map_fetchall(
self, mock_connection: turu.core.mock.MockConnection, rowsize: int
):
expected = [RowPydantic(id=i) for i in range(rowsize)]
mock_connection.inject_response(RowPydantic, expected)
expected = [RowDataclass(id=i) for i in range(rowsize)]
mock_connection.inject_response(RowDataclass, expected)

cursor = mock_connection.cursor().execute_map(RowPydantic, "SELECT 1")
cursor = mock_connection.cursor().execute_map(RowDataclass, "SELECT 1")

assert list(cursor.fetchall()) == expected
assert cursor.fetchall() == []

@pytest.mark.parametrize(
"GenericRowType", [RowNamedTuple, RowDataclass, RowPydantic]
)
@pytest.mark.parametrize("GenericRowType", ROW_TYPE_LIST)
def test_execute_map_by_rowtype(
self, GenericRowType: Any, mock_connection: turu.core.mock.MockConnection
):
Expand All @@ -109,30 +115,30 @@ def test_execute_map_multi_call(
self, mock_connection: turu.core.mock.MockConnection
):
expected_array = [
[RowPydantic(id=1), RowPydantic(id=2), RowPydantic(id=3)],
[RowPydantic(id=4), RowPydantic(id=5), RowPydantic(id=6)],
[RowPydantic(id=7), RowPydantic(id=8), RowPydantic(id=9)],
[RowDataclass(id=1), RowDataclass(id=2), RowDataclass(id=3)],
[RowDataclass(id=4), RowDataclass(id=5), RowDataclass(id=6)],
[RowDataclass(id=7), RowDataclass(id=8), RowDataclass(id=9)],
]

for expected in expected_array:
mock_connection.inject_response(RowPydantic, expected)
mock_connection.inject_response(RowDataclass, expected)

cursor = mock_connection.cursor()
for expected in expected_array:
assert cursor.execute_map(RowPydantic, "SELECT 1").fetchall() == expected
assert cursor.execute_map(RowDataclass, "SELECT 1").fetchall() == expected

assert cursor.fetchone() is None

@pytest.mark.parametrize("execition_time", range(5))
def test_execute_map_each_inject_and_execute(
self, execition_time: int, mock_connection: turu.core.mock.MockConnection
):
expected = [RowPydantic(id=i) for i in range(3)]
expected = [RowDataclass(id=i) for i in range(3)]
for _ in range(execition_time):
mock_connection.inject_response(RowPydantic, expected)
mock_connection.inject_response(RowDataclass, expected)
cursor = mock_connection.cursor()

assert cursor.execute_map(RowPydantic, "SELECT 1").fetchall() == expected
assert cursor.execute_map(RowDataclass, "SELECT 1").fetchall() == expected
assert cursor.fetchone() is None

def test_executemany(self, mock_connection: turu.core.mock.MockConnection):
Expand All @@ -141,42 +147,45 @@ def test_executemany(self, mock_connection: turu.core.mock.MockConnection):
assert cursor.fetchall() == [(1,), (1,)]

def test_executemany_map(self, mock_connection: turu.core.mock.MockConnection):
expected = [RowPydantic(id=i) for i in range(3)]
mock_connection.inject_response(RowPydantic, expected)
expected = [RowDataclass(id=i) for i in range(3)]
mock_connection.inject_response(RowDataclass, expected)

with mock_connection.executemany_map(
RowPydantic, "SELECT 1", [(), ()]
RowDataclass, "SELECT 1", [(), ()]
) as cursor:
assert cursor.fetchall() == expected
assert cursor.fetchone() is None

def test_multi_injection(self, mock_connection: turu.core.mock.MockConnection):
expected = [RowPydantic(id=i) for i in range(3)]
expected = [RowDataclass(id=i) for i in range(3)]
(
mock_connection.chain()
.inject_response(RowPydantic, expected)
.inject_response(RowPydantic, expected)
.inject_response(RowPydantic, expected)
.inject_response(RowPydantic, expected)
.inject_response(RowDataclass, expected)
.inject_response(RowDataclass, expected)
.inject_response(RowDataclass, expected)
.inject_response(RowDataclass, expected)
)

cursor = mock_connection.cursor()
for _ in range(4):
assert cursor.execute_map(RowPydantic, "SELECT 1").fetchall() == expected
assert cursor.execute_map(RowDataclass, "SELECT 1").fetchall() == expected
assert cursor.fetchone() is None

def test_cursor_iterator(self, mock_connection: turu.core.mock.MockConnection):
expected = [RowPydantic(id=i) for i in range(3)]
mock_connection.inject_response(RowPydantic, expected)
expected = [RowDataclass(id=i) for i in range(3)]
mock_connection.inject_response(RowDataclass, expected)

for i, row in enumerate(
mock_connection.cursor().execute_map(RowPydantic, "SELECT 1")
mock_connection.cursor().execute_map(RowDataclass, "SELECT 1")
):
assert row == expected[i]

@pytest.mark.skipif(not USE_PYDANTIC, reason="pydantic is not found")
def test_inject_response_from_csv(
self, mock_connection: turu.core.mock.MockConnection
):
from pydantic import BaseModel # type: ignore[import]

class Row(BaseModel):
id: int
name: str
Expand All @@ -194,16 +203,16 @@ class Row(BaseModel):
]

def test_with_statement(self, mock_connection: turu.core.mock.MockConnection):
expected = [RowPydantic(id=i) for i in range(3)]
expected = [RowDataclass(id=i) for i in range(3)]

mock_connection.inject_response(RowPydantic, expected)
mock_connection.inject_response(RowDataclass, expected)

with mock_connection.execute_map(RowPydantic, "SELECT 1") as cursor:
with mock_connection.execute_map(RowDataclass, "SELECT 1") as cursor:
assert cursor.fetchall() == expected
assert cursor.fetchone() is None

def test_inject_execption(self, mock_connection: turu.core.mock.MockConnection):
mock_connection.inject_response(RowPydantic, ValueError("test"))
mock_connection.inject_response(RowDataclass, ValueError("test"))

with pytest.raises(ValueError):
mock_connection.execute_map(RowPydantic, "SELECT 1")
mock_connection.execute_map(RowDataclass, "SELECT 1")
35 changes: 18 additions & 17 deletions turu-core/tests/turu/core/test_record.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import tempfile
from dataclasses import dataclass
from pathlib import Path
from textwrap import dedent
from typing import Any, Literal

import pytest
import turu.core.mock
from pydantic import BaseModel
from turu.core.exception import TuruRowTypeNotSupportedError
from turu.core.record import RecordCursor, record_to_csv
from typing_extensions import Never, Self


class RowPydantic(BaseModel):
@dataclass
class Row:
id: int
name: str

Expand Down Expand Up @@ -63,13 +64,13 @@ def test_record_to_csv_execute_tuple_without_header(
def test_record_to_csv_execute_map(
self, mock_connection: turu.core.mock.MockConnection
):
expected = [RowPydantic(id=i, name=f"name{i}") for i in range(5)]
mock_connection.inject_response(RowPydantic, expected)
expected = [Row(id=i, name=f"name{i}") for i in range(5)]
mock_connection.inject_response(Row, expected)

with tempfile.NamedTemporaryFile() as file:
with record_to_csv(
file.name,
mock_connection.execute_map(RowPydantic, "select 1, 'name"),
mock_connection.execute_map(Row, "select 1, 'name"),
) as cursor:
assert cursor.fetchall() == expected

Expand All @@ -90,13 +91,13 @@ def test_record_to_csv_execute_map(
def test_record_to_csv_execute_map_without_header_options(
self, mock_connection: turu.core.mock.MockConnection
):
expected = [RowPydantic(id=i, name=f"name{i}") for i in range(5)]
mock_connection.inject_response(RowPydantic, expected)
expected = [Row(id=i, name=f"name{i}") for i in range(5)]
mock_connection.inject_response(Row, expected)

with tempfile.NamedTemporaryFile() as file:
with record_to_csv(
file.name,
mock_connection.execute_map(RowPydantic, "select 1, 'name"),
mock_connection.execute_map(Row, "select 1, 'name"),
header=False,
) as cursor:
assert cursor.fetchall() == expected
Expand All @@ -117,13 +118,13 @@ def test_record_to_csv_execute_map_without_header_options(
def test_record_to_csv_execute_map_with_limit_options(
self, mock_connection: turu.core.mock.MockConnection
):
expected = [RowPydantic(id=i, name=f"name{i}") for i in range(5)]
mock_connection.inject_response(RowPydantic, expected)
expected = [Row(id=i, name=f"name{i}") for i in range(5)]
mock_connection.inject_response(Row, expected)

with tempfile.NamedTemporaryFile() as file:
with record_to_csv(
file.name,
mock_connection.execute_map(RowPydantic, "select 1, 'name"),
mock_connection.execute_map(Row, "select 1, 'name"),
limit=3,
) as cursor:
assert cursor.fetchall() == expected
Expand All @@ -146,13 +147,13 @@ def test_record_to_csv_execute_map_with_enable_options(
mock_connection: turu.core.mock.MockConnection,
enable: Literal["true", True],
):
expected = [RowPydantic(id=i, name=f"name{i}") for i in range(5)]
mock_connection.inject_response(RowPydantic, expected)
expected = [Row(id=i, name=f"name{i}") for i in range(5)]
mock_connection.inject_response(Row, expected)

with tempfile.NamedTemporaryFile() as file:
with record_to_csv(
file.name,
mock_connection.execute_map(RowPydantic, "select 1, 'name"),
mock_connection.execute_map(Row, "select 1, 'name"),
enable=enable,
) as cursor:
assert isinstance(cursor, RecordCursor)
Expand All @@ -178,13 +179,13 @@ def test_record_to_csv_execute_map_with_disable_options(
mock_connection: turu.core.mock.MockConnection,
enable: Literal["false", False, None],
):
expected = [RowPydantic(id=i, name=f"name{i}") for i in range(5)]
mock_connection.inject_response(RowPydantic, expected)
expected = [Row(id=i, name=f"name{i}") for i in range(5)]
mock_connection.inject_response(Row, expected)

with tempfile.NamedTemporaryFile() as file:
with record_to_csv(
file.name,
mock_connection.execute_map(RowPydantic, "select 1, 'name"),
mock_connection.execute_map(Row, "select 1, 'name"),
enable=enable,
) as cursor:
assert not isinstance(cursor, RecordCursor)
Expand Down
Loading

0 comments on commit b1e0f5d

Please sign in to comment.