Skip to content

Commit 507c480

Browse files
author
TROUVERIE Joachim
committed
Add tests
1 parent 462e169 commit 507c480

File tree

8 files changed

+354
-49
lines changed

8 files changed

+354
-49
lines changed

.travis.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
language: python
2+
python:
3+
- '3.7-dev'
4+
- '3.6'
5+
6+
install:
7+
- pip install -r REQUIREMENTS.txt
8+
- pip install pytest flake8
9+
10+
script:
11+
- python -m pytest -vv tests
12+
- flake8

REQUIREMENTS.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pyyaml

pybeeryaml/__init__.py

Lines changed: 5 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -18,49 +18,10 @@
1818
# along with this program. If not, see <http://www.gnu.org/licenses/>.
1919

2020

21-
try:
22-
from lxml import etree as ET
23-
except ImportError:
24-
import xml.etree.ElementTree as ET
21+
from pybeeryaml.recipe import Recipe
2522

2623

27-
class BeerComponent:
28-
"""Base class for beer component
29-
30-
:param objname: object name
31-
:param data: object data
32-
:param mandatory_fields: mandatory_fields
33-
"""
34-
35-
def __init__(self, objname: str, data: dict, mandatory_fields: list):
36-
self.version = 1
37-
self._objname = objname
38-
self._mandatory_fields = mandatory_fields
39-
40-
for field in self._mandatory_fields:
41-
setattr(self, field, data.pop(field))
42-
43-
for key, value in data.items():
44-
if not isinstance(value, list):
45-
setattr(self, key, value)
46-
47-
def to_xml(self) -> str:
48-
"""Convert to beerxml format"""
49-
root = ET.Element(self._objname.upper())
50-
for key, value in self.__dict__.items():
51-
52-
if key.startswith("_"):
53-
continue
54-
55-
subelt = ET.SubElement(root, key.upper())
56-
57-
if isinstance(value, list):
58-
for elt in value:
59-
subelt.append(ET.fromstring(elt.to_xml()))
60-
61-
elif isinstance(value, BeerComponent):
62-
subelt.append(ET.fromstring(value.to_xml()))
63-
64-
else:
65-
subelt.text = str(value)
66-
return ET.tostring(root)
24+
__all__ = ["Recipe"]
25+
__version__ = "1.0"
26+
__author__ = "TROUVERIE Joachim <joachim.trouverie@linoame.fr>"
27+
__url__ = "https://github.com/j0ack/pybeeryaml"

pybeeryaml/meta.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#!/usr/bin/python3
2+
# -*- coding: utf-8 -*-
3+
4+
# Pybeeryaml
5+
# Copyright (C) 2018 TROUVERIE Joachim <joachim.trouverie@linoame.fr>
6+
#
7+
# This program is free software: you can redistribute it and/or modify
8+
# it under the terms of the GNU General Public License as published by
9+
# the Free Software Foundation, either version 3 of the License, or
10+
# (at your option) any later version.
11+
#
12+
# This program is distributed in the hope that it will be useful,
13+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
# GNU General Public License for more details.
16+
#
17+
# You should have received a copy of the GNU General Public License
18+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
19+
20+
21+
import keyword
22+
try:
23+
from lxml import etree as ET
24+
except ImportError:
25+
import xml.etree.ElementTree as ET
26+
27+
28+
class BeerComponent:
29+
"""Base class for beer component
30+
31+
:param objname: object name
32+
:param data: object data
33+
:param mandatory_fields: mandatory_fields
34+
"""
35+
36+
def __init__(self, objname: str, data: dict, mandatory_fields: list):
37+
self.version = 1
38+
self._objname = objname
39+
self._mandatory_fields = mandatory_fields
40+
41+
for field in self._mandatory_fields:
42+
setattr(self, field, data.pop(field))
43+
44+
for key, value in data.items():
45+
if isinstance(value, list):
46+
continue
47+
48+
if keyword.iskeyword(key):
49+
key = f"beeryaml_{key}"
50+
51+
setattr(self, key, value)
52+
53+
def to_xml(self) -> str:
54+
"""Convert to beerxml format"""
55+
root = ET.Element(self._objname.upper())
56+
for key, value in self.__dict__.items():
57+
58+
if key.startswith("_"):
59+
continue
60+
elif key.startswith("beeryaml_"):
61+
key = key[9:]
62+
63+
if isinstance(value, BeerComponent):
64+
root.append(ET.fromstring(value.to_xml()))
65+
else:
66+
subelt = ET.SubElement(root, key.upper())
67+
68+
if isinstance(value, list):
69+
for elt in value:
70+
subelt.append(ET.fromstring(elt.to_xml()))
71+
else:
72+
subelt.text = str(value)
73+
74+
return ET.tostring(root)

pybeeryaml/recipe.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020

2121
from yaml import safe_load
22-
from pybeeryaml import BeerComponent
22+
from pybeeryaml.meta import BeerComponent
2323

2424
RECIPE_FIELDS = ["name", "brewer", "batch_size", "boil_time"]
2525
HOP_FIELDS = ["name", "alpha", "amount", "use", "time"]
@@ -59,7 +59,8 @@ def __init__(self, data: dict):
5959
for mdata in miscs
6060
]
6161

