예제 #1
0
 def test_dictionary_unpacking_passes(self):
     snake_code = (
         f"rule a:\n"
         f'{TAB * 1}params: **config["params"]\n'
         f'{TAB * 1}shell: "mycommand {{params}}"'
     )
     setup_formatter(snake_code)
예제 #2
0
 def test_modified_rule_from_module_passes(self):
     setup_formatter("use rule a from mymodule with:\n" f"{TAB * 1}threads: 4")
     setup_formatter(
         "use rule b from mymodule as my_b with:\n"
         f"{TAB * 1}output:\n"
         f'{TAB * 2}"new_output"'
     )
예제 #3
0
 def test_implicitly_unrecognised_keyword(self):
     """
     The keyword lives in the 'base' space, so could also be interpreted as Python
     code.
     In that case black will complain of invalid python and not format it.
     """
     with pytest.raises(InvalidPython):
         setup_formatter(f"role a: \n" f'{TAB * 1}input: "b"')
예제 #4
0
 def test_rules_inside_python_code_passes(self):
     snake = (
         f"if condition1:\n"
         f"{TAB * 1}if condition2:\n"
         f"{TAB * 2}rule a:\n"
         f'{TAB * 3}input:"in"\n'
     )
     setup_formatter(snake)
예제 #5
0
 def test_multicopy_parameter_keyword_inside_python_code_passes(self):
     snake = (
         f"if condition1:\n"
         f"{TAB * 1}if condition2:\n"
         f'{TAB * 2}configfile: "f1"\n'
         f"{TAB * 1}else:\n"
         f'{TAB * 2}configfile: "f2"\n'
     )
     setup_formatter(snake)
예제 #6
0
 def test_invalid_python_code_preceding_nested_rule_fails(self):
     snakecode = (
         f"if invalid code here:\n" f"{TAB * 1}rule a:\n" f"{TAB * 2}threads: 1"
     )
     snakecode2 = f"def p:\n" f"{TAB * 1}rule a:\n" f"{TAB * 2}threads: 1"
     with pytest.raises(InvalidPython):
         setup_formatter(snakecode)
     with pytest.raises(InvalidPython):
         setup_formatter(snakecode2)
예제 #7
0
 def test_snakecode_inside_run_directive_fails(self):
     snake_code = (
         f"rule a:\n"
         f"{TAB * 1}run:\n"
         f"{TAB * 2}if condition:\n"
         f"{TAB * 3}rule b:\n"
         f'{TAB * 4}input: "in"\n'
     )
     with pytest.raises(InvalidPython):
         setup_formatter(snake_code)
예제 #8
0
    def test_python_code_before_nested_snakecode_gets_formatted(self):
        snakecode = "b=2\n" "if condition:\n" f'{TAB * 1}include: "a"\n'
        with mock.patch("snakefmt.formatter.Formatter.run_black_format_str",
                        spec=True) as mock_m:
            mock_m.return_value = "b=2\nif condition:\n"
            setup_formatter(snakecode)
            assert mock_m.call_count == 2

        formatter = setup_formatter(snakecode)
        expected = "b = 2\n" "if condition:\n\n" f'{TAB * 1}include: "a"\n'
        assert formatter.get_formatted() == expected
예제 #9
0
 def test_multicopy_rule_name_after_python_code_fails(self):
     snake = (
         f"if condition1:\n"
         f"{TAB * 1}rule all:\n"
         f'{TAB * 2}wrapper:"a"\n'
         f"rule b:\n"
         f'{TAB * 1}wrapper:"b"\n'
         f"rule b:\n"
         f'{TAB * 1}wrapper:"b"'
     )
     with pytest.raises(DuplicateKeyWordError):
         setup_formatter(snake)
예제 #10
0
 def test_multicopy_rule_name_inside_python_code_passes(self):
     snake = (
         f"if condition1:\n"
         f"{TAB * 1}rule all:\n"
         f'{TAB * 2}wrapper:"a"\n'
         f"elif condition2:\n"
         f"{TAB * 1}rule all:\n"
         f'{TAB * 2}wrapper:"b"\n'
         f"else:\n"
         f"{TAB * 1}rule all:\n"
         f'{TAB * 2}wrapper:"c"'
     )
     setup_formatter(snake)
예제 #11
0
    def test_python_code_with_multi_indent_passes(self):
        python_code = "if p:\n" f"{TAB * 1}for elem in p:\n" f"{TAB * 2}dothing(elem)\n"
        # test black gets called
        with mock.patch(
                "snakefmt.formatter.Formatter.run_black_format_str",
                spec=True,
                return_value="",
        ) as mock_m:
            setup_formatter(python_code)
            mock_m.assert_called_once()

        # test black formatting output (here, is identical)
        formatter = setup_formatter(python_code)
        actual = formatter.get_formatted()
        assert actual == python_code
