Skip to content

Commit

Permalink
Added option to pass (V)Array ID to create method
Browse files Browse the repository at this point in the history
  • Loading branch information
imatiushin committed Oct 16, 2023
1 parent 77e470a commit b5ef89a
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 59 deletions.
5 changes: 2 additions & 3 deletions deker/ABC/base_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
from deker.schemas import ArraySchema, TimeDimensionSchema, VArraySchema
from deker.subset import Subset, VSubset
from deker.tools.array import check_memory, get_id
from deker.validators import is_valid_uuid
from deker.tools.schema import create_dimensions
from deker.types.private.classes import ArrayMeta, Serializer
from deker.types.private.typings import FancySlice, Numeric, Slice
Expand Down Expand Up @@ -251,9 +252,7 @@ def _validate(
primary_attributes: Optional[dict] = None,
custom_attributes: Optional[dict] = None,
) -> None:
if id_ is not None and (
not isinstance(id_, str) or len(id_.split("-")) != 5 # noqa[PLR2004]
):
if id_ is not None and not is_valid_uuid(id_):
raise DekerValidationError(
f"{self.__class__.__name__} id shall be a non-empty uuid.uuid5 string or None"
)
Expand Down
33 changes: 22 additions & 11 deletions deker/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,17 +109,20 @@ def _create( # type: ignore
schema: "BaseArraysSchema",
primary_attributes: Optional[dict] = None,
custom_attributes: Optional[dict] = None,
id_: Optional[str]=None
) -> Union[Array, VArray]:
"""Create Array or VArray.
:param primary_attributes: array primary attribute
:param custom_attributes: array custom attributes
:param schema: schema decides which array will be created
:param id_: (V)Array uuid string
"""
arr_params = {
"collection": self.__collection,
"primary_attributes": primary_attributes,
"custom_attributes": custom_attributes,
"id_": id_,
}

