]>
Commit | Line | Data |
---|---|---|
e6adf6ce SW |
1 | # paperdoorknob: Print glowfic |
2 | # | |
3 | # This program is free software: you can redistribute it and/or modify it | |
4 | # under the terms of the GNU General Public License as published by the | |
5 | # Free Software Foundation, version 3. | |
6 | ||
d6e27f4b | 7 | from io import BytesIO |
19ed28f3 | 8 | from sys import stderr |
e6adf6ce SW |
9 | import unittest |
10 | ||
d6e27f4b SW |
11 | from typing import Optional |
12 | ||
19ed28f3 | 13 | from fetch import FakeFetcher |
aa060d9b | 14 | from images import FakeImageStore |
94027099 | 15 | from glowfic import makeChunk, Thread |
19ed28f3 | 16 | from spec import Spec |
62043b2b | 17 | from texify import PandocTexifier |
e6adf6ce SW |
18 | |
19 | ||
d6e27f4b | 20 | def spec_for_testing(html: bytes, outbuf: Optional[BytesIO] = None) -> Spec: |
075f2f08 SW |
21 | return Spec('https://fake/test', |
22 | FakeFetcher({'https://fake/test': html, | |
23 | 'https://fake/test?view=flat': html}), | |
19ed28f3 SW |
24 | FakeImageStore(), |
25 | lambda x: x, | |
26 | lambda x: None, | |
27 | PandocTexifier('pandoc'), | |
28 | lambda x: x, | |
29 | 20, | |
30 | b'', | |
31 | None, | |
d6e27f4b | 32 | stderr.buffer if outbuf is None else outbuf, |
19ed28f3 SW |
33 | lambda x: None) |
34 | ||
35 | ||
e6adf6ce SW |
36 | class TestSplit(unittest.TestCase): |
37 | ||
38 | def testSplit1(self) -> None: | |
19ed28f3 | 39 | t = Thread(spec_for_testing(b''' |
e6adf6ce SW |
40 | <html><body><div class="post-container post-post"> |
41 | The "post" | |
19ed28f3 | 42 | </div></body></html>''')) |
94027099 | 43 | self.assertEqual([list(t.stripped_strings) for t in t.chunkDOMs()], |
e6adf6ce SW |
44 | [['The "post"']]) |
45 | ||
46 | def testSplit2(self) -> None: | |
19ed28f3 | 47 | t = Thread(spec_for_testing(b''' |
e6adf6ce SW |
48 | <html><body> |
49 | <div class="post-container post-post">The "post"</div> | |
50 | <div class="flat-post-replies"> | |
51 | <div class="post-container post-reply">The "reply"</div> | |
52 | </div> | |
19ed28f3 | 53 | </body></html>''')) |
94027099 | 54 | self.assertEqual([list(t.stripped_strings) for t in t.chunkDOMs()], |
e6adf6ce SW |
55 | [['The "post"'], ['The "reply"']]) |
56 | ||
57 | def testSplit3(self) -> None: | |
19ed28f3 | 58 | t = Thread(spec_for_testing(b''' |
e6adf6ce SW |
59 | <html><body> |
60 | <div class="post-container post-post">The "post"</div> | |
61 | <div class="flat-post-replies"> | |
62 | <div class="post-container post-reply">1st reply</div> | |
63 | <div class="post-container post-reply">2nd reply</div> | |
64 | </div> | |
19ed28f3 | 65 | </body></html>''')) |
94027099 | 66 | self.assertEqual([list(t.stripped_strings) for t in t.chunkDOMs()], |
e6adf6ce SW |
67 | [['The "post"'], ['1st reply'], ['2nd reply']]) |
68 | ||
69 | ||
aa060d9b SW |
70 | class TestMakeChunk(unittest.TestCase): |
71 | ||
72 | def testEmptyContent(self) -> None: | |
73 | with open('testdata/empty-content.html', 'rb') as f: | |
19ed28f3 | 74 | t = Thread(spec_for_testing(f.read((9999)))) |
94027099 | 75 | c = makeChunk(next(iter(t.chunkDOMs())), FakeImageStore()) |
aa060d9b SW |
76 | self.assertEqual( |
77 | c.icon, | |
78 | 'stored:https://d1anwqy6ci9o1i.cloudfront.net/' + | |
79 | 'users%2F366%2Ficons%2Fxqmypqvflgdy28aorw9ml_shock.png') | |
37c47bc2 SW |
80 | assert c.character |
81 | assert c.screen_name | |
82 | assert c.author | |
83 | self.assertEqual(list(c.character.stripped_strings), ['Keltham']) | |
84 | self.assertEqual( | |
85 | list(c.screen_name.stripped_strings), ['lawful chaotic']) | |
86 | self.assertEqual(list(c.author.stripped_strings), ['Iarwain']) | |
aa060d9b SW |
87 | self.assertEqual(str(c.content), |
88 | '<div class="post-content"><p></p></div>') | |
89 | ||
62043b2b SW |
90 | self.assertEqual( |
91 | PandocTexifier("pandoc").texify(c.character), b'{Keltham}\n') | |
92 | ||
0668adb7 SW |
93 | def testMinimal(self) -> None: |
94 | t = Thread(spec_for_testing(b''' | |
95 | <html><body> | |
96 | <div class="post-container post-post"> | |
97 | <div class="post-content">Just content</div> | |
98 | </div> | |
99 | </body></html>''')) | |
100 | c = makeChunk(next(iter(t.chunkDOMs())), FakeImageStore()) | |
101 | self.assertIsNone(c.icon) | |
102 | self.assertIsNone(c.character) | |
103 | self.assertIsNone(c.screen_name) | |
104 | self.assertIsNone(c.author) | |
105 | self.assertEqual(str(c.content), | |
106 | '<div class="post-content">Just content</div>') | |
107 | ||
aa060d9b | 108 | |
21e82200 SW |
109 | class TestThread(unittest.TestCase): |
110 | ||
111 | def testTitle(self) -> None: | |
19ed28f3 | 112 | t = Thread(spec_for_testing(b''' |
21e82200 SW |
113 | <html><body> |
114 | <div class="content-header"> | |
115 | <span id="post-title"> | |
116 | <a href="/posts/1234">Teh Story!</a> | |
117 | </span> | |
118 | </div> | |
119 | <div class="post-container post-post">The "post"</div> | |
19ed28f3 | 120 | </body></html>''')) |
21e82200 SW |
121 | self.assertEqual(t.title(), 'Teh Story!') |
122 | ||
fc2aaa75 | 123 | def testNextThreadRelative(self) -> None: |
53f396b4 SW |
124 | t = Thread(spec_for_testing(b''' |
125 | <html><body> | |
126 | <div class="post-navheader"> | |
127 | <a class="view-button-link" href="/posts/4567"><div class="view-button">Next Post »</div> | |
128 | </a><a class="view-button-link" href="/posts/4321"><div class="view-button float-none">« Previous Post</div> | |
129 | </a> | |
130 | </div> | |
131 | <div class="post-container post-post">The "post"</div> | |
132 | </body></html>''')) | |
fc2aaa75 SW |
133 | self.assertEqual(t.next_thread(), 'https://fake/posts/4567') |
134 | ||
135 | def testNextThreadAbsolute(self) -> None: | |
136 | t = Thread(spec_for_testing(b''' | |
137 | <html><body> | |
138 | <div class="post-navheader"> | |
139 | <a class="view-button-link" href="https://elsewhere/posts/4567"><div class="view-button">Next Post »</div> | |
140 | </a><a class="view-button-link" href="https://elsewhere/posts/4321"><div class="view-button float-none">« Previous Post</div> | |
141 | </a> | |
142 | </div> | |
143 | <div class="post-container post-post">The "post"</div> | |
144 | </body></html>''')) | |
145 | self.assertEqual(t.next_thread(), 'https://elsewhere/posts/4567') | |
53f396b4 | 146 | |
21e82200 | 147 | |
d6e27f4b SW |
148 | class TestEmit(unittest.TestCase): |
149 | ||
150 | def testEmit(self) -> None: | |
151 | buf = BytesIO() | |
152 | Thread(spec_for_testing(b''' | |
153 | <html><body> | |
154 | <div class="post-container post-post"> | |
155 | <div class="post-content">A</div> | |
156 | </div> | |
157 | <div class="flat-post-replies"> | |
158 | <div class="post-container post-reply"> | |
159 | <div class="post-content">B</div> | |
160 | </div> | |
161 | </div> | |
162 | </body></html>''', buf)).emit() | |
163 | self.assertEqual(buf.getvalue(), rb'''\glowhead{}{}{}{}A | |
164 | \glowhead{}{}{}{}B | |
165 | ''') | |
166 | ||
167 | ||
e6adf6ce SW |
168 | if __name__ == '__main__': |
169 | unittest.main() |