Skip to content

Commit

Permalink
updating for revisions in wc_utils.schema.io
Browse files Browse the repository at this point in the history
  • Loading branch information
jonrkarr committed Dec 8, 2016
1 parent aaa9b75 commit e42da5a
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 122 deletions.
25 changes: 19 additions & 6 deletions tests/test_io.py
Expand Up @@ -9,8 +9,7 @@
from wc_lang.core import (Model, Taxon, TaxonRank, Submodel, Reaction, SpeciesType, SpeciesTypeType, Species, Compartment,
ReactionParticipant, Parameter, Reference, ReferenceType, CrossReference,
RateLaw, RateLawEquation, SubmodelAlgorithm, Concentration)
from wc_lang.io import ExcelIo
from wc_utils.schema.core import Validator
from wc_lang.io import Writer, Reader, create_template
import os
import tempfile
import unittest
Expand All @@ -26,8 +25,8 @@ def tearDown(self):
os.remove(self.filename)

def test_create_template(self):
ExcelIo.create_template(self.filename)
self.assertEqual(ExcelIo.read(self.filename), None)
create_template(self.filename)
self.assertEqual(Reader().run(self.filename), None)


class TestSimpleModel(unittest.TestCase):
Expand Down Expand Up @@ -128,9 +127,23 @@ def tearDown(self):
os.remove(self.filename)

def test_write_read(self):
ExcelIo.write(self.filename, self.model)
model = ExcelIo.read(self.filename)
Writer().run(self.filename, self.model)
model = Reader().run(self.filename)
self.assertEqual(model.validate(), None)

self.assertEqual(model, self.model)
self.assertEqual(self.model.difference(model), '')


class TestExampleModel(unittest.TestCase):

def setUp(self):
_, self.filename = tempfile.mkstemp(suffix='.xlsx')

def tearDown(self):
if os.path.isfile(self.filename):
os.remove(self.filename)

@unittest.skip('Implement me')
def test_read_write(self):
pass
18 changes: 9 additions & 9 deletions tests/test_main.py
Expand Up @@ -12,7 +12,7 @@
from tempfile import mkdtemp
from wc_lang.__main__ import App as WcLangCli
from wc_lang.core import Model
from wc_lang.io import ExcelIo
from wc_lang.io import Writer, Reader
import unittest
import wc_lang

Expand All @@ -35,7 +35,7 @@ def test_validate(self):
model = Model(id='model', name='test model', version='0.0.1a', wc_lang_version='0.0.1')
self.assertEqual(model.validate(), None)
filename = path.join(self.tempdir, 'model.xlsx')
ExcelIo.write(filename, model)
Writer().run(filename, model)

with CaptureOutput() as capturer:
with WcLangCli(argv=['validate', filename]) as app:
Expand All @@ -45,15 +45,15 @@ def test_validate(self):
def test_difference(self):
model1 = Model(id='model', name='test model', version='0.0.1a', wc_lang_version='0.0.0')
filename1 = path.join(self.tempdir, 'model1.xlsx')
ExcelIo.write(filename1, model1)
Writer().run(filename1, model1)

model2 = Model(id='model', name='test model', version='0.0.1a', wc_lang_version='0.0.0')
filename2 = path.join(self.tempdir, 'model2.xlsx')
ExcelIo.write(filename2, model2)
Writer().run(filename2, model2)

model3 = Model(id='model', name='test model', version='0.0.1a', wc_lang_version='0.0.1')
filename3 = path.join(self.tempdir, 'model3.xlsx')
ExcelIo.write(filename3, model3)
Writer().run(filename3, model3)

with CaptureOutput() as capturer:
with WcLangCli(argv=['difference', filename1, filename2]) as app:
Expand All @@ -80,7 +80,7 @@ def test_difference(self):
def test_transform(self):
source = path.join(self.tempdir, 'source.xlsx')
model = Model(id='model', name='test model', version='0.0.1a', wc_lang_version='0.0.0')
ExcelIo.write(source, model)
Writer().run(source, model)

destination = path.join(self.tempdir, 'destination.xlsx')
with WcLangCli(argv=['transform', source, destination, '--transform', 'MergeAlgorithmicallyLikeSubmodels']) as app:
Expand All @@ -93,7 +93,7 @@ def test_convert(self):
filename_csv = path.join(self.tempdir, 'model-*.csv')

model = Model(id='model', name='test model', version='0.0.1a', wc_lang_version='0.0.0')
ExcelIo.write(filename_xls, model)
Writer().run(filename_xls, model)

with WcLangCli(argv=['convert', filename_xls, filename_csv]) as app:
app.run()
Expand All @@ -113,10 +113,10 @@ def test_update_wc_lang_version(self):

model = Model(id='model', name='test model', version='0.0.1a', wc_lang_version='0.0.0')
self.assertNotEqual(model.wc_lang_version, wc_lang.__version__)
ExcelIo.write(filename, model)
Writer().run(filename, model)

