Skip to content

Commit

Permalink
Merge master branch into release
Browse files Browse the repository at this point in the history
  • Loading branch information
gi0baro committed Oct 2, 2015
2 parents ff5d26c + 5d2d3dc commit 29c4ce0
Show file tree
Hide file tree
Showing 58 changed files with 953 additions and 1,230 deletions.
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ cache:
python:
- "2.7"
- "pypy"
- "3.3"
- "3.4"
- "pypy3"

install:
- pip install tox>=1.8
Expand Down
12 changes: 12 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
weppy changelog
===============

Version 0.5
-----------

Released on October 2nd 2015, codename Elnath

- Introduced python 3 support
- Introduced multiple inheritance support on `Model` class
- Added optional keyed arguments support to `HasManyViaSet.add` for additional
columns on join tables
- Minor bugfixes


Version 0.4
-----------

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ weppy is currently released in beta stage.
* That the code may contain *noteworthy* bugs
* That you can use it on production but cannot blame the developers if something goes wrong

Also, please keep in mind that currently weppy doesn't provide support to python 3.
weppy provides support for python 2.7, 3.3 and 3.4 versions.

## How can I help?

Expand Down
1 change: 1 addition & 0 deletions docs/dal.md
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ Since the object is a specific set of your database responding to a query, you h
| update | update all the records in the set |
| validate\_and\_update | perform a validation and update the records |
| delete | delete all the records in the set |
| where | return a subset given additional queries |
| add | add a row to the set |

As you observed, until now we used a shortcut for the `select` method just calling the set:
Expand Down
4 changes: 4 additions & 0 deletions docs/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def user(username):

@app.expose('/double/<int:number>')
def double(number):
number = int(number)
return "%d * 2 = %d" % (number, number*2)
```

Expand All @@ -64,6 +65,9 @@ It's quite simple, isn't it? And which are the types of variables you can use? H
| alpha | accepts strings containing only literals |
| any | accepts any path (also with slashes) |

> **Note:**
> the type specification won't change the type of the input variables, that will always be strings (as they are parts of the url). If you want to use these parts as real integers or dates, you have to parse them depending on your needs.
So basically, if we try to open the url for the `double` function of the last example with a string, like '/double/foo', it won't match and weppy will return a 404 error.

> – Ok, fine. But, what if I want a conditional argument for my function?
Expand Down
9 changes: 9 additions & 0 deletions docs/upgrading.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@ or *pip*:
$ pip install -U weppy
```

Version 0.5
-----------

weppy 0.5 introduces python 3 support. Fortunately, there are no changes in the main code that require changes in your application code.

> **Note:**
> Internally, weppy dropped an old library for utf8 utilities, needed for the translator. Since this part of weppy had been rewritten for python 3 support, the usage of that library (`Utf8` class) is no longer required. If you used it in your own code, please make the appropriate changes in order to drop it.

Version 0.4
-----------

