def test_transform(self):
        ps0 = (
            Regex(r".+"),
            OneOf("foo", "bar"),
            AllOf("foo", "bar"),
            Either("foo", "bar"),
            Each(SubclassOf(int)),
            EachItem(InstanceOf(str), SubclassOf(type)),
            Parameters(int, k=str),
            Items(foo=17),
            Attrs(bar=117),
            At(path=["foo", "bar"], pattern=...),
            Arguments(foo=int, bar=float),
            Returns(str),
            Object(SomeClass, 8, bar='quuz'),
            {
                "foo": 1
            }**Remainder(...),
            [1, 2, 3],
            "foo",
            1.0,
        )
        ts = (
            Not,
            Strict,
            lambda pat: Transformed(identity, pat),
            lambda pat: Capture(pat, name="qux"),
        )
        ps = [
            AllOf(*ps0),
            OneOf(*ps0),
            NoneOf(*ps0),
        ]
        for p in ps0:
            for fs in powerset(ts):
                for fsp in permutations(fs):
                    pp = p
                    for f in fsp:
                        pp = f(pp)
                    ps.append(pp)

        for p in ps:
            types = set()
            t = transform(p, record_type(types))
            self.assertEqual(p, t)
            self.assertNotEqual(p, transform(p, lambda x: Not(x)))
            # since we already invested so much time into building combinations of patterns,
            # check that match does not error out (this will sometimes even match due to Not(...))
            expected_to_match = Not in types
            self.assertEqual(expected_to_match, bool(match(None, t)))
            # also do a check for captureall=, which is using a more fancy transform
            results = {}
            self.assertEqual(expected_to_match,
                             bool(match(None, p, captureall=results)))
            if expected_to_match:
                self.assertTrue(bool(results))
    def test_fancy_transform(self):
        # noinspection PyDefaultArgument
        def generate_name(static={'count': 0}):
            static['count'] += 1
            return f"n{static['count']}"

        pattern = (1, Many(...), 3)
        transformed = transform(pattern, lambda x: Capture(x, name=generate_name()))
        result = match((1, 2, 3), transformed)
        self.assertTrue(result)
        self.assertEqual({
            'n1': 1,
            'n2': 2,
            'n3': [2],
            'n4': 3,
            'n5': (1, 2, 3),
        }, result.groups())
 def test_string_transform(self):
     pt0 = String("a", "b", "c")
     pt1 = transform(pt0, lambda x: x)
     self.assertEqual(pt0, pt1)
 def test_some_transform(self):
     pt0 = (1, Many(...), 3)
     pt1 = transform(pt0, lambda x: x)
     self.assertEqual(pt0, pt1)