with WcLangCli(argv=['update-wc-lang-version', filename]) as app:
app.run()

model = ExcelIo.read(filename)
model = Reader().run(filename)
self.assertEqual(model.wc_lang_version, wc_lang.__version__)
25 changes: 19 additions & 6 deletions tests/test_util.py
Expand Up @@ -6,10 +6,10 @@
:License: MIT
"""

from wc_lang.core import (Model, Submodel, Reaction, SpeciesType, SpeciesTypeType, Species, Compartment,
from wc_lang.core import (Model, Taxon, Submodel, Reaction, SpeciesType, SpeciesTypeType, Species, Compartment,
ReactionParticipant, Parameter, Reference, ReferenceType, CrossReference,
RateLaw, RateLawEquation, SubmodelAlgorithm, Concentration)
from wc_lang.util import Utils
from wc_lang.util import get_model_size, get_model_summary, get_reaction_string, get_models
import unittest


Expand Down Expand Up @@ -90,7 +90,7 @@ def setUp(self):

def test_get_model_size(self):
model = self.model
size = Utils.get_model_size(model)
size = get_model_size(model)
self.assertEqual(3, size['submodels'])
self.assertEqual(8, size['species_types'])
self.assertEqual(8, size['species'])
Expand All @@ -101,23 +101,36 @@ def test_get_model_size(self):

def test_get_model_summary(self):
model = self.model
summary = Utils.get_model_summary(model)
summary = get_model_summary(model)
self.assertIsInstance(summary, str)

def test_get_reaction_string(self):
species_types = self.species_types
species = self.species

self.assertIn(Utils.get_reaction_string(self.rxn_0), [
self.assertIn(get_reaction_string(self.rxn_0), [
'[{0}]: ({1}) {2} + ({3}) {4} ==> {5}'.format(self.comp_0.id, 2,
species_types[0].id, 3, species_types[1].id, species_types[2].id),
'[{0}]: ({3}) {4} + ({1}) {2} ==> {5}'.format(self.comp_0.id, 2,
species_types[0].id, 3, species_types[1].id, species_types[2].id),
])

self.assertIn(Utils.get_reaction_string(self.rxn_1), [
self.assertIn(get_reaction_string(self.rxn_1), [
'({0}) {1} + ({2}) {3} ==> (2) {4}'.format(2,
species[0].serialize(), 3, species[1].serialize(), species[3].serialize()),
'({2}) {3} + ({0}) {1} ==> (2) {4}'.format(2,
species[0].serialize(), 3, species[1].serialize(), species[3].serialize()),
])

def test_get_models(self):
non_inline_models = set([
Model, Taxon,
Submodel, Compartment, SpeciesType, Concentration,
Reaction, RateLaw, Parameter,
Reference, CrossReference,
])
inline_models = set([
Species, ReactionParticipant, RateLawEquation
])
self.assertEqual(set(get_models()), non_inline_models | inline_models)
self.assertEqual(set(get_models(inline=False)), non_inline_models)
18 changes: 9 additions & 9 deletions wc_lang/__main__.py
Expand Up @@ -8,8 +8,8 @@

from cement.core.foundation import CementApp
from cement.core.controller import CementBaseController, expose
from wc_lang.io import ExcelIo
from wc_lang import transform
from wc_lang.io import Writer, Reader, create_template
from wc_utils.workbook.io import convert as convert_workbook
from wc_utils.workbook.io import read as read_workbook
import wc_lang
Expand Down Expand Up @@ -43,7 +43,7 @@ class Meta:
@expose(hide=True)
def default(self):
args = self.app.pargs
model = ExcelIo.read(args.path)
model = Reader().run(args.path)
error = model.validate()
if error:
print(str(error))
Expand Down Expand Up @@ -76,8 +76,8 @@ def default(self):
diff = model1.difference(model2)

else:
model1 = ExcelIo.read(args.path_1)
model2 = ExcelIo.read(args.path_2)
model1 = Reader().run(args.path_1)
model2 = Reader().run(args.path_2)
diff = model1.difference(model2)

if diff:
Expand Down Expand Up @@ -115,7 +115,7 @@ def default(self):
return

# read model
model = ExcelIo.read(args.source)
model = Reader().run(args.source)

# apply transforms
transforms = transform.get_transforms()
Expand All @@ -125,7 +125,7 @@ def default(self):
instance.run(model)

# write model
ExcelIo.write(args.destination, model)
Writer().run(args.destination, model)


class ConvertController(CementBaseController):
Expand Down Expand Up @@ -162,7 +162,7 @@ class Meta:
@expose(hide=True)
def default(self):
args = self.app.pargs
ExcelIo.create_template(args.path)
create_template(args.path)


class UpdateWcLangVersionController(CementBaseController):
Expand All @@ -180,9 +180,9 @@ class Meta:
@expose(hide=True)
def default(self):
args = self.app.pargs
model = ExcelIo.read(args.path)
model = Reader().run(args.path)
model.wc_lang_version = wc_lang.__version__
ExcelIo.write(args.path, model)
Writer().run(args.path, model)


class App(CementApp):
Expand Down
10 changes: 5 additions & 5 deletions wc_lang/core.py
Expand Up @@ -10,14 +10,14 @@
from itertools import chain
from math import isnan
from six import with_metaclass
from wc_utils.schema.core import Model as BaseModel
from wc_utils.schema.core import Validator as BaseValidator
from wc_utils.schema.core import (BooleanAttribute, EnumAttribute, FloatAttribute, IntegerAttribute, PositiveIntegerAttribute,
from wc_utils.schema.core import (Model as BaseModel,
BooleanAttribute, EnumAttribute, FloatAttribute, IntegerAttribute, PositiveIntegerAttribute,
RegexAttribute, SlugAttribute, StringAttribute, LongStringAttribute, UrlAttribute,
OneToOneAttribute, ManyToOneAttribute, OneToManyAttribute, ManyToManyAttribute,
InvalidObjectSet, InvalidModel, InvalidObject, InvalidAttribute,
OneToOneAttribute, ManyToOneAttribute, ManyToManyAttribute,
InvalidModel, InvalidObject, InvalidAttribute,
TabularOrientation)
import re
import sys


class TaxonRankMeta(EnumMeta):
Expand Down
82 changes: 48 additions & 34 deletions wc_lang/io.py
@@ -1,4 +1,8 @@
""" Classes for reading and writing models to/from files.
""" Reading and writing models to/from files.
* Comma separated values (.csv)
* Excel (.xlsx)
* Tab separated values (.tsv)
:Author: Jonathan Karr <karr@mssm.edu>
:Date: 2016-12-05
Expand All @@ -9,59 +13,69 @@
from wc_lang.core import (Model, Taxon, Submodel, Compartment, SpeciesType,
Concentration, Reaction, RateLaw, Parameter, Reference,
CrossReference)
from wc_utils.schema.io import ExcelIo as BaseExcelIo
from wc_lang.util import get_models
from wc_utils.schema import io


class ExcelIo(object):
""" Read/write model to/from Excel workbooks """
class Writer(object):
""" Write model to file(s) """

@classmethod
def write(cls, filename, model):
""" Write model to file
def run(self, path, model=None):
""" Write model to file(s)
Args:
filename (:obj:`str`): path to file
path (:obj:`str`): path to file(s)
model (:obj:`Model`): model
"""
BaseExcelIo.write(filename, set((model,)), [
Model, Taxon, Submodel, Compartment, SpeciesType,
Concentration, Reaction, RateLaw, Parameter, Reference,
CrossReference],
title=model.id, description=model.name, version=model.version,
language='wc_lang', creator=cls.__module__ + '.' + cls.__name__)
models = [
Model, Taxon,
Submodel, Compartment, SpeciesType, Concentration,
Reaction, RateLaw, Parameter,
Reference, CrossReference,
]

