Skip to content

Commit bb97efa

Browse files
committed
Add TestCaseFilter class
1 parent 0c59fe4 commit bb97efa

3 files changed

Lines changed: 114 additions & 0 deletions

File tree

aas_test_engines/config.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,40 @@
11
from typing import Optional
22
from dataclasses import dataclass
3+
import fnmatch
4+
import re
5+
from .exception import InvalidFilterException
6+
7+
8+
# Implement gtest-like test filter:
9+
# https://google.github.io/googletest/advanced.html#running-a-subset-of-the-tests
10+
class TestCaseFilter:
11+
FILTER_SEP = "~"
12+
PATTERN_SEP = ":"
13+
14+
def __init__(self, filter_pattern: str):
15+
tokens = filter_pattern.split(self.FILTER_SEP)
16+
if len(tokens) == 1:
17+
include_pattern = tokens[0]
18+
exclude_pattern = ""
19+
elif len(tokens) == 2:
20+
include_pattern = tokens[0]
21+
exclude_pattern = tokens[1]
22+
else:
23+
raise InvalidFilterException(f"Separator {self.FILTER_SEP} must only occur once")
24+
self.includes = [re.compile(fnmatch.translate(i)) for i in include_pattern.split(self.PATTERN_SEP) if i.strip()]
25+
self.excludes = [re.compile(fnmatch.translate(i)) for i in exclude_pattern.split(self.PATTERN_SEP) if i.strip()]
26+
27+
def selects(self, test_case: str) -> bool:
28+
if self.includes and not any(i.match(test_case) for i in self.includes):
29+
return False
30+
if self.excludes and any(i.match(test_case) for i in self.excludes):
31+
return False
32+
return True
333

434

535
@dataclass
636
class CheckApiConfig:
737
suite: str
838
version: Optional[str] = None
939
dry: bool = False
40+
filter: Optional[TestCaseFilter] = None

aas_test_engines/exception.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
11
class AasTestToolsException(Exception):
22
pass
3+
4+
5+
class InvalidFilterException(AasTestToolsException):
6+
pass

test/test_config.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
from unittest import TestCase
2+
from aas_test_engines.config import TestCaseFilter
3+
from aas_test_engines.exception import InvalidFilterException
4+
5+
6+
class TestFilter(TestCase):
7+
8+
def test_empty(self):
9+
filter = TestCaseFilter("")
10+
self.assertEqual(len(filter.includes), 0)
11+
self.assertEqual(len(filter.excludes), 0)
12+
self.assertTrue(filter.selects("I am a test"))
13+
14+
def test_accept_all(self):
15+
filter = TestCaseFilter("*")
16+
self.assertEqual(len(filter.includes), 1)
17+
self.assertEqual(len(filter.excludes), 0)
18+
self.assertTrue(filter.selects("I am a test"))
19+
20+
def test_reject_all(self):
21+
filter = TestCaseFilter("~*")
22+
self.assertEqual(len(filter.includes), 0)
23+
self.assertEqual(len(filter.excludes), 1)
24+
self.assertFalse(filter.selects("I am a test"))
25+
26+
def test_accept_and_reject_all(self):
27+
filter = TestCaseFilter("*:~*")
28+
self.assertEqual(len(filter.includes), 1)
29+
self.assertEqual(len(filter.excludes), 1)
30+
self.assertFalse(filter.selects("I am a test"))
31+
32+
def test_accept_single(self):
33+
filter = TestCaseFilter("I am a test")
34+
self.assertEqual(len(filter.includes), 1)
35+
self.assertEqual(len(filter.excludes), 0)
36+
self.assertTrue(filter.selects("I am a test"))
37+
38+
def test_accept_multiple(self):
39+
filter = TestCaseFilter("I am a test:Test2")
40+
self.assertEqual(len(filter.includes), 2)
41+
self.assertEqual(len(filter.excludes), 0)
42+
self.assertTrue(filter.selects("I am a test"))
43+
self.assertTrue(filter.selects("Test2"))
44+
45+
def test_reject_multiple(self):
46+
filter = TestCaseFilter("~I am a test:Test2")
47+
self.assertEqual(len(filter.includes), 0)
48+
self.assertEqual(len(filter.excludes), 2)
49+
self.assertFalse(filter.selects("I am a test"))
50+
self.assertFalse(filter.selects("Test2"))
51+
52+
def test_accept_glob(self):
53+
filter = TestCaseFilter("*test*")
54+
self.assertEqual(len(filter.includes), 1)
55+
self.assertEqual(len(filter.excludes), 0)
56+
self.assertTrue(filter.selects("I am a test"))
57+
self.assertTrue(filter.selects("test2"))
58+
self.assertFalse(filter.selects("Test2")) # case sensitive
59+
60+
def test_reject_glob(self):
61+
filter = TestCaseFilter("~*test*")
62+
self.assertEqual(len(filter.includes), 0)
63+
self.assertEqual(len(filter.excludes), 1)
64+
self.assertFalse(filter.selects("I am a test"))
65+
self.assertFalse(filter.selects("test2"))
66+
self.assertTrue(filter.selects("Test2")) # case sensitive
67+
68+
def test_complex(self):
69+
filter = TestCaseFilter("GetAll*:*Submodels~GetAllSubmodels:*Post*")
70+
self.assertEqual(len(filter.includes), 2)
71+
self.assertEqual(len(filter.excludes), 2)
72+
self.assertTrue(filter.selects("GetAllShells"))
73+
self.assertFalse(filter.selects("GetAllSubmodels"))
74+
self.assertFalse(filter.selects("PostSubmodels"))
75+
self.assertTrue(filter.selects("PutSubmodels"))
76+
77+
def test_invalid(self):
78+
with self.assertRaises(InvalidFilterException):
79+
TestCaseFilter("a~b~c")

0 commit comments

Comments
 (0)