1
0
Fork 0
mirror of https://github.com/shouptech/humulus.git synced 2026-02-03 22:09:41 +00:00

Compare commits

..

2 commits

Author SHA1 Message Date
c219ae3301
Flake8 fixes for tests 2019-07-11 21:16:51 -06:00
756be12a2a
Flake8 fixes for src 2019-07-11 21:08:58 -06:00
12 changed files with 61 additions and 53 deletions

View file

@ -13,3 +13,5 @@
# limitations under the License. # limitations under the License.
from humulus.app import create_app from humulus.app import create_app
__all__ = ['create_app', ]

View file

@ -14,8 +14,6 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import os
from flask import Flask, render_template from flask import Flask, render_template

View file

@ -26,6 +26,7 @@ from flask import abort, current_app, g
from flask.cli import with_appcontext from flask.cli import with_appcontext
from slugify import slugify from slugify import slugify
def get_couch(): def get_couch():
"""Connect to the configured CouchDB.""" """Connect to the configured CouchDB."""
if 'couch' not in g: if 'couch' not in g:

View file

@ -59,7 +59,7 @@ def recipe_fg(recipe):
) / 200 ) / 200
) )
return '{:.3f}'.format( return '{:.3f}'.format(
round(1 + (og - 1 - og_delta)*(1 - attenuation) + og_delta, 3) round(1 + (og - 1 - og_delta) * (1 - attenuation) + og_delta, 3)
) )
@ -123,9 +123,11 @@ def sort_hops(hops, form=False):
by_use[hop['use']].append(hop) by_use[hop['use']].append(hop)
if form: if form:
key = lambda hop: float(hop.duration.data) def key(hop):
return float(hop.duration.data)
else: else:
key = lambda hop: float(hop['duration']) def key(hop):
return float(hop['duration'])
hops_sorted = sorted(by_use['FWH'], key=key, reverse=True) hops_sorted = sorted(by_use['FWH'], key=key, reverse=True)
hops_sorted.extend(sorted(by_use['Boil'], key=key, reverse=True)) hops_sorted.extend(sorted(by_use['Boil'], key=key, reverse=True))
@ -145,7 +147,7 @@ def ferm_pct(fermentables):
total += float(ferm['amount']) total += float(ferm['amount'])
# Add a pct to each ferm # Add a pct to each ferm
for ferm in fermentables: for ferm in fermentables:
ferm['pct'] = 100*float(ferm['amount'])/total ferm['pct'] = 100 * float(ferm['amount']) / total
return fermentables return fermentables

View file

