示例#1
0
    def test_cookies(self):
        changer = util.MtimeChanger()
        index = os.path.join(self.app_dir, 'index.ks')
        app = Keystone(self.app_dir)

        with file(index, 'w') as fp:
            fp.write(
                'set_cookie("name", "value")\n----\n<strong>this is HTML</strong>\n'
            )

        req = Request(wsgi_environ('GET', '/'))
        template = app.engine.get_template(index)
        response = app.render_keystone(req, template)
        self.assertEqual(response.headers['Set-Cookie'], 'name=value; Path=/')

        with changer.change_times(file(index, 'w')) as fp:
            fp.write(
                'delete_cookie("name")\n----\n<strong>this is HTML</strong>\n')

        req = Request(wsgi_environ('GET', '/'))
        template = app.engine.get_template(index)
        response = app.render_keystone(req, template)
        self.assertEqual(
            response.headers['Set-Cookie'],
            'name=; expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Path=/')
示例#2
0
    def test_render_static(self):
        static = os.path.join(self.app_dir, 'base.css')

        with file(static, 'w') as fp:
            fp.write('* { background-color: white }\n')

        app = Keystone(self.app_dir)
        req = Request(wsgi_environ('POST', '/base.css'))

        fileobj = file(static, 'rb')
        self.assertRaises(http.MethodNotAllowed, app.render_static, req, fileobj)

        req = Request(wsgi_environ('GET', '/base.css'))
        fileobj.seek(0, 0)
        response = app.render_static(req, fileobj)
        self.assertEqual(response.data, '* { background-color: white }\n')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.content_length, 30)
        self.assertEqual(response.mimetype, 'text/css')
        self.assertTrue('ETag' in response.headers)
        self.assertTrue('Last-Modified' in response.headers)
        self.assertTrue('Expires' in response.headers)

        last_modified = response.headers['Last-Modified']

        req = Request(wsgi_environ('GET', '/base.css', headers={'If-Modified-Since': last_modified}))
        response = app.render_static(req, fileobj)
        self.assertEqual(response.data, '')
        self.assertEqual(response.status_code, 304)
示例#3
0
    def test_render_static(self):
        static = os.path.join(self.app_dir, 'base.css')

        with file(static, 'w') as fp:
            fp.write('* { background-color: white }\n')

        app = Keystone(self.app_dir)
        req = Request(wsgi_environ('POST', '/base.css'))

        fileobj = file(static, 'rb')
        self.assertRaises(http.MethodNotAllowed, app.render_static, req,
                          fileobj)

        req = Request(wsgi_environ('GET', '/base.css'))
        fileobj.seek(0, 0)
        response = app.render_static(req, fileobj)
        self.assertEqual(response.data, '* { background-color: white }\n')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.content_length, 30)
        self.assertEqual(response.mimetype, 'text/css')
        self.assertTrue('ETag' in response.headers)
        self.assertTrue('Last-Modified' in response.headers)
        self.assertTrue('Expires' in response.headers)

        last_modified = response.headers['Last-Modified']

        req = Request(
            wsgi_environ('GET',
                         '/base.css',
                         headers={'If-Modified-Since': last_modified}))
        response = app.render_static(req, fileobj)
        self.assertEqual(response.data, '')
        self.assertEqual(response.status_code, 304)
示例#4
0
    def test_headers(self):
        index = os.path.join(self.app_dir, 'index.ks')
        app = Keystone(self.app_dir)

        with file(index, 'w') as fp:
            fp.write('headers.set("X-Key", "value")\n----\n<strong>this is HTML</strong>\n')

        req = Request(wsgi_environ('GET', '/'))
        template = app.engine.get_template(index)
        response = app.render_keystone(req, template)
        self.assertTrue('X-Key' in response.headers)
        self.assertEqual(response.headers['X-Key'], 'value')
