diff --git a/src/omero_cli_render.py b/src/omero_cli_render.py index 3ae2ffe..76113b1 100755 --- a/src/omero_cli_render.py +++ b/src/omero_cli_render.py @@ -584,21 +584,28 @@ def _read_default_planes(self, img, data, ignore_errors=False): def_t = None return (def_z, def_t) - @gateway_required - def set(self, args): - """ Implements the 'set' command """ - newchannels = {} - data = pydict_text_io.load( - args.channels, session=self.client.getSession()) + def _load_rendering_settings(self, source, session=None): + """Load a rendering dictionary from a source (file or object)""" + try: + data = pydict_text_io.load(source, session=session) + except Exception as e: + self.ctx.dbg(e) + self.ctx.die(103, "Could not read %s" % source) + if 'channels' not in data: - self.ctx.die(104, "ERROR: No channels found in %s" % args.channels) + self.ctx.die(104, "ERROR: No channels found in %s" % source) version = _getversion(data) if version == 0: self.ctx.die(124, "ERROR: Cannot determine version. Specify" " version or use either start/end or min/max" " (not both).") + return data + def _read_channels(self, data): + """Read new channels from settings dictionary""" + newchannels = {} + version = _getversion(data) # Read channel setttings from rendering dictionary for chindex, chdict in data['channels'].items(): try: @@ -611,18 +618,12 @@ def set(self, args): try: cobj = ChannelObject(chdict, version) newchannels[cindex] = cobj - print('%d:%s' % (cindex, cobj)) + self.ctx.dbg('%d:%s' % (cindex, cobj)) except Exception as e: self.ctx.err('ERROR: %s' % e) self.ctx.die( 105, "Invalid channel description: %s" % chdict) - try: - greyscale = data['greyscale'] - print('greyscale=%s' % data['greyscale']) - except KeyError: - greyscale = None - namedict = {} cindices = [] rangelist = [] @@ -636,6 +637,18 @@ def set(self, args): cindices.append(i) rangelist.append([c.start, c.end]) colourlist.append(c.color) + return (namedict, cindices, rangelist, colourlist) + + @gateway_required + def set(self, args): + """ Implements the 'set' command """ + data = self._load_rendering_settings( + args.channels, session=self.client.getSession()) + (namedict, cindices, rangelist, colourlist) = self._read_channels( + data) + greyscale = data.get('greyscale', None) + if greyscale is not None: + self.ctx.dbg('greyscale=%s' % greyscale) iids = [] for img in self.render_images(self.gateway, args.object, batch=1): @@ -657,6 +670,7 @@ def set(self, args): img.set_active_channels( cindices, windows=rangelist, colors=colourlist) + if greyscale is not None: if greyscale: img.setGreyscaleRenderingModel() diff --git a/test/unit/test_set.py b/test/unit/test_set.py new file mode 100644 index 0000000..d8dadf3 --- /dev/null +++ b/test/unit/test_set.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# +# Copyright (C) 2015-2018 University of Dundee & Open Microscopy Environment. +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + +from omero.cli import CLI, NonZeroReturnCode +from omero_cli_render import RenderControl + +import pytest +import uuid +import yaml + + +def write_yaml(d, tmpdir): + f = tmpdir.join(str(uuid.uuid4()) + ".yml") + f.write(yaml.dump(d, explicit_start=True, width=80, indent=4, + default_flow_style=False)) + return str(f) + + +class TestLoadRenderingSettings: + def setup_method(self): + self.cli = CLI() + self.cli.register("render", RenderControl, "TEST") + self.render = self.cli.controls['render'] + + def test_none(self): + with pytest.raises(NonZeroReturnCode): + self.render._load_rendering_settings(None) + + def test_non_existing_file(self): + with pytest.raises(NonZeroReturnCode) as e: + self.render._load_rendering_settings(str(uuid.uuid4()) + '.yml') + assert e.value.rv == 103 + + def test_no_channels(self, tmpdir): + d = {'version': 1} + f = write_yaml(d, tmpdir) + with pytest.raises(NonZeroReturnCode) as e: + self.render._load_rendering_settings(f) + assert e.value.rv == 104 + + def test_bad_version(self, tmpdir): + d = {'channels': {1: {'label': 'foo'}}} + f = write_yaml(d, tmpdir) + with pytest.raises(NonZeroReturnCode) as e: + self.render._load_rendering_settings(f) + assert e.value.rv == 124 + + +class TestReadChannels: + def setup_method(self): + self.cli = CLI() + self.cli.register("render", RenderControl, "TEST") + self.render = self.cli.controls['render'] + + def test_non_integer_channel(self): + d = {'channels': {'GFP': {'label': 'foo'}}} + with pytest.raises(NonZeroReturnCode) as e: + self.render._read_channels(d) + assert e.value.rv == 105 + + @pytest.mark.parametrize('key', ['min', 'max', 'start', 'end']) + def test_float_keys(self, key): + d = {'channels': {1: {key: 'foo'}}} + with pytest.raises(NonZeroReturnCode) as e: + self.render._read_channels(d) + assert e.value.rv == 105