TST: Travis/Coveralls setup (#10)

- add travis.yml
- linting
- coveralls
- readme
This commit is contained in:
Matthew Ryan Dillon 2016-08-28 16:30:20 -07:00
parent 8622e2323d
commit 983ce6f021
15 changed files with 107 additions and 50 deletions

View file

@ -1,3 +1,9 @@
[run]
omit = ./venv/*,./config/*,manage.py
omit =
*/venv/*
*/config/*
*/migrations/*
manage.py
branch = True
source = ccdb
include = */ccdb/*

18
.travis.yml Normal file
View file

@ -0,0 +1,18 @@
language: python
python:
- 3.5
services:
- postgresql
before_install:
- psql -c 'CREATE DATABASE ccdbdjango;' -U postgres
- export DJANGO_SETTINGS_MODULE=config.settings.local
- export DATABASE_URL=postgres://postgres@localhost/ccdbdjango
install:
- pip install -r requirements/local.txt
- pip install coveralls
script:
- python manage.py migrate
- flake8 --exclude=migrations,settings,manage.py,misc/existing.py
- coverage run --rcfile .coveragerc manage.py test
after_success:
- coveralls

View file

@ -1,5 +1,8 @@
# CCDB - Collections and Contaminants Database
[![Build Status](https://travis-ci.org/thermokarst/ccdb.svg?branch=master)](https://travis-ci.org/thermokarst/ccdb)
[![Coverage Status](https://coveralls.io/repos/github/thermokarst/ccdb/badge.svg?branch=master)](https://coveralls.io/github/thermokarst/ccdb?branch=master)
A collections and contaminants database.
## Development Setup

View file

@ -11,7 +11,8 @@ router.register(r'administrative-urls', api_v.AdminURLs, base_name='adminurls')
urlpatterns = [
url(r'^auth/login/', api_v.Login.as_view()),
url(r'^auth/password/reset/confirm/', api_v.PasswordResetConfirm.as_view()),
url(r'^auth/password/reset/confirm/',
api_v.PasswordResetConfirm.as_view()),
url(r'^auth/password/reset/', api_v.PasswordReset.as_view()),
url(r'^auth/', include('djoser.urls.authtoken')),
url(r'^v1/', include(router.urls, namespace='v1')),

View file

@ -73,7 +73,8 @@ class CollectionTestCase(TestCase):
def test_uniqueness(self):
c1 = CollectionFactory()
with transaction.atomic(), self.assertRaises(IntegrityError):
CollectionFactory(project=c1.project, study_location=c1.study_location,
CollectionFactory(project=c1.project,
study_location=c1.study_location,
collection_type=c1.collection_type,
collection_start_date=c1.collection_start_date,
collection_end_date=c1.collection_end_date,
@ -99,8 +100,10 @@ class CollectionTrapTestCase(TestCase):
def test_uniqueness(self):
c1 = CollectionTrapFactory()
with transaction.atomic(), self.assertRaises(IntegrityError):
CollectionTrapFactory(collection=c1.collection, date_opened=c1.date_opened,
time_opened=c1.time_opened, date_closed=c1.date_closed,
CollectionTrapFactory(collection=c1.collection,
date_opened=c1.date_opened,
time_opened=c1.time_opened,
date_closed=c1.date_closed,
time_closed=c1.time_closed)
c3 = CollectionTrapFactory()
self.assertTrue(isinstance(c3, CollectionTrap))

View file

@ -1,7 +1,7 @@
from django.contrib import admin
from .models import Flaw, Experiment, ProtocolAttachment, TreatmentType, \
Treatment, TreatmentReplicate, AliveDeadCount
from .models import (Flaw, Experiment, ProtocolAttachment, TreatmentType,
Treatment, TreatmentReplicate, AliveDeadCount)
class FlawAdmin(admin.ModelAdmin):
@ -17,7 +17,8 @@ class ExperimentAdmin(admin.ModelAdmin):
list_display_links = ('name',)
search_fields = ('name', 'code', 'description', 'flaw', 'sort_order')
list_per_page = 25
fields = ('name', 'code', 'description', 'flaw', 'collections', 'sort_order')
fields = ('name', 'code', 'description', 'flaw', 'collections',
'sort_order')
class ProtocolAttachmentAdmin(admin.ModelAdmin):
@ -30,46 +31,46 @@ class ProtocolAttachmentAdmin(admin.ModelAdmin):
class TreatmentTypeAdmin(admin.ModelAdmin):
list_display = ('experiment', 'name', 'code', 'treatment_type',
'placement', 'description', 'sort_order')
'placement', 'description', 'sort_order')
list_display_links = ('name',)
search_fields = ('experiment', 'name', 'code', 'treatment_type',
'placement', 'description')
'placement', 'description')
list_per_page = 25
fields = ('experiment', 'name', 'code', 'treatment_type', 'placement',
'description', 'sort_order')
'description', 'sort_order')
class TreatmentAdmin(admin.ModelAdmin):
list_display = ('treatment_type', 'container', 'study_location', 'species',
'sex', 'flaw')
'sex', 'flaw')
list_display_links = ('treatment_type',)
search_fields = ('treatment_type', 'container', 'study_location', 'species',
'sex', 'flaw')
search_fields = ('treatment_type', 'container', 'study_location',
'species', 'sex', 'flaw')
list_per_page = 25
fields = ('treatment_type', 'container', 'study_location', 'species',
'sex', 'flaw')
'sex', 'flaw')
class TreatmentReplicateAdmin(admin.ModelAdmin):
list_display = ('treatment', 'name', 'setup_date', 'setup_time',
'setup_sample_size', 'mass_g', 'flaw')
'setup_sample_size', 'mass_g', 'flaw')
list_display_links = ('name',)
search_fields = ('treatment', 'name', 'setup_date', 'setup_time',
'setup_sample_size', 'mass_g', 'flaw')
'setup_sample_size', 'mass_g', 'flaw')
list_per_page = 25
fields = ('treatment', 'name', 'setup_date', 'setup_time',
'setup_sample_size', 'mass_g', 'flaw')
'setup_sample_size', 'mass_g', 'flaw')
class AliveDeadCountAdmin(admin.ModelAdmin):
list_display = ('treatment', 'tr', 'status_date',
'status_time', 'count_alive', 'count_dead', 'flaw')
list_display = ('treatment', 'tr', 'status_date', 'status_time',
'count_alive', 'count_dead', 'flaw')
list_display_links = ('status_date',)
search_fields = ('treatment_replicate', 'status_date', 'status_time',
'count_alive', 'count_dead', 'flaw')
'count_alive', 'count_dead', 'flaw')
list_per_page = 25
fields = ('treatment_replicate', 'status_date', 'status_time',
'count_alive', 'count_dead', 'flaw')
'count_alive', 'count_dead', 'flaw')
def treatment(self, obj):
return obj.treatment_replicate.treatment
@ -77,8 +78,8 @@ class AliveDeadCountAdmin(admin.ModelAdmin):
def tr(self, obj):
return "{}_{}_{}".format(obj.treatment_replicate.setup_date,
obj.treatment_replicate.name,
obj.treatment_replicate.setup_sample_size)
obj.treatment_replicate.name,
obj.treatment_replicate.setup_sample_size)
tr.short_description = 'Treatment Replicate'

View file

@ -17,7 +17,8 @@ class Experiment(models.Model):
name = models.CharField(max_length=150)
code = models.CharField(max_length=10, blank=True)
description = models.CharField(max_length=255, blank=True)
flaw = models.ForeignKey(Flaw, blank=True, null=True, related_name='experiments')
flaw = models.ForeignKey(Flaw, blank=True, null=True,
related_name='experiments')
sort_order = models.IntegerField(blank=True, null=True)
collections = models.ManyToManyField('collections_ccdb.Collection')
@ -63,19 +64,22 @@ class TreatmentType(models.Model):
class Treatment(models.Model):
treatment_type = models.ForeignKey(TreatmentType, related_name='treatments')
treatment_type = models.ForeignKey(TreatmentType,
related_name='treatments')
container = models.ForeignKey('misc.Container', blank=True, null=True,
related_name='treatments')
study_location = models.ForeignKey('locations.StudyLocation',
related_name='treatments')
species = models.ForeignKey('species.Species', related_name='treatments')
sex = models.CharField(max_length=25)
flaw = models.ForeignKey(Flaw, blank=True, null=True, related_name='treatments')
flaw = models.ForeignKey(Flaw, blank=True, null=True,
related_name='treatments')
display_name = models.CharField(max_length=255, editable=False)
def save(self, *args, **kwargs):
self.display_name = "{}_{}_{}_{}".format(self.treatment_type,
self.study_location, self.species,
self.study_location,
self.species,
self.sex)
super(Treatment, self).save(*args, **kwargs)
@ -88,13 +92,15 @@ class Treatment(models.Model):
class TreatmentReplicate(models.Model):
treatment = models.ForeignKey(Treatment, related_name='treatment_replicates')
treatment = models.ForeignKey(Treatment,
related_name='treatment_replicates')
name = models.CharField(max_length=50)
setup_date = models.DateField(blank=True, null=True)
setup_time = models.TimeField(blank=True, null=True)
setup_sample_size = models.IntegerField(blank=True, null=True)
mass_g = models.FloatField(blank=True, null=True)
flaw = models.ForeignKey(Flaw, blank=True, null=True, related_name='treatment_replicates')
flaw = models.ForeignKey(Flaw, blank=True, null=True,
related_name='treatment_replicates')
display_name = models.CharField(max_length=255, editable=False)
def save(self, *args, **kwargs):

View file

@ -15,7 +15,8 @@ class Region(models.Model):
class Site(models.Model):
region = models.ForeignKey(Region, blank=True, null=True, related_name='sites')
region = models.ForeignKey(Region, blank=True, null=True,
related_name='sites')
name = models.CharField(max_length=100)
code = models.CharField(max_length=10, blank=True)
description = models.CharField(max_length=255, blank=True)
@ -51,7 +52,8 @@ class StudyLocation(models.Model):
study_location_type = models.CharField(max_length=50, blank=True)
treatment_type = models.CharField(max_length=100, blank=True)
municipal_location = models.ForeignKey(MunicipalLocation,
blank=True, null=True, related_name='study_locations')
blank=True, null=True,
related_name='study_locations')
collecting_location = models.BooleanField(default=False)
description = models.CharField(max_length=255, blank=True)
sort_order = models.IntegerField(blank=True, null=True)

View file

@ -21,9 +21,12 @@ class MeasurementType(models.Model):
code = models.CharField(max_length=10, blank=True)
measurement_type_class = models.CharField(max_length=50, blank=True)
description = models.CharField(max_length=255, blank=True)
default_measurement_unit = models.ForeignKey('MeasurementUnit', blank=True,
null=True,
related_name='measurement_types')
default_measurement_unit = models.ForeignKey(
'MeasurementUnit',
blank=True,
null=True,
related_name='measurement_types'
)
sort_order = models.IntegerField(blank=True, null=True)
def __str__(self):
@ -72,8 +75,8 @@ class Container(models.Model):
material = models.ForeignKey(Material, blank=True, null=True,
related_name='containers')
volume = models.FloatField(blank=True, null=True)
measurement_unit = models.ForeignKey(MeasurementUnit, blank=True, null=True,
related_name='containers')
measurement_unit = models.ForeignKey(MeasurementUnit, blank=True,
null=True, related_name='containers')
sort_order = models.IntegerField(blank=True, null=True)
def __str__(self):

View file

@ -30,8 +30,11 @@ class MeasurementTypeTestCase(TestCase):
def test_uniqueness(self):
m1 = MeasurementTypeFactory()
with transaction.atomic(), self.assertRaises(IntegrityError):
MeasurementTypeFactory(name=m1.name, code=m1.code,
measurement_type_class=m1.measurement_type_class)
MeasurementTypeFactory(
name=m1.name,
code=m1.code,
measurement_type_class=m1.measurement_type_class
)
m3 = MeasurementTypeFactory()
self.assertTrue(isinstance(m3, MeasurementType))
@ -59,7 +62,8 @@ class ColorTestCase(TestCase):
def test_uniqueness(self):
c1 = ColorFactory()
with transaction.atomic(), self.assertRaises(IntegrityError):
ColorFactory(name=c1.name, code=c1.code, color_number=c1.color_number)
ColorFactory(name=c1.name, code=c1.code,
color_number=c1.color_number)
c3 = ColorFactory()
self.assertTrue(isinstance(c3, Color))

View file

@ -53,10 +53,12 @@ class Processing(models.Model):
measurement_unit = models.ForeignKey('misc.MeasurementUnit', blank=True,
null=True, related_name='processings')
minutes_in_reagent = models.IntegerField(blank=True, null=True)
flaw = models.ForeignKey(Flaw, blank=True, null=True, related_name='processings')
flaw = models.ForeignKey(Flaw, blank=True, null=True,
related_name='processings')
def __str__(self):
return "{} {} {}".format(self.process_date, self.process_type, self.container_label)
return "{} {} {}".format(self.process_date, self.process_type,
self.container_label)
class Meta:
unique_together = ('process_type', 'container', 'container_label',

View file

@ -52,13 +52,15 @@ class ProcessingTestCase(TestCase):
def test_creation(self):
p = ProcessingFactory()
self.assertTrue(isinstance(p, Processing))
name = "{} {} {}".format(p.process_date, p.process_type, p.container_label)
name = "{} {} {}".format(p.process_date, p.process_type,
p.container_label)
self.assertEqual(p.__str__(), name)
def test_uniqueness(self):
p1 = ProcessingFactory()
with transaction.atomic(), self.assertRaises(IntegrityError):
ProcessingFactory(process_type=p1.process_type, container=p1.container,
ProcessingFactory(process_type=p1.process_type,
container=p1.container,
container_label=p1.container_label,
process_date=p1.process_date,
process_time=p1.process_time, reagent=p1.reagent)

View file

@ -37,4 +37,3 @@ class GrantReportFactory(factory.DjangoModelFactory):
due_date = factory.LazyFunction(datetime.now)
submitted_date = factory.LazyFunction(datetime.now)
sort_order = factory.Sequence(lambda n: n)

View file

@ -4,7 +4,8 @@ from .models import Species, TrapSpecies, CollectionSpecies
class SpeciesAdmin(admin.ModelAdmin):
list_display = ('common_name', 'genus', 'species', 'parasite', 'sort_order')
list_display = ('common_name', 'genus', 'species', 'parasite',
'sort_order')
list_display_links = ('common_name',)
search_fields = ('common_name', 'genus', 'species', 'parasite')
list_per_page = 25
@ -12,9 +13,11 @@ class SpeciesAdmin(admin.ModelAdmin):
class TrapSpeciesAdmin(admin.ModelAdmin):
list_display = ('collection_trap', 'species', 'sex', 'count', 'count_estimated')
list_display = ('collection_trap', 'species', 'sex', 'count',
'count_estimated')
list_display_links = ('count',)
search_fields = ('collection_trap', 'species', 'sex', 'count', 'count_estimated')
search_fields = ('collection_trap', 'species', 'sex', 'count',
'count_estimated')
list_per_page = 25
fields = ('collection_trap', 'species', 'sex', 'count', 'count_estimated')
@ -22,7 +25,8 @@ class TrapSpeciesAdmin(admin.ModelAdmin):
class CollectionSpeciesAdmin(admin.ModelAdmin):
list_display = ('collection', 'species', 'sex', 'count', 'count_estimated')
list_display_links = ('count',)
search_fields = ('collection', 'species', 'sex', 'count', 'count_estimated')
search_fields = ('collection', 'species', 'sex', 'count',
'count_estimated')
list_per_page = 25
fields = ('collection', 'species', 'sex', 'count', 'count_estimated')

View file

@ -62,7 +62,10 @@ sqlite3.register_converter("dtdt", dtdt)
def setup_sqlite(dbfile):
if os.path.exists(dbfile):
db = sqlite3.connect(dbfile, detect_types=sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES)
db = sqlite3.connect(
dbfile,
detect_types=sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES
)
db.row_factory = sqlite3.Row
return db.cursor()
else: