/*
* Copyright (C) 2010 Brockmann Consult GmbH (info@brockmann-consult.de)
*
* 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 3 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, see http://www.gnu.org/licenses/
*/
package com.bc.ceres.binding;
import com.bc.ceres.binding.validators.TypeValidator;
import com.bc.ceres.binding.validators.MultiValidator;
import com.bc.ceres.binding.validators.NotNullValidator;
import junit.framework.TestCase;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.HashMap;
public class PropertyTest extends TestCase {
private static final long LEGAL_PLONG = 999L;
private static final Long LEGAL_OLONG = 999L;
private static final String ILLEGAL = "42";
private static final float FLOAT_EPS = 1.0e-4f;
private static final double DOUBLE_EPS = 1.0e-10;
private static final String MODE_ACCURATE = "acc";
private static final String MODE_FUZZY = "fuz";
long plong;
Long olong;
float pfloat;
Float ofloat;
double pdouble;
Double odouble;
public void testFactoryUsingClassFieldAccessor() throws ValidationException {
testPLong(Property.createForField(this, "plong"), 0L);
testOLong(Property.createForField(this, "olong"), null);
assertEquals(LEGAL_PLONG, plong);
assertEquals(LEGAL_OLONG, olong);
testPLong(Property.createForField(this, "plong", 42L), 42L);
testOLong(Property.createForField(this, "olong", 43L), 43L);
assertEquals(LEGAL_PLONG, plong);
assertEquals(LEGAL_OLONG, olong);
}
public void testFactoryUsingMapEntryAccessor() throws ValidationException {
HashMap<String, Object> map = new HashMap<String, Object>();
testPLong(Property.createForMapEntry(map, "plong", Long.TYPE), 0L);
testOLong(Property.createForMapEntry(map, "olong", Long.class), null);
assertEquals(LEGAL_OLONG, map.get("plong"));
assertEquals(LEGAL_OLONG, map.get("olong"));
testPLong(Property.createForMapEntry(map, "plong", Long.TYPE, 42L), 42L);
testOLong(Property.createForMapEntry(map, "olong", Long.class, 43L), 43L);
assertEquals(LEGAL_OLONG, map.get("plong"));
assertEquals(LEGAL_OLONG, map.get("olong"));
}
public void testDefaultFactoryWithType() throws ValidationException {
testPLong(Property.create("plong", Long.TYPE), 0L);
testOLong(Property.create("olong", Long.class), null);
testOLong(Property.create("olong", 42L), 42L);
}
private void testPLong(Property vm, Object expectedValue) throws ValidationException {
assertNotNull(vm.getDescriptor());
assertEquals("plong", vm.getDescriptor().getName());
assertSame(Long.TYPE, vm.getDescriptor().getType());
assertEquals(true, vm.getDescriptor().isNotNull());
assertNotNull(vm.getDescriptor().getConverter());
assertSame(MultiValidator.class, vm.getValidator().getClass());
Validator[] validators = ((MultiValidator) vm.getValidator()).getValidators();
assertEquals(2, validators.length);
assertSame(NotNullValidator.class, validators[0].getClass());
assertSame(TypeValidator.class, validators[1].getClass());
assertTrue(vm.getValue() instanceof Long);
assertEquals(expectedValue, vm.getValue());
testSetLegalValue(vm);
testSetIllegalValue(vm);
}
private void testOLong(Property vm, Object expectedValue) throws ValidationException {
assertNotNull(vm.getDescriptor());
assertEquals("olong", vm.getDescriptor().getName());
assertEquals(false, vm.getDescriptor().isNotNull());
assertSame(Long.class, vm.getDescriptor().getType());
assertNotNull(vm.getDescriptor().getConverter());
assertSame(TypeValidator.class, vm.getValidator().getClass());
assertEquals(expectedValue, vm.getValue());
testSetLegalValue(vm);
testSetIllegalValue(vm);
}
private void testSetLegalValue(Property vm) throws ValidationException {
vm.setValue(LEGAL_OLONG);
assertEquals(LEGAL_OLONG, vm.getValue());
}
private void testSetIllegalValue(Property property) {
try {
property.setValue(ILLEGAL);
fail("ValidationException expected");
} catch (ValidationException e) {
// ok
}
}
public void testPropertyChangeEvents() throws ValidationException {
final Property plong = Property.createForField(this, "plong");
final Property olong = Property.createForField(this, "olong");
final Property pfloat = Property.createForField(this, "pfloat");
final Property ofloat = Property.createForField(this, "ofloat");
final Property pdouble = Property.createForField(this, "pdouble");
final Property odouble = Property.createForField(this, "odouble");
final PropertyContainer container = new PropertyContainer();
final ValueModelChangeListener listener = new ValueModelChangeListener();
container.addPropertyChangeListener(listener);
container.addProperty(plong);
container.addProperty(olong);
container.addProperty(pfloat);
container.addProperty(ofloat);
container.addProperty(pdouble);
container.addProperty(odouble);
testPCLLong(plong, listener);
testPCLLong(olong, listener);
testPCLFloat(pfloat, listener, MODE_ACCURATE);
testPCLFloat(ofloat, listener, MODE_ACCURATE);
testPCLDouble(pdouble, listener, MODE_ACCURATE);
testPCLDouble(odouble, listener, MODE_ACCURATE);
pfloat.getDescriptor().setAttribute("eps", FLOAT_EPS);
ofloat.getDescriptor().setAttribute("eps", FLOAT_EPS);
pdouble.getDescriptor().setAttribute("eps", DOUBLE_EPS);
odouble.getDescriptor().setAttribute("eps", DOUBLE_EPS);
testPCLLong(plong, listener);
testPCLLong(olong, listener);
testPCLFloat(pfloat, listener, MODE_FUZZY);
testPCLFloat(ofloat, listener, MODE_FUZZY);
testPCLDouble(pdouble, listener, MODE_FUZZY);
testPCLDouble(odouble, listener, MODE_FUZZY);
}
private void testPCLLong(Property model, ValueModelChangeListener listener) throws ValidationException {
final int n0 = listener.events.size();
model.setValue(1L);
assertEquals(1, listener.events.size() - n0);
model.setValue(1L);
assertEquals(1, listener.events.size() - n0);
model.setValue(2L);
assertEquals(2, listener.events.size() - n0);
}
private void testPCLFloat(Property model, ValueModelChangeListener listener, String mode) throws ValidationException {
final int n0 = listener.events.size();
model.setValue(1.0f);
assertEquals(1, listener.events.size() - n0);
model.setValue(1.0f);
assertEquals(1, listener.events.size() - n0);
model.setValue(2.0f);
assertEquals(2, listener.events.size() - n0);
if (mode.equals(MODE_FUZZY)) {
model.setValue(2.0f - 0.99f * FLOAT_EPS);
assertEquals(2, listener.events.size() - n0);
model.setValue(2.0f + 0.99f * FLOAT_EPS);
assertEquals(2, listener.events.size() - n0);
} else {
model.setValue(2.0f - 0.99f * FLOAT_EPS);
assertEquals(3, listener.events.size() - n0);
model.setValue(2.0f + 0.99f * FLOAT_EPS);
assertEquals(4, listener.events.size() - n0);
}
}
private void testPCLDouble(Property model, ValueModelChangeListener listener, String mode) throws ValidationException {
final int n0 = listener.events.size();
model.setValue(1.0);
assertEquals(1, listener.events.size() - n0);
model.setValue(1.0);
assertEquals(1, listener.events.size() - n0);
model.setValue(2.0);
assertEquals(2, listener.events.size() - n0);
if (mode.equals(MODE_FUZZY)) {
model.setValue(2.0 - 0.99 * DOUBLE_EPS);
assertEquals(2, listener.events.size() - n0);
model.setValue(2.0 + 0.99 * DOUBLE_EPS);
assertEquals(2, listener.events.size() - n0);
} else {
model.setValue(2.0 - 0.99 * DOUBLE_EPS);
assertEquals(3, listener.events.size() - n0);
model.setValue(2.0 + 0.99 * DOUBLE_EPS);
assertEquals(4, listener.events.size() - n0);
}
}
private static class ValueModelChangeListener implements PropertyChangeListener {
ArrayList<PropertyChangeEvent> events = new ArrayList<PropertyChangeEvent>();
@Override
public void propertyChange(PropertyChangeEvent event) {
events.add(event);
}
}
}