aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThéo de la Hogue2022-11-16 20:01:05 +0100
committerThéo de la Hogue2022-11-16 20:01:05 +0100
commit33c8d6b7ed9f1ab2993da405430cca2910c5c636 (patch)
tree8a2ab8f4aaad6dc5b665681467202037c45a8e9a
parent980abf0392021296a6c3b5f765277cd9b74f64a2 (diff)
downloadargaze-33c8d6b7ed9f1ab2993da405430cca2910c5c636.zip
argaze-33c8d6b7ed9f1ab2993da405430cca2910c5c636.tar.gz
argaze-33c8d6b7ed9f1ab2993da405430cca2910c5c636.tar.bz2
argaze-33c8d6b7ed9f1ab2993da405430cca2910c5c636.tar.xz
Testing instance representation.
-rw-r--r--src/argaze.test/DataStructures.py35
-rw-r--r--src/argaze.test/GazeFeatures.py165
2 files changed, 196 insertions, 4 deletions
diff --git a/src/argaze.test/DataStructures.py b/src/argaze.test/DataStructures.py
index 5f0a4ac..c1b78d5 100644
--- a/src/argaze.test/DataStructures.py
+++ b/src/argaze.test/DataStructures.py
@@ -1,6 +1,7 @@
#!/usr/bin/env python
import unittest
+from dataclasses import dataclass, field
from argaze import DataStructures
@@ -27,6 +28,12 @@ def random_data_buffer(size, data_keys):
return ts_buffer
+@dataclass()
+class BasicDataClass():
+ """Define a basic dataclass for testing purpose."""
+
+ value: tuple
+
class TestTimeStampedBufferClass(unittest.TestCase):
"""Test TimeStampedBuffer class."""
@@ -56,12 +63,17 @@ class TestTimeStampedBufferClass(unittest.TestCase):
DataStructures.TimeStampedBuffer({"first": ""})
- def test_str(self):
+ def test___repr__(self):
"""Test TimeStampedBuffer string representation."""
- self.assertEqual(str(DataStructures.TimeStampedBuffer()), "{}")
- self.assertEqual(str(DataStructures.TimeStampedBuffer({0: ""})), "{\"0\": \"\"}")
- self.assertEqual(str(DataStructures.TimeStampedBuffer({0.1: ""})), "{\"0.1\": \"\"}")
+ self.assertEqual(repr(DataStructures.TimeStampedBuffer()), "{}")
+ self.assertEqual(repr(DataStructures.TimeStampedBuffer({0: ""})), "{\"0\": \"\"}")
+ self.assertEqual(repr(DataStructures.TimeStampedBuffer({0.1: ""})), "{\"0.1\": \"\"}")
+
+ data = BasicDataClass((123, 456))
+ ts_buffer = DataStructures.TimeStampedBuffer({0: data})
+
+ self.assertEqual(repr(ts_buffer), "{\"0\": {\"value\": [123, 456]}}")
def test_append(self):
"""Test TimeStampedBuffer append method."""
@@ -170,6 +182,11 @@ class TestTimeStampedBufferClass(unittest.TestCase):
self.assertEqual(ts_buffer_dataframe.columns[1], "data_B")
self.assertEqual(ts_buffer_dataframe.columns[2], "data_C")
+ self.assertEqual(ts_buffer_dataframe.index.dtype, 'float64')
+ self.assertEqual(ts_buffer_dataframe["data_A"].dtype, 'object')
+ self.assertEqual(ts_buffer_dataframe["data_B"].dtype, 'object')
+ self.assertEqual(ts_buffer_dataframe["data_C"].dtype, 'object')
+
# Check data exclusion option
ts_buffer_dataframe = ts_buffer.as_dataframe(exclude=["data_B"])
@@ -192,6 +209,16 @@ class TestTimeStampedBufferClass(unittest.TestCase):
self.assertEqual(ts_buffer_dataframe.columns[2], "data_B1")
self.assertEqual(ts_buffer_dataframe.columns[3], "data_C")
+ # Check dataframe conversion with dataclass
+ data = BasicDataClass((123, 456))
+ ts_buffer_dataframe = DataStructures.TimeStampedBuffer({0: data}).as_dataframe()
+
+ self.assertEqual(ts_buffer_dataframe.index.name, "timestamp")
+ self.assertEqual(ts_buffer_dataframe.index.size, 1)
+
+ self.assertEqual(ts_buffer_dataframe.columns.size, 1)
+ self.assertEqual(ts_buffer_dataframe.columns[0], "value")
+
if __name__ == '__main__':
unittest.main() \ No newline at end of file
diff --git a/src/argaze.test/GazeFeatures.py b/src/argaze.test/GazeFeatures.py
index 692b6cf..5a3c2d9 100644
--- a/src/argaze.test/GazeFeatures.py
+++ b/src/argaze.test/GazeFeatures.py
@@ -4,6 +4,29 @@ import unittest
from argaze import GazeFeatures
+import numpy
+
+def random_gaze_positions(size):
+ """ Generate random TimeStampedGazePsoitions for testing purpose.
+ Timestamps are current time.
+ GazePositions are random values.
+ """
+
+ import random
+ import time
+
+ ts_gaze_positions = GazeFeatures.TimeStampedGazePositions()
+
+ for i in range(0, size):
+
+ # Edit gaze position
+ random_gaze_position = GazeFeatures.GazePosition((random.random(), random.random()))
+
+ # Store gaze position
+ ts_gaze_positions[time.time()] = random_gaze_position
+
+ return ts_gaze_positions
+
class TestGazePositionClass(unittest.TestCase):
"""Test GazePosition class."""
@@ -12,8 +35,150 @@ class TestGazePositionClass(unittest.TestCase):
# Check empty GazePosition
empty_gaze_position = GazeFeatures.GazePosition()
+
self.assertEqual(empty_gaze_position.value, (0, 0))
+ self.assertEqual(empty_gaze_position[0], 0)
+ self.assertEqual(empty_gaze_position[1], 0)
+
+ for v in empty_gaze_position:
+ self.assertEqual(v, 0)
+
self.assertEqual(empty_gaze_position.accuracy, 0.)
+ self.assertEqual(len(empty_gaze_position), 2)
+ self.assertEqual(empty_gaze_position.valid, True)
+ self.assertEqual(numpy.array(empty_gaze_position).shape, (2,))
+
+ # Check integer GazePosition
+ int_gaze_position = GazeFeatures.GazePosition((123, 456), accuracy=55)
+
+ self.assertEqual(int_gaze_position.value, (123, 456))
+ self.assertEqual(int_gaze_position[0], 123)
+ self.assertEqual(int_gaze_position[1], 456)
+ self.assertEqual(int_gaze_position.accuracy, 55)
+ self.assertEqual(len(int_gaze_position), 2)
+ self.assertEqual(int_gaze_position.valid, True)
+ self.assertEqual(numpy.array(empty_gaze_position).shape, (2,))
+
+ # Check float GazePosition
+ float_gaze_position = GazeFeatures.GazePosition((1.23, 4.56), accuracy=5.5)
+
+ self.assertEqual(float_gaze_position.value, (1.23, 4.56))
+ self.assertEqual(float_gaze_position[0], 1.23)
+ self.assertEqual(float_gaze_position[1], 4.56)
+ self.assertEqual(float_gaze_position.accuracy, 5.5)
+ self.assertEqual(len(float_gaze_position), 2)
+ self.assertEqual(float_gaze_position.valid, True)
+ self.assertEqual(numpy.array(empty_gaze_position).shape, (2,))
+
+ def test_properties(self):
+ """Test GazePosition properties cannot be modified after creation."""
+
+ gaze_position = GazeFeatures.GazePosition()
+
+ # Check that gaze position value setting fails
+ with self.assertRaises(AttributeError):
+
+ gaze_position.value = (123, 456)
+
+ self.assertNotEqual(gaze_position.value, (123, 456))
+ self.assertEqual(gaze_position.value, (0, 0))
+
+ def test___repr__(self):
+ """Test GazePosition string representation."""
+
+ # Check empty GazePosition representation
+ self.assertEqual(repr(GazeFeatures.GazePosition()), "{\"value\": [0, 0], \"accuracy\": 0.0}")
+
+class TestUnvalidGazePositionClass(unittest.TestCase):
+ """Test UnvalidGazePosition class."""
+
+ def test_new(self):
+ """Test UnvalidGazePosition creation."""
+
+ import math
+
+ unvalid_gaze_position = GazeFeatures.UnvalidGazePosition()
+
+ self.assertEqual(unvalid_gaze_position.value, (None, None))
+ self.assertEqual(unvalid_gaze_position.accuracy, None)
+ self.assertEqual(unvalid_gaze_position.valid, False)
+
+ def test___repr__(self):
+ """Test UnvalidGazePosition string representation."""
+
+ self.assertEqual(repr(GazeFeatures.UnvalidGazePosition()), "{\"value\": [null, null], \"accuracy\": null}")
+
+class TestTimeStampedGazePositionsClass(unittest.TestCase):
+ """Test TimeStampedGazePositions class."""
+
+ def test___setitem__(self):
+ """Test __setitem__ method."""
+
+ ts_gaze_positions = GazeFeatures.TimeStampedGazePositions()
+ ts_gaze_positions[0] = GazeFeatures.GazePosition()
+ ts_gaze_positions[1] = GazeFeatures.UnvalidGazePosition()
+
+ # Check GazePosition is correctly stored and accessible as a GazePosition
+ self.assertIsInstance(ts_gaze_positions[0], GazeFeatures.GazePosition)
+ self.assertEqual(ts_gaze_positions[0].valid, True)
+
+ # Check UnvalidGazePosition is correctly stored and accessible as a UnvalidGazePosition
+ self.assertIsInstance(ts_gaze_positions[1], GazeFeatures.UnvalidGazePosition)
+ self.assertEqual(ts_gaze_positions[1].valid, False)
+
+ # Check that bad data type insertion fails
+ with self.assertRaises(AssertionError):
+
+ ts_gaze_positions[2] = "This string is not a gaze position value."
+
+ # Check final lenght
+ self.assertEqual(len(ts_gaze_positions), 2)
+
+ def test___repr__(self):
+ """Test inherited string representation."""
+
+ ts_gaze_positions = GazeFeatures.TimeStampedGazePositions()
+
+ self.assertEqual(repr(GazeFeatures.TimeStampedGazePositions()), "{}")
+
+ ts_gaze_positions[0] = GazeFeatures.GazePosition()
+
+ self.assertEqual(repr(ts_gaze_positions), "{\"0\": {\"value\": [0, 0], \"accuracy\": 0.0}}")
+
+ ts_gaze_positions[0] = GazeFeatures.UnvalidGazePosition()
+
+ self.assertEqual(repr(ts_gaze_positions), "{\"0\": {\"value\": [null, null], \"accuracy\": null}}")
+
+ def test_as_dataframe(self):
+ """Test inherited as_dataframe method."""
+
+ ts_gaze_positions_dataframe = random_gaze_positions(10).as_dataframe()
+
+ # Check dataframe conversion
+ self.assertEqual(ts_gaze_positions_dataframe.index.name, "timestamp")
+ self.assertEqual(ts_gaze_positions_dataframe.index.size, 10)
+
+ self.assertEqual(ts_gaze_positions_dataframe.columns.size, 2)
+ self.assertEqual(ts_gaze_positions_dataframe.columns[0], "value")
+ self.assertEqual(ts_gaze_positions_dataframe.columns[1], "accuracy")
+
+ self.assertEqual(ts_gaze_positions_dataframe["value"].dtype, 'object')
+ self.assertEqual(ts_gaze_positions_dataframe["accuracy"].dtype, 'float64')
+
+ # Check unvalid position conversion
+ ts_gaze_positions = GazeFeatures.TimeStampedGazePositions()
+ ts_gaze_positions[0] = GazeFeatures.UnvalidGazePosition()
+ ts_gaze_positions_dataframe = ts_gaze_positions.as_dataframe()
+
+ self.assertEqual(ts_gaze_positions_dataframe.index.name, "timestamp")
+ self.assertEqual(ts_gaze_positions_dataframe.index.size, 1)
+
+ self.assertEqual(ts_gaze_positions_dataframe.columns.size, 2)
+ self.assertEqual(ts_gaze_positions_dataframe.columns[0], "value")
+ self.assertEqual(ts_gaze_positions_dataframe.columns[1], "accuracy")
+
+ self.assertEqual(ts_gaze_positions_dataframe["value"].dtype, 'object')
+ self.assertEqual(ts_gaze_positions_dataframe["accuracy"].dtype, 'O') # Python object type
if __name__ == '__main__':