301:508c24e708e0
Anton Shestakov <av6@dwimlabs.net>, Sat, 23 Sep 2017 12:43:15 +0800
models: it's now obvious that the order of columns should be this Now the index helps with "where project_id = ?" and "order by ordinal" as well.

next change 303:cfaaf0b0ec71
previous change 294:df33e25d8960

tests/test_viewer.py

Permissions: -rw-r--r--

Other formats: Feeds:
from datetime import datetime
from xml.etree import ElementTree
from pytest import raises
from tornado.escape import json_encode
from tornado.testing import AsyncHTTPTestCase
from tornado.web import HTTPError
from candolint.handlers import get_project_or_404
from candolint.models import database, Project, Change, Check
from viewer import CandolintViewer
XMLNS = {
'atom': 'http://www.w3.org/2005/Atom',
'svg': 'http://www.w3.org/2000/svg'
}
def setup_module():
with database.transaction():
project = Project.create(
url='https://example.com/alice/test-viewer',
domain='example.com',
user='alice',
name='test-viewer')
change = Change.create(
rev=42,
node='92cfceb39d57d914ed8b14d0e37643de0797ae56',
branch='default',
date='2016-07-19 22:23 +0800',
author='alice',
message='component: do a thing',
project=project)
Check.create(
ordinal=Check.get_next_ordinal(project),
errors=0,
warnings=0,
lines='[]',
success=True,
started=datetime.fromtimestamp(0),
finished=datetime.fromtimestamp(0),
change=change,
project=project)
lines = [{
'text': '# C&O job started: 2016-08-20T02:38:06+00:00',
'cls': 'meta'
}, {
'text': '# C&O task: setup',
'task': 'setup',
'cls': 'task'
}, {
'text': '$ ../venv2/bin/flake8 --version',
'task': 'setup'
}, {
'text': '3.0.3',
'task': 'setup'
}, {
'text': '# C&O task: checks',
'task': 'checks',
'cls': 'task'
}, {
'line_number': 20,
'task': 'checks',
'link_start': 0,
'text': 'test.py:20:80: E501 line too long (82 > 79 characters)',
'filename': 'test.py',
'link_end': 10,
'cls': 'warning'
}, {
'text': '# C&O job finished: 2016-08-20T02:38:53+00:00',
'cls': 'meta'
}]
Check.create(
ordinal=Check.get_next_ordinal(project),
errors=1,
warnings=1,
lines=json_encode(lines),
success=True,
started=datetime(2016, 8, 20, 2, 38, 6),
finished=datetime(2016, 8, 20, 2, 38, 53),
change=change,
project=project)
def test_get_project_or_404():
with raises(HTTPError) as error:
get_project_or_404('butt.cloud', 'cyber', 'wizard-attack')
assert error.value.status_code == 404
project = get_project_or_404('example.com', 'alice', 'test-viewer')
assert project.id is not None
assert project.url == 'https://example.com/alice/test-viewer'
class ViewerTestCase(AsyncHTTPTestCase):
def get_app(self):
return CandolintViewer()
def test_index(self):
response = self.fetch('/')
assert response.code == 200
assert 'online linter' in response.body
assert '1 error' in response.body
assert '1 warning' in response.body
assert '<a href="#">default</a>' in response.body
def test_404(self):
response = self.fetch('/nobodyhere')
assert response.code == 404
assert 'online linter' in response.body
def test_project(self):
response = self.fetch('/butt.cloud/cyber/wizard-attack')
assert response.code == 404
assert 'online linter' in response.body
response = self.fetch('/example.com/alice/test-viewer')
assert response.code == 200
assert 'Clone URL' in response.body
assert 'status.svg' in response.body
assert '.. image:: http' in response.body
assert '1 error' in response.body
assert '1 warning' in response.body
assert '<a href="#">default</a>' in response.body
assert ('<link rel="alternate"'
' href="/example.com/alice/test-viewer/atom"'
' type="application/atom+xml"'
' title="test-viewer feed">') in response.body
def test_atom(self):
response = self.fetch('/example.com/alice/test-viewer/atom')
assert response.code == 200
assert 'atom+xml' in response.headers['Content-Type']
root = ElementTree.fromstring(response.body)
assert root.tag == '{%s}%s' % (XMLNS['atom'], 'feed')
title = root.find('./atom:entry/atom:title', XMLNS)
assert title is not None
assert title.text.startswith('Check #')
assert title.text.endswith(' 1 error, 1 warning')
updates = [el.text for el in root.findall('.//atom:updated', XMLNS)]
assert len(updates) == min(Check.select().count(), 20) + 1
assert updates[0] == updates[1] == '2016-08-20T02:38:53Z'
def test_check(self):
response = self.fetch('/butt.cloud/cyber/wizard-attack/latest')
assert response.code == 404
assert 'online linter' in response.body
response = self.fetch('/example.com/alice/test-viewer/latest')
assert response.code == 200
assert '1 error' in response.body
assert '1 warning' in response.body
assert '<a href="#">default</a>' in response.body
assert '<a href="#" class="filelink">test.py:20</a>' in response.body
assert ('<time datetime="2016-08-20T02:38:53Z"'
' title="2016-08-20 02:38:53 UTC">'
'2016-08-20 02:38:53 UTC</time>') in response.body
assert ('<time datetime="2016-07-19T22:23+0800"'
' title="2016-07-19 22:23 +0800">'
'2016-07-19 22:23 +0800</time>') in response.body
response = self.fetch('/example.com/alice/test-viewer/latest/raw')
assert response.code == 200
assert response.headers['Content-Type'] == 'text/plain; charset=utf-8'
assert 'test.py' in response.body
def test_compare(self):
base_url = '/example.com/alice/test-viewer/latest'
response = self.fetch(base_url + '/compare/latest')
assert response.code == 200
assert 'same commit' in response.body
assert 'Diff is empty' in response.body
response = self.fetch(base_url + '/compare/1')
assert response.code == 200
assert 'same commit' in response.body
assert 'E501' in response.body
def test_status(self):
response = self.fetch('/butt.cloud/cyber/wizard-attack/status.svg')
assert response.code == 404
assert 'online linter' in response.body
response = self.fetch('/example.com/alice/test-viewer/status.svg')
assert response.code == 200
root = ElementTree.fromstring(response.body)
assert root.tag == '{%s}%s' % (XMLNS['svg'], 'svg')
assert root.attrib.get('height') == '20'
text = [el.text for el in root.findall('./svg:g/svg:text', XMLNS)]
assert text[::2] == ['lint', '1 error', '1 warning']
def test_dot(self):
response = self.fetch('/example.com/alice/test-viewer/latest/dot.svg')
assert response.code == 200
root = ElementTree.fromstring(response.body)
assert root.tag == '{%s}%s' % (XMLNS['svg'], 'svg')
assert root.attrib.get('height') == '12'
circles = root.findall('./svg:circle', XMLNS)
assert len(circles) == 1
assert circles[0].attrib.get('fill').startswith('#')