예제 #12
0
 def test_rf_string_tpq_supported(self):
     """Deliberately tests for consecutive r/f strings and with
     single or double quotes"""
     for preceding in {"r", "f"}:
         snakecode = ("rule top:\n"
                      f"{TAB * 1}shell:\n"
                      f'{TAB * 2}{preceding}"""\n'
                      f"{TAB * 2}Multi_line\n"
                      f'{TAB * 2}"""\n'
                      f'{TAB * 2}{preceding}"""\n'
                      f"{TAB * 2}Other multi_line\n"
                      f'{TAB * 2}"""\n')
         assert setup_formatter(snakecode).get_formatted() == snakecode
         snakecode2 = snakecode.replace('"""', "'''")
         assert setup_formatter(snakecode2).get_formatted() == snakecode
예제 #13
0
def test_emptyInput_emptyOutput():
    formatter = setup_formatter("")

    actual = formatter.get_formatted()
    expected = ""

    assert actual == expected
예제 #14
0
 def test_use_rule_rule_like_indented(self):
     snakecode = ('include: "file.txt"\n\n\n'
                  "use rule a from module with:\n"
                  f"{TAB * 1}input:\n"
                  f"{TAB * 2}b=2,\n")
     formatter = setup_formatter(snakecode)
     assert formatter.get_formatted() == snakecode
예제 #15
0
    def test_long_line_within_rule_indentation_taken_into_account(self):
        snakecode = (
            f"rule coverage_report:\n"
            f"{TAB * 1}input:\n"
            f"{TAB * 2}lineage=expand(\n"
            f'{TAB * 3}str(report_dir / "lineage_assignment" / "{{sample}}.lineage.csv"), sample=samples\n'  # noqa: E501  due to readability of test
            f"{TAB * 2}),\n"
            f"{TAB * 2}subsample_logs=list(subsample_logfiles),"
        )
        line_length = 88
        formatter = setup_formatter(snakecode, line_length)

        actual = formatter.get_formatted()
        print(actual)
        expected = (
            f"rule coverage_report:\n"
            f"{TAB * 1}input:\n"
            f"{TAB * 2}lineage=expand(\n"
            f'{TAB * 3}str(report_dir / "lineage_assignment" / "{{sample}}.lineage.csv"),\n'  # noqa: E501  due to readability of test
            f"{TAB * 3}sample=samples,\n"
            f"{TAB * 2}),\n"
            f"{TAB * 2}subsample_logs=list(subsample_logfiles),\n"
        )

        assert actual == expected
예제 #16
0
    def test_initial_comment_does_not_trigger_spacing(self):
        snakecode = (
            f"# load config\n" f"rule all:\n" f"{TAB * 1}input:\n" f"{TAB * 2}files,\n"
        )

        formatter = setup_formatter(snakecode)
        assert formatter.get_formatted() == snakecode
예제 #17
0
    def test_double_spacing_for_rules(self):
        formatter = setup_formatter(f"""above_rule = "2spaces"
rule a:
{TAB * 1}threads: 1



rule b:
{TAB * 1}threads: 2
below_rule = "2spaces"
""")

        expected = f"""above_rule = "2spaces"


rule a:
{TAB * 1}threads: 1


rule b:
{TAB * 1}threads: 2


below_rule = "2spaces"
"""
        actual = formatter.get_formatted()

        assert actual == expected
예제 #18
0
    def test_parameter_keyword_spacing_above(self):
        formatter = setup_formatter("b = 2\n" 'configfile: "config.yaml"')

        actual = formatter.get_formatted()
        expected = 'b = 2\n\n\nconfigfile: "config.yaml"\n'

        assert actual == expected
예제 #19
0
 def test_comment_outside_keyword_context_stays_untouched(self):
     snakecode = (f"rule a:\n"
                  f"{TAB * 1}run:\n"
                  f"{TAB * 2}f()\n\n\n"
                  f"# A comment\n")
     formatter = setup_formatter(snakecode)
     assert formatter.get_formatted() == snakecode
예제 #20
0
 def test_rule_re_indenting(self):
     """Indented rule gets dendented"""
     formatter = setup_formatter(f"{TAB * 1}rule a:\n"
                                 f"{TAB * 2}wrapper:\n"
                                 f'{TAB * 3}"a"\n')
     expected = f"rule a:\n" f"{TAB * 1}wrapper:\n" f'{TAB * 2}"a"\n'
     assert formatter.get_formatted() == expected
예제 #21
0
 def test_comments_after_parameters_kept(self):
     snakecode = (f"rule a:\n"
                  f"{TAB * 1}input:\n"
                  f'{TAB * 2}"myparam",  # a comment\n'
                  f'{TAB * 2}b="param2",  # another comment\n')
     formatter = setup_formatter(snakecode)
     assert formatter.get_formatted() == snakecode