示例#5
0
    def test_score_candidates(self):
        cases = [
            ('foo', ['%x.ks', 'foo.ks'], [0, 1]),
            ('bar', ['%x.ks', '%y.ks'], [0, 0]),
            ('baz', ['baz.ks'], [1]),
            ('foo/bar', ['%y/%x.ks', 'foo/%x.ks', '%y/bar.ks'], [0, 1, 1]),
            ('foo/', ['%y/%x.ks', 'foo/%x.ks', '%y/index.ks'], [0, 1, 2]),
            ('foo/baz', ['%x/%y.ks', 'foo/%y.ks', '%x/baz', '%x/baz.ks'], [0, 1, 1, 1]),
        ]

        app = Keystone()
        for path, candidates, expected in cases:
            scores = app._score_candidates(path, candidates)
            self.assertEqual(scores, expected, 'wrong scores for %r: %r, expected %r' % (path, scores, expected))
示例#6
0
    def test_headers(self):
        index = os.path.join(self.app_dir, 'index.ks')
        app = Keystone(self.app_dir)

        with file(index, 'w') as fp:
            fp.write(
                'headers.set("X-Key", "value")\n----\n<strong>this is HTML</strong>\n'
            )

        req = Request(wsgi_environ('GET', '/'))
        template = app.engine.get_template(index)
        response = app.render_keystone(req, template)
        self.assertTrue('X-Key' in response.headers)
        self.assertEqual(response.headers['X-Key'], 'value')
示例#7
0
def serve(parser, args):
    from keystone.main import Keystone
    import werkzeug.serving

    if args.paas == 'heroku':
        args.host = '0.0.0.0'
        args.port = int(os.environ['PORT'])
        args.app_dir = os.getcwd()

    if args.debug:
        args.threaded = False

    extra = {}
    if args.static_expires:
        extra['static_expires'] = int(args.static_expires)

    app = Keystone(app_dir=args.app_dir, **extra)
    return werkzeug.serving.run_simple(
        hostname=args.host,
        port=args.port,
        application=app,
        use_reloader=args.debug,
        use_debugger=args.debug,
        use_evalex=args.debug,
        threaded=args.threaded,
    )
示例#8
0
    def test_template_filters(self):
        with file(os.path.join(self.app_dir, 'startup.py'), 'w') as fp:
            fp.write('from keystone.render import template_filter\n')
            fp.write('@template_filter\n')
            fp.write('def silly(value):\n')
            fp.write('    return "silly"\n')

        with file(os.path.join(self.app_dir, 'index.ks'), 'w') as fp:
            fp.write('{{novar|silly}}')

        app = Keystone(self.app_dir)
        req = Request(wsgi_environ('GET', '/'))

        response = app.dispatch(req)
        output = ''.join(response.response)
        self.assertTrue(isinstance(response, BaseResponse))
        self.assertEqual(output, 'silly')
示例#9
0
    def test_score_candidates(self):
        cases = [
            ('foo', ['%x.ks', 'foo.ks'], [0, 1]),
            ('bar', ['%x.ks', '%y.ks'], [0, 0]),
            ('baz', ['baz.ks'], [1]),
            ('foo/bar', ['%y/%x.ks', 'foo/%x.ks', '%y/bar.ks'], [0, 1, 1]),
            ('foo/', ['%y/%x.ks', 'foo/%x.ks', '%y/index.ks'], [0, 1, 2]),
            ('foo/baz', ['%x/%y.ks', 'foo/%y.ks', '%x/baz',
                         '%x/baz.ks'], [0, 1, 1, 1]),
        ]

        app = Keystone()
        for path, candidates, expected in cases:
            scores = app._score_candidates(path, candidates)
            self.assertEqual(
                scores, expected, 'wrong scores for %r: %r, expected %r' %
                (path, scores, expected))
示例#10
0
    def test_template_filters(self):
        with file(os.path.join(self.app_dir, 'startup.py'), 'w') as fp:
            fp.write('from keystone.render import template_filter\n')
            fp.write('@template_filter\n')
            fp.write('def silly(value):\n')
            fp.write('    return "silly"\n')

        with file(os.path.join(self.app_dir, 'index.ks'), 'w') as fp:
            fp.write('{{novar|silly}}')

        app = Keystone(self.app_dir)
        req = Request(wsgi_environ('GET', '/'))

        response = app.dispatch(req)
        output = ''.join(response.response)
        self.assertTrue(isinstance(response, BaseResponse))
        self.assertEqual(output, 'silly')
