Repository: psf/black
File: tests/test_black.py (Python)

Code before:
            self.assertIn(
                Feature.RELAXED_DECORATORS,
                black.get_features_used(node),
                msg=(
                    f"decorator '{decorator}' uses python3.9+ syntax"
                    "but is detected as python<=3.8"
                    # f"The full node is\n{node!r}"
                ),
            )

    def test_get_features_used(self) -> None:
        node = black.lib2to3_parse("def f(*, arg): ...\n")
        self.assertEqual(black.get_features_used(node), set())
        node = black.lib2to3_parse("def f(*, arg,): ...\n")
        self.assertEqual(black.get_features_used(node), {Feature.TRAILING_COMMA_IN_DEF})
        node = black.lib2to3_parse("f(*arg,)\n")
        self.assertEqual(
            black.get_features_used(node), {Feature.TRAILING_COMMA_IN_CALL}
        )
        node = black.lib2to3_parse("def f(*, arg): f'string'\n")
        self.assertEqual(black.get_features_used(node), {Feature.F_STRINGS})
        node = black.lib2to3_parse("123_456\n")
        self.assertEqual(black.get_features_used(node), {Feature.NUMERIC_UNDERSCORES})
        node = black.lib2to3_parse("123456\n")
        self.assertEqual(black.get_features_used(node), set())
        source, expected = read_data("simple_cases", "function.py")
        node = black.lib2to3_parse(source)
        expected_features = {
            Feature.TRAILING_COMMA_IN_CALL,
            Feature.TRAILING_COMMA_IN_DEF,
            Feature.F_STRINGS,
        }
        self.assertEqual(black.get_features_used(node), expected_features)
        node = black.lib2to3_parse(expected)
        self.assertEqual(black.get_features_used(node), expected_features)
        source, expected = read_data("simple_cases", "expression.py")
        node = black.lib2to3_parse(source)
        self.assertEqual(black.get_features_used(node), set())
        node = black.lib2to3_parse(expected)
        self.assertEqual(black.get_features_used(node), set())
        node = black.lib2to3_parse("lambda a, /, b: ...")
        self.assertEqual(black.get_features_used(node), {Feature.POS_ONLY_ARGUMENTS})
        node = black.lib2to3_parse("def fn(a, /, b): ...")
        self.assertEqual(black.get_features_used(node), {Feature.POS_ONLY_ARGUMENTS})
        node = black.lib2to3_parse("def fn(): yield a, b")
        self.assertEqual(black.get_features_used(node), set())
        node = black.lib2to3_parse("def fn(): return a, b")
        self.assertEqual(black.get_features_used(node), set())
        node = black.lib2to3_parse("def fn(): yield *b, c")
        self.assertEqual(black.get_features_used(node), {Feature.UNPACKING_ON_FLOW})
        node = black.lib2to3_parse("def fn(): return a, *b, c")

Review comment (suggestion):
```suggestion
        source, expected = read_data("simple_cases", "function")
```

Code after:
                black.get_features_used(node),
                msg=(
                    f"decorator '{decorator}' uses python3.9+ syntax"
                    "but is detected as python<=3.8"
                    # f"The full node is\n{node!r}"
                ),
            )

    def test_get_features_used(self) -> None:
        node = black.lib2to3_parse("def f(*, arg): ...\n")
        self.assertEqual(black.get_features_used(node), set())
        node = black.lib2to3_parse("def f(*, arg,): ...\n")
        self.assertEqual(black.get_features_used(node), {Feature.TRAILING_COMMA_IN_DEF})
        node = black.lib2to3_parse("f(*arg,)\n")
        self.assertEqual(
            black.get_features_used(node), {Feature.TRAILING_COMMA_IN_CALL}
        )
        node = black.lib2to3_parse("def f(*, arg): f'string'\n")
        self.assertEqual(black.get_features_used(node), {Feature.F_STRINGS})
        node = black.lib2to3_parse("123_456\n")
        self.assertEqual(black.get_features_used(node), {Feature.NUMERIC_UNDERSCORES})
        node = black.lib2to3_parse("123456\n")
        self.assertEqual(black.get_features_used(node), set())
        source, expected = read_data("simple_cases", "function")
        node = black.lib2to3_parse(source)
        expected_features = {
            Feature.TRAILING_COMMA_IN_CALL,
            Feature.TRAILING_COMMA_IN_DEF,
            Feature.F_STRINGS,
        }
        self.assertEqual(black.get_features_used(node), expected_features)
        node = black.lib2to3_parse(expected)
        self.assertEqual(black.get_features_used(node), expected_features)
        source, expected = read_data("simple_cases", "expression")
        node = black.lib2to3_parse(source)
        self.assertEqual(black.get_features_used(node), set())
        node = black.lib2to3_parse(expected)
        self.assertEqual(black.get_features_used(node), set())
        node = black.lib2to3_parse("lambda a, /, b: ...")
        self.assertEqual(black.get_features_used(node), {Feature.POS_ONLY_ARGUMENTS})
        node = black.lib2to3_parse("def fn(a, /, b): ...")
        self.assertEqual(black.get_features_used(node), {Feature.POS_ONLY_ARGUMENTS})
        node = black.lib2to3_parse("def fn(): yield a, b")
        self.assertEqual(black.get_features_used(node), set())
        node = black.lib2to3_parse("def fn(): return a, b")
        self.assertEqual(black.get_features_used(node), set())
        node = black.lib2to3_parse("def fn(): yield *b, c")
        self.assertEqual(black.get_features_used(node), {Feature.UNPACKING_ON_FLOW})
        node = black.lib2to3_parse("def fn(): return a, *b, c")
        self.assertEqual(black.get_features_used(node), {Feature.UNPACKING_ON_FLOW})
        node = black.lib2to3_parse("x = a, *b, c")