Пример #1
0
    def test_scaled_value_expr_integers_stay_as_ints(self) -> None:
        compiled = compile_markdown("{5}")
        assert compiled.render(Fraction(1, 3)) == (
            '<p><span class="rg-scaled-value">1 <sup>2</sup>&frasl;<sub>3</sub></span></p>\n'
        )

        compiled = compile_markdown("{5.0}")
        assert compiled.render(Fraction(
            1, 3)) == ('<p><span class="rg-scaled-value">1.67</span></p>\n')
Пример #2
0
    def test_error_message_line_numbers(self, source: str) -> None:
        with pytest.raises(ParseError) as exc_info:
            compile_markdown(dedent(source).strip())

        assert (str(exc_info.value) == dedent("""
                At line 5 column 13:
                    foo = fried()
                                ^
                Expected <action> or <ingredient> or <quantity>
            """).strip())
Пример #3
0
 def test_finds_problems(self, recipe: str, exp_description: str) -> None:
     markdown_recipe = compile_markdown(f"```recipe\n{recipe}\n```")
     recipe_blocks = markdown_recipe.recipes[0]
     lint = list(check_for_unused_ingredients(recipe_blocks))
     assert len(lint) == 1
     assert lint[0].kind == LintKind.unused_ingredient
     assert lint[0].description == exp_description
Пример #4
0
    def test_recipes_split_across_blocks(self) -> None:
        compiled = compile_markdown(
            dedent("""
                A recipe in two parts. Part one:

                    sauce = boil down(tomatoes, water)

                Part two:

                    pour over(pasta, sauce)
                """).strip())

        sr = SubRecipe(
            Step(
                SVS("boil down"),
                (
                    Ingredient(SVS("tomatoes")),
                    Ingredient(SVS("water")),
                ),
            ),
            (SVS("sauce"), ),
        )
        r1 = Recipe((sr, ))
        r2 = Recipe(
            (Step(
                SVS("pour over"),
                (
                    Ingredient(SVS("pasta")),
                    Reference(sr),
                ),
            ), ),
            follows=r1,
        )

        assert compiled.recipes == [[r1, r2]]
Пример #5
0
 def test_title_parsing(
     self,
     source: str,
     exp_title: Optional[str],
     exp_servings: Optional[int],
     exp_html: str,
     exp_html_10: str,
 ) -> None:
     compiled = compile_markdown(dedent(source).strip())
     assert compiled.title == exp_title
     assert compiled.servings == exp_servings
     assert compiled.render(1) == exp_html
     assert compiled.render(10) == exp_html_10
Пример #6
0
    def test_separate_recipes(self) -> None:
        compiled = compile_markdown(
            dedent("""
                Fried egg:

                ```recipe
                1 egg
                ```

                ```recipe
                fry(egg)
                ```

                Boiled egg:

                ```new-recipe
                2 egg
                ```

                ```recipe
                boil(egg)
                ```
                """).strip())

        e1 = SubRecipe(
            Ingredient(SVS("egg"), Quantity(1)),
            (SVS("egg"), ),
            show_output_names=False,
        )
        r1 = Recipe((e1, ))
        r2 = Recipe((Step(SVS("fry"), (Reference(e1), )), ), follows=r1)

        e2 = SubRecipe(
            Ingredient(SVS("egg"), Quantity(2)),
            (SVS("egg"), ),
            show_output_names=False,
        )
        r3 = Recipe((e2, ))
        r4 = Recipe((Step(SVS("boil"), (Reference(e2), )), ), follows=r3)

        assert compiled.recipes == [[r1, r2], [r3, r4]]

        # Check anchor IDs are unique too
        html = compiled.render()
        assert 'id="recipe-egg"' in html
        assert 'href="#recipe-egg"' in html
        assert 'id="recipe2-egg"' in html
        assert 'href="#recipe2-egg"' in html
Пример #7
0
def main() -> None:
    parser = ArgumentParser(description="""
            Check a recipe grid markdown file for possible mistakes.
        """, )

    parser.add_argument(
        "recipe",
        type=Path,
        nargs="*",
        help="""
            The filename of the recipe grid markdown file to compile. Pass
            multiple filenames to check multiple files.
        """,
    )

    parser.add_argument(
        "--ignore",
        "-i",
        action="extend",
        default=[],
        nargs="+",
        choices=[k.name for k in LintKind],
        help="""
            Ignore warnings of a certain types.
        """,
    )

    args = parser.parse_args()

    failed = False
    for page in args.recipe:
        try:
            markdown_recipe = compile_markdown(page.open().read())
            for recipe in markdown_recipe.recipes:
                for lint in check(recipe):
                    if lint.kind.name not in args.ignore:
                        failed = True
                        print(
                            f"{page}: Warning: {lint.description} [{lint.kind.name}]"
                        )
        except (ParseError, RecipeCompileError) as e:
            failed = True
            print(f"{page}: Error: {e}")

    sys.exit(1 if failed else 0)
