Skip to content

Commit 8a6a942

Browse files
authored
Merge pull request #315 from clamsproject/312-missing-isoformat-convert
fixed some missing conversion in tuh.convert implementation
2 parents 364af05 + 2d8bc0f commit 8a6a942

File tree

4 files changed

+38
-12
lines changed

4 files changed

+38
-12
lines changed

mmif/utils/timeunit_helper.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,18 +67,29 @@ def convert(t: Union[int, float, str], in_unit: str, out_unit: str, fps: float)
6767
return t
6868
elif out_unit == 'frame':
6969
# ms>f
70-
if 'millisecond' == in_unit:
70+
if in_unit == 'millisecond':
7171
return round(t / 1000 * fps)
7272
# s>f
7373
elif 'second' == in_unit:
7474
return round(t * fps)
75+
# i>f
76+
else:
77+
return round(_isoformat_to_millisecond(t) / 1000 * fps)
7578
# s>(ms or i)
7679
elif in_unit == 'second':
7780
return round(t * 1000) if out_unit == 'millisecond' else _second_to_isoformat(t)
7881
# ms>(s or i)
7982
elif in_unit == 'millisecond':
8083
return t / 1000 if out_unit == 'second' else _millisecond_to_isoformat(t)
81-
# f>ms, f>s
84+
# f>
8285
else:
83-
return (t / fps) if out_unit == 'second' else round(round(t / fps, 3) * 1000) # pytype: disable=bad-return-type
86+
# f>s
87+
if out_unit == 'second':
88+
return t / fps
89+
# f>ms
90+
elif out_unit == 'millisecond':
91+
return round(round(t / fps, 3) * 1000)
92+
# f>i
93+
else:
94+
return _second_to_isoformat(t / fps)
8495

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
deepdiff>5
2+
orderly-set==5.3.* # 5.4 drops py38 support
23
jsonschema

tests/test_serialize.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020

2121
# Flags for skipping tests
2222
DEBUG = False
23-
SKIP_SCHEMA = False, "Not skipping TestSchema by default"
23+
SKIP_SCHEMA = True, "Not skipping TestSchema by default"
24+
# skipping jsonschema testing until vocab-type level validation is fully implemented
25+
# (https://github.com/clamsproject/mmif-python/issues/309)
2426
not_existing_attype = 'http://not.existing/type'
2527
tester_appname = 'http://not.existing/app'
2628

tests/test_utils.py

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,29 @@
99
from mmif.utils import timeunit_helper as tuh
1010
from mmif.utils import video_document_helper as vdh
1111
from tests.mmif_examples import *
12+
from hypothesis import given, strategies as st
1213

1314

1415
class TestTimeunitHelper(unittest.TestCase):
15-
FPS = 30
16-
17-
def test_convert(self):
18-
self.assertEqual(1000, tuh.convert(1, 's', 'ms', self.FPS))
19-
self.assertEqual(1.1, tuh.convert(1100, 'ms', 's', self.FPS))
20-
self.assertEqual('00:01:30.000', tuh.convert(90, 's', 'i', self.FPS))
21-
self.assertEqual(3300, tuh.convert('00:00:03.300', 'i', 'ms', self.FPS))
22-
self.assertEqual(7.77, tuh.convert('00:00:07.770', 'i', 's', self.FPS))
16+
FPS = 100 # 1 frame == 10 ms
17+
18+
@given(st.integers(min_value=300, max_value=10000))
19+
def test_convert(self, value):
20+
# using hypothesis library, test time unit conversions
21+
# four-way between second, millisecond, framenum, and isoformat
22+
for tu1 in ['s', 'm', 'f', 'i']:
23+
for tu2 in ['s', 'm', 'f', 'i']:
24+
if tu1 == tu2:
25+
continue
26+
# since the input (generated by hypothesis) is always integer/millisecond
27+
# I'm going to dual round-trip conversion
28+
# ms > tu1 > tu2 > tu1 > ms
29+
# then see the ends are equal (enough)
30+
in_t = tuh.convert(value, 'm', tu1, self.FPS)
31+
converted = tuh.convert(in_t, tu1, tu2, self.FPS)
32+
converted_back = tuh.convert(converted, tu2, tu1, self.FPS)
33+
out_t = tuh.convert(converted_back, tu1, 'm', self.FPS)
34+
self.assertAlmostEqual(value, out_t, delta=1000/self.FPS) # up to 1 frame error
2335

2436

2537
class TestVideoDocumentHelper(unittest.TestCase):

0 commit comments

Comments
 (0)