示例#11
0
    def test_render_keystone(self):
        changer = util.MtimeChanger()
        index = os.path.join(self.app_dir, 'index.ks')

        with file(index, 'w') as fp:
            fp.write('# this is python\n----\n<strong>this is HTML</strong>\n')

        app = Keystone(self.app_dir)
        template = app.engine.get_template(index)

        req = Request(wsgi_environ('GET', '/'))
        response = app.render_keystone(req, template)

        self.assertEqual(response.data, '<strong>this is HTML</strong>')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.mimetype, 'text/html')
        self.assertTrue('Content-Length' not in response.headers)
        self.assertTrue('ETag' not in response.headers)
        self.assertTrue('Last-Modified' not in response.headers)
        self.assertTrue('Expires' not in response.headers)
        self.assertTrue('Cache-Control' not in response.headers)
        self.assertTrue('Set-Cookie' not in response.headers)

        for method in ('GET', 'POST', 'HEAD', 'OPTIONS', 'PUT', 'DELETE'):
            # none of these should raise
            req = Request(wsgi_environ(method, '/'))
            app.render_keystone(req, template)


        with changer.change_times(file(index, 'w')) as fp:
            fp.write('return_response("hello, world")\n----\n<strong>this is HTML</strong>\n')

        req = Request(wsgi_environ('GET', '/'))
        template = app.engine.get_template(index)
        response = app.render_keystone(req, template)

        self.assertEqual(response.data, 'hello, world')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.mimetype, 'text/html')
        self.assertTrue('Content-Length' not in response.headers)
        self.assertTrue('ETag' not in response.headers)
        self.assertTrue('Last-Modified' not in response.headers)
        self.assertTrue('Expires' not in response.headers)
        self.assertTrue('Cache-Control' not in response.headers)
        self.assertTrue('Set-Cookie' not in response.headers)
示例#12
0
    def test_startup_module(self):
        startup = os.path.join(self.app_dir, 'startup.py')
        with file(startup, 'w') as fp:
            fp.write('# do nothing\n')

        Keystone(self.app_dir)

        self.assertTrue('startup' in sys.modules, 'startup.py was not loaded')
        self.assertEqual(sys.modules['startup'].__file__, startup,
                         'wrong startup.py was loaded')
示例#13
0
    def test_cookies(self):
        changer = util.MtimeChanger()
        index = os.path.join(self.app_dir, 'index.ks')
        app = Keystone(self.app_dir)

        with file(index, 'w') as fp:
            fp.write('set_cookie("name", "value")\n----\n<strong>this is HTML</strong>\n')

        req = Request(wsgi_environ('GET', '/'))
        template = app.engine.get_template(index)
        response = app.render_keystone(req, template)
        self.assertEqual(response.headers['Set-Cookie'], 'name=value; Path=/')

        with changer.change_times(file(index, 'w')) as fp:
            fp.write('delete_cookie("name")\n----\n<strong>this is HTML</strong>\n')

        req = Request(wsgi_environ('GET', '/'))
        template = app.engine.get_template(index)
        response = app.render_keystone(req, template)
        self.assertEqual(response.headers['Set-Cookie'], 'name=; expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Path=/')
示例#14
0
    def test_dispatch(self):
        index = os.path.join(self.app_dir, 'index.ks')
        static = os.path.join(self.app_dir, 'base.css')

        app = Keystone(self.app_dir)
        req = Request(wsgi_environ('GET', '/'))

        response = app.dispatch(req)
        self.assertTrue(isinstance(response, BaseResponse), 'dispatch on missing did not return a Response')
        self.assertEqual(response.status_code, 404, 'missing did not get a 404 HTTPException (got %d)' % response.status_code)

        changer = util.MtimeChanger()

        with changer.change_times(file(index, 'w')) as fp:
            fp.write('raise Exception("blah")\n----\n<strong>this is HTML</strong>\n')

        response = app.dispatch(req)
        self.assertTrue(isinstance(response, BaseResponse), 'dispatch on exception did not return a Response')
        self.assertEqual(response.status_code, 500, 'error did not get a 500 HTTPException (got %d)' % response.status_code)

        with changer.change_times(file(index, 'w')) as fp:
            fp.write('raise http.SeeOther("/foo")\n----\n<strong>this is HTML</strong>\n')

        response = app.dispatch(req)
        self.assertTrue(isinstance(response, BaseResponse), 'dispatch on HTTPException did not return a Response')
        self.assertEqual(response.status_code, 303, 'redirect (see other) did not get a 303 HTTPException (got %d)' % response.status_code)

        with changer.change_times(file(index, 'w')) as fp:
            fp.write('<strong>this is HTML</strong>\n')

        response = app.dispatch(req)
        self.assertTrue(isinstance(response, BaseResponse), 'dispatch on html-only template did not return a Response')
        self.assertEqual(response.status_code, 200, 'dispatch to template did not get a 200 status (got %d)' % response.status_code)

        with changer.change_times(file(index, 'w')) as fp:
            fp.write('# this is python\n----\n<strong>this is HTML</strong>\n')

        response = app.dispatch(req)
        self.assertTrue(isinstance(response, BaseResponse), 'dispatch on mixed template did not return a Response')
        self.assertEqual(response.status_code, 200, 'dispatch to template did not get a 200 status (got %d)' % response.status_code)

        with changer.change_times(file(static, 'w')) as fp:
            fp.write('* { background-color: white }\n')

        req = Request(wsgi_environ('GET', '/base.css'))
        response = app.dispatch(req)
        self.assertTrue(isinstance(response, BaseResponse), 'dispatch on static did not return a Response')
        self.assertEqual(response.status_code, 200, 'dispatch to static did not get a 200 status (got %d)' % response.status_code)
示例#15
0
    def test_app_is_wsgi(self):
        app = Keystone(self.app_dir)

        self.assertTrue(callable(app), 'Keystone object should be callable')
        self.assertEqual(len(getargspec(app.__call__)[0]), 3,
                         'Keystone should take 2 arguments')
        self.assertTrue(
            getargspec(app.__call__)[1] is None,
            'viewfunc should take no varargs')
        self.assertTrue(
            getargspec(app.__call__)[2] is None,
            'viewfunc should take no kwargs')
        self.assertTrue(
            getargspec(app.__call__)[3] is None,
            'viewfunc should have no defaults')

        # test that a simple call gets a valid response
        client = Client(app, BaseResponse)
        response = client.get('/')

        self.assertEqual(response.status_code, 404,
                         'WSGI call did not get 404 for request to empty app')
示例#16
0
    def test_render_keystone(self):
        changer = util.MtimeChanger()
        index = os.path.join(self.app_dir, 'index.ks')

        with file(index, 'w') as fp:
            fp.write('# this is python\n----\n<strong>this is HTML</strong>\n')

        app = Keystone(self.app_dir)
        template = app.engine.get_template(index)

        req = Request(wsgi_environ('GET', '/'))
        response = app.render_keystone(req, template)

        self.assertEqual(response.data, '<strong>this is HTML</strong>')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.mimetype, 'text/html')
        self.assertTrue('Content-Length' not in response.headers)
        self.assertTrue('ETag' not in response.headers)
        self.assertTrue('Last-Modified' not in response.headers)
        self.assertTrue('Expires' not in response.headers)
        self.assertTrue('Cache-Control' not in response.headers)
        self.assertTrue('Set-Cookie' not in response.headers)

        for method in ('GET', 'POST', 'HEAD', 'OPTIONS', 'PUT', 'DELETE'):
            # none of these should raise
            req = Request(wsgi_environ(method, '/'))
            app.render_keystone(req, template)

        with changer.change_times(file(index, 'w')) as fp:
            fp.write(
                'return_response("hello, world")\n----\n<strong>this is HTML</strong>\n'
            )

        req = Request(wsgi_environ('GET', '/'))
        template = app.engine.get_template(index)
        response = app.render_keystone(req, template)

        self.assertEqual(response.data, 'hello, world')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.mimetype, 'text/html')
        self.assertTrue('Content-Length' not in response.headers)
        self.assertTrue('ETag' not in response.headers)
        self.assertTrue('Last-Modified' not in response.headers)
        self.assertTrue('Expires' not in response.headers)
        self.assertTrue('Cache-Control' not in response.headers)
        self.assertTrue('Set-Cookie' not in response.headers)
示例#17
0
    def test_find(self):
        app_contents = {
            'index.ks': 'index',
            'pageA.ks': 'pageA',
            '%widlcard.ks': '----\n{{wildcard}}',
            'file.txt': 'file 1',
            '_base.html': 'hello',
            'something.py': '# blah',
            'something.pyc': '# blah',
            'something.pyo': '# blah',
            '.dotfile': 'dotfile',
            'subdir': {
                'index.ks': 'subdir index',
                'pageA.ks': 'subdir pageA',
                'file.txt': 'file 2',
            },
            '%wildcard': {
                'index.ks': '----\n{{wildcard}} index',
                'pageA.ks': '----\n{{wildcard}} pageA',
                '%wildcard2.ks': '----\n{{wildcard}} {{wildcard2}}',
                'file.txt': 'wildcard file',
            },
            'baddir': {
                '%wildcardA.ks': '----\n{{wildcardA}} A',
                '%wildcardB.ks': '----\n{{wildcardB}} B',
            },
            'static': {
                'file.txt': 'file 3'
            }
        }

        def write_files(root_path, tree):
            for filename, contents in tree.iteritems():
                if isinstance(contents, dict):
                    subdir = os.path.join(root_path, filename)
                    os.makedirs(subdir)
                    write_files(subdir, contents)
                else:
                    with file(os.path.join(root_path, filename), 'w') as fp:
                        fp.write(contents)

        write_files(self.app_dir, app_contents)

        cases = [
            {
                'path': '/',
                'type': Template,
                'body': 'index'
            },
            {
                'path': '/index',
                'type': Template,
                'body': 'index'
            },
            {
                'path': '/index.ks',
                'type': type(None)
            },
            {
                'path': '/something.py',
                'type': type(None)
            },
            {
                'path': '/something.pyc',
                'type': type(None)
            },
            {
                'path': '/something.pyo',
                'type': type(None)
            },
            {
                'path': '/_base.html',
                'type': type(None)
            },
            {
                'path': '/.dotfile',
                'type': type(None)
            },
            {
                'path': '/pageA',
                'type': Template,
                'body': 'pageA'
            },
            {
                'path': '/somePage',
                'type': Template,
                'body': '{{wildcard}}'
            },
            {
                'path': '/anotherPage',
                'type': Template,
                'body': '{{wildcard}}'
            },
            {
                'path': '/file.txt',
                'type': file,
                'contents': 'file 1'
            },

            # TODO: not sure that this is what we should be returning
            # here. options are:
            #
            #  1. return None (404)
            #  2. return the same as /subdir/
            #  3. redirect to /subdir/
            {
                'path': '/subdir',
                'type': Template,
                'body': '{{wildcard}}'
            },
            {
                'path': '/subdir/',
                'type': Template,
                'body': 'subdir index'
            },
            {
                'path': '/subdir/index',
                'type': Template,
                'body': 'subdir index'
            },
            {
                'path': '/subdir/index/',
                'type': type(None)
            },
            {
                'path': '/subdir/pageA',
                'type': Template,
                'body': 'subdir pageA'
            },
            {
                'path': '/subdir/file.txt',
                'type': file,
                'contents': 'file 2'
            },
            {
                'path': '/anydir',
                'type': Template,
                'body': '{{wildcard}}'
            },
            {
                'path': '/anydir/',
                'type': Template,
                'body': '{{wildcard}} index'
            },
            {
                'path': '/anydir/index',
                'type': Template,
                'body': '{{wildcard}} index'
            },
            {
                'path': '/anydir/pageA',
                'type': Template,
                'body': '{{wildcard}} pageA'
            },
            {
                'path': '/anydir/pagename',
                'type': Template,
                'body': '{{wildcard}} {{wildcard2}}'
            },
            {
                'path': '/anydir/pagename/',
                'type': type(None)
            },
            {
                'path': '/anydir/file.txt',
                'type': file,
                'contents': 'wildcard file'
            },
            {
                'path': '/other/file.txt',
                'type': file,
                'contents': 'wildcard file'
            },
            {
                'path': '/baddir/foo',
                'type': Template,
                'body': '{{wildcardA}} A',
                'warns': True
            },
        ]

        app = Keystone(self.app_dir)
        for testcase in cases:
            path = testcase['path']
            with util.WarningCatcher(UserWarning) as wc:
                found = app._find(path)
                if 'warns' in testcase:
                    self.assertTrue(
                        wc.has_warning(UserWarning),
                        '_find(%r) should have warned about multiple matches' %
                        path)

            self.assertEqual(
                type(found), testcase['type'],
                '_find(%r) returned %s, expected %s' %
                (path, type(found), testcase['type']))

            if isinstance(found, Template):
                self.assertEqual(
                    found.body, testcase['body'],
                    '_find(%r).body is %r, expected %r' %
                    (path, found.body, testcase['body']))
            elif isinstance(found, file):
                contents = found.read()
                self.assertEqual(
                    contents, testcase['contents'],
                    '_find(%r).read() is %r, expected %r' %
                    (path, contents, testcase['contents']))
示例#18
0
    def test_find(self):
        app_contents = {
            'index.ks': 'index',
            'pageA.ks': 'pageA',
            '%widlcard.ks': '----\n{{wildcard}}',
            'file.txt': 'file 1',
            '_base.html': 'hello',
            'something.py': '# blah',
            'something.pyc': '# blah',
            'something.pyo': '# blah',
            '.dotfile': 'dotfile',
            'subdir': {
                'index.ks': 'subdir index',
                'pageA.ks': 'subdir pageA',
                'file.txt': 'file 2',
            },
            '%wildcard': {
                'index.ks': '----\n{{wildcard}} index',
                'pageA.ks': '----\n{{wildcard}} pageA',
                '%wildcard2.ks': '----\n{{wildcard}} {{wildcard2}}',
                'file.txt': 'wildcard file',
            },
            'baddir': {
                '%wildcardA.ks': '----\n{{wildcardA}} A',
                '%wildcardB.ks': '----\n{{wildcardB}} B',
            },
            'static': {
                'file.txt': 'file 3'
            }
        }

        def write_files(root_path, tree):
            for filename, contents in tree.iteritems():
                if isinstance(contents, dict):
                    subdir = os.path.join(root_path, filename)
                    os.makedirs(subdir)
                    write_files(subdir, contents)
                else:
                    with file(os.path.join(root_path, filename), 'w') as fp:
                        fp.write(contents)

        write_files(self.app_dir, app_contents)

        cases = [
            {'path': '/', 'type': Template, 'body': 'index'},
            {'path': '/index', 'type': Template, 'body': 'index'},
            {'path': '/index.ks', 'type': type(None)},

            {'path': '/something.py', 'type': type(None)},
            {'path': '/something.pyc', 'type': type(None)},
            {'path': '/something.pyo', 'type': type(None)},
            {'path': '/_base.html', 'type': type(None)},
            {'path': '/.dotfile', 'type': type(None)},

            {'path': '/pageA', 'type': Template, 'body': 'pageA'},

            {'path': '/somePage', 'type': Template, 'body': '{{wildcard}}'},
            {'path': '/anotherPage', 'type': Template, 'body': '{{wildcard}}'},

            {'path': '/file.txt', 'type': file, 'contents': 'file 1'},

            # TODO: not sure that this is what we should be returning
            # here. options are:
            #
            #  1. return None (404)
            #  2. return the same as /subdir/
            #  3. redirect to /subdir/
            {'path': '/subdir', 'type': Template, 'body': '{{wildcard}}'},

            {'path': '/subdir/', 'type': Template, 'body': 'subdir index'},
            {'path': '/subdir/index', 'type': Template, 'body': 'subdir index'},
            {'path': '/subdir/index/', 'type': type(None)},

            {'path': '/subdir/pageA', 'type': Template, 'body': 'subdir pageA'},
            {'path': '/subdir/file.txt', 'type': file, 'contents': 'file 2'},

            {'path': '/anydir', 'type': Template, 'body': '{{wildcard}}'},

            {'path': '/anydir/', 'type': Template, 'body': '{{wildcard}} index'},
            {'path': '/anydir/index', 'type': Template, 'body': '{{wildcard}} index'},
            {'path': '/anydir/pageA', 'type': Template, 'body': '{{wildcard}} pageA'},

            {'path': '/anydir/pagename', 'type': Template, 'body': '{{wildcard}} {{wildcard2}}'},
            {'path': '/anydir/pagename/', 'type': type(None)},

            {'path': '/anydir/file.txt', 'type': file, 'contents': 'wildcard file'},
            {'path': '/other/file.txt', 'type': file, 'contents': 'wildcard file'},

            {'path': '/baddir/foo', 'type': Template, 'body': '{{wildcardA}} A', 'warns': True},
        ]

        app = Keystone(self.app_dir)
        for testcase in cases:
            path = testcase['path']
            with util.WarningCatcher(UserWarning) as wc:
                found = app._find(path)
                if 'warns' in testcase:
                    self.assertTrue(wc.has_warning(UserWarning), '_find(%r) should have warned about multiple matches' % path)

            self.assertEqual(type(found), testcase['type'], '_find(%r) returned %s, expected %s' % (path, type(found), testcase['type']))

            if isinstance(found, Template):
                self.assertEqual(found.body, testcase['body'], '_find(%r).body is %r, expected %r' % (path, found.body, testcase['body']))
            elif isinstance(found, file):
                contents = found.read()
                self.assertEqual(contents, testcase['contents'], '_find(%r).read() is %r, expected %r' % (path, contents, testcase['contents']))
示例#19
0
from keystone.main import Keystone
application = Keystone("/app")
示例#20
0
    def test_dispatch(self):
        index = os.path.join(self.app_dir, 'index.ks')
        static = os.path.join(self.app_dir, 'base.css')

        app = Keystone(self.app_dir)
        req = Request(wsgi_environ('GET', '/'))

        response = app.dispatch(req)
        self.assertTrue(isinstance(response, BaseResponse),
                        'dispatch on missing did not return a Response')
        self.assertEqual(
            response.status_code, 404,
            'missing did not get a 404 HTTPException (got %d)' %
            response.status_code)

        changer = util.MtimeChanger()

        with changer.change_times(file(index, 'w')) as fp:
            fp.write(
                'raise Exception("blah")\n----\n<strong>this is HTML</strong>\n'
            )

        response = app.dispatch(req)
        self.assertTrue(isinstance(response, BaseResponse),
                        'dispatch on exception did not return a Response')
        self.assertEqual(
            response.status_code, 500,
            'error did not get a 500 HTTPException (got %d)' %
            response.status_code)

        with changer.change_times(file(index, 'w')) as fp:
            fp.write(
                'raise http.SeeOther("/foo")\n----\n<strong>this is HTML</strong>\n'
            )

        response = app.dispatch(req)
        self.assertTrue(isinstance(response, BaseResponse),
                        'dispatch on HTTPException did not return a Response')
        self.assertEqual(
            response.status_code, 303,
            'redirect (see other) did not get a 303 HTTPException (got %d)' %
            response.status_code)

        with changer.change_times(file(index, 'w')) as fp:
            fp.write('<strong>this is HTML</strong>\n')

        response = app.dispatch(req)
        self.assertTrue(
            isinstance(response, BaseResponse),
            'dispatch on html-only template did not return a Response')
        self.assertEqual(
            response.status_code, 200,
            'dispatch to template did not get a 200 status (got %d)' %
            response.status_code)

        with changer.change_times(file(index, 'w')) as fp:
            fp.write('# this is python\n----\n<strong>this is HTML</strong>\n')

        response = app.dispatch(req)
        self.assertTrue(
            isinstance(response, BaseResponse),
            'dispatch on mixed template did not return a Response')
        self.assertEqual(
            response.status_code, 200,
            'dispatch to template did not get a 200 status (got %d)' %
            response.status_code)

        with changer.change_times(file(static, 'w')) as fp:
            fp.write('* { background-color: white }\n')

        req = Request(wsgi_environ('GET', '/base.css'))
        response = app.dispatch(req)
        self.assertTrue(isinstance(response, BaseResponse),
                        'dispatch on static did not return a Response')
        self.assertEqual(
            response.status_code, 200,
            'dispatch to static did not get a 200 status (got %d)' %
            response.status_code)