if isinstance(schema, VArraySchema):
Expand All @@ -135,15 +138,19 @@ def _create( # type: ignore
return array

def create(
self, primary_attributes: Optional[dict] = None, custom_attributes: Optional[dict] = None
self,
primary_attributes: Optional[dict] = None,
custom_attributes: Optional[dict] = None,
id_: Optional[str] = None
) -> Union[Array, VArray]:
"""Create array or varray.
:param primary_attributes: Primary attributes
:param custom_attributes: Custom attributes
:param primary_attributes: primary attributes
:param custom_attributes: custom attributes
:param id_: unique UUID string
"""
schema = self.__collection.varray_schema or self.__collection.array_schema
return self._create(schema, primary_attributes, custom_attributes)
return self._create(schema, primary_attributes, custom_attributes, id_)


class VArrayManager(SelfLoggerMixin, DataManager):
Expand Down Expand Up @@ -177,14 +184,16 @@ def create(
self,
primary_attributes: Optional[dict] = None,
custom_attributes: Optional[dict] = None,
id_: Optional[str] = None
) -> VArray:
"""Create varray in collection.
:param primary_attributes: Primary attributes the varray
:param custom_attributes: Custom attributes the varray
:param primary_attributes: VArray primary attributes
:param custom_attributes: VArray custom attributes
:param id_: VArray unique UUID string
"""
return self._create( # type: ignore[return-value]
self.__collection.varray_schema, primary_attributes, custom_attributes # type: ignore[arg-type]
self.__collection.varray_schema, primary_attributes, custom_attributes, id_ # type: ignore[arg-type]
)

def __iter__(self) -> Generator[VArray, None, None]:
Expand Down Expand Up @@ -223,14 +232,16 @@ def create(
self,
primary_attributes: Optional[dict] = None,
custom_attributes: Optional[dict] = None,
id_: Optional[str] = None
) -> Array:
"""Create varray in collection.
"""Create array in collection.
:param primary_attributes: Primary attributes the varray
:param custom_attributes: Custom attributes the varray
:param primary_attributes: Array primary attributes
:param custom_attributes: Array custom attributes
:param id_: Array unique UUID string
"""
return self._create( # type: ignore[return-value]
self.__collection.array_schema, primary_attributes, custom_attributes
self.__collection.array_schema, primary_attributes, custom_attributes, id_
)

def __iter__(self) -> Generator[Array, None, None]:
Expand Down
15 changes: 15 additions & 0 deletions deker/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.

import datetime
import uuid

from typing import TYPE_CHECKING, Optional, Tuple, Union

Expand Down Expand Up @@ -131,3 +132,17 @@ def process_attributes(
)
__process_attrs(attrs_schema, attributes, primary_attributes, custom_attributes) # type: ignore[arg-type]
return primary_attributes, custom_attributes


def is_valid_uuid(id_: str) -> bool:
"""Validate if id is in uuid format.
:param id_: id to validate
"""
if not isinstance(id_, str) or len(id_.split("-")) != 5 or len(id_) != 36:
return False
try:
uuid.UUID(id_)
return True
except ValueError:
return False
153 changes: 108 additions & 45 deletions tests/test_cases/test_managers/test_managers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
import uuid

from datetime import datetime, timedelta

Expand All @@ -9,7 +10,7 @@
from deker.arrays import Array, VArray
from deker.client import Client
from deker.collection import Collection
from deker.errors import DekerFilterError
from deker.errors import DekerFilterError, DekerValidationError, DekerArrayError
from deker.schemas import (
ArraySchema,
AttributeSchema,
Expand All @@ -20,13 +21,44 @@


class TestDataManagerMethods:
def test_manager_create_array(self, collection_manager):
@pytest.mark.parametrize("array_params", [
{},
{"id_": str(uuid.uuid4())}
])
def test_manager_create_array(self, collection_manager, array_params):
"""Tests if manager can create array.
:param collection_manager: fixture
"""
array = collection_manager.create()
array = collection_manager.create(**array_params)
assert isinstance(array, Array)
if array_params.get("id_"):
assert array.id == array_params["id_"]

@pytest.mark.parametrize("id_", [
(str(uuid.uuid4()))[:-10],
"123",
"{20f5484b-88ae-49b0-8af0-3a389b4917dd}",
"20f5484b88ae49b08af03a389b4917dd"
])
def test_manager_create_array_fail_bad_id(self, collection_manager, id_):
"""Tests if manager returns error on incorrect id param.
:param collection_manager: fixture
:param id_: incorrect uuid
"""
with pytest.raises(DekerValidationError):
collection_manager.create(id_=id_)

def test_manager_create_array_fail_exists(self, inserted_array: Array, collection_manager):
"""Tests if manager returns error on trying to create array with uuid of existing array.
:param inserted_array: fixture
:param collection_manager: fixture
"""
with pytest.raises(DekerArrayError) as e:
collection_manager.create(id_=inserted_array.id)
assert inserted_array.id in str(e) and "already exists" in str(e)

def test_get_array_by_id(self, inserted_array: Array, collection_manager):
"""Tests possibility of getting an array by id.
Expand Down Expand Up @@ -91,9 +123,9 @@ def test_get_array_by_primary_attribute(

@pytest.mark.parametrize("property_name", ["first", "last"])
def test_get_array_by_primary_attribute_datetime(
self,
client: Client,
property_name: str,
self,
client: Client,
property_name: str,
):
"""Tests possibility of getting an array by datetme primary attributes.
Expand Down Expand Up @@ -134,9 +166,9 @@ def test_get_array_by_primary_attribute_datetime(

@pytest.mark.parametrize("property_name", ["first", "last"])
def test_get_varray_by_primary_attribute_datetime(
self,
client: Client,
property_name: str,
self,
client: Client,
property_name: str,
):
"""Tests possibility of getting an array by datetme primary attributes.
Expand Down Expand Up @@ -180,10 +212,10 @@ def test_get_varray_by_primary_attribute_datetime(

@pytest.mark.parametrize("property_name", ["first", "last"])
def test_get_array_by_primary_attribute_no_such_attribute(
self,
inserted_array_with_attributes: Array,
collection_manager_with_attributes,
property_name: str,
self,
inserted_array_with_attributes: Array,
collection_manager_with_attributes,
property_name: str,
):
"""Tests None is returned if there is no array with such primary attributes.
Expand All @@ -200,10 +232,10 @@ def test_get_array_by_primary_attribute_no_such_attribute(

@pytest.mark.parametrize("property_name", ["first", "last"])
def test_get_array_by_primary_attribute_empty_collection(
self,
array_with_attributes: Array,
collection_manager_with_attributes,
property_name: str,
self,
array_with_attributes: Array,
collection_manager_with_attributes,
property_name: str,
):
"""Tests None is returned if collection is empty.
Expand All @@ -218,9 +250,9 @@ def test_get_array_by_primary_attribute_empty_collection(
assert array is None

def test_get_array_by_primary_attribute_fails_too_many_attrs(
self,
inserted_array_with_attributes: Array,
collection_manager_with_attributes,
self,
inserted_array_with_attributes: Array,
collection_manager_with_attributes,
):
"""Tests if filtering fails of there is too many attributes
Expand All @@ -240,9 +272,9 @@ def test_get_array_by_primary_attribute_fails_too_many_attrs(
assert "Some arguments don't exist in schema" == str(error.value)

def test_get_array_by_primary_attribute_absence(
self,
inserted_array_with_attributes: Array,
collection_manager_with_attributes,
self,
inserted_array_with_attributes: Array,
collection_manager_with_attributes,
):
with pytest.raises(NotImplementedError):
collection_manager_with_attributes.filter({"extra": 12}).first()
Expand All @@ -252,13 +284,44 @@ def test_get_array_by_primary_attribute_absence(


class TestDataManagerMethodsVArray:
def test_manager_create_varray(self, va_collection_manager):
"""Tests if manager creates array.
@pytest.mark.parametrize("varray_params", [
{},
{"id_": str(uuid.uuid4())}
])
def test_manager_create_varray(self, va_collection_manager, varray_params):
"""Tests if manager can create VArray.
:param va_collection_manager: fixture
"""
array = va_collection_manager.create()
assert isinstance(array, VArray)
varray = va_collection_manager.create(**varray_params)
assert isinstance(varray, VArray)
if varray_params.get("id_"):
assert varray.id == varray_params["id_"]

@pytest.mark.parametrize("id_", [
str(uuid.uuid4())[:-1],
"123",
"{20f5484b-88ae-49b0-8af0-3a389b4917dd}",
"20f5484b88ae49b08af03a389b4917dd"
])
def test_manager_create_varray_fail_bad_id(self, va_collection_manager, id_):
"""Tests if manager returns error on incorrect id param.
:param va_collection_manager: fixture
:param id_: incorrect uuid
"""
with pytest.raises(DekerValidationError):
va_collection_manager.create(id_=id_)

def test_manager_create_varray_fail_exists(self, inserted_varray: VArray, va_collection_manager):
"""Tests if manager returns error on trying to create varray with uuid of existing varray.
:param inserted_varray: fixture
:param va_collection_manager: fixture
"""
with pytest.raises(DekerArrayError) as e:
va_collection_manager.create(id_=inserted_varray.id)
assert inserted_varray.id in str(e) and "already exists" in str(e)

def test_get_array_by_id(self, inserted_varray: VArray, va_collection_manager):
"""Tests possibility of getting an array by id.
Expand Down Expand Up @@ -295,10 +358,10 @@ def test_get_varray_by_id_empty_collection(self, varray: VArray, va_collection_m

@pytest.mark.parametrize("property_name", ["first", "last"])
def test_get_varray_by_primary_attribute(
self,
inserted_varray_with_attributes: VArray,
va_collection_manager_with_attributes,
property_name: str,
self,
inserted_varray_with_attributes: VArray,
va_collection_manager_with_attributes,
property_name: str,
):
"""Tests possibility of getting an array by primary attributes.
Expand All @@ -319,10 +382,10 @@ def test_get_varray_by_primary_attribute(

@pytest.mark.parametrize("property_name", ["first", "last"])
def test_get_varray_by_primary_attribute_no_such_attribute(
self,
inserted_varray_with_attributes: VArray,
va_collection_manager_with_attributes,
property_name: str,
self,
inserted_varray_with_attributes: VArray,
va_collection_manager_with_attributes,
property_name: str,
):
"""Tests None is returned if there is no array with such primary attributes.
Expand All @@ -339,10 +402,10 @@ def test_get_varray_by_primary_attribute_no_such_attribute(

@pytest.mark.parametrize("property_name", ["first", "last"])
def test_get_varray_by_primary_attribute_empty_collection(
self,
varray_with_attributes: VArray,
va_collection_manager_with_attributes,
property_name: str,
self,
varray_with_attributes: VArray,
va_collection_manager_with_attributes,
property_name: str,
):
"""Tests None is returned if collection is empty.
Expand All @@ -359,9 +422,9 @@ def test_get_varray_by_primary_attribute_empty_collection(
assert array is None

def test_get_array_by_primary_attribute_fails_too_many_attrs(
self,
inserted_array_with_attributes: Array,
va_collection_manager_with_attributes,
self,
inserted_array_with_attributes: Array,
va_collection_manager_with_attributes,
):
"""Tests if filtering fails if there is too many attributes
Expand All @@ -381,9 +444,9 @@ def test_get_array_by_primary_attribute_fails_too_many_attrs(
assert "Some arguments don't exist in schema" == str(error.value)

def test_get_varray_by_primary_attribute_absence(
self,
inserted_varray_with_attributes: Array,
va_collection_manager_with_attributes,
self,
inserted_varray_with_attributes: Array,
va_collection_manager_with_attributes,
):
with pytest.raises(NotImplementedError) as error:
va_collection_manager_with_attributes.filter({"extra": 12}).first()
Expand Down

0 comments on commit b5ef89a

Please sign in to comment.