Merge branch 'master' of github.com:web2py/web2py
This commit is contained in:
@@ -7,11 +7,11 @@
|
||||
# Language from default.py or 'en' (if the file is not found) is used as
|
||||
# a default_language
|
||||
#
|
||||
# See <web2py-root-dir>/router.example.py for parameter's detail
|
||||
# See <web2py-root-dir>/examples/routes.parametric.example.py for parameter's detail
|
||||
#-------------------------------------------------------------------------------------
|
||||
# To enable this route file you must do the steps:
|
||||
#
|
||||
# 1. rename <web2py-root-dir>/router.example.py to routes.py
|
||||
# 1. rename <web2py-root-dir>/examples/routes.parametric.example.py to routes.py
|
||||
# 2. rename this APP/routes.example.py to APP/routes.py
|
||||
# (where APP - is your application directory)
|
||||
# 3. restart web2py (or reload routes in web2py admin interfase)
|
||||
|
||||
@@ -269,53 +269,51 @@ class FastStorage(dict):
|
||||
|
||||
|
||||
class List(list):
|
||||
|
||||
"""
|
||||
Like a regular python list but a[i] if i is out of bounds returns None
|
||||
instead of `IndexOutOfBounds`
|
||||
instead of `IndexOutOfBounds`.
|
||||
"""
|
||||
|
||||
def __call__(self, i, default=DEFAULT, cast=None, otherwise=None):
|
||||
def __call__(self, i, default=None, cast=None, otherwise=None):
|
||||
"""Allows to use a special syntax for fast-check of `request.args()`
|
||||
validity
|
||||
|
||||
Args:
|
||||
i: index
|
||||
default: use this value if arg not found
|
||||
cast: type cast
|
||||
otherwise: can be:
|
||||
|
||||
- None: results in a 404
|
||||
- str: redirect to this address
|
||||
- callable: calls the function (nothing is passed)
|
||||
|
||||
Example:
|
||||
You can use::
|
||||
|
||||
request.args(0,default=0,cast=int,otherwise='http://error_url')
|
||||
request.args(0,default=0,cast=int,otherwise=lambda:...)
|
||||
|
||||
"""
|
||||
value = self[i] or default
|
||||
try:
|
||||
if cast:
|
||||
value = cast(value)
|
||||
if not value and otherwise:
|
||||
raise ValueError('Otherwise will raised.')
|
||||
except (ValueError, TypeError):
|
||||
from http import HTTP, redirect
|
||||
if otherwise is None:
|
||||
raise HTTP(404)
|
||||
elif isinstance(otherwise, str):
|
||||
redirect(otherwise)
|
||||
elif callable(otherwise):
|
||||
return otherwise()
|
||||
else:
|
||||
raise RuntimeError("invalid otherwise")
|
||||
return value
|
||||
|
||||
def __getitem__(self, i):
|
||||
n = len(self)
|
||||
if 0 <= i < n or -n <= i < 0:
|
||||
value = self[i]
|
||||
elif default is DEFAULT:
|
||||
value = None
|
||||
else:
|
||||
value, cast = default, False
|
||||
if cast:
|
||||
try:
|
||||
value = cast(value)
|
||||
except (ValueError, TypeError):
|
||||
from http import HTTP, redirect
|
||||
if otherwise is None:
|
||||
raise HTTP(404)
|
||||
elif isinstance(otherwise, str):
|
||||
redirect(otherwise)
|
||||
elif callable(otherwise):
|
||||
return otherwise()
|
||||
else:
|
||||
raise RuntimeError("invalid otherwise")
|
||||
return value
|
||||
return super(List, self).__getitem__(i)
|
||||
return None
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -13,6 +13,7 @@ fix_sys_path(__file__)
|
||||
|
||||
from storage import Storage
|
||||
from cache import CacheInRam, CacheOnDisk, Cache
|
||||
from gluon.dal import DAL, Field
|
||||
|
||||
oldcwd = None
|
||||
|
||||
@@ -30,6 +31,11 @@ def tearDownModule():
|
||||
if oldcwd:
|
||||
os.chdir(oldcwd)
|
||||
oldcwd = None
|
||||
try:
|
||||
os.unlink('dummy.db')
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class TestCache(unittest.TestCase):
|
||||
@@ -107,7 +113,34 @@ class TestCache(unittest.TestCase):
|
||||
cache.clear(regex=r'a*')
|
||||
self.assertEqual(cache('a1', lambda: 2, 0), 2)
|
||||
self.assertEqual(cache('a2', lambda: 3, 100), 3)
|
||||
return
|
||||
|
||||
def testDALcache(self):
|
||||
s = Storage({'application': 'admin',
|
||||
'folder': 'applications/admin'})
|
||||
cache = Cache(s)
|
||||
db = DAL(check_reserved=['all'])
|
||||
db.define_table('t_a', Field('f_a'))
|
||||
db.t_a.insert(f_a='test')
|
||||
db.commit()
|
||||
a = db(db.t_a.id > 0).select(cache=(cache.ram, 60), cacheable=True)
|
||||
b = db(db.t_a.id > 0).select(cache=(cache.ram, 60), cacheable=True)
|
||||
self.assertEqual(a.as_csv(), b.as_csv())
|
||||
c = db(db.t_a.id > 0).select(cache=(cache.disk, 60), cacheable=True)
|
||||
d = db(db.t_a.id > 0).select(cache=(cache.disk, 60), cacheable=True)
|
||||
self.assertEqual(c.as_csv(), d.as_csv())
|
||||
self.assertEqual(a.as_csv(), c.as_csv())
|
||||
self.assertEqual(b.as_csv(), d.as_csv())
|
||||
e = db(db.t_a.id > 0).select(cache=(cache.disk, 60))
|
||||
f = db(db.t_a.id > 0).select(cache=(cache.disk, 60))
|
||||
self.assertEqual(e.as_csv(), f.as_csv())
|
||||
self.assertEqual(a.as_csv(), f.as_csv())
|
||||
g = db(db.t_a.id > 0).select(cache=(cache.ram, 60))
|
||||
h = db(db.t_a.id > 0).select(cache=(cache.ram, 60))
|
||||
self.assertEqual(g.as_csv(), h.as_csv())
|
||||
self.assertEqual(a.as_csv(), h.as_csv())
|
||||
db.t_a.drop()
|
||||
db.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setUpModule() # pre-python-2.7
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
Unit tests for gluon.dal
|
||||
"""
|
||||
|
||||
import os
|
||||
import unittest
|
||||
from fix_path import fix_sys_path
|
||||
|
||||
@@ -12,8 +13,15 @@ fix_sys_path(__file__)
|
||||
|
||||
from gluon.dal import DAL, Field
|
||||
|
||||
def tearDownModule():
|
||||
try:
|
||||
os.unlink('dummy.db')
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
class TestDALSubclass(unittest.TestCase):
|
||||
|
||||
def testRun(self):
|
||||
from gluon.serializers import custom_json, xml
|
||||
from gluon import sqlhtml
|
||||
@@ -22,19 +30,26 @@ class TestDALSubclass(unittest.TestCase):
|
||||
self.assertEqual(db.serializers['xml'], xml)
|
||||
self.assertEqual(db.representers['rows_render'], sqlhtml.represent)
|
||||
self.assertEqual(db.representers['rows_xml'], sqlhtml.SQLTABLE)
|
||||
db.close()
|
||||
|
||||
def testSerialization(self):
|
||||
import pickle
|
||||
db = DAL(check_reserved=['all'])
|
||||
db.define_table('t_a', Field('f_a'))
|
||||
db.t_a.insert(f_a='test')
|
||||
a = db(db.t_a.id>0).select(cacheable=True)
|
||||
a = db(db.t_a.id > 0).select(cacheable=True)
|
||||
s = pickle.dumps(a)
|
||||
b = pickle.loads(s)
|
||||
self.assertEqual(a.db, b.db)
|
||||
db.t_a.drop()
|
||||
db.close()
|
||||
|
||||
""" TODO:
|
||||
class TestDefaultValidators(unittest.TestCase):
|
||||
def testRun(self):
|
||||
pass
|
||||
"""
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
tearDownModule()
|
||||
|
||||
@@ -125,8 +125,12 @@ class TestList(unittest.TestCase):
|
||||
def test_listcall(self):
|
||||
a = List((1, 2, 3))
|
||||
self.assertEqual(a(1), 2)
|
||||
self.assertEqual(a[1], 2)
|
||||
self.assertEqual(a(3), None)
|
||||
self.assertEqual(a[3], None)
|
||||
self.assertEqual(a(-1), 3)
|
||||
self.assertEqual(a(-5), None)
|
||||
self.assertEqual(a[-5], None)
|
||||
self.assertEqual(a(-5, default='x'), 'x')
|
||||
self.assertEqual(a(-3, cast=str), '1')
|
||||
a.append('1234')
|
||||
|
||||
@@ -62,7 +62,7 @@ do_start()
|
||||
start-stop-daemon --stop --test --quiet --pidfile $PIDFILE \
|
||||
&& return 1
|
||||
|
||||
start-stop-daemon --start --quiet --pidfile $PIDFILE \
|
||||
start-stop-daemon --start --quiet -m --pidfile $PIDFILE \
|
||||
${DAEMON_USER:+--chuid $DAEMON_USER} --chdir $DAEMON_DIR \
|
||||
--background --exec $DAEMON -- $DAEMON_ARGS \
|
||||
|| return 2
|
||||
|
||||
Reference in New Issue
Block a user