1# -*- coding: utf-8 -*-
2"""
3    Tests for pygments.regexopt
4    ~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
6    :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS.
7    :license: BSD, see LICENSE for details.
8"""
9
10import re
11import random
12from itertools import combinations_with_replacement
13
14from pygments.regexopt import regex_opt
15
16ALPHABET = ['a', 'b', 'c', 'd', 'e']
17
18N_TRIES = 15
19
20
21def generate_keywordlist(length):
22    return [''.join(p) for p in
23            combinations_with_replacement(ALPHABET, length)]
24
25
26def test_randomly():
27    # generate a list of all possible keywords of a certain length using
28    # a restricted alphabet, then choose some to match and make sure only
29    # those do
30    for n in range(3, N_TRIES):
31        kwlist = generate_keywordlist(n)
32        to_match = random.sample(kwlist,
33                                 random.randint(1, len(kwlist) - 1))
34        no_match = set(kwlist) - set(to_match)
35        rex = re.compile(regex_opt(to_match))
36        assert rex.groups == 1
37        for w in to_match:
38            assert rex.match(w)
39        for w in no_match:
40            assert not rex.match(w)
41
42
43def test_prefix():
44    opt = regex_opt(('a', 'b'), prefix=r':{1,2}')
45    print(opt)
46    rex = re.compile(opt)
47    assert not rex.match('a')
48    assert rex.match('::a')
49    assert not rex.match(':::')  # fullmatch
50
51
52def test_suffix():
53    opt = regex_opt(('a', 'b'), suffix=r':{1,2}')
54    print(opt)
55    rex = re.compile(opt)
56    assert not rex.match('a')
57    assert rex.match('a::')
58    assert not rex.match(':::')  # fullmatch
59
60
61def test_suffix_opt():
62    # test that detected suffixes remain sorted.
63    opt = regex_opt(('afoo', 'abfoo'))
64    print(opt)
65    rex = re.compile(opt)
66    m = rex.match('abfoo')
67    assert m.end() == 5
68
69
70def test_different_length_grouping():
71    opt = regex_opt(('a', 'xyz'))
72    print(opt)
73    rex = re.compile(opt)
74    assert rex.match('a')
75    assert rex.match('xyz')
76    assert not rex.match('b')
77    assert rex.groups == 1
78
79
80def test_same_length_grouping():
81    opt = regex_opt(('a', 'b'))
82    print(opt)
83    rex = re.compile(opt)
84    assert rex.match('a')
85    assert rex.match('b')
86    assert not rex.match('x')
87
88    assert rex.groups == 1
89    groups = rex.match('a').groups()
90    assert groups == ('a',)
91
92
93def test_same_length_suffix_grouping():
94    opt = regex_opt(('a', 'b'), suffix='(m)')
95    print(opt)
96    rex = re.compile(opt)
97    assert rex.match('am')
98    assert rex.match('bm')
99    assert not rex.match('xm')
100    assert not rex.match('ax')
101    assert rex.groups == 2
102    groups = rex.match('am').groups()
103    assert groups == ('a', 'm')
104