Skip to content

Commit 5727b29

Browse files
committed
Test EBU-TT-D <--> XML
1 parent 4232dea commit 5727b29

12 files changed

+172
-27
lines changed

Pipfile

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
[[source]]
2+
url = "https://pypi.org/simple"
3+
verify_ssl = true
4+
name = "pypi"
5+
6+
[[source]]
7+
url = "https://pypi.python.org/simple/"
8+
verify_ssl = true
9+
name = "pypipython"
10+
11+
[packages]
12+
ipython = "*"
13+
sphinx = "*"
14+
sphinx-autobuild = "*"
15+
sphinxcontrib-plantuml = "*"
16+
recommonmark = "*"
17+
sphinx-rtd-theme = "*"
18+
pytest-bdd = "<4.0.0"
19+
pytest-cov = "*"
20+
pytest-mock = "*"
21+
pytest-subtests = "*"
22+
pytest-twisted = "*"
23+
coverage = "*"
24+
pytest-runner = "*"
25+
pytest = "*"
26+
jinja2 = "*"
27+
mock = "*"
28+
importlib-metadata = "<4.3,>2.0.0"
29+
ebu-tt-live = {editable = true, file = "file:///Users/megitn02/Code/bbc/ebu-tt-live-toolkit"}
30+
31+
[dev-packages]
32+
33+
[requires]
34+
python_version = "3.7"

ebu_tt_live/adapters/document_data.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,11 @@ class XMLtoEBUTTDAdapter(IDocumentDataAdapter):
7373
_provides = EBUTTDDocument
7474

7575
def convert_data(self, data, **kwargs):
76-
return EBUTTDDocument.create_from_xml(data), kwargs
76+
doc = EBUTTDDocument.create_from_xml(data)
77+
kwargs.update(dict(
78+
raw_xml=data
79+
))
80+
return doc, kwargs
7781

7882

7983
class EBUTTDtoXMLAdapter(IDocumentDataAdapter):
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<tt:tt ttp:timeBase="media" xml:lang="en-GB" xmlns:ebuttm="urn:ebu:tt:metadata" xmlns:ebuttp="urn:ebu:tt:parameters" xmlns:tt="http://www.w3.org/ns/ttml" xmlns:ttp="http://www.w3.org/ns/ttml#parameter" xmlns:tts="http://www.w3.org/ns/ttml#styling" xmlns:xml="http://www.w3.org/XML/1998/namespace">
3+
<tt:head>
4+
<tt:metadata>
5+
<ebuttm:documentMetadata/>
6+
</tt:metadata>
7+
<tt:styling>
8+
<tt:style xml:id="s0"/>
9+
</tt:styling>
10+
<tt:layout>
11+
<tt:region xml:id="r0" tts:origin="10% 10%" tts:extent="80% 80%"></tt:region>
12+
</tt:layout>
13+
</tt:head>
14+
<tt:body>
15+
<tt:div>
16+
<tt:p xml:id="ID001" begin="01:23:45.670" end="01:23:45.890">It only took me six days.</tt:p>
17+
</tt:div>
18+
</tt:body>
19+
</tt:tt>
20+

ebu_tt_live/adapters/test/test_document_data_adapters.py

+46-10
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,49 @@ def test_sequence_id_mismatch(self):
136136

137137

138138
class TestXMLtoEBUTTDAdapter(TestCase):
139-
_output_type = documents.EBUTTDDocument
140139
_adapter_class = document_data.XMLtoEBUTTDAdapter
141-
_expected_keys = []
140+
_test_xml_file = 'testEbuttd.xml'
141+
_test_data_dir_path = os.path.join(os.path.dirname(__file__), 'test_data')
142+
_test_xml_path = os.path.join(_test_data_dir_path, _test_xml_file)
143+
_output_type = documents.EBUTTDDocument
144+
_expected_keys = [
145+
'raw_xml'
146+
]
147+
instance = None
148+
149+
def setUp(self):
150+
self.instance = self._adapter_class()
151+
self.assertIsInstance(self.instance, IDocumentDataAdapter)
142152