kwargs = {
'language': 'wc_lang',
'creator': '{}.{}'.format(self.__class__.__module__, self.__class__.__name__),
}
if model:
objects = set((model,))
kwargs['title'] = model.id
kwargs['description'] = model.name
kwargs['version'] = model.version
else:
objects = set()

io.Writer().run(path, objects, models, **kwargs)


@classmethod
def read(cls, filename):
""" Read model from file
class Reader(object):
""" Read model from file(s) """

def run(self, path):
""" Read model from file(s)
Args:
filename (:obj:`str`): path to file
path (:obj:`str`): path to file(s)
Returns:
:obj:`Model`: model
"""
objects = BaseExcelIo.read(filename, [
Model, Taxon, Submodel, Compartment, SpeciesType,
Concentration, Reaction, RateLaw, Parameter, Reference,
CrossReference, ])
objects = io.Reader().run(path, get_models(inline=False))

if not objects[Model]:
return None

if len(objects[Model]) > 1:
raise ValueError('Model file "{}" should only define one model'.format(filename))
raise ValueError('Model file "{}" should only define one model'.format(path))

return objects[Model].pop()

@classmethod
def create_template(cls, filename):
""" Create file with template (i.e. row, column headings)

Args:
filename (:obj:`str`): path to file
"""
BaseExcelIo.create_template(filename, [
Model, Taxon, Submodel, Compartment, SpeciesType,
Concentration, Reaction, RateLaw, Parameter, Reference,
CrossReference],
language='wc_lang', creator=cls.__module__ + '.' + cls.__name__)
def create_template(path):
""" Create file with model template, including row and column headings
Args:
path (:obj:`str`): path to file(s)
"""
Writer().run(path)

0 comments on commit e42da5a

Please sign in to comment.