@ -37,8 +37,8 @@ bp = Blueprint('recipes', __name__, url_prefix='/recipes')
class FermentableForm(Form): class FermentableForm(Form):
"""Form for fermentables. """Form for fermentables.
CSRF is disabled for this form.yeast.form (using `Form as parent class) because it CSRF is disabled for this form.yeast.form (using `Form as parent class)
is never used by itself. because it is never used by itself.
""" """
name = StringField('Name', validators=[DataRequired()]) name = StringField('Name', validators=[DataRequired()])
type = SelectField('Type', validators=[DataRequired()], type = SelectField('Type', validators=[DataRequired()],
@ -67,8 +67,8 @@ class FermentableForm(Form):
class HopForm(Form): class HopForm(Form):
"""Form for hops. """Form for hops.
CSRF is disabled for this form.yeast.form (using `Form as parent class) because it CSRF is disabled for this form.yeast.form (using `Form as parent class)
is never used by itself. because it is never used by itself.
""" """
name = StringField('Name', validators=[DataRequired()]) name = StringField('Name', validators=[DataRequired()])
use = SelectField('Usage', validators=[DataRequired()], use = SelectField('Usage', validators=[DataRequired()],
@ -96,8 +96,8 @@ class HopForm(Form):
class YeastForm(Form): class YeastForm(Form):
"""Form for yeast. """Form for yeast.
CSRF is disabled for this form.yeast.form (using `Form as parent class) because it CSRF is disabled for this form.yeast.form (using `Form as parent class)
is never used by itself. because it is never used by itself.
""" """
name = StringField('Name', validators=[Optional()]) name = StringField('Name', validators=[Optional()])
type = SelectField('Type', default='', type = SelectField('Type', default='',
@ -192,10 +192,10 @@ class RecipeForm(FlaskForm):
recipe['fermentables'] = [f.doc for f in self.fermentables] recipe['fermentables'] = [f.doc for f in self.fermentables]
recipe['hops'] = [h.doc for h in self.hops] recipe['hops'] = [h.doc for h in self.hops]
if ( if (
self.yeast.doc['name'] and self.yeast.doc['name'] and
self.yeast.doc['low_attenuation'] != "None" and self.yeast.doc['low_attenuation'] != "None" and
self.yeast.doc['high_attenuation'] != "None" self.yeast.doc['high_attenuation'] != "None"
): ):
recipe['yeast'] = self.yeast.doc recipe['yeast'] = self.yeast.doc
return recipe return recipe
@ -360,7 +360,7 @@ def update(id):
'Your changes have been lost.'.format(recipe['name']) 'Your changes have been lost.'.format(recipe['name'])
), ),
'danger' 'danger'
) )
return redirect(url_for('recipes.info', id=id)) return redirect(url_for('recipes.info', id=id))
# Copy values from submitted form to the existing recipe and save # Copy values from submitted form to the existing recipe and save
for key, value in form.doc.items(): for key, value in form.doc.items():

View file

@ -65,23 +65,26 @@ def sub_to_doc(sub):
doc['ibu']['low'] = (sub.find('./stats/ibu/low').text doc['ibu']['low'] = (sub.find('./stats/ibu/low').text
if sub.find('./stats/ibu/low') is not None else '0') if sub.find('./stats/ibu/low') is not None else '0')
doc['ibu']['high'] = (sub.find('./stats/ibu/high').text doc['ibu']['high'] = (sub.find('./stats/ibu/high').text
if sub.find('./stats/ibu/high') is not None else '100') if sub.find('./stats/ibu/high') is not None
else '100')
doc['og']['low'] = (sub.find('./stats/og/low').text doc['og']['low'] = (sub.find('./stats/og/low').text
if sub.find('./stats/og/low') is not None else '1.0') if sub.find('./stats/og/low') is not None else '1.0')
doc['og']['high'] = (sub.find('./stats/og/high').text doc['og']['high'] = (sub.find('./stats/og/high').text
if sub.find('./stats/og/high') is not None else '1.2') if sub.find('./stats/og/high') is not None else '1.2')
doc['fg']['low'] = (sub.find('./stats/fg/low').text doc['fg']['low'] = (sub.find('./stats/fg/low').text
if sub.find('./stats/fg/low') is not None else '1.0') if sub.find('./stats/fg/low') is not None else '1.0')
doc['fg']['high'] = (sub.find('./stats/fg/high').text doc['fg']['high'] = (sub.find('./stats/fg/high').text
if sub.find('./stats/fg/high') is not None else '1.2') if sub.find('./stats/fg/high') is not None else '1.2')
doc['srm']['low'] = (sub.find('./stats/srm/low').text doc['srm']['low'] = (sub.find('./stats/srm/low').text
if sub.find('./stats/srm/low') is not None else '0') if sub.find('./stats/srm/low') is not None else '0')
doc['srm']['high'] = (sub.find('./stats/srm/high').text doc['srm']['high'] = (sub.find('./stats/srm/high').text
if sub.find('./stats/srm/high') is not None else '100') if sub.find('./stats/srm/high') is not None
else '100')
doc['abv']['low'] = (sub.find('./stats/abv/low').text doc['abv']['low'] = (sub.find('./stats/abv/low').text
if sub.find('./stats/abv/low') is not None else '0') if sub.find('./stats/abv/low') is not None else '0')
doc['abv']['high'] = (sub.find('./stats/abv/high').text doc['abv']['high'] = (sub.find('./stats/abv/high').text
if sub.find('./stats/abv/high') is not None else '100') if sub.find('./stats/abv/high') is not None
else '100')
return doc return doc
@ -121,10 +124,10 @@ def get_styles_list():
def import_command(): def import_command():
"""CLI command to import BJCP styles.""" """CLI command to import BJCP styles."""
url = current_app.config.get( url = current_app.config.get(
'BJCP_STYLES_URL', 'BJCP_STYLES_URL',
('https://raw.githubusercontent.com/meanphil' ('https://raw.githubusercontent.com/meanphil'
'/bjcp-guidelines-2015/master/styleguide.xml') '/bjcp-guidelines-2015/master/styleguide.xml')
) )
import_styles(url) import_styles(url)
click.echo("Imported BJCP styles.") click.echo("Imported BJCP styles.")
@ -153,11 +156,11 @@ def index():
return render_template( return render_template(
'styles/index.html', 'styles/index.html',
rows=rows[(page-1)*limit:page*limit], rows=rows[(page - 1) * limit:page * limit],
descending=descending, descending=descending,
sort_by=sort_by, sort_by=sort_by,
page=page, page=page,
num_pages=math.ceil(len(rows)/limit), num_pages=math.ceil(len(rows) / limit),
limit=limit limit=limit
) )

View file

@ -20,6 +20,7 @@ import pytest
from humulus import create_app from humulus import create_app
from humulus.couch import build_couch, get_couch, put_doc from humulus.couch import build_couch, get_couch, put_doc
@pytest.fixture @pytest.fixture
def app(): def app():
dbname = 'test_{}'.format(str(uuid.uuid4())) dbname = 'test_{}'.format(str(uuid.uuid4()))
@ -126,7 +127,8 @@ def app():
}) })
# Add a test style # Add a test style
put_doc({'$type': 'style', put_doc({
'$type': 'style',
'_id': '1A', '_id': '1A',
'abv': {'high': '100', 'low': '0'}, 'abv': {'high': '100', 'low': '0'},
'appearance': 'Good looking', 'appearance': 'Good looking',

View file

@ -12,8 +12,6 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
from flask import session
def test_login(client, auth): def test_login(client, auth):
# Test GET # Test GET
@ -43,6 +41,7 @@ def test_login(client, auth):
assert session['logged_in'] assert session['logged_in']
assert session.permanent assert session.permanent
def test_logout(client, auth): def test_logout(client, auth):
# Login # Login
auth.login() auth.login()

View file

@ -12,10 +12,9 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import uuid
from pathlib import Path from pathlib import Path
from humulus.couch import * from humulus.couch import put_doc, get_doc, update_doc, put_designs, get_view
def test_put_doc(app): def test_put_doc(app):
@ -73,7 +72,7 @@ def test_put_designs(app, monkeypatch):
with app.app_context(): with app.app_context():
# Test initial load of designs # Test initial load of designs
monkeypatch.setattr(Path, 'parent', testpath/'assets/initial') monkeypatch.setattr(Path, 'parent', testpath / 'assets/initial')
put_designs() put_designs()
recipes = get_doc('_design/recipes') recipes = get_doc('_design/recipes')
@ -86,7 +85,7 @@ def test_put_designs(app, monkeypatch):
assert recipes['_rev'] == rev assert recipes['_rev'] == rev
# Test that changes can be loaded # Test that changes can be loaded
monkeypatch.setattr(Path, 'parent', testpath/'assets/changed') monkeypatch.setattr(Path, 'parent', testpath / 'assets/changed')
put_designs() put_designs()
recipes = get_doc('_design/recipes') recipes = get_doc('_design/recipes')
assert 'by-date' in recipes['views'] assert 'by-date' in recipes['views']

View file

@ -14,7 +14,8 @@
from decimal import Decimal from decimal import Decimal
from humulus.filters import * from humulus.filters import (recipe_abv, recipe_fg, recipe_ibu, sort_hops,
recipe_ibu_ratio, recipe_og, recipe_srm, ferm_pct)
from humulus.recipes import HopForm from humulus.recipes import HopForm

View file

@ -16,7 +16,7 @@ import json
from decimal import Decimal from decimal import Decimal
from io import BytesIO from io import BytesIO
from humulus.couch import get_db, get_doc, put_doc from humulus.couch import get_doc
from humulus.recipes import FermentableForm, HopForm, RecipeForm, YeastForm from humulus.recipes import FermentableForm, HopForm, RecipeForm, YeastForm
@ -41,7 +41,6 @@ def test_index(client):
response.data response.data
) )
# Test sort by name descending # Test sort by name descending
response = client.get('/recipes/?descending=true&sort_by=name') response = client.get('/recipes/?descending=true&sort_by=name')
assert ( assert (
@ -119,6 +118,7 @@ def test_index(client):
response.data response.data
) )
def test_create(client, app, auth): def test_create(client, app, auth):
"""Test success in creating a recipe document.""" """Test success in creating a recipe document."""
# Test GET without login # Test GET without login
@ -203,7 +203,7 @@ def test_update(client, app, auth):
query_string={'rev': ''}, data=doc) query_string={'rev': ''}, data=doc)
assert response.status_code == 302 assert response.status_code == 302
with client.session_transaction() as session: with client.session_transaction() as session:
flash_message = dict(session['_flashes']).pop('danger', None) flash_message = dict(session['_flashes']).pop('danger', None)
assert 'Update conflict' in flash_message assert 'Update conflict' in flash_message

