1# Copyright (C) 2020 Red Hat Inc.
2#
3# Authors:
4#  Eduardo Habkost <ehabkost@redhat.com>
5#
6# This work is licensed under the terms of the GNU GPL, version 2.  See
7# the COPYING file in the top-level directory.
8from tempfile import NamedTemporaryFile
9from .patching import FileInfo, FileMatch, Patch, FileList
10from .regexps import *
11
12class BasicPattern(FileMatch):
13    regexp = '[abc]{3}'
14
15    @property
16    def name(self):
17        return self.group(0)
18
19    def replacement(self) -> str:
20        # replace match with the middle character repeated 5 times
21        return self.group(0)[1].upper()*5
22
23def test_pattern_patching():
24    of = NamedTemporaryFile('wt')
25    of.writelines(['one line\n',
26                  'this pattern will be patched: defbbahij\n',
27                  'third line\n',
28                  'another pattern: jihaabfed'])
29    of.flush()
30
31    files = FileList()
32    f = FileInfo(files, of.name)
33    f.load()
34    matches = f.matches_of_type(BasicPattern)
35    assert len(matches) == 2
36    p2 = matches[1]
37
38    # manually add patch, to see if .append() works:
39    f.patches.append(p2.append('XXX'))
40
41    # apply all patches:
42    f.gen_patches(matches)
43    patched = f.get_patched_content()
44    assert patched == ('one line\n'+
45                       'this pattern will be patched: defBBBBBhij\n'+
46                       'third line\n'+
47                       'another pattern: jihAAAAAXXXfed')
48
49class Function(FileMatch):
50    regexp = S(r'BEGIN\s+', NAMED('name', RE_IDENTIFIER), r'\n',
51               r'(.*\n)*?END\n')
52
53class Statement(FileMatch):
54    regexp = S(r'^\s*', NAMED('name', RE_IDENTIFIER), r'\(\)\n')
55
56def test_container_match():
57    of = NamedTemporaryFile('wt')
58    of.writelines(['statement1()\n',
59                   'statement2()\n',
60                   'BEGIN function1\n',
61                   '  statement3()\n',
62                   '  statement4()\n',
63                   'END\n',
64                   'BEGIN function2\n',
65                   '  statement5()\n',
66                   '  statement6()\n',
67                   'END\n',
68                   'statement7()\n'])
69    of.flush()
70
71    files = FileList()
72    f = FileInfo(files, of.name)
73    f.load()
74    assert len(f.matches_of_type(Function)) == 2
75    print(' '.join(m.name for m in f.matches_of_type(Statement)))
76    assert len(f.matches_of_type(Statement)) == 7
77
78    f1 = f.find_match(Function, 'function1')
79    f2 = f.find_match(Function, 'function2')
80    st1 = f.find_match(Statement, 'statement1')
81    st2 = f.find_match(Statement, 'statement2')
82    st3 = f.find_match(Statement, 'statement3')
83    st4 = f.find_match(Statement, 'statement4')
84    st5 = f.find_match(Statement, 'statement5')
85    st6 = f.find_match(Statement, 'statement6')
86    st7 = f.find_match(Statement, 'statement7')
87
88    assert not f1.contains(st1)
89    assert not f1.contains(st2)
90    assert not f1.contains(st2)
91    assert f1.contains(st3)
92    assert f1.contains(st4)
93    assert not f1.contains(st5)
94    assert not f1.contains(st6)
95    assert not f1.contains(st7)
96
97    assert not f2.contains(st1)
98    assert not f2.contains(st2)
99    assert not f2.contains(st2)
100    assert not f2.contains(st3)
101    assert not f2.contains(st4)
102    assert f2.contains(st5)
103    assert f2.contains(st6)
104    assert not f2.contains(st7)
105