From 4a4586f37361c95ad01876758ba8afa2f8704941 Mon Sep 17 00:00:00 2001 From: Mike Shoup Date: Sat, 22 Dec 2018 17:44:58 -0700 Subject: [PATCH] Add MarkdownRecipe object and do many more things. --- src/synthale/recipes.py | 63 +++++++++++++++++++++++++++++++---------- tests/recipes/bad-file | 1 + tests/test_recipes.py | 39 ++++++++++++++++--------- 3 files changed, 75 insertions(+), 28 deletions(-) create mode 100644 tests/recipes/bad-file diff --git a/src/synthale/recipes.py b/src/synthale/recipes.py index 9de33fb..adba2d3 100644 --- a/src/synthale/recipes.py +++ b/src/synthale/recipes.py @@ -6,31 +6,64 @@ import re import pybeerxml -def parse_xmlfile(path): +class MarkdownRecipe: + """A recipe in markdown form.""" + + def __init__(self, recipe): + """Create a MarkdownRecipe object. + + `recipe` is a recipe object from the pybeerxml package. + """ + self.recipe = recipe + + @property + def filename(self): + """Return the filename for the recipe. + + Converts the recipe name to lowercase and replaces all non-word + characters with an underscore. Trailing underscores are removed. + `.md` is appended to the name. + """ + return '{}.md'.format( + re.sub( + r'_$', '', re.sub( + r'[\W]+', '_', self.recipe.name.lower() + ) + ) + ) + + @property + def markdown(self): + """Return generated markdown for the recipe.""" + return '' + + +def load_file(path): """Parse BeerXML file located at `path`. - Returns a list of parsed recipes. + Return a list of MarkdownRecipe objects. If an exception is raised during + parsing, the message is printed to stdout and an empty list is returned. """ - return pybeerxml.Parser().parse(path) + try: + result = pybeerxml.Parser().parse(path) + except Exception as err: + print(err) + return [] + + recipes = [] + for recipe in result: + recipes.append(MarkdownRecipe(recipe)) + return recipes -def load_recipes(path): +def load_all_files(path): """Parse all files in `path` that end in `.xml`. - Returns a list of parsed recipes. + Returns a list of MarkdownRecipe objects. """ recipes = [] for name in os.listdir(path): if name.endswith('.xml'): - recipes.extend(parse_xmlfile(os.path.join(path, name))) + recipes.extend(load_file(os.path.join(path, name))) return recipes - - -def name_to_slug(name): - """Convert a recipe name to a slug. - - Converts the name to lowercase and replaces all non-word characters with an - underscore. Additionally, removes any trailing underscores. - """ - return re.sub(r'_$', '', re.sub(r'[\W]+', '_', name.lower())) diff --git a/tests/recipes/bad-file b/tests/recipes/bad-file new file mode 100644 index 0000000..c4869ba --- /dev/null +++ b/tests/recipes/bad-file @@ -0,0 +1 @@ +Bad file diff --git a/tests/test_recipes.py b/tests/test_recipes.py index d831d46..5a845b9 100644 --- a/tests/test_recipes.py +++ b/tests/test_recipes.py @@ -1,24 +1,37 @@ """Contains tests for the synthale.recipes module.""" -from synthale.recipes import parse_xmlfile, load_recipes, name_to_slug +import pybeerxml + +from synthale.recipes import MarkdownRecipe, load_file, load_all_files -def test_parse_xmlfile(): +def test_load_file(): """Load the sample XML file and ensure the name is parsed.""" - result = parse_xmlfile('tests/recipes/weizen.xml') - assert result[0].name == 'Weizen' + result = load_file('tests/recipes/weizen.xml') + assert result[0].recipe.name == 'Weizen' + + result = load_file('tests/recipes/bad-file') + assert result == [] -def test_load_recipes(): +def test_load_all_files(): """Load all sample XML files and ensure the count is correct.""" - result = load_recipes('tests/recipes') - result.sort(key=lambda recipe: recipe.name) + result = load_all_files('tests/recipes') + result.sort(key=lambda item: item.recipe.name) assert len(result) == 2 - assert result[0].name == 'Coffee Stout' - assert result[1].name == 'Weizen' + assert result[0].recipe.name == 'Coffee Stout' + assert result[1].recipe.name == 'Weizen' -def test_name_to_slug(): - """Ensure names are properly converted to slugs.""" - name = 'Convert!This name@$ @!to a slug.' - assert name_to_slug(name) == 'convert_this_name_to_a_slug' +def test_markdown_recipe_filename(): + """Validate a generated markdown recipe's filename.""" + xml_recipe = pybeerxml.Recipe() + xml_recipe.name = 'Validate@!#This!' + recipe = MarkdownRecipe(xml_recipe) + assert recipe.filename == 'validate_this.md' + + +def test_markdown_recipe_markdown(): + """Validate the generated markdown.""" + recipe = MarkdownRecipe(None) + assert recipe.markdown == ''