Mercurial > silorider
annotate tests/conftest.py @ 18:a921cc2306bc
Do our own HTML parsing/stripping of micropost contents.
- This lets us properly handle various forms of linking.
- Add tests for processing posts with links.
- Fix configuration in tests.
- Basic error handling for processing posts.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Sun, 16 Sep 2018 21:16:20 -0700 |
parents | a1b7a459326a |
children | d3c4c5082bbc |
rev | line source |
---|---|
0 | 1 import io |
2 import os | |
3 import os.path | |
4 import re | |
5 import logging | |
6 import tempfile | |
7 import pytest | |
8 import silorider.main | |
9 | |
10 | |
11 # def pytest_collect_file(parent, path): | |
12 # if path.ext == ".html" and path.basename.startswith("feeds"): | |
13 # return FeedFile(path, parent) | |
14 | |
15 | |
16 re_feed_test_sep = re.compile(r'^---$') | |
17 | |
18 | |
19 class FeedFile(pytest.File): | |
20 def collect(self): | |
21 with self.fspath.open() as fp: | |
22 markup = fp.read() | |
23 | |
24 name = self.fspath.basename | |
25 html_markup, yaml_markup = re_feed_test_sep.split(markup, 1) | |
26 yield FeedItem(name, self, html_markup, yaml_markup) | |
27 | |
28 | |
29 class FeedItem(pytest.Item): | |
30 def __init__(self, name, parent, in_spec, out_spec): | |
31 super().__init__(name, parent) | |
32 self.in_spec = in_spec | |
33 self.out_spec = out_spec | |
34 | |
35 def runtest(self): | |
36 pass | |
37 | |
38 | |
39 @pytest.fixture | |
40 def cli(): | |
41 return CliRunner() | |
42 | |
43 | |
44 class CliRunner: | |
45 def __init__(self): | |
46 self._cfgtxt = """ | |
47 [cache] | |
48 uri=memory://for_test | |
49 """ | |
18
a921cc2306bc
Do our own HTML parsing/stripping of micropost contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
50 self._feedcfg = [] |
0 | 51 self._pre_hooks = [] |
52 self._cleanup = [] | |
53 | |
54 def getFeedPath(self, name): | |
55 return os.path.join(os.path.dirname(__file__), | |
56 'feeds', | |
57 '%s.html' % name) | |
58 | |
59 def createTempFeed(self, contents): | |
60 tmpfd, tmpname = tempfile.mkstemp() | |
61 with os.fdopen(tmpfd, 'w', encoding='utf8') as tmpfp: | |
62 tmpfp.write(contents) | |
63 self._cleanup.append(tmpname) | |
64 return tmpname | |
65 | |
66 def setConfig(self, cfgtxt): | |
67 self._cfgtxt = cfgtxt | |
68 return self | |
69 | |
70 def appendConfig(self, cfgtxt): | |
71 self._cfgtxt += cfgtxt | |
72 return self | |
73 | |
18
a921cc2306bc
Do our own HTML parsing/stripping of micropost contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
74 def appendFeedConfig(self, feed_name, feed_url): |
a921cc2306bc
Do our own HTML parsing/stripping of micropost contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
75 self._feedcfg.append((feed_name, feed_url)) |
a921cc2306bc
Do our own HTML parsing/stripping of micropost contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
76 return self |
a921cc2306bc
Do our own HTML parsing/stripping of micropost contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
77 |
a921cc2306bc
Do our own HTML parsing/stripping of micropost contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
78 def setFeedConfig(self, feed_name, feed_url): |
a921cc2306bc
Do our own HTML parsing/stripping of micropost contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
79 self._feedcfg = [] |
a921cc2306bc
Do our own HTML parsing/stripping of micropost contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
80 return self.appendFeedConfig(feed_name, feed_url) |
a921cc2306bc
Do our own HTML parsing/stripping of micropost contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
81 |
0 | 82 def appendSiloConfig(self, silo_name, silo_type, **options): |
83 cfgtxt = '[silo:%s]\n' % silo_name | |
84 cfgtxt += 'type=%s\n' % silo_type | |
85 if options is not None: | |
86 for n, v in options.items(): | |
87 cfgtxt += '%s=%s\n' % (n, v) | |
88 return self.appendConfig(cfgtxt) | |
89 | |
90 def preExecHook(self, hook): | |
91 self._pre_hooks.append(hook) | |
92 | |
93 def run(self, *args): | |
94 pre_args = [] | |
18
a921cc2306bc
Do our own HTML parsing/stripping of micropost contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
95 if self._cfgtxt or self._feedcfg: |
a921cc2306bc
Do our own HTML parsing/stripping of micropost contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
96 cfgtxt = self._cfgtxt |
a921cc2306bc
Do our own HTML parsing/stripping of micropost contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
97 cfgtxt += '\n\n[urls]\n' |
a921cc2306bc
Do our own HTML parsing/stripping of micropost contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
98 for n, u in self._feedcfg: |
a921cc2306bc
Do our own HTML parsing/stripping of micropost contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
99 cfgtxt += '%s=%s\n' % (n, u) |
a921cc2306bc
Do our own HTML parsing/stripping of micropost contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
100 |
0 | 101 tmpfd, tmpcfg = tempfile.mkstemp() |
102 print("Creating temporary configuration file: %s" % tmpcfg) | |
103 with os.fdopen(tmpfd, 'w') as tmpfp: | |
18
a921cc2306bc
Do our own HTML parsing/stripping of micropost contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
104 tmpfp.write(cfgtxt) |
0 | 105 self._cleanup.append(tmpcfg) |
106 pre_args = ['-c', tmpcfg] | |
107 | |
108 captured = io.StringIO() | |
109 handler = logging.StreamHandler(captured) | |
110 handler.setLevel(logging.INFO) | |
111 silorider_logger = logging.getLogger('silorider') | |
112 silorider_logger.addHandler(handler) | |
113 | |
114 main_ctx = None | |
115 main_res = None | |
116 | |
117 def pre_exec_hook(ctx): | |
118 for h in self._pre_hooks: | |
119 h(ctx) | |
120 | |
121 def post_exec_hook(ctx, res): | |
122 nonlocal main_ctx, main_res | |
123 main_ctx = ctx | |
124 main_res = res | |
125 | |
126 silorider.main.pre_exec_hook = pre_exec_hook | |
127 silorider.main.post_exec_hook = post_exec_hook | |
128 | |
129 args = pre_args + list(args) | |
130 print("Running command: %s" % list(args)) | |
131 try: | |
132 silorider.main._unsafe_main(args) | |
133 finally: | |
134 silorider.main.pre_exec_hook = None | |
135 silorider.main.post_exec_hook = None | |
136 | |
137 silorider_logger.removeHandler(handler) | |
138 | |
139 print("Cleaning %d temporary files." % len(self._cleanup)) | |
140 for tmpname in self._cleanup: | |
18
a921cc2306bc
Do our own HTML parsing/stripping of micropost contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
141 try: |
a921cc2306bc
Do our own HTML parsing/stripping of micropost contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
142 os.remove(tmpname) |
a921cc2306bc
Do our own HTML parsing/stripping of micropost contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
143 except FileNotFoundError: |
a921cc2306bc
Do our own HTML parsing/stripping of micropost contents.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
144 pass |
0 | 145 |
146 return main_ctx, main_res | |
147 | |
148 | |
149 @pytest.fixture | |
150 def feedutil(): | |
151 return FeedUtil() | |
152 | |
153 | |
154 class FeedUtil: | |
155 def makeFeed(self, *entries): | |
156 feed = '<html><body>\n' | |
157 for e in entries: | |
158 feed += '<article class="h-entry">\n' | |
159 feed += e | |
160 feed += '</article>\n' | |
161 feed += '</body></html>' | |
162 return feed |