Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace hypothesis by polyfactory in tests #537

Closed
wants to merge 19 commits into from
1 change: 0 additions & 1 deletion docs/CHANGELOG.md

This file was deleted.

1 change: 0 additions & 1 deletion docs/LICENSE.md

This file was deleted.

6 changes: 0 additions & 6 deletions docs/commands.md

This file was deleted.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ dev = [
"black==23.11.0",
"cryptography==41.0.5",
"factory-boy==3.3.0",
"hypothesis==6.88.3",
"logging-gelf==0.0.31",
"mike==2.0.0",
"mkdocs==1.5.3",
Expand All @@ -96,6 +95,7 @@ dev = [
"moto==4.2.8",
"mypy==1.7.0",
"neoteroi-mkdocs==1.0.4",
"polyfactory==2.12.0",
"pyfakefs==5.3.0",
"pymdown-extensions==10.4",
"pytest==7.4.3",
Expand Down
29 changes: 21 additions & 8 deletions src/ralph/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,18 @@
import sys
from enum import Enum
from pathlib import Path
from typing import List, Sequence, Tuple, Union

from pydantic import AnyHttpUrl, AnyUrl, BaseModel, BaseSettings, Extra, root_validator
from typing import Annotated, List, Sequence, Tuple, Union

from pydantic import (
AnyHttpUrl,
AnyUrl,
BaseModel,
BaseSettings,
Extra,
Field,
constr,
root_validator,
)

from ralph.exceptions import ConfigurationException

Expand All @@ -30,6 +39,13 @@
MODEL_PATH_SEPARATOR = "__"


NonEmptyStr = Annotated[str, Field(min_length=1)]
NonEmptyStrictStrPatch = Annotated[str, Field(min_length=1)]
NonEmptyStrictStr = constr(
min_length=1, strict=True
) # Annotated[StrictStr, Field(min_length=1)]


class BaseSettingsConfig:
"""Pydantic model for BaseSettings Configuration."""

Expand Down Expand Up @@ -122,13 +138,10 @@ class ParserSettings(BaseModel):
class XapiForwardingConfigurationSettings(BaseModel):
"""Pydantic model for xAPI forwarding configuration item."""

class Config: # noqa: D106
min_anystr_length = 1

url: AnyUrl
is_active: bool
basic_username: str
basic_password: str
basic_username: NonEmptyStr
basic_password: NonEmptyStr
max_retries: int
timeout: float

Expand Down
5 changes: 3 additions & 2 deletions src/ralph/models/edx/enrollment/statements.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ class EdxCourseEnrollmentActivated(BaseServerModel):
__selector__ = selector(
event_source="server", event_type="edx.course.enrollment.activated"
)

event: Union[
Json[EnrollmentEventField],
EnrollmentEventField,
Expand All @@ -59,6 +58,7 @@ class EdxCourseEnrollmentDeactivated(BaseServerModel):
event_source="server", event_type="edx.course.enrollment.deactivated"
)


event: Union[
Json[EnrollmentEventField],
EnrollmentEventField,
Expand All @@ -83,9 +83,10 @@ class EdxCourseEnrollmentModeChanged(BaseServerModel):
event_source="server", event_type="edx.course.enrollment.mode_changed"
)


event: Union[
Json[EnrollmentEventField],
EnrollmentEventField,
Json[EnrollmentEventField],
]
event_type: Literal["edx.course.enrollment.mode_changed"]
name: Literal["edx.course.enrollment.mode_changed"]
Expand Down
117 changes: 72 additions & 45 deletions src/ralph/models/edx/problem_interaction/fields/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

import sys
from datetime import datetime
from typing import Dict, List, Optional, Union
from typing import Annotated, Dict, List, Optional, Union

from pydantic import constr
from pydantic import Field

from ...base import AbstractBaseEventField, BaseModelWithConfig

Expand Down Expand Up @@ -62,7 +62,7 @@ class State(BaseModelWithConfig):
"""

correct_map: Dict[
constr(regex=r"^[a-f0-9]{32}_[0-9]_[0-9]$"),
Annotated[str, Field(regex=r"^[a-f0-9]{32}_[0-9]_[0-9]$")],
CorrectMap,
]
done: Optional[bool]
Expand Down Expand Up @@ -170,23 +170,26 @@ class ProblemCheckEventField(AbstractBaseEventField):
"""

answers: Dict[
constr(regex=r"^[a-f0-9]{32}_[0-9]_[0-9]$"),
Union[List[str], str],
Annotated[str, Field(regex=r"^[a-f0-9]{32}_[0-9]_[0-9]$")],
Union[str, List[str]],
]
attempts: int
correct_map: Dict[
constr(regex=r"^[a-f0-9]{32}_[0-9]_[0-9]$"),
Annotated[str, Field(regex=r"^[a-f0-9]{32}_[0-9]_[0-9]$")],
CorrectMap,
]
grade: int
max_grade: int
problem_id: constr(
regex=r"^block-v1:[^\/+]+(\/|\+)[^\/+]+(\/|\+)[^\/?]+"
r"type@problem\+block@[a-f0-9]{32}$"
)
problem_id: Annotated[
str,
Field(
regex=r"^block-v1:[^\/+]+(\/|\+)[^\/+]+(\/|\+)[^\/?]+"
r"type@problem\+block@[a-f0-9]{32}$"
),
]
state: State
submission: Dict[
constr(regex=r"^[a-f0-9]{32}_[0-9]_[0-9]$"),
Annotated[str, Field(regex=r"^[a-f0-9]{32}_[0-9]_[0-9]$")],
SubmissionAnswerField,
]
success: Union[Literal["correct"], Literal["incorrect"]]
Expand All @@ -204,14 +207,17 @@ class ProblemCheckFailEventField(AbstractBaseEventField):
"""

answers: Dict[
constr(regex=r"^[a-f0-9]{32}_[0-9]_[0-9]$"),
Union[List[str], str],
Annotated[str, Field(regex=r"^[a-f0-9]{32}_[0-9]_[0-9]$")],
Union[str, List[str]],
]
failure: Union[Literal["closed"], Literal["unreset"]]
problem_id: constr(
regex=r"^block-v1:[^\/+]+(\/|\+)[^\/+]+(\/|\+)[^\/?]+"
r"type@problem\+block@[a-f0-9]{32}$"
)
problem_id: Annotated[
str,
Field(
regex=r"^block-v1:[^\/+]+(\/|\+)[^\/+]+(\/|\+)[^\/?]+"
r"type@problem\+block@[a-f0-9]{32}$"
),
]
state: State


Expand All @@ -235,10 +241,13 @@ class ProblemRescoreEventField(AbstractBaseEventField):
new_total: int
orig_score: int
orig_total: int
problem_id: constr(
regex=r"^block-v1:[^\/+]+(\/|\+)[^\/+]+(\/|\+)[^\/?]+"
r"type@problem\+block@[a-f0-9]{32}$"
)
problem_id: Annotated[
str,
Field(
regex=r"^block-v1:[^\/+]+(\/|\+)[^\/+]+(\/|\+)[^\/?]+"
r"type@problem\+block@[a-f0-9]{32}$"
),
]
state: State
success: Union[Literal["correct"], Literal["incorrect"]]

Expand All @@ -253,10 +262,13 @@ class ProblemRescoreFailEventField(AbstractBaseEventField):
"""

failure: Union[Literal["closed"], Literal["unreset"]]
problem_id: constr(
regex=r"^block-v1:[^\/+]+(\/|\+)[^\/+]+(\/|\+)[^\/?]+"
r"type@problem\+block@[a-f0-9]{32}$"
)
problem_id: Annotated[
str,
Field(
regex=r"^block-v1:[^\/+]+(\/|\+)[^\/+]+(\/|\+)[^\/?]+"
r"type@problem\+block@[a-f0-9]{32}$"
),
]
state: State


Expand Down Expand Up @@ -293,10 +305,13 @@ class ResetProblemEventField(AbstractBaseEventField):

new_state: State
old_state: State
problem_id: constr(
regex=r"^block-v1:[^\/+]+(\/|\+)[^\/+]+(\/|\+)[^\/?]+"
r"type@problem\+block@[a-f0-9]{32}$"
)
problem_id: Annotated[
str,
Field(
regex=r"^block-v1:[^\/+]+(\/|\+)[^\/+]+(\/|\+)[^\/?]+"
r"type@problem\+block@[a-f0-9]{32}$"
),
]


class ResetProblemFailEventField(AbstractBaseEventField):
Expand All @@ -310,10 +325,13 @@ class ResetProblemFailEventField(AbstractBaseEventField):

failure: Union[Literal["closed"], Literal["not_done"]]
old_state: State
problem_id: constr(
regex=r"^block-v1:[^\/+]+(\/|\+)[^\/+]+(\/|\+)[^\/?]+"
r"type@problem\+block@[a-f0-9]{32}$"
)
problem_id: Annotated[
str,
Field(
regex=r"^block-v1:[^\/+]+(\/|\+)[^\/+]+(\/|\+)[^\/?]+"
r"type@problem\+block@[a-f0-9]{32}$"
),
]


class SaveProblemFailEventField(AbstractBaseEventField):
Expand All @@ -329,10 +347,13 @@ class SaveProblemFailEventField(AbstractBaseEventField):

answers: Dict[str, Union[int, str, list, dict]]
failure: Union[Literal["closed"], Literal["done"]]
problem_id: constr(
regex=r"^block-v1:[^\/+]+(\/|\+)[^\/+]+(\/|\+)[^\/?]+"
r"type@problem\+block@[a-f0-9]{32}$"
)
problem_id: Annotated[
str,
Field(
regex=r"^block-v1:[^\/+]+(\/|\+)[^\/+]+(\/|\+)[^\/?]+"
r"type@problem\+block@[a-f0-9]{32}$"
),
]
state: State


Expand All @@ -347,10 +368,13 @@ class SaveProblemSuccessEventField(AbstractBaseEventField):
"""

answers: Dict[str, Union[int, str, list, dict]]
problem_id: constr(
regex=r"^block-v1:[^\/+]+(\/|\+)[^\/+]+(\/|\+)[^\/?]+"
r"type@problem\+block@[a-f0-9]{32}$"
)
problem_id: Annotated[
str,
Field(
regex=r"^block-v1:[^\/+]+(\/|\+)[^\/+]+(\/|\+)[^\/?]+"
r"type@problem\+block@[a-f0-9]{32}$"
),
]
state: State


Expand All @@ -361,7 +385,10 @@ class ShowAnswerEventField(AbstractBaseEventField):
problem_id (str): Consists of the ID of the problem being shown.
"""

problem_id: constr(
regex=r"^block-v1:[^\/+]+(\/|\+)[^\/+]+(\/|\+)[^\/?]+"
r"type@problem\+block@[a-f0-9]{32}$"
)
problem_id: Annotated[
str,
Field(
regex=r"^block-v1:[^\/+]+(\/|\+)[^\/+]+(\/|\+)[^\/?]+"
r"type@problem\+block@[a-f0-9]{32}$"
),
]
5 changes: 3 additions & 2 deletions src/ralph/models/edx/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
from pathlib import Path
from typing import Union

from pydantic import Json
from pydantic import Json, validator

from ralph.models.selector import LazyModelField, selector

from .base import AbstractBaseEventField, BaseEdxModel

if sys.version_info >= (3, 8):
from typing import Literal
from typing import Any, Literal
else:
from typing_extensions import Literal

Expand All @@ -22,6 +22,7 @@ class BaseServerModel(BaseEdxModel):
event_source: Literal["server"]



class ServerEventField(AbstractBaseEventField):
"""Pydantic model for common server `event` field."""

Expand Down
6 changes: 4 additions & 2 deletions src/ralph/models/edx/video/fields/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import sys

from pydantic import NonNegativeFloat

from ...base import AbstractBaseEventField

if sys.version_info >= (3, 8):
Expand Down Expand Up @@ -61,8 +63,8 @@ class SeekVideoEventField(VideoBaseEventField):
within the video, either `onCaptionSeek` or `onSlideSeek` value.
"""

new_time: float
old_time: float
new_time: NonNegativeFloat # TODO: Ask Quitterie if this is valid
old_time: NonNegativeFloat
type: str


Expand Down
10 changes: 5 additions & 5 deletions src/ralph/models/xapi/base/agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
from abc import ABC
from typing import Optional, Union

from pydantic import StrictStr
from ralph.conf import NonEmptyStrictStr
from ralph.models.xapi.config import BaseModelWithConfig

from ..config import BaseModelWithConfig
from .common import IRI
from .ifi import (
BaseXapiAccountIFI,
Expand All @@ -30,21 +30,21 @@ class BaseXapiAgentAccount(BaseModelWithConfig):
"""

homePage: IRI
name: StrictStr
name: NonEmptyStrictStr


class BaseXapiAgentCommonProperties(BaseModelWithConfig, ABC):
"""Pydantic model for core `Agent` type property.

It defines who performed the action.

Attributes:
Attributes:name:
objectType (str): Consists of the value `Agent`.
name (str): Consists of the full name of the Agent.
"""

objectType: Optional[Literal["Agent"]]
name: Optional[StrictStr]
name: Optional[NonEmptyStrictStr]


class BaseXapiAgentWithMbox(BaseXapiAgentCommonProperties, BaseXapiMboxIFI):
Expand Down
Loading