1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
|
# type: ignore
# As done in parser_obj.py, this module is not used for now, so we just skip
# type checking for the sake of simplicity.
""" Tests for functions and classes in parser_obj.py """
import sys
import unittest
from unittest import mock
import pytest
from certbot_nginx._internal.parser_obj import COMMENT_BLOCK
from certbot_nginx._internal.parser_obj import parse_raw
class CommentHelpersTest(unittest.TestCase):
def test_is_comment(self):
from certbot_nginx._internal.parser_obj import _is_comment
assert _is_comment(parse_raw(['#']))
assert _is_comment(parse_raw(['#', ' literally anything else']))
assert not _is_comment(parse_raw(['not', 'even', 'a', 'comment']))
def test_is_certbot_comment(self):
from certbot_nginx._internal.parser_obj import _is_certbot_comment
assert _is_certbot_comment(
parse_raw(COMMENT_BLOCK))
assert not _is_certbot_comment(
parse_raw(['#', ' not a certbot comment']))
assert not _is_certbot_comment(
parse_raw(['#', ' managed by Certbot', ' also not a certbot comment']))
assert not _is_certbot_comment(
parse_raw(['not', 'even', 'a', 'comment']))
def test_certbot_comment(self):
from certbot_nginx._internal.parser_obj import _certbot_comment
from certbot_nginx._internal.parser_obj import _is_certbot_comment
comment = _certbot_comment(None)
assert _is_certbot_comment(comment)
assert comment.dump() == COMMENT_BLOCK
assert comment.dump(True) == [' '] + COMMENT_BLOCK
assert _certbot_comment(None, 2).dump(True) == [' '] + COMMENT_BLOCK
class ParsingHooksTest(unittest.TestCase):
def test_is_sentence(self):
from certbot_nginx._internal.parser_obj import Sentence
assert not Sentence.should_parse([])
assert Sentence.should_parse([''])
assert Sentence.should_parse(['word'])
assert Sentence.should_parse(['two', 'words'])
assert not Sentence.should_parse([[]])
assert not Sentence.should_parse(['word', []])
def test_is_block(self):
from certbot_nginx._internal.parser_obj import Block
assert not Block.should_parse([])
assert not Block.should_parse([''])
assert not Block.should_parse(['two', 'words'])
assert not Block.should_parse([[[]], []])
assert not Block.should_parse([['block_name'], ['hi', []], []])
assert not Block.should_parse([['block_name'], 'lol'])
assert Block.should_parse([['block_name'], ['hi', []]])
assert Block.should_parse([['hello'], []])
assert Block.should_parse([['block_name'], [['many'], ['statements'], 'here']])
assert Block.should_parse([['if', ' ', '(whatever)'], ['hi']])
@mock.patch("certbot_nginx._internal.parser_obj.Parsable.parsing_hooks")
def test_parse_raw(self, parsing_hooks):
fake_parser1 = mock.Mock()
fake_parser1.should_parse = lambda x: True
fake_parser2 = mock.Mock()
fake_parser2.should_parse = lambda x: True
parsing_hooks.return_value = (fake_parser1, fake_parser2,)
# First encountered "match" should parse.
parse_raw([])
fake_parser1().parse.assert_called_once()
fake_parser2().parse.assert_not_called()
fake_parser1.reset_mock()
# "match" that returns False shouldn't parse.
fake_parser1.should_parse = lambda x: False
parse_raw([])
fake_parser1().parse.assert_not_called()
fake_parser2().parse.assert_called_once()
@mock.patch("certbot_nginx._internal.parser_obj.Parsable.parsing_hooks")
def test_parse_raw_no_match(self, parsing_hooks):
from certbot import errors
fake_parser1 = mock.Mock()
fake_parser1.should_parse = lambda x: False
parsing_hooks.return_value = (fake_parser1,)
with pytest.raises(errors.MisconfigurationError):
parse_raw([])
parsing_hooks.return_value = ()
with pytest.raises(errors.MisconfigurationError):
parse_raw([])
@mock.patch("certbot_nginx._internal.parser_obj.Parsable.parsing_hooks")
def test_parse_raw_passes_add_spaces(self, parsing_hooks):
fake_parser1 = mock.Mock()
fake_parser1.should_parse = lambda x: True
parsing_hooks.return_value = (fake_parser1,)
parse_raw([])
fake_parser1().parse.assert_called_with([], False)
parse_raw([], add_spaces=True)
fake_parser1().parse.assert_called_with([], True)
class SentenceTest(unittest.TestCase):
def setUp(self):
from certbot_nginx._internal.parser_obj import Sentence
self.sentence = Sentence(None)
def test_parse_bad_sentence_raises_error(self):
from certbot import errors
with pytest.raises(errors.MisconfigurationError):
self.sentence.parse('lol')
with pytest.raises(errors.MisconfigurationError):
self.sentence.parse([[]])
with pytest.raises(errors.MisconfigurationError):
self.sentence.parse([5])
def test_parse_sentence_words_hides_spaces(self):
og_sentence = ['\r\n', 'hello', ' ', ' ', '\t\n ', 'lol', ' ', 'spaces']
self.sentence.parse(og_sentence)
assert self.sentence.words == ['hello', 'lol', 'spaces']
assert self.sentence.dump() == ['hello', 'lol', 'spaces']
assert self.sentence.dump(True) == og_sentence
def test_parse_sentence_with_add_spaces(self):
self.sentence.parse(['hi', 'there'], add_spaces=True)
assert self.sentence.dump(True) == ['hi', ' ', 'there']
self.sentence.parse(['one', ' ', 'space', 'none'], add_spaces=True)
assert self.sentence.dump(True) == ['one', ' ', 'space', ' ', 'none']
def test_iterate(self):
expected = [['1', '2', '3']]
self.sentence.parse(['1', ' ', '2', ' ', '3'])
for i, sentence in enumerate(self.sentence.iterate()):
assert sentence.dump() == expected[i]
def test_set_tabs(self):
self.sentence.parse(['tabs', 'pls'], add_spaces=True)
self.sentence.set_tabs()
assert self.sentence.dump(True)[0] == '\n '
self.sentence.parse(['tabs', 'pls'], add_spaces=True)
def test_get_tabs(self):
self.sentence.parse(['no', 'tabs'])
assert self.sentence.get_tabs() == ''
self.sentence.parse(['\n \n ', 'tabs'])
assert self.sentence.get_tabs() == ' '
self.sentence.parse(['\n\t ', 'tabs'])
assert self.sentence.get_tabs() == '\t '
self.sentence.parse(['\n\t \n', 'tabs'])
assert self.sentence.get_tabs() == ''
class BlockTest(unittest.TestCase):
def setUp(self):
from certbot_nginx._internal.parser_obj import Block
self.bloc = Block(None)
self.name = ['server', 'name']
self.contents = [['thing', '1'], ['thing', '2'], ['another', 'one']]
self.bloc.parse([self.name, self.contents])
def test_iterate(self):
# Iterates itself normally
assert self.bloc == next(self.bloc.iterate())
# Iterates contents while expanded
expected = [self.bloc.dump()] + self.contents
for i, elem in enumerate(self.bloc.iterate(expanded=True)):
assert expected[i] == elem.dump()
def test_iterate_match(self):
# can match on contents while expanded
from certbot_nginx._internal.parser_obj import Block
from certbot_nginx._internal.parser_obj import Sentence
expected = [['thing', '1'], ['thing', '2']]
for i, elem in enumerate(self.bloc.iterate(expanded=True,
match=lambda x: isinstance(x, Sentence) and 'thing' in x.words)):
assert expected[i] == elem.dump()
# can match on self
assert self.bloc == next(self.bloc.iterate(
expanded=True,
match=lambda x: isinstance(x, Block) and 'server' in x.names))
def test_parse_with_added_spaces(self):
import copy
self.bloc.parse([copy.copy(self.name), self.contents], add_spaces=True)
assert self.bloc.dump() == [self.name, self.contents]
assert self.bloc.dump(True) == [
['server', ' ', 'name', ' '],
[['thing', ' ', '1'],
['thing', ' ', '2'],
['another', ' ', 'one']]]
def test_bad_parse_raises_error(self):
from certbot import errors
with pytest.raises(errors.MisconfigurationError):
self.bloc.parse([[[]], [[]]])
with pytest.raises(errors.MisconfigurationError):
self.bloc.parse(['lol'])
with pytest.raises(errors.MisconfigurationError):
self.bloc.parse(['fake', 'news'])
def test_set_tabs(self):
self.bloc.set_tabs()
assert self.bloc.names.dump(True)[0] == '\n '
for elem in self.bloc.contents.dump(True)[:-1]:
assert elem[0] == '\n '
assert self.bloc.contents.dump(True)[-1][0] == '\n'
def test_get_tabs(self):
self.bloc.parse([[' \n \t', 'lol'], []])
assert self.bloc.get_tabs() == ' \t'
class StatementsTest(unittest.TestCase):
def setUp(self):
from certbot_nginx._internal.parser_obj import Statements
self.statements = Statements(None)
self.raw = [
['sentence', 'one'],
['sentence', 'two'],
['and', 'another']
]
self.raw_spaced = [
['\n ', 'sentence', ' ', 'one'],
['\n ', 'sentence', ' ', 'two'],
['\n ', 'and', ' ', 'another'],
'\n\n'
]
def test_set_tabs(self):
self.statements.parse(self.raw)
self.statements.set_tabs()
for statement in self.statements.iterate():
assert statement.dump(True)[0] == '\n '
def test_set_tabs_with_parent(self):
# Trailing whitespace should inherit from parent tabbing.
self.statements.parse(self.raw)
self.statements.parent = mock.Mock()
self.statements.parent.get_tabs.return_value = '\t\t'
self.statements.set_tabs()
for statement in self.statements.iterate():
assert statement.dump(True)[0] == '\n '
assert self.statements.dump(True)[-1] == '\n\t\t'
def test_get_tabs(self):
self.raw[0].insert(0, '\n \n \t')
self.statements.parse(self.raw)
assert self.statements.get_tabs() == ' \t'
self.statements.parse([])
assert self.statements.get_tabs() == ''
def test_parse_with_added_spaces(self):
self.statements.parse(self.raw, add_spaces=True)
assert self.statements.dump(True)[0] == ['sentence', ' ', 'one']
def test_parse_bad_list_raises_error(self):
from certbot import errors
with pytest.raises(errors.MisconfigurationError):
self.statements.parse('lol not a list')
def test_parse_hides_trailing_whitespace(self):
self.statements.parse(self.raw + ['\n\n '])
assert isinstance(self.statements.dump()[-1], list)
assert self.statements.dump(True)[-1].isspace() is True
assert self.statements.dump(True)[-1] == '\n\n '
def test_iterate(self):
self.statements.parse(self.raw)
expected = [['sentence', 'one'], ['sentence', 'two']]
for i, elem in enumerate(self.statements.iterate(match=lambda x: 'sentence' in x)):
assert expected[i] == elem.dump()
if __name__ == "__main__":
sys.exit(pytest.main(sys.argv[1:] + [__file__])) # pragma: no cover
|