Пример #8
0
def test_add_recipe_scaling_links() -> None:
    html = compile_markdown("# A recipe serving 3").render(Fraction(2, 3))

    assert postprocess_html(
        html,
        False,
        [
            partial(
                add_recipe_scaling_links,
                from_path="/serves2/foo/bar.html",
                scaled_paths={
                    1: "/serves1/foo/bar.html",
                    2: "/serves2/foo/bar.html",
                    3: "/serves3/foo/bar.html",
                    4: "/serves4/foo/bar.html",
                },
                native_servings=3,
            )
        ],
    ) == ('<header><h1 class="rg-title-scalable">A recipe '
          '<span class="rg-serving-count">'
          '<a href="#" class="rg-serving-count-current">'
          'serving <span class="rg-scaled-value">2</span>'
          "</a>"
          "<ul>"
          '<li><a href="../../serves1/foo/bar.html">serving '
          '<span class="rg-scaled-value">1</span></a></li>'
          '<li><a href="bar.html">serving '
          '<span class="rg-scaled-value">2</span></a></li>'
          '<li><a href="../../serves3/foo/bar.html">serving '
          '<span class="rg-scaled-value">3</span></a></li>'
          '<li><a href="../../serves4/foo/bar.html">serving '
          '<span class="rg-scaled-value">4</span></a></li>'
          "</ul>"
          "</span></h1><p>Rescaled from "
          '<span class="rg-original-servings">'
          '<a href="../../serves3/foo/bar.html">3 servings</a></span>.</p>'
          "</header>\n")
Пример #9
0
    def test_recipe_code_blocks_and_scaled_rendering(self,
                                                     source: str) -> None:
        compiled = compile_markdown(dedent(source).strip())
        assert compiled.title == "A recipe"
        assert compiled.servings == 2
        assert compiled.recipes == [[
            Recipe((Step(
                SVS("fry"),
                (
                    Ingredient(SVS("spam"), Quantity(100, "g")),
                    Ingredient(SVS("eggs"), Quantity(2)),
                ),
            ), )),
        ]]
        assert (compiled.render(2) == dedent("""
                <header><h1 class="rg-title-scalable">A recipe <span class="rg-serving-count">for <span class="rg-scaled-value">4</span></span></h1><p>Rescaled from <span class="rg-original-servings">2 servings</span>.</p></header>
                <div class="rg-recipe-block">
                  <table class="rg-table">
                    <tr>
                      <td class="rg-ingredient rg-border-left-sub-recipe rg-border-top-sub-recipe">
                        <span class="rg-quantity-with-conversions rg-scaled-value" tabindex="0">
                          200g<ul class="rg-quantity-conversions">
                            <li><sup>1</sup>&frasl;<sub>5</sub>kg</li>
                            <li>0.441lb</li>
                            <li>7.05oz</li>
                          </ul>
                        </span> spam
                      </td>
                      <td class="rg-step rg-border-right-sub-recipe rg-border-top-sub-recipe rg-border-bottom-sub-recipe" rowspan="2">fry</td>
                    </tr>
                    <tr><td class="rg-ingredient rg-border-left-sub-recipe rg-border-bottom-sub-recipe"><span class="rg-quantity-unitless rg-scaled-value">4</span> eggs</td></tr>
                  </table>
                </div><p>Ta-da!</p>
            """

                                             # noqa: E501
                                             ).lstrip())
Пример #10
0
 def test_quiet_when_everything_adds_up(self, recipe: str) -> None:
     markdown_recipe = compile_markdown(f"```recipe\n{recipe}\n```")
     recipe_blocks = markdown_recipe.recipes[0]
     assert list(
         check_sub_recipe_references_sum_to_whole(recipe_blocks)) == []
Пример #11
0
 def test_quiet_when_nothing_unused(self, recipe: str) -> None:
     markdown_recipe = compile_markdown(f"```recipe\n{recipe}\n```")
     recipe_blocks = markdown_recipe.recipes[0]
     assert list(check_for_unused_ingredients(recipe_blocks)) == []
Пример #12
0
 def test_finds_problems(self, recipe: str, exp_lint: List[Lint]) -> None:
     markdown_recipe = compile_markdown(f"```recipe\n{recipe}\n```")
     recipe_blocks = markdown_recipe.recipes[0]
     lint = list(check_sub_recipe_references_sum_to_whole(recipe_blocks))
     assert len(lint) == len(exp_lint)
     assert set(lint) == set(exp_lint)
Пример #13
0
 def test_scaled_value_expr(self, markdown: str, exp: str,
                            exp10: str) -> None:
     compiled = compile_markdown(markdown)
     assert compiled.render(1) == exp
     assert compiled.render(10) == exp10
Пример #14
0
 def test_no_recipes(self) -> None:
     assert compile_markdown("").render() == ""
     assert compile_markdown("Hello").render() == "<p>Hello</p>\n"
Пример #15
0
 def test_non_recipe_fenced_block(self) -> None:
     assert (compile_markdown("~~~\nfoo\n~~~").render() ==
             "<pre><code>foo\n</code></pre>\n")