# -*- coding: utf-8 -*- # ***************************************************************************** # # 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., # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Module authors: # Enrico Faulhaber # # ***************************************************************************** """test data types.""" # no fixtures needed import pytest from frappy.datatypes import BoolType, FloatRange, IntRange, StructOf from frappy.errors import ProgrammingError from frappy.modules import HasAccessibles from frappy.params import Command, Parameter def test_Command(): class Mod(HasAccessibles): @Command() def cmd(self): """do something""" @Command(IntRange(-9,9), result=IntRange(-1,1), description='do some other thing') def cmd2(self): pass assert Mod.cmd.description == 'do something' assert Mod.cmd.argument is None assert Mod.cmd.result is None assert Mod.cmd.for_export() == {'datainfo': {'type': 'command'}, 'description': 'do something'} assert Mod.cmd2.description == 'do some other thing' assert isinstance(Mod.cmd2.argument, IntRange) assert isinstance(Mod.cmd2.result, IntRange) assert Mod.cmd2.for_export() == {'datainfo': {'type': 'command', 'argument': {'type': 'int', 'min': -9, 'max': 9}, 'result': {'type': 'int', 'min': -1, 'max': 1}}, 'description': 'do some other thing'} assert Mod.cmd2.exportProperties() == {'datainfo': {'type': 'command', 'argument': {'type': 'int', 'max': 9, 'min': -9}, 'result': {'type': 'int', 'max': 1, 'min': -1}}, 'description': 'do some other thing'} def test_cmd_struct_opt(): with pytest.raises(ProgrammingError): class WrongName(HasAccessibles): # pylint: disable=unused-variable @Command(StructOf(a=IntRange(), b=IntRange())) def cmd(self, a, c): pass class Mod(HasAccessibles): @Command(StructOf(a=IntRange(), b=IntRange())) def cmd(self, a=5, b=5): pass assert Mod.cmd.datatype.argument.optional == ['a', 'b'] class Mod2(HasAccessibles): @Command(StructOf(a=IntRange(), b=IntRange())) def cmd(self, a, b=5): pass assert Mod2.cmd.datatype.argument.optional == ['b'] class Mod3(HasAccessibles): @Command(StructOf(a=IntRange(), b=IntRange())) def cmd(self, a, b): pass assert Mod3.cmd.datatype.argument.optional == [] def test_Parameter(): class Mod(HasAccessibles): p1 = Parameter('desc1', datatype=FloatRange(), default=0) p2 = Parameter('desc2', datatype=FloatRange(), default=0, readonly=True) p3 = Parameter('desc3', datatype=FloatRange(), default=0, readonly=False) p4 = Parameter('desc4', datatype=FloatRange(), constant=1) assert repr(Mod.p1) != repr(Mod.p3) assert id(Mod.p1.datatype) != id(Mod.p2.datatype) assert Mod.p1.exportProperties() == {'datainfo': {'type': 'double'}, 'description': 'desc1', 'readonly': True} assert Mod.p2.exportProperties() == {'datainfo': {'type': 'double'}, 'description': 'desc2', 'readonly': True} assert Mod.p3.exportProperties() == {'datainfo': {'type': 'double'}, 'description': 'desc3', 'readonly': False} assert Mod.p4.exportProperties() == {'datainfo': {'type': 'double'}, 'description': 'desc4', 'readonly': True, 'constant': 1.0} p3 = Mod.p1.copy() assert id(p3) != id(Mod.p1) assert repr(Mod.p1) == repr(p3) with pytest.raises(ProgrammingError): Parameter(None, datatype=float, inherit=False) def test_Override(): class Base(HasAccessibles): p1 = Parameter('description1', datatype=BoolType, default=False) p2 = Parameter('description1', datatype=BoolType, default=False) p3 = Parameter('description1', datatype=BoolType, default=False) class Mod(Base): p1 = Parameter(default=True) p2 = Parameter() # override without change assert id(Mod.p1) != id(Base.p1) assert id(Mod.p2) != id(Base.p2) assert id(Mod.p3) == id(Base.p3) assert repr(Mod.p2) == repr(Base.p2) # must be a clone assert repr(Mod.p3) == repr(Base.p3) # must be a clone assert Mod.p1.default is True # manipulating default makes Base.p1 and Mod.p1 match Mod.p1.default = False assert repr(Mod.p1) == repr(Base.p1) for cls in locals().values(): if hasattr(cls, 'accessibles'): for p in cls.accessibles.values(): assert isinstance(p.ownProperties, dict) assert p.copy().ownProperties == {} def test_Export(): class Mod(HasAccessibles): param = Parameter('description1', datatype=BoolType, default=False) assert Mod.param.export == '_param' @pytest.mark.parametrize('arg, value', [ ('always', 0), (0, 0), ('never', 999999999), (999999999, 999999999), (1, 1), ]) def test_update_unchanged_ok(arg, value): par = Parameter('', datatype=FloatRange(), default=0, update_unchanged=arg) assert par.update_unchanged == value @pytest.mark.parametrize('arg', ['alws', '', -2, -0.1, None]) def test_update_unchanged_fail(arg): with pytest.raises(ProgrammingError): Parameter('', datatype=FloatRange(), default=0, update_unchanged=arg)