Skip to content

Commit

Permalink
100% test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
khaeru committed Aug 10, 2016
1 parent 4637ac6 commit 310c751
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 29 deletions.
18 changes: 13 additions & 5 deletions data/tests.gms
@@ -1,5 +1,7 @@
$onempty

scalar pi 'Circumference divided by diameter' / 3.14 /;

set s 'Example set of animals' /
a Aardvark
b 'Blue whale'
Expand Down Expand Up @@ -38,18 +40,24 @@ sets
;

parameters
p1(s) 'Example parameter with animal data' / /
p2(t) 'Example parameter with color data' / set.t 0 /
p3(s,t) 'Two-dimensional parameter' / set.s.y 1 /
p4(s1) 'Parameter defined over a subset' / set.s1 1 /
p1(s) 'Example parameter with animal data' / /
p2(t) 'Example parameter with color data' / set.t 0 /
p3(s,t) 'Two-dimensional parameter' / set.s.y 1 /
p4(s1) 'Parameter defined over a subset' / set.s1 1 /
p5(*) 'Empty parameter defined over the universal set'
;

parameter p5(*,*) 'Parameter defined over the universal set' /
parameter p6(*,*) 'Parameter defined over the universal set' /
a.o 1
r.US 2
CA.b 3
/;

equation e1;
variables v1, v2;

e1.. v1 =e= v2;

p1('a') = 1;

alias (s, s_);
Expand Down
30 changes: 14 additions & 16 deletions gdx/__init__.py
Expand Up @@ -111,7 +111,9 @@ def _load_symbol(self, index):
type_str_ = 'scalar'
try:
vartype_str_ = vartype_str[vartype]
except KeyError:
except KeyError: # pragma: no cover
# Some other vartype is returned that's not described by the GDX
# API docs
vartype_str_ = ''
attrs['type_str'] = '{} {}'.format(vartype_str_, type_str_)

Expand All @@ -127,15 +129,11 @@ def _load_symbol(self, index):
elif type_code == gdxcc.GMS_DT_ALIAS:
parent = desc.replace('Aliased with ', '')
self._alias[name] = parent
if self[parent].attrs['_gdx_type_code'] == gdxcc.GMS_DT_SET:
# Duplicate the variable
self._variables[name] = self._variables[parent]
self._state[name] = True
super(File, self).set_coords(name, inplace=True)
else:
raise NotImplementedError('Cannot handle aliases of symbols '
'except GMS_DT_SET: {} {} not loaded'
.format(index, name))
assert self[parent].attrs['_gdx_type_code'] == gdxcc.GMS_DT_SET
# Duplicate the variable
self._variables[name] = self._variables[parent]
self._state[name] = True
super(File, self).set_coords(name, inplace=True)
return name, type_code

# The Symbol is either a Set, Parameter or Variable
Expand Down Expand Up @@ -168,7 +166,7 @@ def _load_symbol_data(self, name):
# If the GAMS method 'sameas' is invoked in a program, the resulting
# GDX file contains an empty Set named 'SameAs' with domain (*,*). Do
# not read this
if name == 'SameAs' and domain == ['*', '*'] and records == 0:
if name == 'SameAs' and domain == ['*', '*']:
self._state[name] = None
self._index[index] = None
return
Expand Down Expand Up @@ -210,7 +208,7 @@ def _cache_data(self, name, index, dim, records):
except Exception:
if len(data) == records:
pass # All data has been read
else:
else: # pragma: no cover
raise # Some other read error

# Cache the read data
Expand Down Expand Up @@ -239,7 +237,7 @@ def _infer_domain(self, name, domain, elements):