62-
self.mash = BeerComponent("mash", data.get("mash", {}), MASH_FIELDS)
62+
self.mash = BeerComponent("mash", data.get("mash", {"name": "mash"}),
63+
MASH_FIELDS)
6364
steps = []
6465
if hasattr(self.mash, "mash_steps"):
6566
msdata = self.flatten(self.mash.mash_steps)
@@ -83,7 +84,7 @@ def flatten(self, data: dict) -> list:
8384
return output
8485

8586
@classmethod
86-
def from_file(cls, filepath: str) -> Recipe:
87+
def from_file(cls, filepath: str):
8788
"""Create recipe from YAML file
8889
8990
:param filepath: YAML file containing recipe data
@@ -93,9 +94,9 @@ def from_file(cls, filepath: str) -> Recipe:
9394
return cls(data)
9495

9596
@classmethod
96-
def from_yaml(cls, data: str) -> Recipe:
97+
def from_yaml(cls, data: str):
9798
"""Create recipe from YAML data
9899
99100
:param data: YAML recipe data
100101
"""
101-
return cls(data)
102+
return cls(safe_load(data))

tests/beer.xml

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?xml version="1.0" encoding="ISO-8859-1"?>
2+
<RECIPE>
3+
<VERSION>1</VERSION>
4+
<NAME>Dry Stout</NAME>
5+
<TYPE>All Grain</TYPE>
6+
<BREWER>Brad Smith</BREWER>
7+
<DATE>3 jan 04</DATE>
8+
<STYLE>Dry Stout</STYLE>
9+
<BATCH_SIZE>18.93</BATCH_SIZE>
10+
<BOIL_SIZE>20.82</BOIL_SIZE>
11+
<BOIL_TIME>60.0</BOIL_TIME>
12+
<HOPS>
13+
<HOP>
14+
<VERSION>1</VERSION>
15+
<NAME>Goldings, East Kent</NAME>
16+
<ALPHA>5.0</ALPHA>
17+
<AMOUNT>0.0638</AMOUNT>
18+
<USE>boil</USE>
19+
<TIME>60.0</TIME>
20+
<NOTES>Great all purpose uk hop for ales, stouts, porters</NOTES>
21+
</HOP>
22+
</HOPS>
23+
<FERMENTABLES>
24+
<FERMENTABLE>
25+
<VERSION>1</VERSION>
26+
<NAME>Pale Malt (2 row) UK</NAME>
27+
<AMOUNT>2.27</AMOUNT>
28+
<TYPE>Grain</TYPE>
29+
<YIELD>78.0</YIELD>
30+
<COLOR>3.0</COLOR>
31+
<NOTES>All purpose base malt for English styles</NOTES>
32+
</FERMENTABLE>
33+
<FERMENTABLE>
34+
<VERSION>1</VERSION>
35+
<NAME>Barley, Flaked</NAME>
36+
<AMOUNT>0.91</AMOUNT>
37+
<TYPE>Grain</TYPE>
38+
<YIELD>70.0</YIELD>
39+
<COLOR>2.0</COLOR>
40+
<NOTES>Adds body to porters and stouts, must be mashed</NOTES>
41+
</FERMENTABLE>
42+
</FERMENTABLES>
43+
<YEASTS>
44+
<YEAST>
45+
<VERSION>1</VERSION>
46+
<NAME>Irish Ale</NAME>
47+
<FORM>Liquid</FORM>
48+
<AMOUNT>0.25</AMOUNT>
49+
<TYPE>Ale</TYPE>
50+
</YEAST>
51+
</YEASTS>
52+
<MASH>
53+
<VERSION>1</VERSION>
54+
<NAME>single step infusion, 68 c</NAME>
55+
<MASH_STEPS>
56+
<MASH_STEP>
57+
<VERSION>1</VERSION>
58+
<TYPE>Infusion</TYPE>
59+
<NAME>Conversion Step, 68C</NAME>
60+
<STEP_TIME>60.0</STEP_TIME>
61+
<STEP_TEMP>68.0</STEP_TEMP>
62+
</MASH_STEP>
63+
</MASH_STEPS>
64+
</MASH>
65+
<MISCS/>
66+
</RECIPE>

tests/beer.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: Dry Stout
2+
type: All Grain
3+
brewer: Brad Smith
4+
batch_size: 18.93
5+
boil_size: 20.82
6+
boil_time: 60.0
7+
date: 3 jan 04
8+
style: Dry Stout
9+
hops:
10+
Goldings, East Kent:
11+
alpha: 5.0
12+
amount: 0.0638
13+
use: boil
14+
time: 60.0
15+
notes: Great all purpose uk hop for ales, stouts, porters
16+
17+
fermentables:
18+
Pale Malt (2 row) UK:
19+
amount: 2.27
20+
type: Grain
21+
yield: 78.0
22+
color: 3.0
23+
notes: All purpose base malt for English styles
24+
Barley, Flaked:
25+
amount: 0.91
26+
type: Grain
27+
yield: 70.0
28+
color: 2.0
29+
notes: Adds body to porters and stouts, must be mashed
30+
31+
yeasts:
32+
Irish Ale:
33+
type: Ale
34+
form: Liquid
35+
amount: 0.25
36+
37+
mash:
38+
name: single step infusion, 68 c
39+
mash_steps:
40+
Conversion Step, 68C:
41+
type: Infusion
42+
step_temp: 68.0
43+
step_time: 60.0

0 commit comments

Comments
 (0)