Skip to content

Commit

Permalink
Export ListValidator to python. Refs #4399
Browse files Browse the repository at this point in the history
  • Loading branch information
martyngigg committed Apr 15, 2012
1 parent d62796c commit ae56ffc
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 1 deletion.
1 change: 1 addition & 0 deletions Code/Mantid/Framework/PythonInterface/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ set ( TEST_PY_FILES
test/python/InstrumentInfoTest.py
test/python/InstrumentTest.py
test/python/ITableWorkspaceTest.py
test/python/ListValidatorTest.py
test/python/LoggerTest.py
test/python/MatrixWorkspaceTest.py
test/python/MDHistoWorkspaceTest.py
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ set ( EXPORT_FILES
src/Exports/InstrumentInfo.cpp
src/Exports/FacilityInfo.cpp
src/Exports/NullValidator.cpp
src/Exports/ListValidator.cpp
)

set ( SRC_FILES
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include "MantidKernel/ListValidator.h"
#include "MantidPythonInterface/kernel/Converters/PySequenceToVector.h"

#include <boost/python/class.hpp>
#include <boost/python/list.hpp>
#include <boost/python/make_constructor.hpp>
#include <boost/python/default_call_policies.hpp>

#include <string>

using Mantid::Kernel::ListValidator;
using Mantid::Kernel::IValidator;
namespace Converters = Mantid::PythonInterface::Converters;
using namespace boost::python;

namespace
{

/**
* Factory function to allow the allowed values to be specified as a python list
* @param allowedValues :: The list of allowed values
* @return A new ListValidator instance
*/
template<typename T>
ListValidator<T> * createListValidator(const boost::python::list & allowedValues)
{
return new ListValidator<T>(Converters::PySequenceToVector<T>(allowedValues)());
}


#define EXPORT_LISTVALIDATOR(type, prefix) \
class_<ListValidator<type>, bases<IValidator>, \
boost::noncopyable>(#prefix"ListValidator") \
.def("__init__", make_constructor(&createListValidator<type>, default_call_policies(), \
arg("allowedValues"))) \
.def("addAllowedValue", &ListValidator<type>::addAllowedValue, \
"Adds a value to the list of accepted values") \
;

}

void export_ListValidator()
{
EXPORT_LISTVALIDATOR(std::string, String);
}

Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"""Test the exposed ArrayProperty
"""
import unittest
from mantid import FloatArrayProperty, Direction, NullValidator
from mantid import (FloatArrayProperty, StringArrayProperty, Direction,
NullValidator, PythonAlgorithm)
import numpy as np

class ArrayPropertyTest(unittest.TestCase):
Expand Down Expand Up @@ -90,3 +91,53 @@ def _check_object_attributes(self, arrprop, name, direction, length = 0):
self.assertEquals(arrprop.direction, direction)
self.assertEquals(len(arrprop.value), length)

def test_PythonAlgorithm_setProperty_with_FloatArrayProperty(self):
"""
Test ArrayProperty within a python algorithm
"""
class AlgWithFloatArrayProperty(PythonAlgorithm):

_input_values = None

def PyInit(self):
name = "numbers"
self.declareProperty(
FloatArrayProperty("Input", Direction.Input), "Float array")

def PyExec(self):
self._input_values = self.getProperty("Input").value

input_values = [1.1,2.5,5.6,4.6,9.0,6.0]
self._do_algorithm_test(AlgWithFloatArrayProperty, input_values)

def test_PythonAlgorithm_setProperty_with_StringArrayProperty(self):
"""
Test StringArrayProperty within a python algorithm
"""
class AlgWithStringArrayProperty(PythonAlgorithm):

_input_values = None

def PyInit(self):
self.declareProperty(
StringArrayProperty("Input", Direction.Input), "string array")

def PyExec(self):
self._input_values = self.getProperty("Input").value

input_values = ["val1","val2","val3"]
self._do_algorithm_test(AlgWithStringArrayProperty, input_values)

def _do_algorithm_test(self, class_, input_values):
"""
Run the algorithm and test the values are passed correctly
"""
alg = class_()
alg.initialize()
alg.setProperty("Input", input_values)
alg.execute()

self.assertTrue(alg._input_values is not None)
self.assertEquals(len(alg._input_values), len(input_values))
for index, val in enumerate(input_values):
self.assertEquals(val,input_values[index])
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import unittest
import testhelpers

from mantid import (StringListValidator, Direction, PythonAlgorithm)


class ListValidatorTest(unittest.TestCase):

def test_empty_ListValidator_allows_nothing(self):
"""
Test that a list validator restricts the values
for a property
"""

class EmptyListValidator(PythonAlgorithm):

def PyInit(self):
validator = StringListValidator()
self.declareProperty("Input", "", validator)

def PyExec(self):
pass

alg = EmptyListValidator()
alg.initialize()
self.assertRaises(ValueError, alg.setProperty, "Input", "AnyOldString")

def test_ListValidator_plus_addAllowedValued_allows_that_value(self):
"""
Test that a list validator restricts the values
for a property
"""

class SingleItemListValidator(PythonAlgorithm):

_allowed = "OnlyThis"

def PyInit(self):
validator = StringListValidator()
validator.addAllowedValue(self._allowed)
self.declareProperty("Input", "", validator)

def PyExec(self):
pass

alg = SingleItemListValidator()
alg.initialize()
self.assertRaises(ValueError, alg.setProperty, "Input", "NotValid")
testhelpers.assertRaisesNothing(self, alg.setProperty, "Input", alg._allowed)

def test_ListValidator_with_values_in_constructor_restricts_property_values(self):
"""
Test that a list validator restricts the values
for a property
"""

class MultiValueValidator(PythonAlgorithm):

_allowed_vals = ["Val1", "Val2","Val3"]

def PyInit(self):
validator = StringListValidator(self._allowed_vals)
self.declareProperty("Input", "", validator)

def PyExec(self):
pass

alg = MultiValueValidator()
alg.initialize()
self.assertRaises(ValueError, alg.setProperty, "Input", "NotValid")
for val in alg._allowed_vals:
testhelpers.assertRaisesNothing(self, alg.setProperty, "Input", val)


if __name__ == '__main__':
unittest.main()

0 comments on commit ae56ffc

Please sign in to comment.