Skip to content

Commit 74808d0

Browse files
committed
core: Add ProjectBear
A ProjectBear runs on all files at once, so it has the worst degree of parallelization. It just spawns a single task.
1 parent db8868c commit 74808d0

2 files changed

Lines changed: 159 additions & 0 deletions

File tree

coalib/core/ProjectBear.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
from coalib.core.Bear import Bear
2+
from coalib.settings.FunctionMetadata import FunctionMetadata
3+
4+
5+
class ProjectBear(Bear):
6+
"""
7+
This bear base class does not parallelize tasks at all, it runs on the
8+
whole file base provided.
9+
"""
10+
11+
def __init__(self, section, file_dict):
12+
"""
13+
:param section:
14+
The section object where bear settings are contained. A section
15+
passed here is considered to be immutable.
16+
:param file_dict:
17+
A dictionary containing filenames to process as keys and their
18+
contents (line-split with trailing return characters) as values.
19+
"""
20+
Bear.__init__(self, section, file_dict)
21+
22+
self._kwargs = self.get_metadata().create_params_from_section(section)
23+
24+
def execute_task(self, args, kwargs):
25+
# To optimize performance a bit and memory usage, we use args and
26+
# kwargs from this class instance, instead of passing them via the
27+
# task.
28+
return Bear.execute_task(self, (self.file_dict,), self._kwargs)
29+
30+
@classmethod
31+
def get_metadata(cls):
32+
"""
33+
:return:
34+
Metadata for the ``analyze`` function extracted from its signature.
35+
Excludes parameters ``self`` and ``files``.
36+
"""
37+
return FunctionMetadata.from_function(
38+
cls.analyze,
39+
omit={'self', 'files'})
40+
41+
def generate_tasks(self):
42+
return (tuple(), {}),

tests/core/ProjectBearTest.py

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import unittest
2+
3+
from coalib.core.ProjectBear import ProjectBear
4+
from coalib.core.Core import run
5+
from coalib.settings.Section import Section
6+
7+
8+
class TestProjectBear(ProjectBear):
9+
10+
def analyze(self, files):
11+
yield '\n'.join(filename + ':' + str(files[filename])
12+
for filename in sorted(files))
13+
14+
15+
class TestProjectBearWithParameters(ProjectBear):
16+
17+
def analyze(self, files, prefix: str='---'):
18+
yield '\n'.join(prefix + filename + ':' + str(files[filename])
19+
for filename in sorted(files))
20+
21+
22+
class ProjectBearTest(unittest.TestCase):
23+
24+
def assertResultsEqual(self, bear_type, expected,
25+
section=None, file_dict=None):
26+
"""
27+
Asserts whether the expected results do match the output of the bear.
28+
29+
Asserts for the results out-of-order.
30+
31+
:param bear_type:
32+
The bear class to check.
33+
:param expected:
34+
A sequence of expected results.
35+
:param section:
36+
A section for the bear to use. By default uses a new section with
37+
name ``test-section``.
38+
:param file_dict:
39+
A file-dictionary for the bear to use. By default uses an empty
40+
dictionary.
41+
"""
42+
if section is None:
43+
section = Section('test-section')
44+
if file_dict is None:
45+
file_dict = {}
46+
47+
uut = bear_type(section, file_dict)
48+
49+
results = []
50+
51+
def on_result(result):
52+
results.append(result)
53+
54+
run({uut}, on_result)
55+
56+
self.assertEqual(sorted(expected), sorted(results))
57+
58+
def test_bear_without_parameters(self):
59+
self.assertResultsEqual(
60+
TestProjectBear,
61+
file_dict={},
62+
expected=[''])
63+
self.assertResultsEqual(
64+
TestProjectBear,
65+
file_dict={'fileX': []},
66+
expected=['fileX:[]'])
67+
self.assertResultsEqual(
68+
TestProjectBear,
69+
file_dict={'fileX': [], 'fileY': ['hello']},
70+
expected=["fileX:[]\nfileY:['hello']"],)
71+
self.assertResultsEqual(
72+
TestProjectBear,
73+
file_dict={'fileX': [], 'fileY': ['hello'], 'fileZ': ['x\ny']},
74+
expected=["fileX:[]\nfileY:['hello']\nfileZ:['x\\ny']"])
75+
76+
def test_bear_with_parameters_but_keep_defaults(self):
77+
self.assertResultsEqual(
78+
TestProjectBearWithParameters,
79+
file_dict={},
80+
expected=[''])
81+
self.assertResultsEqual(
82+
TestProjectBearWithParameters,
83+
file_dict={'fileX': []},
84+
expected=['---fileX:[]'])
85+
self.assertResultsEqual(
86+
TestProjectBearWithParameters,
87+
file_dict={'fileX': [], 'fileY': ['hello']},
88+
expected=["---fileX:[]\n---fileY:['hello']"], )
89+
self.assertResultsEqual(
90+
TestProjectBearWithParameters,
91+
file_dict={'fileX': [], 'fileY': ['hello'], 'fileZ': ['x\ny']},
92+
expected=["---fileX:[]\n---fileY:['hello']\n---fileZ:['x\\ny']"])
93+
94+
def test_bear_with_parameters(self):
95+
section = Section('test-section')
96+
section['prefix'] = '___'
97+
98+
self.assertResultsEqual(
99+
TestProjectBearWithParameters,
100+
section=section,
101+
file_dict={},
102+
expected=[''])
103+
self.assertResultsEqual(
104+
TestProjectBearWithParameters,
105+
section=section,
106+
file_dict={'fileX': []},
107+
expected=['___fileX:[]'])
108+
self.assertResultsEqual(
109+
TestProjectBearWithParameters,
110+
section=section,
111+
file_dict={'fileX': [], 'fileY': ['hello']},
112+
expected=["___fileX:[]\n___fileY:['hello']"], )
113+
self.assertResultsEqual(
114+
TestProjectBearWithParameters,
115+
section=section,
116+
file_dict={'fileX': [], 'fileY': ['hello'], 'fileZ': ['x\ny']},
117+
expected=["___fileX:[]\n___fileY:['hello']\n___fileZ:['x\\ny']"])

0 commit comments

Comments
 (0)