예제 #22
0
    def test_docstrings_get_retabbed_for_snakecode_only(self):
        """Black only retabs the first tpq in a docstring."""
        snakecode = '''def f():
  """Does not do
  much
"""
  pass


rule a:
  """The rule a
"""
  message:
    "a"
'''
        formatter = setup_formatter(snakecode)
        expected = f'''def f():
{TAB * 1}"""Does not do
    much"""
{TAB * 1}pass


rule a:
{TAB * 1}"""The rule a
{TAB * 1}"""
{TAB * 1}message:
{TAB * 2}"a"
'''
        assert formatter.get_formatted() == expected
예제 #23
0
 def test_python_code_inside_run_keyword(self):
     snake_code = ("rule a:\n"
                   f"{TAB * 1}run:\n"
                   f"{TAB * 2}def s(a):\n"
                   f"{TAB * 3}if a:\n"
                   f'{TAB * 4}return "Hello World"\n')
     formatter = setup_formatter(snake_code)
     assert formatter.get_formatted() == snake_code
예제 #24
0
 def test_no_inline_comments_stay_untouched(self):
     snakecode = ("rule all:\n"
                  f"{TAB * 1}input:\n"
                  f"{TAB * 2}p=2,\n"
                  f"{TAB * 2}#comment1\n"
                  f"{TAB * 2}#comment2\n")
     formatter = setup_formatter(snakecode)
     assert formatter.get_formatted() == snakecode
예제 #25
0
 def test_aligned_comments_stay_untouched(self):
     snakecode = ("rule eval:                             # [hide]\n"
                  f"{TAB * 1}output:                      # [hide]\n"
                  f'{TAB * 2}directory("resources/eval"), # [hide]\n'
                  f"{TAB * 1}wrapper:                     # [hide]\n"
                  f'{TAB * 2}"master/bio/benchmark/eval"  # [hide]\n')
     formatter = setup_formatter(snakecode)
     assert formatter.get_formatted() == snakecode
예제 #26
0
 def test_comment_below_paramkeyword_stays_untouched(self):
     snakecode = ("rule all:\n"
                  f"{TAB * 1}input:\n"
                  f"{TAB * 2}# A list of inputs\n"
                  f"{TAB * 2}elem1,  #The first elem\n"
                  f"{TAB * 2}elem1,  #The second elem\n")
     formatter = setup_formatter(snakecode)
     assert formatter.get_formatted() == snakecode
예제 #27
0
 def test_parameter_keywords_inside_python_code(self):
     snakecode = ("if condition:\n\n"
                  f'{TAB * 1}include: "a"\n\n\n'
                  f"else:\n\n"
                  f'{TAB * 1}include: "b"\n'
                  f'include: "c"\n')
     formatter = setup_formatter(snakecode)
     assert formatter.get_formatted() == snakecode
예제 #28
0
 def test_comment_support_after_python_code(self):
     snakecode = ('if config["a"]:\n\n'
                  f'{TAB * 1}include: "module_a.smk"\n\n\n'
                  f'# include: "module_b.smk"\n\n\n'
                  f'if config["c"]:\n\n'
                  f'{TAB * 1}include: "module_c.smk"\n')
     formatter = setup_formatter(snakecode)
     assert formatter.get_formatted() == snakecode
예제 #29
0
 def test_spaced_out_consecutive_dedented_directive(self):
     snakecode = ('if config["load"]:\n\n'
                  f'{TAB * 1}include: "module_a.smk"\n\n\n'
                  f"else:\n\n"
                  f'{TAB * 1}include: "module_b.smk"\n\n\n'
                  f'include: "other.smk"\n')
     formatter = setup_formatter(snakecode)
     assert formatter.get_formatted() == snakecode
예제 #30
0
    def test_python_code_after_nested_snakecode_gets_formatted(self):
        snakecode = "if condition:\n" f'{TAB * 1}include: "a"\n' "b=2\n"
        with mock.patch("snakefmt.formatter.Formatter.run_black_format_str",
                        spec=True) as mock_m:
            mock_m.return_value = "if condition:\n"
            setup_formatter(snakecode)
            assert mock_m.call_count == 3
            assert mock_m.call_args_list[1] == mock.call('"a"', 0, 0)
            assert mock_m.call_args_list[2] == mock.call("b = 2\n", 0)

        formatter = setup_formatter(snakecode)
        expected = (
            "if condition:\n\n"
            f'{TAB * 1}include: "a"\n'
            "\n\nb = 2\n"  # python code gets formatted here
        )
        assert formatter.get_formatted() == expected