have the app process the rules

Signed-off-by: Doug Hellmann <doug@doughellmann.com>
This commit is contained in:
Doug Hellmann 2017-08-23 14:46:24 -04:00
parent bcc2b80be2
commit e7c0b47795
3 changed files with 118 additions and 5 deletions

View File

@ -15,18 +15,74 @@
# License for the specific language governing permissions and limitations
# under the License.
from __future__ import print_function
import argparse
import io
from whereto import parser
from whereto import rules
def process_tests(ruleset, tests):
"""Run the tests against the ruleset and return the results.
Results are generated as tuples containing the inputs that did not
match the expected value. The first element is the test tuple
(line, input, expected), and the second element is the list of any
rules that did match the input pattern.
:param ruleset: The redirect rules.
:type ruleset: RuleSet
"""
for linenum, input, code, expected in tests:
matches = list(ruleset.match(input))
if len(matches) == 1:
match = matches[0]
if (code, expected) == match[1:]:
continue
yield ((linenum, input, code, expected), matches)
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
arg_parser = argparse.ArgumentParser()
arg_parser.add_argument(
'htaccess_file',
help='file with rewrite rules',
)
parser.add_argument(
arg_parser.add_argument(
'test_file',
help='file with test data',
)
args = parser.parse_args()
print(args)
args = arg_parser.parse_args()
ruleset = rules.RuleSet()
with io.open(args.htaccess_file, 'r', encoding='utf-8') as f:
for linenum, params in parser.parse_rules(f):
ruleset.add(linenum, *params)
with io.open(args.test_file, 'r', encoding='utf-8') as f:
tests = [
(linenum,) + tuple(params)
for linenum, params in parser.parse_rules(f)
]
failures = 0
for test, matches in process_tests(ruleset, tests):
failures += 1
if not matches:
print('No rule matched test on line {}: {}'.format(
test[0], ' '.join(test[1:]))
)
else:
print('Test on line {} did not produce expected result: {}'.format(
test[0], ' '.join(test[1:]))
)
for match in matches:
print(' {}'.format(ruleset[match[0]]))
if failures:
print('\n{} failures'.format(failures))
return 1
return 0

View File

@ -82,11 +82,16 @@ class RuleSet(object):
def __init__(self):
self._rules = []
self._by_num = {}
def add(self, linenum, *params):
rule_type = params[0].lower()
rule = self._factories[rule_type](linenum, *params)
self._rules.append(rule)
self._by_num[linenum] = rule
def __getitem__(self, index):
return self._by_num[index]
def __iter__(self):
return iter(self._rules)

52
whereto/tests/test_app.py Normal file
View File

@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from whereto import app
from whereto import rules
from whereto.tests import base
class TestProcessTests(base.TestCase):
def setUp(self):
super(TestProcessTests, self).setUp()
self.ruleset = rules.RuleSet()
self.ruleset.add(
1,
'redirect', '301', '/path', '/new/path',
)
def test_one_match(self):
actual = list(app.process_tests(
self.ruleset,
[(1, '/path', '301', '/new/path')],
))
expected = []
self.assertEqual(expected, actual)
def test_two_matches(self):
self.ruleset.add(
2,
'redirect', '301', '/path', '/duplicate/redirect',
)
actual = list(app.process_tests(
self.ruleset,
[(1, '/path', '301', '/new/path')],
))
expected = [
((1, '/path', '301', '/new/path'),
[(1, '301', '/new/path'),
(2, '301', '/duplicate/redirect')])
]
self.assertEqual(expected, actual)