/*
* Copyright (c) 2005-2011 Grameen Foundation USA
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
* See also http://www.apache.org/licenses/LICENSE-2.0.html for an
* explanation of the license and how it is applied.
*/
package org.mifos.framework.formulaic;
import java.math.BigInteger;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import junit.framework.Assert;
import junit.framework.TestCase;
import org.joda.time.DateMidnight;
import org.testng.annotations.Test;
@SuppressWarnings("unchecked")
@Test(groups={"unit", "fastTestsSuite"}, dependsOnGroups={"productMixTestSuite"})
public class ValidatorsTest extends TestCase {
private void checkException(Validator val, Object input, String error) {
try {
val.validate(input);
Assert.fail();
} catch (ValidationError e) {
Assert.assertTrue(e.getMsg().endsWith(error));
}
}
public void testDateComponentValidator() throws Exception {
Validator validator = new DateComponentValidator();
Map<String, String> inputMap = new HashMap<String, String>();
Date expectedDate = new DateMidnight(2000, 05, 20).toDate();
inputMap.put("DD", "20");
inputMap.put("MM", "5");
inputMap.put("YY", "2000");
Assert.assertEquals(expectedDate, validator.validate(inputMap));
inputMap.put("MM", "20");
checkException(validator, inputMap, ErrorType.DATE_FORMAT.toString());
Schema schema = new Schema();
schema.setMapValidator("mydate", validator);
inputMap = new HashMap<String, String>();
inputMap.put("mydate_DD", "20");
inputMap.put("mydate_MM", "5");
inputMap.put("mydate_YY", "2000");
Assert.assertEquals(expectedDate, schema.validate(inputMap).get("mydate"));
}
public void testDateValidator() throws Exception {
Validator validator = new DateValidator();
Date expectedDate = new DateMidnight(2005, 04, 03).toDate();
Assert.assertEquals(expectedDate, validator.validate("3/4/2005"));
checkException(validator, "5/13/2000", ErrorType.DATE_FORMAT.toString());
}
public void testSchemaCompoundFunctionality() {
Map<String, Object> data = new HashMap<String, Object>();
data.put("simple", "a");
data.put("map_one", "b");
data.put("map_two", "c");
Assert.assertEquals("a", Schema.parseField("simple", Schema.FieldType.SIMPLE, data));
Assert.assertNull(Schema.parseField("notafield", Schema.FieldType.SIMPLE, data));
Map<String, Object> expectedResults = new HashMap<String, Object>();
expectedResults.put("one", "b");
expectedResults.put("two", "c");
Assert.assertEquals(expectedResults, Schema.parseField("map", Schema.FieldType.MAP, data));
}
private enum TestEnum {
VALUE_ONE,
}
public void testEnumValidator() throws Exception {
Validator val = new EnumValidator(TestEnum.class);
Assert.assertEquals(TestEnum.VALUE_ONE, val.validate("VALUE_ONE"));
Assert.assertEquals(TestEnum.VALUE_ONE, val.validate("value_one"));
checkException(val, null, ErrorType.MISSING.toString());
checkException(val, "bad value", ErrorType.INVALID_ENUM.toString());
}
public void testSwitchValidator() throws Exception {
SwitchValidator val = new SwitchValidator("switch_field");
Schema schemaA = new Schema();
schemaA.setSimpleValidator("age", new IntValidator());
val.addCase("a", schemaA);
Schema schemaB = new Schema();
schemaB.setSimpleValidator("name", new MaxLengthValidator(5));
val.addCase("b", schemaB);
Map<String, String> data = new HashMap<String, String>();
data.put("switch_field", "a");
data.put("age", "2");
Map<String, Object> results = val.validate(data);
Assert.assertEquals(2, results.get("age"));
data.put("name", "bob");
data.put("switch_field", "b");
results = val.validate(data);
Assert.assertEquals("bob", results.get("name"));
try {
data.put("switch_field", "c");
val.validate(data);
Assert.fail();
} catch (ValidationError e) {
Assert.assertEquals(val.getKey(ErrorType.MISSING_EXPECTED_VALUE.toString()), e.getMsg());
}
val.setDefaultCase(schemaB);
val.validate(data);
}
public void testIntValidator() throws Exception {
Validator val = new IntValidator();
Assert.assertEquals(42, val.validate("42"));
Assert.assertEquals(42, val.validate("042"));
checkException(val, "notanumber", ErrorType.INVALID_INT.toString());
// check error when given wrong type
checkException(val, new LinkedList(), ErrorType.WRONG_TYPE.toString());
checkException(val, " 042", ErrorType.INVALID_INT.toString());
}
public void testIsInstanceValidator() throws Exception {
Validator val = new IsInstanceValidator(Number.class);
Assert.assertEquals(42, val.validate(42));
Assert.assertEquals(new BigInteger("42"), val.validate(new BigInteger("42")));
checkException(val, "a string", ErrorType.WRONG_TYPE.toString());
}
public void testIdentityValidator() throws Exception {
Validator val = new IdentityValidator();
String input = "a string";
Assert.assertEquals(input, val.validate(input));
Assert.assertEquals(null, val.validate(null));
}
public void testNullValidator() throws Exception {
Validator val = new NullValidator(new IntValidator());
Assert.assertEquals(null, val.validate(null));
Assert.assertEquals(42, val.validate("42"));
checkException(val, "a string", ErrorType.INVALID_INT.toString());
}
public void testMaxLengthValidator() throws Exception {
Validator val = new MaxLengthValidator(4);
Assert.assertEquals("abc", val.validate("abc"));
Assert.assertEquals("abcd", val.validate("abcd"));
checkException(val, "toolong", ErrorType.STRING_TOO_LONG.toString());
}
public void testSchema() throws Exception {
Schema schema = new Schema();
BaseValidator intValidator = new IntValidator();
schema.setSimpleValidator("fieldOne", intValidator);
BaseValidator maxLengthValidator = new MaxLengthValidator(4);
schema.setSimpleValidator("fieldTwo", maxLengthValidator);
Map<String, String> input = new HashMap<String, String>();
input.put("fieldOne", "42");
input.put("fieldTwo", "abcd");
Map<String, Object> results = schema.validate(input);
Assert.assertTrue(42 == (Integer) results.get("fieldOne"));
Assert.assertEquals("abcd", (String) results.get("fieldTwo"));
input.put("fieldOne", null);
input.put("fieldTwo", "abcde");
try {
schema.validate(input);
Assert.fail();
} catch (SchemaValidationError e) {
Assert.assertEquals(2, e.size());
Assert.assertEquals(maxLengthValidator.getKey(ErrorType.STRING_TOO_LONG.toString()), e.getFieldMsg("fieldTwo"));
Assert.assertEquals(intValidator.getKey(ErrorType.MISSING.toString()), e.getFieldMsg("fieldOne"));
}
// now make field one optional
schema.setSimpleValidator("fieldOne", new NullValidator(new IntValidator()));
try {
schema.validate(input);
Assert.fail();
} catch (SchemaValidationError e) {
Assert.assertEquals(1, e.size());
Assert.assertEquals(maxLengthValidator.getKey(ErrorType.STRING_TOO_LONG.toString()), e.getFieldMsg("fieldTwo"));
}
}
// the itemsource version of OneOfValidator is intended to
// be used with inner classes (perhaps anonymous) like this..
// so that instance methods to access hibernate persistence
// will work
private class TestItemSource implements OneOfValidatorSource {
@Override
public Collection getItems() {
LinkedList<String> items = new LinkedList<String>();
items.add("one");
items.add("two");
return items;
}
}
public void testOneOfValidator() throws Exception {
LinkedList<String> items = new LinkedList<String>();
items.add("one");
items.add("two");
Validator val = new OneOfValidator(items);
Assert.assertEquals("one", val.validate("one"));
checkException(val, null, ErrorType.MISSING.toString());
checkException(val, "three", ErrorType.NOT_A_CHOICE.toString());
val = new OneOfValidator(new TestItemSource());
Assert.assertEquals("one", val.validate("one"));
checkException(val, null, ErrorType.MISSING.toString());
checkException(val, "three", ErrorType.NOT_A_CHOICE.toString());
}
}