143-
# TODO: Finish this once we have EBUTT-D parsing
153+
def _assert_output_type(self, result):
154+
self.assertIsInstance(result, self._output_type)
155+
156+
def _assert_kwargs_passtrough(self, result_kwargs, expected_keys):
157+
self.assertEqual(set(result_kwargs.keys()), set(expected_keys))
158+
159+
def _get_xml(self):
160+
with open(self._test_xml_path, 'r') as xml_file:
161+
xml_data = xml_file.read()
162+
return xml_data
163+
164+
def _get_input(self):
165+
return self._get_xml()
166+
167+
def test_success(self):
168+
expected_keys = []
169+
expected_keys.extend(self._expected_keys)
170+
result, res_kwargs = self.instance.convert_data(self._get_input())
171+
self._assert_output_type(result)
172+
self._assert_kwargs_passtrough(res_kwargs, expected_keys)
173+
174+
def test_kwargs_passthrough(self):
175+
in_kwargs = {
176+
'foo': 'bar'
177+
}
178+
expected_keys = ['foo']
179+
expected_keys.extend(self._expected_keys)
180+
result, res_kwargs = self.instance.convert_data(self._get_input(), **in_kwargs)
181+
self._assert_kwargs_passtrough(res_kwargs, expected_keys)
144182

145183

146184
class TestEBUTT3toXMLAdapter(TestXMLtoEBUTT3Adapter):
@@ -164,20 +202,18 @@ def test_sequence_id_match(self):
164202
pass
165203

166204

167-
class TestEBUTTDtoXMLAdapter(TestEBUTT3toXMLAdapter):
205+
class TestEBUTTDtoXMLAdapter(TestXMLtoEBUTTDAdapter):
206+
_output_type = six.text_type
168207
_adapter_class = document_data.EBUTTDtoXMLAdapter
169208
_expected_keys = []
170209

210+
def _get_input(self):
211+
return documents.EBUTTDDocument.create_from_xml(self._get_xml())
212+
171213
def _get_input(self):
172214
input_doc = documents.EBUTTDDocument(lang='en-GB')
173215
return input_doc
174216

175-
def test_sequence_id_mismatch(self):
176-
pass
177-
178-
def test_sequence_id_match(self):
179-
pass
180-
181217

182218
class TestEBUTT3toEBUTTDAdapter(TestXMLtoEBUTT3Adapter):
183219
_adapter_class = document_data.EBUTT3toEBUTTDAdapter

ebu_tt_live/bindings/_ebuttdt.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,11 @@ def _ConvertArguments_vx(cls, args, kw):
6868
context = get_xml_parsing_context()
6969
if context is not None:
7070
# This means we are in XML parsing context. There should be a timeBase and a timing_attribute_name in the
71-
# context object.
72-
time_base = context['timeBase']
71+
# context object. But if there's no timeBase, in the context
72+
# of EBU-TT-D, we will assume media. Some files in the wild
73+
# trigger this behaviour, for reasons not yet identified, i.e.
74+
# we somehow get here without having a timeBase context set.
75+
time_base = context.get('timeBase', 'media')
7376
# It is possible for a timing type to exist as the value of an element not an attribute,
7477
# in which case no timing_attribute_name is in the context; in that case don't attempt
7578
# to validate the data against a timebase. At the moment this only affects the

ebu_tt_live/bindings/pyxb_utils.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def get_xml_parsing_context():
2323
into account the timeBase attribute on the tt element. In that case when the timeBase element is encountered by the
2424
parser is is added to the parsing context object to help PyXB make the right type in the timingType union.
2525
26-
:return: dict that is te parsing context for the currently running parser
26+
:return: dict that is the parsing context for the currently running parser
2727
:return: None if not in parsing mode
2828
"""
2929
log.debug('Accessing xml_parsing_context: {}'.format(__xml_parsing_context))

p0bmslf8_gaps.json

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
> /Users/megitn02/Code/bbc/ebu-tt-live-toolkit/ebu_tt_live/scripts/get_times_from_ebuttd.py(1)<module>()
2+
-> from ebu_tt_live.documents import EBUTTDDocument
3+
(Pdb) --KeyboardInterrupt--
4+
(Pdb)

package-lock.json

+6-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

testing/bdd/conftest.py

+17
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,18 @@
1616
import os
1717
import unittest
1818

19+
20+
# if os.getenv('_PYTEST_RAISE', "0") != "0":
21+
#
22+
# @pytest.hookimpl(tryfirst=True)
23+
# def pytest_exception_interact(call):
24+
# raise call.excinfo.value
25+
#
26+
# @pytest.hookimpl(tryfirst=True)
27+
# def pytest_internalerror(excinfo):
28+
# raise excinfo.value
29+
30+
1931
denester_node = DenesterNode(
2032
node_id = "denester_node",
2133
sequence_identifier = "denestedSequenceT"
@@ -221,6 +233,11 @@ def when_converter_set_to_use_fixed_offset_smpte_converter(test_context):
221233
else:
222234
print('tried making a FixedOffsetSMPTEConvverter but document timebase was not SMPTE')
223235

236+
@when('the document\'s timeBase is set to <timebase>')
237+
def when_document_timebase(template_dict, timebase):
238+
# timeBase in ebutt1_template.xml is 'media' by default
239+
template_dict['timeBase'] = timebase
240+
224241
@when('the EBU-TT-1 document is converted to EBU-TT-Live')
225242
def when_ebutt1_converted_to_ebutt3(test_context, template_file, template_dict):
226243
use_doc_id_as_seq_id = test_context.get('use_doc_id_as_seq_id', False)

testing/bdd/features/ebutt1/ebutt1_conversion.feature

+32
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,35 @@ Feature: Converting EBU-TT Part 1 files
5555
And the EBU-TT-1 document is converted to EBU-TT-Live
5656
Then the EBU-TT-Live document is valid
5757
And the sequenceIdentifier is "TestConverter"
58+
59+
Scenario: Pass conversion check with non-smpte timebase
60+
Given an xml file <xml_file>
61+
When the document contains a "styling" element
62+
And the document contains a "style" element
63+
And the document contains a "layout" element
64+
And the document contains a "region" element
65+
And the document's timeBase is set to <timebase>
66+
And the XML is parsed as a valid EBU-TT-1 document
67+
And the EBU-TT-1 document is converted to EBU-TT-Live
68+
Then the EBU-TT-Live document is valid
69+
70+
Examples:
71+
| timebase |
72+
| media |
73+
| clock |
74+
75+
Scenario: Pass conversion check with smpte timebase
76+
Given an xml file <xml_file>
77+
When the document contains a "styling" element
78+
And the document contains a "style" element
79+
And the document contains a "layout" element
80+
And the document contains a "region" element
81+
And the document's timeBase is set to <timebase>
82+
And the XML is parsed as a valid EBU-TT-1 document
83+
And the EBU-TT-1 converter is set to use a FixedOffsetSMPTEConverter
84+
And the EBU-TT-1 document is converted to EBU-TT-Live
85+
Then the EBU-TT-Live document is valid
86+
87+
Examples:
88+
| timebase |
89+
| smpte |

testing/bdd/templates/ebutt1_template.xml

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
ttp:timeBase="{{timeBase}}"
55
{% if timeBase == 'smpte' %}
66
ttp:frameRate="25"
7+
ttp:frameRateMultiplier="1 1"
78
ttp:dropMode="nonDrop"
89
ttp:markerMode="continuous"
910
{% elif timeBase == 'clock' %}
@@ -55,7 +56,7 @@
5556
<tt:p begin="{% if timeBase == 'smpte' %}00:00:00:12{% else %}500ms{% endif %}" end="{% if timeBase == 'smpte' %}00:00:03:12{% else %}3420ms{% endif %}" xml:id="ID005">
5657
<tt:span>Some example text...</tt:span>
5758
<tt:br/>
58-
<tt:span>And another line</tt:span>
59+
<tt:span {% if timeBase == 'smpte' %} begin="00:00:01:04" end="00:00:03:20" {% endif %}>And another line</tt:span>
5960
</tt:p>
6061
</tt:div>
6162
</tt:body>

testing/bdd/test_ebutt1_parsing.py

-6
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,6 @@ def when_document_body_contains_attribute(template_dict, attribute):
1616
template_dict[attribute] = True
1717

1818

19-
@when('the document\'s timeBase is set to <timebase>')
20-
def when_document_timebase(template_dict, timebase):
21-
# timeBase in ebutt1_template.xml is 'media' by default
22-
template_dict['timeBase'] = timebase
23-
24-
2519
@when('the document contains an ebuttp attribute <attribute>')
2620
def when_document_contains_ebuttp_attribute(template_dict, attribute):
2721
template_dict['ebuttp'] = True

0 commit comments

Comments
 (0)