Expand Down
14 changes: 12 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,19 @@
"""

import re
import ast
from setuptools import setup

_version_re = re.compile(r'__version__\s+=\s+(.*)')

with open('weppy/__init__.py', 'rb') as f:
version = str(ast.literal_eval(_version_re.search(
f.read().decode('utf-8')).group(1)))

setup(
name='weppy',
version='0.4.2',
version=version,
url='http://github.com/gi0baro/weppy/',
license='BSD',
author='Giovanni Barillari',
Expand All @@ -33,7 +42,7 @@
install_requires=[
'click>=0.6',
'pyaes',
'pyDAL>=15.07',
'pyDAL>=15.9',
'pyyaml'
],
classifiers=[
Expand All @@ -44,6 +53,7 @@
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 3',
'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
'Topic :: Software Development :: Libraries :: Python Modules'
],
Expand Down
4 changes: 4 additions & 0 deletions tests/languages/de.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
{
"partly cloudy": u"teilweise bewölkt"
}
4 changes: 4 additions & 0 deletions tests/languages/it.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
{
"partly cloudy": "nuvolosità variabile"
}
4 changes: 4 additions & 0 deletions tests/languages/ru.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
{
u"partly cloudy": u"переменная облачность"
}
20 changes: 20 additions & 0 deletions tests/templates/layout.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
{{include_meta}}
{{include_helpers}}
{{include_static 'style.css'}}
</head>
<body>
<div class="page">
<a href="/" class="title"><h1>Test</h1></a>
<div class="nav">
<a href="/">{{=current.T("partly cloudy")}}</a>
</div>
{{block main}}
{{include}}
{{end}}
</div>
</body>
</html>
10 changes: 10 additions & 0 deletions tests/templates/test.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{{extend 'layout.html'}}

<ul class="posts">
{{for post in posts:}}
<li>
<h2>{{=post['title']}}</h2>
<hr />
</li>
{{pass}}
</ul>
30 changes: 29 additions & 1 deletion tests/test_dal.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,21 @@ class Appointment(Model):
date = Field('datetime')


class User(Model):
name = Field()
has_many('memberships', {'organizations': {'via': 'memberships'}})


class Organization(Model):
name = Field()
has_many('memberships', {'users': {'via': 'memberships'}})


class Membership(Model):
belongs_to('user', 'organization')
role = Field()


class House(Model):
name = Field()

Expand Down Expand Up @@ -226,7 +241,8 @@ def db():
db = DAL(app, config=sdict(uri='sqlite://dal.db'))
db.define_models([
Stuff, Person, Thing, Feature, Price, Doctor, Patient, Appointment,
House, Mouse, NeedSplit, Zoo, Animal, Elephant
User, Organization, Membership, House, Mouse, NeedSplit, Zoo, Animal,
Elephant
])
return db

Expand Down Expand Up @@ -354,6 +370,18 @@ def test_relations(db):
assert len(doctor.appointments()) == 1
assert len(patient.doctors()) == 1
assert len(patient.appointments()) == 1
joe = db.User.insert(name='joe')
jim = db.User.insert(name='jim')
org = db.Organization.insert(name='')
org.users.add(joe, role='admin')
org.users.add(jim, role='manager')
assert len(org.users()) == 2
assert len(joe.organizations()) == 1
assert len(jim.organizations()) == 1
assert joe.organizations().first().id == org
assert jim.organizations().first().id == org
assert joe.memberships().first().role == 'admin'
assert jim.memberships().first().role == 'manager'


def test_tablenames(db):
Expand Down
140 changes: 140 additions & 0 deletions tests/test_templates.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# -*- coding: utf-8 -*-
"""
tests.templates
---------------
Test weppy templating module
:copyright: (c) 2015 by Giovanni Barillari
:license: BSD, see LICENSE for more details.
"""

import pytest
from weppy import App
from weppy.globals import current
from weppy.templating import render
from weppy.templating.core import Templater


@pytest.fixture(scope='module')
def app():
app = App(__name__)
return app


def test_define(app):
templater = Templater(app)
assert templater.render(source='{{=1}}', filename='test1') == '1'
assert templater.render(
source='{{=a}}', filename='test2',
context={'a': 'nuvolosità variabile'}
) == 'nuvolosità variabile'
assert templater.render(
source='{{=a}}', path='templates', filename='test3',
context={'a': u'nuvolosità variabile'}
) == 'nuvolosità variabile'
assert templater.render(
source='{{=a}}', filename='test4',
context={'a': [i for i in range(0, 5)]}
) == "[0, 1, 2, 3, 4]"


# def test_superblock(app):
# pass


def test_helpers(app):
templater = Templater(app)
r = templater.render(source="{{include_helpers}}", filename='testh')
assert r == '<script type="text/javascript" ' + \
'src="/__weppy__/jquery.min.js"></script>\n' + \
'<script type="text/javascript" ' + \
'src="/__weppy__/helpers.js"></script>'


def test_meta(app):
current.initialize({
'PATH_INFO': '/', 'wpp.appnow': '', 'wpp.now.utc': '',
'wpp.now.local': '', 'wpp.application': ''})
current.response.meta.foo = "bar"
current.response.meta_prop.foo = "bar"
templater = Templater(app)
r = templater.render(
source="{{include_meta}}", filename='mtest',
context={'current': current})
assert r == '<meta name="foo" content="bar" />\n' + \
'<meta property="foo" content="bar" />\n'


def test_static(app):
templater = Templater(app)
s = "{{include_static 'foo.js'}}\n{{include_static 'bar.css'}}"
r = templater.render(source=s, filename="stest")
assert r == '<script type="text/javascript" src="/static/foo.js">' + \
'</script>\n<link rel="stylesheet" href="/static/bar.css" ' + \
'type="text/css" />'


def test_pycode(app):
templater = Templater(app)
#: test if block
s = "{{if a == 1:}}foo{{elif a == 2:}}bar{{else:}}foobar{{pass}}"
r = templater.render(source=s, filename="ptest1", context={'a': 1})
assert r == "foo"
r = templater.render(source=s, filename="ptest1", context={'a': 2})
assert r == "bar"
r = templater.render(source=s, filename="ptest1", context={'a': 25})
assert r == "foobar"
#: test for block
s = "{{for i in range(0, 5):}}{{=i}}\n{{pass}}"
r = templater.render(source=s, filename="ptest2")
assert r == "0\n1\n2\n3\n4\n"


rendered_value = """
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<meta name="foo" content="bar" />
<meta property="foo" content="bar" />
<script type="text/javascript" src="/__weppy__/jquery.min.js"></script>
<script type="text/javascript" src="/__weppy__/helpers.js"></script>
<link rel="stylesheet" href="/static/style.css" type="text/css" />
</head>
<body>
<div class="page">
<a href="/" class="title"><h1>Test</h1></a>
<div class="nav">
<a href="/">nuvolosità variabile</a>
</div>
<ul class="posts">
<li>
<h2>foo</h2>
<hr />
</li>
<li>
<h2>bar</h2>
<hr />
</li>
</ul>
</div>
</body>
</html>
"""


def test_render(app):
current._language = 'it'
r = render(
app, app.template_path, 'test.html', {
'current': current, 'posts': [{'title': 'foo'}, {'title': 'bar'}]
}
)
assert "".join([l.strip() for l in r.splitlines()]) == \
"".join([l.strip() for l in rendered_value.splitlines()])


# def test_cache(app):
# pass
Loading

0 comments on commit 29c4ce0

Please sign in to comment.