Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 46 additions & 1 deletion datkit/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,53 @@
# For copyright, sharing, and licensing, see https://github.com/myokit/datkit/
#
import os

import unittest

# The test directory
DIR_TEST = os.path.abspath(os.path.dirname(__file__))


class TestCase(unittest.TestCase):
"""
Adds methods to ``unittest.TestCase``.
"""

def array_args_unchanged(self, func, *args):
"""
Test if sequence-type arguments are unchanged by the given function.
"""
import numpy as np

new_args = []
seq_args = {}
for k, arg in enumerate(args):
new_args.append(arg)
if not isinstance(arg, (str, bytes, dict)):
try:
len(arg)
except TypeError:
pass
else:
new_args[k] = np.array(arg)
seq_args[k] = np.array(arg, copy=True)
if len(seq_args) == 0:
return True

# Call, check if unchanged
func(*new_args)
for k, b in seq_args.items():
a = new_args[k]
if a.shape != b.shape:
return False
if np.any(a != b):
return False
return True

def assertUnchanged(self, func, *args):
"""
Fail if the given function changes the sequence-type arguments.
"""
self.assertTrue(self.array_args_unchanged(func, *args))


del os, unittest
18 changes: 14 additions & 4 deletions datkit/tests/test_check_times.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@
# This file is part of Datkit.
# For copyright, sharing, and licensing, see https://github.com/myokit/datkit/
#
import unittest

import numpy as np

import datkit as d
import datkit.tests


class CheckTimesTest(unittest.TestCase):
class CheckTimesTest(datkit.tests.TestCase):
""" Tests methods from the hidden _check_times module. """

def test_is_increasing(self):
Expand Down Expand Up @@ -42,6 +41,10 @@ def test_is_increasing(self):
x = [(0, 1), [1, 2]]
self.assertRaisesRegex(ValueError, '1-d', d.is_increasing, x)

# Test if input is unchanged
self.assertUnchanged(d.is_increasing, np.linspace(0, 1, 101))
self.assertUnchanged(d.is_increasing, (5, 4, 3, 1))

def test_is_regularly_increasing(self):

x = np.linspace(0, 1, 101)
Expand All @@ -62,6 +65,10 @@ def test_is_regularly_increasing(self):

self.assertTrue(d.is_regularly_increasing(-13 + np.arange(10) / 100))

# Test if input is unchanged
self.assertUnchanged(d.is_regularly_increasing, np.linspace(0, 1, 101))
self.assertUnchanged(d.is_regularly_increasing, np.geomspace(1, 2, 10))

def test_sampling_interval(self):

self.assertEqual(d.sampling_interval(np.arange(10)), 1)
Expand All @@ -72,7 +79,6 @@ def test_sampling_interval(self):
self.assertAlmostEqual(
d.sampling_interval(-13 + np.arange(1000) / 100), 0.01)
x = -13 + np.arange(1000) / 100
print(len(x))

self.assertRaisesRegex(ValueError, 'two', d.sampling_interval, [])
self.assertRaisesRegex(ValueError, 'two', d.sampling_interval, [0])
Expand All @@ -82,6 +88,10 @@ def test_sampling_interval(self):
x = [(0, 1), [1, 2]]
self.assertRaisesRegex(ValueError, '1-d', d.sampling_interval, x)

# Test if input is unchanged
self.assertUnchanged(d.sampling_interval, np.linspace(0, 1, 10))


if __name__ == '__main__':
import unittest
unittest.main()
72 changes: 69 additions & 3 deletions datkit/tests/test_points.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@
# This file is part of Datkit.
# For copyright, sharing, and licensing, see https://github.com/myokit/datkit/
#
import unittest

import numpy as np

import datkit as d
import datkit.tests


class PointsTest(unittest.TestCase):
class PointsTest(datkit.tests.TestCase):
""" Tests methods from the hidden _points module. """

def test_abs_max_on(self):
Expand All @@ -25,6 +24,10 @@ def test_abs_max_on(self):
self.assertEqual(d.abs_max_on(t, v, 1.5, 2), (t[99], v[99]))
self.assertEqual(d.abs_max_on(t, v, 1.5, 2, False, True), (2, 1))

t = np.linspace(0, 2, 101)
v = np.cos(t * np.pi)
self.assertUnchanged(d.abs_max_on, t, v)

def test_data_on(self):
t = [0, 1, 2, 3, 4, 5, 6, 7]
v = [10, 11, 12, 13, 14, 15, 16, 17]
Expand All @@ -34,6 +37,10 @@ def test_data_on(self):
self.assertEqual(d.data_on(t, v, t1=2, include_right=True),
([0, 1, 2], [10, 11, 12]))

