diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 967c58b0..ac1ccf41 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -90,12 +90,15 @@ jobs: python-version: ${{ matrix.python-version }} cache: "pip" + # A PyMEOS-CFFI branch named as this one carries a matching CFFI change; otherwise the + # CFFI of the MEOS line the package version maps to: stable-X.Y on a released line, + # master on the next one. - name: Fetch PyMEOS CFFI sources env: BRANCH_NAME: ${{ github.head_ref || github.ref_name }} run: | git clone --branch ${{ env.BRANCH_NAME }} --depth 1 https://github.com/MobilityDB/PyMEOS-CFFI \ - || git clone --branch ${{ github.base_ref || 'master' }} --depth 1 https://github.com/MobilityDB/PyMEOS-CFFI + || git clone --branch ${{ steps.meos_branch.outputs.meos_branch }} --depth 1 https://github.com/MobilityDB/PyMEOS-CFFI - name: Install python dependencies run: | diff --git a/pymeos/temporal/tsequenceset.py b/pymeos/temporal/tsequenceset.py index 0e14de63..e63ffc20 100644 --- a/pymeos/temporal/tsequenceset.py +++ b/pymeos/temporal/tsequenceset.py @@ -1,16 +1,16 @@ from __future__ import annotations from abc import ABC +from datetime import timedelta from typing import TYPE_CHECKING, Any, TypeVar from pymeos_cffi import * -from .temporal import Temporal, import_pandas +from .temporal import Temporal, TInterpolation, import_pandas if TYPE_CHECKING: import pandas as pd - TBase = TypeVar("TBase") TG = TypeVar("TG", bound="Temporal[Any]") TI = TypeVar("TI", bound="TInstant[Any]") @@ -67,6 +67,18 @@ def from_sequences( """ return cls(sequence_list=sequence_list, normalize=normalize) + @classmethod + def from_instants_with_gaps( + cls, + instants: list[TI], + interpolation: TInterpolation, + max_time: timedelta = None, + max_distance: float = 0.0, + ): + instant_inners = [x._inner for x in instants] + interval = timedelta_to_interval(max_time) if max_time is not None else None + return cls(_inner=tsequenceset_make_gaps(instant_inners, interpolation, interval, max_distance)) + # ------------------------- Accessors ------------------------------------- def num_sequences(self) -> int: """ diff --git a/tests/main/tbool_test.py b/tests/main/tbool_test.py index 92400c62..f91b1997 100644 --- a/tests/main/tbool_test.py +++ b/tests/main/tbool_test.py @@ -2,6 +2,7 @@ from datetime import datetime, timedelta, timezone import pytest +from pymeos_cffi import MeosException from pymeos import ( TBool, @@ -241,6 +242,61 @@ def test_instant_list_sequence_constructor(self, list, interpolation, normalize, assert str(tbs2) == expected assert tbs2.interpolation() == interpolation + @pytest.mark.parametrize( + "params, result", + [ + ( + ( + [ + TBoolInst("True@2000-01-01"), + TBoolInst("False@2000-01-02"), + TBoolInst("False@2000-01-05"), + ], + TInterpolation.STEPWISE, + None, + ), + TBoolSeqSet("{[True@2000-01-01, False@2000-01-02, False@2000-01-05]}"), + ), + ( + ( + [ + TBoolInst("True@2000-01-01"), + TBoolInst("False@2000-01-02"), + TBoolInst("False@2000-01-05"), + ], + TInterpolation.STEPWISE, + timedelta(days=2), + ), + TBoolSeqSet("{[True@2000-01-01, False@2000-01-02], [False@2000-01-05]}"), + ), + ], + ids=["No Gaps", "With Gaps"], + ) + def test_gaps_constructor(self, params, result): + assert TBoolSeqSet.from_instants_with_gaps(*params) == result + + @pytest.mark.parametrize( + "params", + [ + {"interpolation": TInterpolation.STEPWISE, "max_distance": 2}, + {"interpolation": TInterpolation.LINEAR}, + {"interpolation": TInterpolation.DISCRETE}, + ], + ids=[ + "Max Distance", + "Linear Interpolation", + "Discrete Interpolation", + ], + ) + def test_gaps_constructor_with_invalid_parameters_raises(self, params): + instants = [ + TBoolInst(value=True, timestamp="2000-01-01"), + TBoolInst(value=False, timestamp="2000-01-02"), + TBoolInst(value=False, timestamp="2000-01-03"), + ] + with pytest.raises(MeosException): + TBoolSeqSet.from_instants_with_gaps(instants, **params) + @pytest.mark.parametrize( "temporal", [tbi, tbds, tbs, tbss], diff --git a/tests/main/tfloat_test.py b/tests/main/tfloat_test.py index b3e97c59..fe53546c 100644 --- a/tests/main/tfloat_test.py +++ b/tests/main/tfloat_test.py @@ -3,7 +3,7 @@ from operator import not_ import pytest -from pymeos_cffi import MeosInvalidArgValueError +from pymeos_cffi import MeosException, MeosInvalidArgValueError from pymeos import ( FloatSet, @@ -249,6 +249,142 @@ def test_instant_list_sequence_constructor(self, list, interpolation, normalize, assert str(tfs2) == expected assert tfs2.interpolation() == interpolation + @pytest.mark.parametrize( + "params, result", + [ + ( + ( + [ + TFloatInst("1@2000-01-01"), + TFloatInst("5@2000-01-02"), + TFloatInst("6@2000-01-05"), + ], + TInterpolation.STEPWISE, + None, + ), + TFloatSeqSet("Interp=Step;{[1@2000-01-01, 5@2000-01-02, 6@2000-01-05]}"), + ), + ( + ( + [ + TFloatInst("1@2000-01-01"), + TFloatInst("5@2000-01-02"), + TFloatInst("6@2000-01-05"), + ], + TInterpolation.STEPWISE, + None, + 2.0, + ), + TFloatSeqSet("Interp=Step;{[1@2000-01-01], [5@2000-01-02, 6@2000-01-05]}"), + ), + ( + ( + [ + TFloatInst("1@2000-01-01"), + TFloatInst("5@2000-01-02"), + TFloatInst("6@2000-01-05"), + ], + TInterpolation.STEPWISE, + timedelta(days=2), + ), + TFloatSeqSet("Interp=Step;{[1@2000-01-01, 5@2000-01-02], [6@2000-01-05]}"), + ), + ( + ( + [ + TFloatInst("1@2000-01-01"), + TFloatInst("5@2000-01-02"), + TFloatInst("6@2000-01-05"), + ], + TInterpolation.STEPWISE, + timedelta(days=2), + 2.0, + ), + TFloatSeqSet("Interp=Step;{[1@2000-01-01], [5@2000-01-02], [6@2000-01-05]}"), + ), + ( + ( + [ + TFloatInst("1@2000-01-01"), + TFloatInst("5@2000-01-02"), + TFloatInst("6@2000-01-05"), + ], + TInterpolation.LINEAR, + None, + ), + TFloatSeqSet("{[1@2000-01-01, 5@2000-01-02, 6@2000-01-05]}"), + ), + ( + ( + [ + TFloatInst("1@2000-01-01"), + TFloatInst("5@2000-01-02"), + TFloatInst("6@2000-01-05"), + ], + TInterpolation.LINEAR, + None, + 2.0, + ), + TFloatSeqSet("{[1@2000-01-01], [5@2000-01-02, 6@2000-01-05]}"), + ), + ( + ( + [ + TFloatInst("1@2000-01-01"), + TFloatInst("5@2000-01-02"), + TFloatInst("6@2000-01-05"), + ], + TInterpolation.LINEAR, + timedelta(days=2), + ), + TFloatSeqSet("{[1@2000-01-01, 5@2000-01-02], [6@2000-01-05]}"), + ), + ( + ( + [ + TFloatInst("1@2000-01-01"), + TFloatInst("5@2000-01-02"), + TFloatInst("6@2000-01-05"), + ], + TInterpolation.LINEAR, + timedelta(days=2), + 2.0, + ), + TFloatSeqSet("{[1@2000-01-01], [5@2000-01-02], [6@2000-01-05]}"), + ), + ], + ids=[ + "No Gaps Stepwise", + "Value Gaps Stepwise", + "Time Gaps Stepwise", + "Value and Time Gaps Stepwise", + "No Gaps Linear", + "Value Gaps Linear", + "Time Gaps Linear", + "Value and Time Gaps Linear", + ], + ) + def test_gaps_constructor(self, params, result): + assert TFloatSeqSet.from_instants_with_gaps(*params) == result + + @pytest.mark.parametrize( + "params", + [ + {"interpolation": TInterpolation.DISCRETE}, + ], + ids=[ + "Discrete Interpolation", + ], + ) + def test_gaps_constructor_with_invalid_parameters_raises(self, params): + instants = [ + TFloatInst(value=1, timestamp="2000-01-01"), + TFloatInst(value=5, timestamp="2000-01-02"), + TFloatInst(value=6, timestamp="2000-01-03"), + ] + with pytest.raises(MeosException): + TFloatSeqSet.from_instants_with_gaps(instants, **params) + @pytest.mark.parametrize( "temporal", [tfi, tfds, tfs, tfss, tfsts, tfstss], diff --git a/tests/main/tgeogpoint_test.py b/tests/main/tgeogpoint_test.py index 4e415c37..d97b7699 100644 --- a/tests/main/tgeogpoint_test.py +++ b/tests/main/tgeogpoint_test.py @@ -5,7 +5,7 @@ import numpy as np import pytest import shapely.geometry -from pymeos_cffi import MeosInvalidArgValueError +from pymeos_cffi import MeosException, MeosInvalidArgValueError from shapely import LineString, Point, set_srid from pymeos import ( @@ -286,6 +286,148 @@ def test_instant_list_sequence_constructor(self, list, interpolation, normalize, assert str(tps2) == expected assert tps2.interpolation() == interpolation + @pytest.mark.parametrize( + "params, result", + [ + ( + ( + [ + TGeogPointInst("POINT(1 1)@2000-01-01"), + TGeogPointInst("POINT(5 5)@2000-01-02"), + TGeogPointInst("POINT(6 6)@2000-01-05"), + ], + TInterpolation.STEPWISE, + None, + ), + TGeogPointSeqSet("Interp=Step;{[POINT(1 1)@2000-01-01, POINT(5 5)@2000-01-02, POINT(6 6)@2000-01-05]}"), + ), + ( + ( + [ + TGeogPointInst("POINT(1 1)@2000-01-01"), + TGeogPointInst("POINT(5 5)@2000-01-02"), + TGeogPointInst("POINT(6 6)@2000-01-05"), + ], + TInterpolation.STEPWISE, + None, + 200000.0, + ), + TGeogPointSeqSet( + "Interp=Step;{[POINT(1 1)@2000-01-01], [POINT(5 5)@2000-01-02, POINT(6 6)@2000-01-05]}" + ), + ), + ( + ( + [ + TGeogPointInst("POINT(1 1)@2000-01-01"), + TGeogPointInst("POINT(5 5)@2000-01-02"), + TGeogPointInst("POINT(6 6)@2000-01-05"), + ], + TInterpolation.STEPWISE, + timedelta(days=2), + ), + TGeogPointSeqSet( + "Interp=Step;{[POINT(1 1)@2000-01-01, POINT(5 5)@2000-01-02], [POINT(6 6)@2000-01-05]}" + ), + ), + ( + ( + [ + TGeogPointInst("POINT(1 1)@2000-01-01"), + TGeogPointInst("POINT(5 5)@2000-01-02"), + TGeogPointInst("POINT(6 6)@2000-01-05"), + ], + TInterpolation.STEPWISE, + timedelta(days=2), + 200000.0, + ), + TGeogPointSeqSet( + "Interp=Step;{[POINT(1 1)@2000-01-01], [POINT(5 5)@2000-01-02], [POINT(6 6)@2000-01-05]}" + ), + ), + ( + ( + [ + TGeogPointInst("POINT(1 1)@2000-01-01"), + TGeogPointInst("POINT(5 5)@2000-01-02"), + TGeogPointInst("POINT(6 6)@2000-01-05"), + ], + TInterpolation.LINEAR, + None, + ), + TGeogPointSeqSet("{[POINT(1 1)@2000-01-01, POINT(5 5)@2000-01-02, POINT(6 6)@2000-01-05]}"), + ), + ( + ( + [ + TGeogPointInst("POINT(1 1)@2000-01-01"), + TGeogPointInst("POINT(5 5)@2000-01-02"), + TGeogPointInst("POINT(6 6)@2000-01-05"), + ], + TInterpolation.LINEAR, + None, + 200000.0, + ), + TGeogPointSeqSet("{[POINT(1 1)@2000-01-01], [POINT(5 5)@2000-01-02, POINT(6 6)@2000-01-05]}"), + ), + ( + ( + [ + TGeogPointInst("POINT(1 1)@2000-01-01"), + TGeogPointInst("POINT(5 5)@2000-01-02"), + TGeogPointInst("POINT(6 6)@2000-01-05"), + ], + TInterpolation.LINEAR, + timedelta(days=2), + ), + TGeogPointSeqSet("{[POINT(1 1)@2000-01-01, POINT(5 5)@2000-01-02], [POINT(6 6)@2000-01-05]}"), + ), + ( + ( + [ + TGeogPointInst("POINT(1 1)@2000-01-01"), + TGeogPointInst("POINT(5 5)@2000-01-02"), + TGeogPointInst("POINT(6 6)@2000-01-05"), + ], + TInterpolation.LINEAR, + timedelta(days=2), + 200000.0, + ), + TGeogPointSeqSet("{[POINT(1 1)@2000-01-01], [POINT(5 5)@2000-01-02], [POINT(6 6)@2000-01-05]}"), + ), + ], + ids=[ + "No Gaps Stepwise", + "Value Gaps Stepwise", + "Time Gaps Stepwise", + "Value and Time Gaps Stepwise", + "No Gaps Linear", + "Value Gaps Linear", + "Time Gaps Linear", + "Value and Time Gaps Linear", + ], + ) + def test_gaps_constructor(self, params, result): + assert TGeogPointSeqSet.from_instants_with_gaps(*params) == result + + @pytest.mark.parametrize( + "params", + [ + {"interpolation": TInterpolation.DISCRETE}, + ], + ids=[ + "Discrete Interpolation", + ], + ) + def test_gaps_constructor_with_invalid_parameters_raises(self, params): + instants = [ + TGeogPointInst(point="POINT(1 1)", timestamp="2000-01-01"), + TGeogPointInst(point="POINT(5 5)", timestamp="2000-01-02"), + TGeogPointInst(point="POINT(6 6)", timestamp="2000-01-03"), + ] + with pytest.raises(MeosException): + TGeogPointSeqSet.from_instants_with_gaps(instants, **params) + @pytest.mark.parametrize( "temporal", [tpi, tpds, tps, tpss, tpi3d, tpds3d, tps3d, tpss3d], diff --git a/tests/main/tgeompoint_test.py b/tests/main/tgeompoint_test.py index d08c6a03..54144dc7 100644 --- a/tests/main/tgeompoint_test.py +++ b/tests/main/tgeompoint_test.py @@ -5,7 +5,7 @@ import numpy as np import pytest -from pymeos_cffi import MeosInvalidArgValueError +from pymeos_cffi import MeosException, MeosInvalidArgValueError from shapely import GeometryCollection, LineString, MultiPoint, Point, Polygon from pymeos import ( @@ -280,6 +280,148 @@ def test_instant_list_sequence_constructor(self, list, interpolation, normalize, assert str(tps2) == expected assert tps2.interpolation() == interpolation + @pytest.mark.parametrize( + "params, result", + [ + ( + ( + [ + TGeomPointInst("POINT(1 1)@2000-01-01"), + TGeomPointInst("POINT(5 5)@2000-01-02"), + TGeomPointInst("POINT(6 6)@2000-01-05"), + ], + TInterpolation.STEPWISE, + None, + ), + TGeomPointSeqSet("Interp=Step;{[POINT(1 1)@2000-01-01, POINT(5 5)@2000-01-02, POINT(6 6)@2000-01-05]}"), + ), + ( + ( + [ + TGeomPointInst("POINT(1 1)@2000-01-01"), + TGeomPointInst("POINT(5 5)@2000-01-02"), + TGeomPointInst("POINT(6 6)@2000-01-05"), + ], + TInterpolation.STEPWISE, + None, + 2.0, + ), + TGeomPointSeqSet( + "Interp=Step;{[POINT(1 1)@2000-01-01], [POINT(5 5)@2000-01-02, POINT(6 6)@2000-01-05]}" + ), + ), + ( + ( + [ + TGeomPointInst("POINT(1 1)@2000-01-01"), + TGeomPointInst("POINT(5 5)@2000-01-02"), + TGeomPointInst("POINT(6 6)@2000-01-05"), + ], + TInterpolation.STEPWISE, + timedelta(days=2), + ), + TGeomPointSeqSet( + "Interp=Step;{[POINT(1 1)@2000-01-01, POINT(5 5)@2000-01-02], [POINT(6 6)@2000-01-05]}" + ), + ), + ( + ( + [ + TGeomPointInst("POINT(1 1)@2000-01-01"), + TGeomPointInst("POINT(5 5)@2000-01-02"), + TGeomPointInst("POINT(6 6)@2000-01-05"), + ], + TInterpolation.STEPWISE, + timedelta(days=2), + 2.0, + ), + TGeomPointSeqSet( + "Interp=Step;{[POINT(1 1)@2000-01-01], [POINT(5 5)@2000-01-02], [POINT(6 6)@2000-01-05]}" + ), + ), + ( + ( + [ + TGeomPointInst("POINT(1 1)@2000-01-01"), + TGeomPointInst("POINT(5 5)@2000-01-02"), + TGeomPointInst("POINT(6 6)@2000-01-05"), + ], + TInterpolation.LINEAR, + None, + ), + TGeomPointSeqSet("{[POINT(1 1)@2000-01-01, POINT(5 5)@2000-01-02, POINT(6 6)@2000-01-05]}"), + ), + ( + ( + [ + TGeomPointInst("POINT(1 1)@2000-01-01"), + TGeomPointInst("POINT(5 5)@2000-01-02"), + TGeomPointInst("POINT(6 6)@2000-01-05"), + ], + TInterpolation.LINEAR, + None, + 2.0, + ), + TGeomPointSeqSet("{[POINT(1 1)@2000-01-01], [POINT(5 5)@2000-01-02, POINT(6 6)@2000-01-05]}"), + ), + ( + ( + [ + TGeomPointInst("POINT(1 1)@2000-01-01"), + TGeomPointInst("POINT(5 5)@2000-01-02"), + TGeomPointInst("POINT(6 6)@2000-01-05"), + ], + TInterpolation.LINEAR, + timedelta(days=2), + ), + TGeomPointSeqSet("{[POINT(1 1)@2000-01-01, POINT(5 5)@2000-01-02], [POINT(6 6)@2000-01-05]}"), + ), + ( + ( + [ + TGeomPointInst("POINT(1 1)@2000-01-01"), + TGeomPointInst("POINT(5 5)@2000-01-02"), + TGeomPointInst("POINT(6 6)@2000-01-05"), + ], + TInterpolation.LINEAR, + timedelta(days=2), + 2.0, + ), + TGeomPointSeqSet("{[POINT(1 1)@2000-01-01], [POINT(5 5)@2000-01-02], [POINT(6 6)@2000-01-05]}"), + ), + ], + ids=[ + "No Gaps Stepwise", + "Value Gaps Stepwise", + "Time Gaps Stepwise", + "Value and Time Gaps Stepwise", + "No Gaps Linear", + "Value Gaps Linear", + "Time Gaps Linear", + "Value and Time Gaps Linear", + ], + ) + def test_gaps_constructor(self, params, result): + assert TGeomPointSeqSet.from_instants_with_gaps(*params) == result + + @pytest.mark.parametrize( + "params", + [ + {"interpolation": TInterpolation.DISCRETE}, + ], + ids=[ + "Discrete Interpolation", + ], + ) + def test_gaps_constructor_with_invalid_parameters_raises(self, params): + instants = [ + TGeomPointInst(point="POINT(1 1)", timestamp="2000-01-01"), + TGeomPointInst(point="POINT(5 5)", timestamp="2000-01-02"), + TGeomPointInst(point="POINT(6 6)", timestamp="2000-01-03"), + ] + with pytest.raises(MeosException): + TGeomPointSeqSet.from_instants_with_gaps(instants, **params) + @pytest.mark.parametrize( "temporal", [tpi, tpds, tps, tpss, tpi3d, tpds3d, tps3d, tpss3d], diff --git a/tests/main/tint_test.py b/tests/main/tint_test.py index 42431b0c..c52ebfd7 100644 --- a/tests/main/tint_test.py +++ b/tests/main/tint_test.py @@ -3,6 +3,7 @@ from operator import not_ import pytest +from pymeos_cffi import MeosException from pymeos import ( IntSet, @@ -244,6 +245,90 @@ def test_instant_list_sequence_constructor(self, list, interpolation, normalize, assert str(tis2) == expected assert tis2.interpolation() == interpolation + @pytest.mark.parametrize( + "params, result", + [ + ( + ( + [ + TIntInst("1@2000-01-01"), + TIntInst("5@2000-01-02"), + TIntInst("6@2000-01-05"), + ], + TInterpolation.STEPWISE, + None, + ), + TIntSeqSet("Interp=Step;{[1@2000-01-01, 5@2000-01-02, 6@2000-01-05]}"), + ), + ( + ( + [ + TIntInst("1@2000-01-01"), + TIntInst("5@2000-01-02"), + TIntInst("6@2000-01-05"), + ], + TInterpolation.STEPWISE, + None, + 2.0, + ), + TIntSeqSet("Interp=Step;{[1@2000-01-01], [5@2000-01-02, 6@2000-01-05]}"), + ), + ( + ( + [ + TIntInst("1@2000-01-01"), + TIntInst("5@2000-01-02"), + TIntInst("6@2000-01-05"), + ], + TInterpolation.STEPWISE, + timedelta(days=2), + ), + TIntSeqSet("Interp=Step;{[1@2000-01-01, 5@2000-01-02], [6@2000-01-05]}"), + ), + ( + ( + [ + TIntInst("1@2000-01-01"), + TIntInst("5@2000-01-02"), + TIntInst("6@2000-01-05"), + ], + TInterpolation.STEPWISE, + timedelta(days=2), + 2.0, + ), + TIntSeqSet("Interp=Step;{[1@2000-01-01], [5@2000-01-02], [6@2000-01-05]}"), + ), + ], + ids=[ + "No Gaps Stepwise", + "Value Gaps Stepwise", + "Time Gaps Stepwise", + "Value and Time Gaps Stepwise", + ], + ) + def test_gaps_constructor(self, params, result): + assert TIntSeqSet.from_instants_with_gaps(*params) == result + + @pytest.mark.parametrize( + "params", + [ + {"interpolation": TInterpolation.LINEAR}, + {"interpolation": TInterpolation.DISCRETE}, + ], + ids=[ + "Linear Interpolation", + "Discrete Interpolation", + ], + ) + def test_gaps_constructor_with_invalid_parameters_raises(self, params): + instants = [ + TIntInst(value=1, timestamp="2000-01-01"), + TIntInst(value=5, timestamp="2000-01-02"), + TIntInst(value=6, timestamp="2000-01-03"), + ] + with pytest.raises(MeosException): + TIntSeqSet.from_instants_with_gaps(instants, **params) + @pytest.mark.parametrize( "temporal", [tii, tids, tis, tiss], diff --git a/tests/main/ttext_test.py b/tests/main/ttext_test.py index c575a447..f4437e53 100644 --- a/tests/main/ttext_test.py +++ b/tests/main/ttext_test.py @@ -2,6 +2,7 @@ from datetime import datetime, timedelta, timezone import pytest +from pymeos_cffi import MeosException from pymeos import ( TBoolInst, @@ -242,6 +243,57 @@ def test_instant_list_sequence_constructor(self, list, interpolation, normalize, assert str(tts2) == expected assert tts2.interpolation() == interpolation + @pytest.mark.parametrize( + "params, result", + [ + ( + ( + [ + TTextInst("A@2000-01-01"), + TTextInst("B@2000-01-02"), + TTextInst("C@2000-01-05"), + ], + TInterpolation.STEPWISE, + None, + ), + TTextSeqSet("{[A@2000-01-01, B@2000-01-02, C@2000-01-05]}"), + ), + ( + ( + [ + TTextInst("A@2000-01-01"), + TTextInst("B@2000-01-02"), + TTextInst("C@2000-01-05"), + ], + TInterpolation.STEPWISE, + timedelta(days=2), + ), + TTextSeqSet("{[A@2000-01-01, B@2000-01-02], [C@2000-01-05]}"), + ), + ], + ids=["No Gaps", "With Gaps"], + ) + def test_gaps_constructor(self, params, result): + assert TTextSeqSet.from_instants_with_gaps(*params) == result + + @pytest.mark.parametrize( + "params", + [ + {"interpolation": TInterpolation.STEPWISE, "max_distance": 2}, + {"interpolation": TInterpolation.LINEAR}, + {"interpolation": TInterpolation.DISCRETE}, + ], + ids=["Max Distance", "Linear Interpolation", "Discrete Interpolation"], + ) + def test_gaps_constructor_with_invalid_parameters_raises(self, params): + instants = [ + TTextInst(value="A", timestamp="2000-01-01"), + TTextInst(value="B", timestamp="2000-01-02"), + TTextInst(value="C", timestamp="2000-01-03"), + ] + with pytest.raises(MeosException): + TTextSeqSet.from_instants_with_gaps(instants, **params) + @pytest.mark.parametrize( "temporal", [tti, ttds, tts, ttss],