View file

@ -145,20 +145,21 @@ def test_import_styles(monkeypatch):
monkeypatch.setattr('humulus.styles.put_doc', fake_put_doc) monkeypatch.setattr('humulus.styles.put_doc', fake_put_doc)
import_styles(None) import_styles(None)
assert PutRecorder.doc == {'$type': 'style', assert PutRecorder.doc == {
'_id': '1A', '$type': 'style',
'abv': {'high': '100', 'low': '0'}, '_id': '1A',
'appearance': 'Good looking', 'abv': {'high': '100', 'low': '0'},
'aroma': 'Smelly', 'appearance': 'Good looking',
'fg': {'high': '1.2', 'low': '1.0'}, 'aroma': 'Smelly',
'flavor': 'Good tasting', 'fg': {'high': '1.2', 'low': '1.0'},
'ibu': {'high': '100', 'low': '0'}, 'flavor': 'Good tasting',
'impression': 'Refreshing', 'ibu': {'high': '100', 'low': '0'},
'mouthfeel': 'Good feeling', 'impression': 'Refreshing',
'name': 'Test Style', 'mouthfeel': 'Good feeling',
'og': {'high': '1.2', 'low': '1.0'}, 'name': 'Test Style',
'srm': {'high': '100', 'low': '0'} 'og': {'high': '1.2', 'low': '1.0'},
} 'srm': {'high': '100', 'low': '0'}
}
MockDB.db = {'1A': ''} MockDB.db = {'1A': ''}
PutRecorder.doc = None PutRecorder.doc = None