for i, d in enumerate(domain_): # Iterate over dimensions
e = set(elements[i])
if d.name != '*' or len(e) == 0:
if d.name != '*' or len(e) == 0: # pragma: no cover
assert set(d.values).issuperset(e)
continue # The stated domain matches the data; or no data
# '*' is given
Expand Down Expand Up @@ -428,7 +426,7 @@ def _loaded_and_cached(self, type_code):
tc = self._variables[name].attrs['_gdx_type_code']
elif isinstance(state, dict):
tc = state['attrs']['type_code']
else:
else: # pragma: no cover
continue
if tc == type_code:
names.add(name)
Expand Down Expand Up @@ -462,10 +460,10 @@ def __getitem__(self, key):
"""Set element access."""
try:
return super(File, self).__getitem__(key)
except KeyError:
except KeyError as e:
if isinstance(self._state[key], dict):
debug('Lazy-loading {}'.format(key))
self._load_symbol_data(key)
return super(File, self).__getitem__(key)
else:
raise
raise KeyError(key) from e
33 changes: 25 additions & 8 deletions gdx/test/test_gdx.py
Expand Up @@ -40,13 +40,14 @@ def gdxfile(rawgdx):


@pytest.fixture(scope='class')
def gdxfile_implicit(rawgdx):
def gdxfile_explicit(rawgdx):
"""A gdx.File fixture, instantiated with implicit=False."""
return gdx.File(rawgdx, implicit=False)


actual = OrderedDict([
('*', None),
('pi', 3.14),
('s', ['a', 'b', 'c', 'd', 'e', 'f', 'g']),
('t', ['r', 'o', 'y', 'g', 'b', 'i', 'v']),
('u', ['CA', 'US', 'CN', 'JP']),
Expand All @@ -62,10 +63,11 @@ def gdxfile_implicit(rawgdx):
('p3', None),
('p4', None),
('p5', None),
('p6', None),
])
actual_info = {
'N sets': 12,
'N parameters': 5,
'N parameters': 7,
}
actual_info['N symbols'] = sum(actual_info.values()) + 1

Expand All @@ -89,6 +91,7 @@ def test_bad_method(self):
class TestFile:
def test_init(self, rawgdx):
gdx.File(rawgdx)
gdx.File(rawgdx, lazy=False)
with pytest.raises(FileNotFoundError):
gdx.File('nonexistent.gdx')

Expand All @@ -98,7 +101,7 @@ def test_parameters(self, gdxfile):

def test_sets(self, gdxfile):
sets = gdxfile.sets()
assert len(sets) == actual_info['N sets'] + 1
assert len(sets) == actual_info['N sets']

def test_get_symbol(self, gdxfile):
gdxfile['s']
Expand All @@ -122,20 +125,34 @@ def test_getitem(self, gdxfile):
gdxfile[name]
with pytest.raises(KeyError):
gdxfile['notasymbolname']
with pytest.raises(KeyError):
gdxfile['e1']

def test_info1(self, gdxfile):
assert gdxfile.info('s1').startswith("<xarray.DataArray 's1' (s: 7)>")

def test_info2(self, rawgdx):
# Use a File where p1 is guaranteed to not have been loaded:
assert (gdx.File(rawgdx).info('p1') == 'unknown parameter p1(s) — 1 '
'records: Example parameter with animal data')

def test_dealias(self, gdxfile):
assert gdxfile.dealias('s_').equals(gdxfile['s'])

def test_extract(self, gdxfile):
def test_extract(self, gdxfile, gdxfile_explicit):
for name in ['p1', 'p2', 'p3', 'p4']:
gdxfile.extract(name)
gdxfile_explicit.extract('p5')
with pytest.raises(KeyError):
gdxfile.extract('notasymbolname')

def test_implicit(self, gdxfile):
assert gdxfile['p5'].shape == (3, 3)
assert gdxfile['p6'].shape == (3, 3)


def test_implicit(gdxfile_implicit):
N = len(gdxfile_implicit['*'])
assert gdxfile_implicit['p5'].shape == (N, N)
def test_implicit(gdxfile_explicit):
N = len(gdxfile_explicit['*'])
assert gdxfile_explicit['p6'].shape == (N, N)


class TestSet:
Expand Down

0 comments on commit 310c751

Please sign in to comment.