6 class T(unittest
.TestCase
):
9 'trivial.xml': '''<?xml version="1.0" encoding="ISO-8859-1"?>
10 <!DOCTYPE tv SYSTEM "http://iceguide.icetv.com.au/iceguide/iceguide.dtd">
13 <display-name>TwentyThree</display-name>
14 <region-name>Melbourne</region-name>
17 <programme start="20091030110000 +0000" stop="20091030113000 +0000" channel="2300">
18 <title lang="en">Spiderman</title>
19 <sub-title lang="en">The One Where Spiderman Eats Salad</sub-title>
20 <desc lang="en">Action is his reward.</desc>
21 <category lang="en">News</category>
22 <category lang="en">Sport</category>
23 <episode-num system="icetv">169-0</episode-num>
25 <programme start="20091104093500 +0000" stop="20091104110500 +0000" channel="32">
26 <title lang="en">Soccer: UEFA Champions League</title>
27 <sub-title lang="en">TBA</sub-title>
28 <category lang="en">Football</category>
29 <category lang="en">Soccer</category>
30 <category lang="en">Sport</category>
31 <episode-num system="icetv">14328-72386</episode-num>
32 <previously-shown start="20090917"/>
34 <programme start="20091105093500 +0000" stop="20091105110500 +0000" channel="32">
35 <title lang="en">Suburb of the Moths</title>
36 <desc lang="en">A suburb is terrorised by shrimp moths from hell.</desc>
38 <director>Dave Keenan</director>
39 <actor>Marvin O'Gravel Balloon-Face</actor>
40 <actor>Oliver Boliver Butt</actor>
41 <actor>Zanzibar Buck-Buck McFate</actor>
44 <category lang="en">Movie</category>
45 <subtitles type="teletext"/>
51 <programme start="20091030110000 +0000" stop="20091030113000 +0000" channel="2300">
52 <category lang="en"></category>
59 {'title': 'Spiderman',
60 'sub-title': 'The One Where Spiderman Eats Salad',
61 'desc': 'Action is his reward.',
62 'categories': ['News', 'Sport'],
64 'start': datetime
.datetime(2009, 10, 30, 11, 0),
65 'stop': datetime
.datetime(2009, 10, 30, 11, 30)}
67 def open_fake(self
, filename
):
68 from StringIO
import StringIO
69 return StringIO(self
.fake_files
[filename
])
72 self
.parser
= icetotgd
.IceToTgd()
73 self
.parser
.use_xml_file(self
.open_fake('trivial.xml'))
75 def test_can_load_channels(self
):
76 self
.assertEqual(self
.parser
.channels
,
77 {'2300': {'lcn': '23',
78 'display-name': 'TwentyThree'}})
80 def test_can_load_one_programme(self
):
81 p
= self
.parser
.programmes
[0]
82 self
.assertEqual(p
['title'], 'Spiderman')
83 self
.assertEqual(p
['sub-title'], 'The One Where Spiderman Eats Salad')
84 self
.assertEqual(p
['desc'], 'Action is his reward.')
85 self
.assertEqual(p
['categories'], ['News', 'Sport'])
86 self
.assertEqual(p
['channel'], '2300')
87 self
.assertTrue('rating' not in p
)
88 self
.assertEqual(p
['start'], datetime
.datetime(2009, 10, 30, 11, 0))
89 self
.assertEqual(p
['stop'], datetime
.datetime(2009, 10, 30, 11, 30))
91 def test_time_to_tgd(self
):
92 start
= datetime
.datetime(2009, 10, 30, 11, 30)
93 tgd_start
= icetotgd
.tgd_time_from_timestamp(start
)
94 self
.assertEqual(tgd_start
, '2009/10/30 22:30')
96 def test_duration_to_tgd(self
):
97 start
= datetime
.datetime(2009, 10, 30, 11, 00)
98 stop
= datetime
.datetime(2009, 10, 30, 11, 30)
99 duration
= stop
- start
100 tgd_duration
= icetotgd
.tgd_duration_from_timedelta(duration
)
101 self
.assertEqual(tgd_duration
, '30')
103 def test_programme_to_tgd(self
):
104 tgd_line
= self
.parser
.programme_to_tgd(self
.programme
)
105 self
.assertEqual(tgd_line
,
106 '23\t2009/10/30 22:00\t30\tSpiderman\tThe One Where Spiderman Eats Salad [News/Sport]\tAction is his reward.\tX\tN')
108 def test_can_parse_programme_xml_without_desc(self
):
109 p
= self
.parser
.programmes
[1]
110 self
.assertTrue('desc' not in p
)
112 def test_programme_xml_with_year(self
):
113 p
= self
.parser
.programmes
[2]
114 self
.assertEqual(p
['date'], '1996')
116 def test_tgd_title_includes_year(self
):
117 p
= self
.parser
.programmes
[2]
118 title
= self
.parser
.tgd_title(p
)
119 self
.assertEqual(title
, 'Suburb of the Moths (1996)')
121 def test_unrated_programmes_are_rated_x(self
):
122 p
= self
.parser
.programmes
[0]
123 rating
= self
.parser
.tgd_rating(p
)
124 self
.assertEqual(rating
, 'X')
126 def test_can_get_programme_rating(self
):
127 p
= self
.parser
.programmes
[2]
128 rating
= self
.parser
.tgd_rating(p
)
129 self
.assertEqual(rating
, 'M')
131 def test_description_says_subtitles_if_they_exist(self
):
132 p
= self
.parser
.programmes
[2]
133 description
= self
.parser
.tgd_description(p
)
134 self
.assertTrue(description
.index('[Subtitles]'))
136 def test_description_doesnt_say_repeat_if_its_not_a_repeat(self
):
137 p
= self
.parser
.programmes
[0]
138 description
= self
.parser
.tgd_description(p
)
139 self
.assertTrue(description
.find('[Repeat]') == -1)
141 def test_description_says_repeat_if_its_a_repeat(self
):
142 p
= self
.parser
.programmes
[2]
143 description
= self
.parser
.tgd_description(p
)
144 self
.assertTrue(description
.find('[Repeat]') != -1)
146 def test_description_says_repeat_with_date_if_its_a_repeat_with_a_known_date(self
):
147 p
= self
.parser
.programmes
[1]
148 description
= self
.parser
.tgd_description(p
)
149 date
= datetime
.date(2009, 9, 17).strftime('%x')
150 self
.assertTrue(description
.find('[Repeat, last shown ' + date
+ ']') != -1)
152 def test_tgd_short_description_includes_category(self
):
153 p
= self
.parser
.programmes
[0]
154 short_desc
= self
.parser
.tgd_short_description(p
)
155 self
.assertEqual(short_desc
, 'The One Where Spiderman Eats Salad [News/Sport]')
157 def test_blank_categories_arent_retained(self
):
158 p
= self
.parser
.programmes
[3]
159 self
.assertTrue('categories' not in p
)
161 def test_can_convert_programme_xml_without_desc(self
):
162 p
= self
.programme
.copy()
164 tgd_line
= self
.parser
.programme_to_tgd(p
)
165 self
.assertEqual(tgd_line
,
166 '23\t2009/10/30 22:00\t30\tSpiderman\tThe One Where Spiderman Eats Salad [News/Sport]\t\tX\tN')
168 def test_str_or_empty(self
):
169 from icetotgd
import str_or_empty
170 self
.assertEqual('', str_or_empty(None))
171 self
.assertEqual('', str_or_empty(''))
172 self
.assertEqual('foo', str_or_empty('foo'))
174 def test_filter_None_from_dict(self
):
175 d
= {'a': 3, 'b': [6, 16], 'c': None, 'd': 9}
176 d2
= icetotgd
.filter_dict(d
, lambda k
,v
: v
is not None)
177 self
.assertEqual(d2
, {'a': 3, 'b': [6, 16], 'd': 9})
179 def test_filter_None_and_empty_list_from_dict(self
):
181 return type(x
) is type([])
182 d
= {'a': 3, 'b': [6, 16], 'c': None, 'd': []}
183 d2
= icetotgd
.filter_dict(
185 lambda k
,v
: (v
is not None) and (not listp(v
) or v
))
186 self
.assertEqual(d2
, {'a': 3, 'b': [6, 16]})
188 def test_filename_from_programme(self
):
189 filename
= icetotgd
.tgd_filename_from_programme(self
.programme
)
190 self
.assertEqual(filename
, '20091030.tgd')
192 def test_programme_xml_with_director(self
):
193 p
= self
.parser
.programmes
[2]
194 self
.assertEqual(p
['directors'], ['Dave Keenan'])
196 def test_programme_xml_with_actors(self
):
197 p
= self
.parser
.programmes
[2]
198 self
.assertEqual(p
['actors'],
199 ["Marvin O'Gravel Balloon-Face",
200 'Oliver Boliver Butt',
201 'Zanzibar Buck-Buck McFate'])
203 def test_no_director_means_no_text_for_description(self
):
204 p
= self
.parser
.programmes
[0]
205 text
= self
.parser
.tgd_director_text(p
)
206 self
.assertEqual(text
, None)
208 def test_single_director_text_for_description(self
):
209 p
= self
.parser
.programmes
[2]
210 text
= self
.parser
.tgd_director_text(p
)
211 self
.assertEqual(text
, 'Dave Keenan')
213 def test_no_actors_means_no_text_for_description(self
):
214 p
= self
.parser
.programmes
[0]
215 text
= self
.parser
.tgd_cast_text(p
)
216 self
.assertEqual(text
, None)
218 def test_three_actors_means_some_text_for_description(self
):
219 p
= self
.parser
.programmes
[2]
220 text
= self
.parser
.tgd_cast_text(p
)
221 self
.assertEqual(text
, "Marvin O'Gravel Balloon-Face, Oliver Boliver Butt, Zanzibar Buck-Buck McFate")
223 def test_tgd_description_has_cast_and_crew(self
):
224 p
= self
.parser
.programmes
[2]
225 text
= self
.parser
.tgd_description(p
)
226 self
.assertTrue(text
.index("Marvin O'Gravel Balloon-Face"))
227 self
.assertTrue(text
.index("Dave Keenan"))
230 if __name__
=='__main__':