def test_render_base(self): contents = linelist.LineList([ 'line1', 'line2', '#replace foo', '#replace spam', '#replace llist', 'line {{bar}} {{baz}} 4', ], 5) obj = template.Section('range', 'name', set(), contents) kwargs = { 'foo': ['sub line1', 'sub line2'], 'bar': 'baz', 'baz': 'spam', 'spam': 'one line', 'llist': linelist.LineList([ 'l1', 'l2', 'l3', ], 1), } result = obj.render(kwargs) assert list(result.iter_coord()) == [ (5, 'line1'), (6, 'line2'), (None, 'sub line1'), (None, 'sub line2'), (None, 'one line'), (1, 'l1'), (2, 'l2'), (3, 'l3'), (10, 'line baz spam 4'), ]
def test_output_location_switch_stream_name(self): obj = linelist.LineList(['l1', 'l2', 'l3']) obj.extend(['l4', 'l5', 'l6'], location.Coordinate('some.path', 10)) obj.extend(['l7', 'l8', 'l9']) obj.extend(['l10', 'l11', 'l12'], location.Coordinate('my.path', 5)) stream = six.StringIO() stream.name = 'base.path' obj.output(stream) assert stream.getvalue() == ('l1\n' 'l2\n' 'l3\n' '#line 10 "some.path"\n' 'l4\n' 'l5\n' 'l6\n' '#line 9 "base.path"\n' 'l7\n' 'l8\n' 'l9\n' '#line 5 "my.path"\n' 'l10\n' 'l11\n' 'l12\n')
def __init__(self): """ Initialize a ``RenderContext`` instance. """ self.output = linelist.LineList() self.sections = collections.defaultdict(linelist.LineList)
def test_iadd_linelist(self, mocker): mock_extend = mocker.patch.object(linelist.LineList, 'extend') obj1 = linelist.LineList(['l1', 'l2', 'l3'], 1) obj2 = linelist.LineList(['l4', 'l5', 'l6']) result = obj1.__iadd__(obj2) assert result is obj1 assert result._entries == [ (1, 'l1'), (2, 'l2'), (3, 'l3'), (None, 'l4'), (None, 'l5'), (None, 'l6'), ] assert not mock_extend.called
def test_init_nocoord(self): result = linelist.LineList(['l1', 'l2', 'l3']) assert result._entries == [ (None, 'l1'), (None, 'l2'), (None, 'l3'), ]
def test_add_other(self, mocker): mock_extend = mocker.patch.object(linelist.LineList, 'extend') obj = linelist.LineList(['l1', 'l2', 'l3'], 1) result = obj.__add__(other) assert result is NotImplemented assert not mock_extend.called
def test_init_withcoord(self): result = linelist.LineList(['l1', 'l2', 'l3'], 5) assert result._entries == [ (5, 'l1'), (6, 'l2'), (7, 'l3'), ]
def test_output_base(self): obj = linelist.LineList(['l1', 'l2', 'l3', 'l4', 'l5']) stream = six.StringIO() stream.name = 'base.path' obj.output(stream, 'other.path') assert stream.getvalue() == 'l1\nl2\nl3\nl4\nl5\n'
def test_iter_coord(self): obj = linelist.LineList(['l1', 'l2', 'l3'], 1) result = list(obj.iter_coord()) assert result == [ (1, 'l1'), (2, 'l2'), (3, 'l3'), ]
def test_append_coord(self): obj = linelist.LineList(['l1', 'l2', 'l3'], 1) obj.append('l4', 18) assert obj._entries == [ (1, 'l1'), (2, 'l2'), (3, 'l3'), (18, 'l4'), ]
def test_append_base(self): obj = linelist.LineList(['l1', 'l2', 'l3'], 1) obj.append('l4') assert obj._entries == [ (1, 'l1'), (2, 'l2'), (3, 'l3'), (None, 'l4'), ]
def test_iadd_list(self, mocker): mock_extend = mocker.patch.object(linelist.LineList, 'extend') obj1 = linelist.LineList(['l1', 'l2', 'l3'], 1) obj2 = ['l4', 'l5', 'l6'] result = obj1.__iadd__(obj2) assert result is obj1 assert result._entries == [ (1, 'l1'), (2, 'l2'), (3, 'l3'), ] mock_extend.assert_called_once_with(obj2)
def test_extend_coord(self): obj = linelist.LineList(['l1', 'l2', 'l3'], 1) lines = ['l4', 'l5', 'l6'] obj.extend(lines, 18) assert obj._entries == [ (1, 'l1'), (2, 'l2'), (3, 'l3'), (18, 'l4'), (19, 'l5'), (20, 'l6'), ]
def test_extend_base(self): obj = linelist.LineList(['l1', 'l2', 'l3'], 1) lines = ['l4', 'l5', 'l6'] obj.extend(lines) assert obj._entries == [ (1, 'l1'), (2, 'l2'), (3, 'l3'), (None, 'l4'), (None, 'l5'), (None, 'l6'), ]
def render(self, kwargs): """ Render a ``Section`` instance. :param dict kwargs: The arguments to use while rendering the section template. :returns: Either ``None`` or an instance of ``hypocrite.linelist.LineList`` containing the lines to add to the designated section. """ if self.requires - set(kwargs): # Missing variables, don't render it return None result = linelist.LineList() for coord, text in self.contents.iter_coord(): if text.startswith('#replace'): # Look up the variable var = text.split()[1] replacement = kwargs[var] # Ensure it's a list if not isinstance(replacement, (list, linelist.LineList)): replacement = [replacement] # Substitute it result += replacement else: # Make any necessary substitutions line = SUBST_RE.sub(lambda x: kwargs[x.group(1)], text) result.append(line, coord) return result
def test_len(self): obj = linelist.LineList(['l1', 'l2', 'l3']) assert len(obj) == 3
def _parse_line(self, coord, line, values): """ Parse a line. This wraps the ``_parse_directive()`` routine, handling deferred processing. Deferred processing allows directives to include content that spans multiple lines; examples include the ``%preamble`` and ``%test`` directives. :param coord: The coordinates of the line. :type coord: ``hypocrite.location.Coordinate`` :param str line: The line to parse. :param dict values: The directive values being accumulated by the parsing process. :raises Continue: Indicates that further input is required. This typically means the line was empty or that a C-style comment spanning multiple lines was encountered. :raises ParseException: An error occurred while parsing the input file. """ # Keep track of how many lines have been processed self._lines += 1 # If we don't have a pending deferred callable, that means # we're looking for directives... if self._deferred is None: # Parse out a directive dir_coord, tokens = self._parse_directive(coord, line) # Is it a valid directive? if (not tokens or tokens[0].type_ != TOK_WORD or tokens[0].value not in self.DIRECTIVES): raise ParseException( 'Invalid directive at %s' % dir_coord ) # Process the directive self._deferred = self.DIRECTIVES[tokens[0].value]( values, dir_coord, tokens[1:] ) self._buf = linelist.LineList() if self._deferred else None # OK, we're accumulating lines looking for an end directive elif (self._comment_pfx is not None or self._continued is not None or line.lstrip().startswith('%')): # Parse out a directive dir_coord, tokens = self._parse_directive(coord, line) # Is it a close directive? if not tokens or tokens[0] != (TOK_CHAR, '}'): raise ParseException( 'Invalid directive at %s' % dir_coord ) # Run the deferred callable self._deferred = self._deferred(dir_coord, self._buf, tokens[1:]) self._buf = linelist.LineList() if self._deferred else None else: # Just accumulate another line self._buf.append(line[:-1] if line.endswith('\n') else line, coord)
def test_init_base(self): result = linelist.LineList() assert result._entries == []
def test_iter(self): obj = linelist.LineList(['l1', 'l2', 'l3']) result = list(iter(obj)) assert result == ['l1', 'l2', 'l3']
def test_getitem_slice(self): obj = linelist.LineList(['l1', 'l2', 'l3', 'l4']) assert obj[1:-1] == ['l2', 'l3']
def test_getitem_base(self): obj = linelist.LineList(['l1', 'l2', 'l3']) assert obj[1] == 'l2'