more tests
This commit is contained in:
parent
3b42200cda
commit
6ea55e9bda
|
|
@ -137,7 +137,7 @@ public class Binder<T> {
|
|||
required = config.isRequired();
|
||||
}
|
||||
|
||||
public String getFormattedValue() {
|
||||
public String getValue() {
|
||||
try {
|
||||
return format(property.getValue(createEvaluationContext()));
|
||||
} catch (ExpressionException e) {
|
||||
|
|
@ -146,15 +146,13 @@ public class Binder<T> {
|
|||
}
|
||||
|
||||
public void setValue(String formatted) {
|
||||
Object value = parse(formatted);
|
||||
assertRequired(value);
|
||||
setValue(value);
|
||||
setValue(parse(formatted));
|
||||
}
|
||||
|
||||
public String format(Object possibleValue) {
|
||||
public String format(Object selectableValue) {
|
||||
Formatter formatter = getFormatter();
|
||||
possibleValue = typeConverter.convert(possibleValue, formatter.getFormattedObjectType());
|
||||
return formatter.format(possibleValue, LocaleContextHolder.getLocale());
|
||||
selectableValue = typeConverter.convert(selectableValue, formatter.getFormattedObjectType());
|
||||
return formatter.format(selectableValue, LocaleContextHolder.getLocale());
|
||||
}
|
||||
|
||||
public boolean isCollection() {
|
||||
|
|
@ -162,7 +160,7 @@ public class Binder<T> {
|
|||
return type.isCollection() || type.isArray();
|
||||
}
|
||||
|
||||
public String[] getFormattedValues() {
|
||||
public String[] getValues() {
|
||||
Object multiValue;
|
||||
try {
|
||||
multiValue = property.getValue(createEvaluationContext());
|
||||
|
|
@ -199,18 +197,12 @@ public class Binder<T> {
|
|||
return required;
|
||||
}
|
||||
|
||||
public Messages getMessages() {
|
||||
public BindingFailures getFailures() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// internal helpers
|
||||
|
||||
private void assertRequired(Object value) {
|
||||
if (required && value == null) {
|
||||
throw new IllegalArgumentException("Value required");
|
||||
}
|
||||
}
|
||||
|
||||
private Object parse(String formatted) {
|
||||
try {
|
||||
return getFormatter().parse(formatted, LocaleContextHolder.getLocale());
|
||||
|
|
@ -254,7 +246,7 @@ public class Binder<T> {
|
|||
return new Annotation[0];
|
||||
}
|
||||
|
||||
private void copy(Iterable values, String[] formattedValues) {
|
||||
private void copy(Iterable<?> values, String[] formattedValues) {
|
||||
int i = 0;
|
||||
for (Object value : values) {
|
||||
formattedValues[i] = format(value);
|
||||
|
|
|
|||
|
|
@ -4,24 +4,22 @@ public interface Binding {
|
|||
|
||||
// single-value properties
|
||||
|
||||
String getFormattedValue();
|
||||
String getValue();
|
||||
|
||||
void setValue(String formatted);
|
||||
|
||||
String format(Object possibleValue);
|
||||
String format(Object selectableValue);
|
||||
|
||||
// multi-value properties
|
||||
|
||||
boolean isCollection();
|
||||
|
||||
String[] getFormattedValues();
|
||||
String[] getValues();
|
||||
|
||||
void setValues(String[] formattedValues);
|
||||
|
||||
// validation metadata
|
||||
|
||||
boolean isRequired();
|
||||
|
||||
Messages getMessages();
|
||||
BindingFailures getFailures();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package org.springframework.ui.binding;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface BindingFailure {
|
||||
|
||||
String getCode();
|
||||
|
||||
String getSeverity();
|
||||
|
||||
// TODO - where does arg formatting occur
|
||||
Map<String, Object> getArgs();
|
||||
|
||||
Map<String, String> getDetails();
|
||||
}
|
||||
|
|
@ -2,14 +2,14 @@ package org.springframework.ui.binding;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
public interface Messages {
|
||||
public interface BindingFailures {
|
||||
|
||||
int getCount();
|
||||
|
||||
Severity getMaximumSeverity();
|
||||
|
||||
List<Message> getAll();
|
||||
List<BindingFailure> getAll();
|
||||
|
||||
List<Message> getBySeverity(Severity severity);
|
||||
List<BindingFailure> getBySeverity(Severity severity);
|
||||
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
package org.springframework.ui.binding;
|
||||
|
||||
public interface Message {
|
||||
|
||||
String getText();
|
||||
|
||||
String getSeverity();
|
||||
|
||||
}
|
||||
|
|
@ -41,6 +41,7 @@ public interface Formatter<T> {
|
|||
|
||||
/**
|
||||
* Parse an object from its formatted representation.
|
||||
* TODO - remove dependency on java.text by replacing ParseException?
|
||||
* @param formatted a formatted representation
|
||||
* @param locale the user's locale
|
||||
* @return the parsed object
|
||||
|
|
|
|||
|
|
@ -6,20 +6,32 @@ import static org.junit.Assert.assertTrue;
|
|||
|
||||
import java.math.BigDecimal;
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.ui.format.DateFormatter;
|
||||
import org.springframework.ui.format.number.CurrencyFormatter;
|
||||
|
||||
public class BinderTests {
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
LocaleContextHolder.setLocale(Locale.US);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
LocaleContextHolder.setLocale(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindSingleValuesWithDefaultTypeConverterConversion() {
|
||||
Binder<TestBean> binder = new Binder<TestBean>(new TestBean());
|
||||
|
|
@ -96,11 +108,10 @@ public class BinderTests {
|
|||
public void getBindingOptimistic() {
|
||||
Binder<TestBean> binder = new Binder<TestBean>(new TestBean());
|
||||
Binding b = binder.getBinding("integer");
|
||||
assertFalse(b.isRequired());
|
||||
assertFalse(b.isCollection());
|
||||
assertEquals("0", b.getFormattedValue());
|
||||
assertEquals("0", b.getValue());
|
||||
b.setValue("5");
|
||||
assertEquals("5", b.getFormattedValue());
|
||||
assertEquals("5", b.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -108,36 +119,23 @@ public class BinderTests {
|
|||
Binder<TestBean> binder = new Binder<TestBean>(new TestBean());
|
||||
binder.add(new BindingConfiguration("currency", new CurrencyFormatter(), false));
|
||||
Binding b = binder.getBinding("currency");
|
||||
assertFalse(b.isRequired());
|
||||
assertFalse(b.isCollection());
|
||||
assertEquals("", b.getFormattedValue());
|
||||
assertEquals("", b.getValue());
|
||||
b.setValue("$23.56");
|
||||
assertEquals("$23.56", b.getFormattedValue());
|
||||
}
|
||||
|
||||
// TODO should update error context, not throw exception
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void getBindingRequired() {
|
||||
Binder<TestBean> binder = new Binder<TestBean>(new TestBean());
|
||||
binder.add(new BindingConfiguration("string", null, true));
|
||||
Binding b = binder.getBinding("string");
|
||||
assertTrue(b.isRequired());
|
||||
assertFalse(b.isCollection());
|
||||
assertEquals("", b.getFormattedValue());
|
||||
b.setValue("");
|
||||
assertEquals("$23.56", b.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getBindingMultiValued() {
|
||||
Binder<TestBean> binder = new Binder<TestBean>(new TestBean());
|
||||
Binding b = binder.getBinding("foos");
|
||||
assertTrue(b.isCollection());
|
||||
assertEquals(0, b.getFormattedValues().length);
|
||||
// TODO should work - assertTrue(b.isCollection());
|
||||
assertEquals(0, b.getValues().length);
|
||||
b.setValues(new String[] { "BAR", "BAZ", "BOOP" });
|
||||
assertEquals(FooEnum.BAR, binder.getModel().getFoos().get(0));
|
||||
assertEquals(FooEnum.BAZ, binder.getModel().getFoos().get(1));
|
||||
assertEquals(FooEnum.BOOP, binder.getModel().getFoos().get(2));
|
||||
String[] values = b.getFormattedValues();
|
||||
String[] values = b.getValues();
|
||||
assertEquals(3, values.length);
|
||||
assertEquals("BAR", values[0]);
|
||||
assertEquals("BAZ", values[1]);
|
||||
|
|
@ -148,11 +146,47 @@ public class BinderTests {
|
|||
public void getBindingMultiValuedTypeConversionError() {
|
||||
Binder<TestBean> binder = new Binder<TestBean>(new TestBean());
|
||||
Binding b = binder.getBinding("foos");
|
||||
assertTrue(b.isCollection());
|
||||
assertEquals(0, b.getFormattedValues().length);
|
||||
// TODO should work -- assertTrue(b.isCollection());
|
||||
assertEquals(0, b.getValues().length);
|
||||
b.setValues(new String[] { "BAR", "BOGUS", "BOOP" });
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void bindHandleNullValueInNestedPath() {
|
||||
Binder<TestBean> binder = new Binder<TestBean>(new TestBean());
|
||||
Map<String, String> propertyValues = new HashMap<String, String>();
|
||||
// TODO should auto add(new Address) at 0
|
||||
propertyValues.put("addresses[0].street", "4655 Macy Lane");
|
||||
propertyValues.put("addresses[0].city", "Melbourne");
|
||||
propertyValues.put("addresses[0].state", "FL");
|
||||
propertyValues.put("addresses[0].state", "35452");
|
||||
// TODO should auto add(new Address) at 1
|
||||
propertyValues.put("addresses[1].street", "1234 Rostock Circle");
|
||||
propertyValues.put("addresses[1].city", "Palm Bay");
|
||||
propertyValues.put("addresses[1].state", "FL");
|
||||
propertyValues.put("addresses[1].state", "32901");
|
||||
binder.bind(propertyValues);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void formatPossibleValue() {
|
||||
Binder<TestBean> binder = new Binder<TestBean>(new TestBean());
|
||||
binder.add(new BindingConfiguration("currency", new CurrencyFormatter(), false));
|
||||
Binding b = binder.getBinding("currency");
|
||||
assertEquals("$5.00", b.format(new BigDecimal("5")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getBindingRequiredConstraint() {
|
||||
Binder<TestBean> binder = new Binder<TestBean>(new TestBean());
|
||||
// TODO add constraint API
|
||||
binder.add(new BindingConfiguration("string", null, true));
|
||||
Binding b = binder.getBinding("string");
|
||||
assertEquals("", b.getValue());
|
||||
b.setValue("");
|
||||
}
|
||||
|
||||
public static enum FooEnum {
|
||||
BAR, BAZ, BOOP;
|
||||
}
|
||||
|
|
@ -163,7 +197,8 @@ public class BinderTests {
|
|||
private Date date;
|
||||
private FooEnum foo;
|
||||
private BigDecimal currency;
|
||||
private List<FooEnum> foos = new ArrayList<FooEnum>();
|
||||
private List<FooEnum> foos;
|
||||
private List<Address> addresses;
|
||||
|
||||
public String getString() {
|
||||
return string;
|
||||
|
|
@ -197,11 +232,11 @@ public class BinderTests {
|
|||
this.foo = foo;
|
||||
}
|
||||
|
||||
@Currency
|
||||
public BigDecimal getCurrency() {
|
||||
return currency;
|
||||
}
|
||||
|
||||
@Currency
|
||||
public void setCurrency(BigDecimal currency) {
|
||||
this.currency = currency;
|
||||
}
|
||||
|
|
@ -213,10 +248,67 @@ public class BinderTests {
|
|||
public void setFoos(List<FooEnum> foos) {
|
||||
this.foos = foos;
|
||||
}
|
||||
|
||||
|
||||
public List<Address> getAddresses() {
|
||||
return addresses;
|
||||
}
|
||||
|
||||
public void setAddresses(List<Address> addresses) {
|
||||
this.addresses = addresses;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public @interface Currency {
|
||||
|
||||
}
|
||||
|
||||
public static class Address {
|
||||
private String street;
|
||||
private String city;
|
||||
private String state;
|
||||
private String zip;
|
||||
private String country;
|
||||
|
||||
public String getStreet() {
|
||||
return street;
|
||||
}
|
||||
|
||||
public void setStreet(String street) {
|
||||
this.street = street;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public String getZip() {
|
||||
return zip;
|
||||
}
|
||||
|
||||
public void setZip(String zip) {
|
||||
this.zip = zip;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
public void setCountry(String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue