Skip to content

Commit

Permalink
add tests (wip) (#1509), fix packaging use (#1550)
Browse files Browse the repository at this point in the history
  • Loading branch information
mikkonie committed Dec 8, 2022
1 parent 76f17f7 commit 8e18c94
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 56 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ Fixed
- iRODS session disconnection issues (#909, #1542)
- **Landingzones**
- Typo in ``LANDINGZONES_TRIGGER_MOVE_INTERVAL`` (#1541)
- **Samplesheets**
- Crash from incompatibility with ``packaging==0.22`` (#1550)

Removed
-------
Expand Down
10 changes: 3 additions & 7 deletions samplesheets/rendering.py
Original file line number Diff line number Diff line change
Expand Up @@ -775,16 +775,15 @@ def build_study_tables(self, study, use_config=True):
else:
logger.debug('No sheet configuration found in app settings')

# NOTE: Parsing version here in case of version-specific tweaks
self._parser_version = (
version.parse(study.investigation.parser_version)
if study.investigation.parser_version
else version.parse('')
else None
)
logger.debug(
'altamISA version at import: {}'.format(
self._parser_version
if not isinstance(self._parser_version, version.LegacyVersion)
else 'LEGACY'
self._parser_version if self._parser_version else 'LEGACY'
)
)

Expand Down Expand Up @@ -820,7 +819,6 @@ def build_study_tables(self, study, use_config=True):
)
return ret

# TODO: Add tests
def build_inv_tables(self, investigation, use_config=True):
"""
Build all study and assay tables of an investigation for rendering.
Expand All @@ -834,7 +832,6 @@ def build_inv_tables(self, investigation, use_config=True):
ret[study] = self.build_study_tables(study, use_config=use_config)
return ret

# TODO: Add tests
def get_study_tables(self, study):
"""
Get study and assay tables for rendering. Retrieve from sodarcache or
Expand Down Expand Up @@ -879,7 +876,6 @@ def get_study_tables(self, study):
)
return study_tables

# TODO: Add tests
@classmethod
def clear_study_cache(cls, study):
"""
Expand Down
166 changes: 117 additions & 49 deletions samplesheets/tests/test_rendering.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,30 @@

# Projectroles dependency
from projectroles.models import Role, SODAR_CONSTANTS
from projectroles.plugins import get_backend_api
from projectroles.tests.test_models import ProjectMixin, RoleAssignmentMixin

from samplesheets.models import GenericMaterial
from samplesheets.rendering import SampleSheetTableBuilder
from samplesheets.rendering import (
SampleSheetTableBuilder,
STUDY_TABLE_CACHE_ITEM,
)
from samplesheets.tests.test_io import (
SampleSheetIOMixin,
SHEET_DIR,
SHEET_DIR_SPECIAL,
)
from samplesheets.tests.test_sheet_config import SheetConfigMixin


# Local constants
APP_NAME = 'samplesheets'
SHEET_PATH = SHEET_DIR + 'i_small.zip'
SHEET_PATH_INSERTED = SHEET_DIR_SPECIAL + 'i_small_insert.zip'
SHEET_PATH_ALT = SHEET_DIR + 'i_small2.zip'


# TODO: Unify with TestTableBuilder if no other classes are needed
class TestRenderingBase(
ProjectMixin, RoleAssignmentMixin, SampleSheetIOMixin, TestCase
):
Expand All @@ -43,86 +50,147 @@ def setUp(self):
self.investigation = self.import_isa_from_file(SHEET_PATH, self.project)
self.study = self.investigation.studies.first()
self.tb = SampleSheetTableBuilder()
# Set up helpers
self.cache_backend = get_backend_api('sodar_cache')
self.cache_name = STUDY_TABLE_CACHE_ITEM.format(
study=self.study.sodar_uuid
)
self.cache_args = [APP_NAME, self.cache_name, self.project]


class TestTableBuilder(TestRenderingBase):
class TestTableBuilder(SheetConfigMixin, TestRenderingBase):
"""Tests for SampleSheetTableBuilder"""

def test_build_study(self):
"""Test building tables for a study"""
def _assert_row_length(self, table):
"""Assert uniform row length"""
row_lengths = set([len(r) for r in table['table_data']])
self.assertEqual(len(row_lengths), 1)

def assert_row_length(table):
"""Assert uniform row length"""
row_lengths = set([len(r) for r in table['table_data']])
self.assertEqual(len(row_lengths), 1)
@classmethod
def _get_column_set(cls, table, pos):
"""Return set of distinct values for a column at pos"""
return set([r[pos]['value'] for r in table['table_data']])

def get_column_set(table, pos):
"""Return set of distinct values for a column at pos"""
return set([r[pos]['value'] for r in table['table_data']])
def test_get_headers(self):
"""Test get_headers()"""
h = self.tb.get_headers(self.investigation)
self.assertIsNotNone(h)
self.assertEqual(len(h['studies'][0]['headers']), 15)
self.assertEqual(len(h['studies'][0]['assays'][0]), 8)

def test_get_headers_compare_row(self):
"""Test comparing get_headers() results for inserted rows"""
investigation2 = self.import_isa_from_file(
SHEET_PATH_INSERTED, self.project
)
h1 = self.tb.get_headers(self.investigation)
h2 = self.tb.get_headers(investigation2)
self.assertIsNotNone(h2)
self.assertEqual(h1, h2)

def test_get_headers_compare_col(self):
"""Test comparing get_headers() for different columns (should fail)"""
investigation2 = self.import_isa_from_file(SHEET_PATH_ALT, self.project)
h1 = self.tb.get_headers(self.investigation)
h2 = self.tb.get_headers(investigation2)
self.assertIsNotNone(h2)
self.assertNotEqual(h1, h2)

def test_build_study_tables(self):
"""Test build_study_tables()"""
tables = self.tb.build_study_tables(self.study)
self.assertIsNotNone(tables)

# Assert tables
self.assertIn('study', tables)
self.assertIn('assays', tables)
self.assertEqual(len(tables['assays']), self.study.assays.count())

# Test study table
assert_row_length(tables['study'])

# Study table
self._assert_row_length(tables['study'])
# Sources
table_sources = get_column_set(tables['study'], 0)
table_sources = self._get_column_set(tables['study'], 0)
db_sources = set(
GenericMaterial.objects.filter(
study=self.study, item_type='SOURCE'
).values_list('name', flat=True)
)
self.assertEqual(table_sources, db_sources)

# Samples
sample_pos = 0

for c in tables['study']['top_header']:
if c['value'] == 'Sample':
break

else:
sample_pos += c['colspan']

table_samples = get_column_set(tables['study'], sample_pos)
table_samples = self._get_column_set(tables['study'], sample_pos)
db_samples = set(
GenericMaterial.objects.filter(
study=self.study, item_type='SAMPLE'
).values_list('name', flat=True)
)
self.assertEqual(table_samples, db_samples)

# Test assay tables
# Aassay tables
for k, assay_table in tables['assays'].items():
assert_row_length(assay_table)

def test_get_headers(self):
"""Test get_headers()"""
h = self.tb.get_headers(self.investigation)
self.assertIsNotNone(h)
self.assertEqual(len(h['studies'][0]['headers']), 15)
self.assertEqual(len(h['studies'][0]['assays'][0]), 8)

def test_get_headers_compare_row(self):
"""Test comparing get_headers() results for inserted rows"""
investigation2 = self.import_isa_from_file(
SHEET_PATH_INSERTED, self.project
self._assert_row_length(assay_table)

# TODO: Test building with sheet config

def test_build_inv_tables(self):
"""Test build_inv_tables()"""
inv_tables = self.tb.build_inv_tables(self.investigation)
self.assertEqual(len(inv_tables.keys()), 1)
for study, study_tables in inv_tables.items():
self.assertEqual(
study_tables, self.tb.build_study_tables(study, use_config=True)
)

def test_build_inv_tables_no_config(self):
"""Test build_inv_tables() with use_config=False"""
inv_tables = self.tb.build_inv_tables(
self.investigation, use_config=False
)
h1 = self.tb.get_headers(self.investigation)
h2 = self.tb.get_headers(investigation2)
self.assertIsNotNone(h2)
self.assertEqual(h1, h2)

def test_get_headers_compare_col(self):
"""Test comparing get_headers() for different columns (should fail)"""
investigation2 = self.import_isa_from_file(SHEET_PATH_ALT, self.project)
h1 = self.tb.get_headers(self.investigation)
h2 = self.tb.get_headers(investigation2)
self.assertIsNotNone(h2)
self.assertNotEqual(h1, h2)
self.assertEqual(len(inv_tables.keys()), 1)
for study, study_tables in inv_tables.items():
self.assertEqual(
study_tables,
self.tb.build_study_tables(study, use_config=False),
)

def test_get_study_tables(self):
"""Test get_study_tables()"""
self.assertIsNone(self.cache_backend.get_cache_item(*self.cache_args))
study_tables = self.tb.get_study_tables(self.study)
cache_item = self.cache_backend.get_cache_item(*self.cache_args)
self.assertEqual(study_tables, cache_item.data)

def test_get_study_tables_cache(self):
"""Test get_study_tables() with existing cache item"""
study_tables = self.tb.build_study_tables(self.study)
cache_item = self.cache_backend.set_cache_item(
APP_NAME, self.cache_name, study_tables, 'json', self.project
)
self.assertIsNotNone(
self.cache_backend.get_cache_item(*self.cache_args)
)
study_tables = self.tb.get_study_tables(self.study)
self.assertEqual(study_tables, cache_item.data)

def test_clear_study_cache(self):
"""Test clear_study_cache()"""
study_tables = self.tb.build_study_tables(self.study)
self.cache_backend.set_cache_item(
APP_NAME, self.cache_name, study_tables, 'json', self.project
)
self.assertIsNotNone(
self.cache_backend.get_cache_item(*self.cache_args)
)
self.tb.clear_study_cache(self.study)
# NOTE: We still have the item, but it's empty
cache_item = self.cache_backend.get_cache_item(*self.cache_args)
self.assertEqual(cache_item.data, {})

def test_clear_study_cache_no_item(self):
"""Test clear_study_cache() without existing item"""
self.assertIsNone(self.cache_backend.get_cache_item(*self.cache_args))
self.tb.clear_study_cache(self.study)
cache_item = self.cache_backend.get_cache_item(*self.cache_args)
self.assertEqual(cache_item.data, {})
3 changes: 3 additions & 0 deletions samplesheets/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@
IRODS_BACKEND_SKIP_MSG = 'iRODS backend not enabled in settings'


# TODO: Add testing for study table cache updates


class TestViewsBase(
ProjectMixin, RoleAssignmentMixin, SampleSheetIOMixin, TestCase
):
Expand Down
3 changes: 3 additions & 0 deletions samplesheets/tests/test_views_ajax.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@
VERSION_DESC = 'description'


# TODO: Add testing for study table cache updates


class RowEditMixin:
"""Helpers for row insert/deletion"""

Expand Down
3 changes: 3 additions & 0 deletions samplesheets/tests/test_views_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@
IRODS_FILE_MD5 = '0b26e313ed4a7ca6904b0e9369e5b957'


# TODO: Add testing for study table cache updates


class TestSampleSheetAPIBase(SampleSheetIOMixin, TestAPIViewsBase):
"""Base view for samplesheets API views tests"""

Expand Down

0 comments on commit 8e18c94

Please sign in to comment.