t = [0, 1, 2, 3, 4, 5, 6, 7]
v = [10, 11, 12, 13, 14, 15, 16, 17]
self.assertUnchanged(d.data_on, t, v)

def test_iabs_max_on(self):
t = np.linspace(0, 2, 101)
v = np.cos(t * np.pi)
Expand All @@ -44,6 +51,10 @@ def test_iabs_max_on(self):
self.assertEqual(d.iabs_max_on(t, v, 1.5, 2), 99)
self.assertEqual(d.iabs_max_on(t, v, 1.5, 2, False, True), 100)

t = np.linspace(0, 2, 30)
v = np.sin(t * np.pi)
self.assertUnchanged(d.iabs_max_on, t, v)

def test_imax_on(self):
t = np.linspace(0, 2, 101)
v = np.cos(t * np.pi)
Expand All @@ -53,6 +64,10 @@ def test_imax_on(self):
self.assertEqual(d.imax_on(t, v, 1.5, 2), 99)
self.assertEqual(d.imax_on(t, v, 1.5, 2, False, True), 100)

t = np.linspace(0, 2, 31)
v = np.cos(t * np.pi + 3)
self.assertUnchanged(d.imax_on, t, v)

def test_imin_on(self):
t = np.linspace(0, 2, 101)
v = np.cos(t * np.pi)
Expand All @@ -62,6 +77,10 @@ def test_imin_on(self):
self.assertEqual(d.imin_on(t, v, 1.5, 2), 75)
self.assertEqual(d.imin_on(t, v, 1.5, 2, False), 76)

t = np.linspace(0, 3, 13)
v = np.cos(t * 2 * np.pi)
self.assertUnchanged(d.imin_on, t, v)

def test_index(self):

# Simple tests
Expand Down Expand Up @@ -127,6 +146,10 @@ def test_index(self):
# Any sequence is accepted
self.assertEqual(d.index(tuple(times), 7.3), 49)

# Input is unchanged
self.assertUnchanged(d.index, np.arange(0, 10), 3)
self.assertUnchanged(d.index, np.arange(0, 10), 0)

def test_index_crossing(self):

# Simple test
Expand Down Expand Up @@ -165,6 +188,10 @@ def test_index_crossing(self):
values = [9, 9, 8, 7, 6, 5, 5, 5, 5, 4, 3, 2, 2]
self.assertEqual(d.index_crossing(values, 5), (4, 9))

# Input is unchanged
values = [4, 5, 6, 7, 8, 6, 7, 8, 9]
self.assertUnchanged(d.index_crossing, values, 6.5)

def test_index_near(self):

# Exact matches
Expand Down Expand Up @@ -192,6 +219,10 @@ def test_index_near(self):
self.assertEqual(d.index_near(tuple(times), 9.6), 19)
self.assertEqual(d.index_near(list(times), 9.6), 19)

# Input should remain unchanged
self.assertUnchanged(d.index_near, np.arange(0, 10), 4)
self.assertUnchanged(d.index_near, np.arange(0, 10), 9)

def test_index_on(self):
t = np.arange(0, 10)
self.assertEqual(d.index_on(t, 2, 4), (2, 4))
Expand Down Expand Up @@ -258,6 +289,11 @@ def test_index_on(self):
self.assertEqual(d.index_on(tuple(t), 3), (2, 10))
self.assertEqual(d.index_on(list(t), 3), (2, 10))

# Input should stay unchanged
self.assertUnchanged(d.index_on, np.arange(0, 10), 2, 4)
self.assertUnchanged(d.index_on, np.arange(0, 10), -5, 4)
self.assertUnchanged(d.index_on, np.arange(0, 10), 12, 14)

def test_max_on(self):
t = np.linspace(0, 2, 101)
v = np.cos(t * np.pi)
Expand All @@ -267,6 +303,10 @@ def test_max_on(self):
self.assertEqual(d.max_on(t, v, 1.5, 2), (t[99], v[99]))
self.assertEqual(d.max_on(t, v, 1.5, 2, False, True), (t[100], v[100]))

t = np.linspace(0, 1, 11)
v = np.sin(3 * t * np.pi)
self.assertUnchanged(d.max_on, t, v)

def test_mean_on(self):
t = np.arange(1, 11)
self.assertEqual(d.mean_on(t, t, 1, 11), 5.5)
Expand All @@ -279,6 +319,10 @@ def test_mean_on(self):
self.assertEqual(d.mean_on(t, v, 4, 8, False), 37)
self.assertEqual(d.mean_on(t, v, 4, 8, True, True), 37)

t = np.arange(1, 11)
v = -3 + 8 * t[::-1]
self.assertUnchanged(d.mean_on, t, v, 2, 7)

def test_min_on(self):
t = np.linspace(0, 2, 101)
v = np.cos(t * np.pi)
Expand All @@ -288,6 +332,10 @@ def test_min_on(self):
self.assertEqual(d.min_on(t, v, 1.5, 2), (t[75], v[75]))
self.assertEqual(d.min_on(t, v, 1.5, 2, False), (t[76], v[76]))

t = np.linspace(0, 2, 101)
v = np.cos(t * np.pi)
self.assertUnchanged(d.min_on, t, v, 1.5, 2, False)

def test_time_crossing(self):
t = np.linspace(1, 5, 100)
v = np.sin(t) + 1
Expand All @@ -302,6 +350,10 @@ def test_time_crossing(self):
self.assertEqual(d.time_crossing(t, v, 25), 6.5)
self.assertEqual(d.time_crossing(t, v, 31), 5.9)

t = np.linspace(1, 5, 100)
v = np.sin(t) + 1
self.assertUnchanged(d.time_crossing, t, v, 0.1)

def test_value_at(self):
t = np.arange(0, 10)
self.assertEqual(d.value_at(t, t, 0), 0)
Expand All @@ -311,6 +363,10 @@ def test_value_at(self):
self.assertEqual(d.value_at(t, v, 0), 20)
self.assertEqual(d.value_at(t, v, 5), 30)

t = np.arange(0, 10)
v = 10 + t
self.assertUnchanged(d.value_at, t, v, 3)

def test_value_interpolated(self):
t, v = [2, 3, 4, 5, 6, 7], [5, 0, 3, -1, 4, 8]
self.assertEqual(d.value_interpolated(t, v, 2), 5)
Expand All @@ -329,6 +385,9 @@ def test_value_interpolated(self):
self.assertEqual(d.value_interpolated(t, v, 1), 6)
self.assertEqual(d.value_interpolated(t, v, 2), 6)

t, v = [2, 3, 4, 5, 6, 7], [5, 0, 3, -1, 4, 8]
self.assertUnchanged(d.value_interpolated, t, v, 3)

def test_value_near(self):
t = np.arange(0, 10)
self.assertEqual(d.value_near(t, t, 0), 0)
Expand All @@ -341,6 +400,13 @@ def test_value_near(self):
self.assertEqual(d.value_at(t, v, 0), 20)
self.assertEqual(d.value_at(t, v, 5), 30)

t = np.arange(0, 10)
v = 30 + 2 * t
self.assertUnchanged(d.value_at, t, v, 0)
self.assertUnchanged(d.value_at, t, v, 5)


if __name__ == '__main__':
import unittest
unittest.main()

19 changes: 16 additions & 3 deletions datkit/tests/test_smoothing.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,17 @@
# This file is part of Datkit.
# For copyright, sharing, and licensing, see https://github.com/myokit/datkit/
#
import unittest

import numpy as np

import datkit as d
import datkit.tests


# Extra output
debug = False


class SmoothingTest(unittest.TestCase):
class SmoothingTest(datkit.tests.TestCase):
""" Tests methods from the hidden _smoothing module. """

def test_gaussian_smoothing(self):
Expand Down Expand Up @@ -93,6 +92,10 @@ def test_gaussian_smoothing(self):
self.assertRaisesRegex(
ValueError, 'same size', d.gaussian_smoothing, t, t[:-1], 3)

# Input is unchanged
self.assertUnchanged(
d.gaussian_smoothing, np.arange(11), np.ones(11), 3)

def test_haar_downsample(self):

# Numerical tests with ones: should return all ones
Expand Down Expand Up @@ -155,6 +158,9 @@ def test_haar_downsample(self):
self.assertRaisesRegex(
ValueError, 'same size', d.haar_downsample, t, t[:-1], 3)

# Input is unchanged
self.assertUnchanged(d.haar_downsample, np.arange(10), np.ones(10))

def test_moving_average(self):

# Numerical tests with ones: should return all ones
Expand Down Expand Up @@ -215,6 +221,9 @@ def test_moving_average(self):
self.assertRaisesRegex(
ValueError, 'same size', d.moving_average, t, v[:-1], 3)

# Input is unchanged
self.assertUnchanged(d.moving_average, np.arange(9), np.ones(9), 3)

def test_window_size(self):

# Window size checking
Expand Down Expand Up @@ -255,10 +264,14 @@ def test_window_size(self):
self.assertRaisesRegex(
ValueError, 'Two window sizes', d.window_size, t, 3, 0.3)

# Input is unchanged
self.assertUnchanged(d.window_size, np.linspace(0, 5, 51), 3)


if __name__ == '__main__':
print('Add -v for more debug output')
import sys
import unittest
if '-v' in sys.argv:
debug = True
unittest.main()
Loading