package org.robobinding.attribute;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import org.junit.Before;
import org.junit.experimental.theories.DataPoints;
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.runner.RunWith;
import org.robobinding.attribute.StaticResourceTest.LegalStaticResource;
import org.robobinding.attribute.ValueModelAttributeTest.LegalValueModelAttributeValue;
/**
*
* @since 1.0
* @version $Revision: 1.0 $
* @author Robert Taylor
*/
@RunWith(Theories.class)
public class PropertyAttributeParserTest {
@DataPoints
public static LegalValueModelAttributeValue[] legalValueModelAttributeValues = ValueModelAttributeTest.legalAttributeValues;
@DataPoints
public static LegalStaticResource[] legalStaticResourceAttributeValues = StaticResourceTest.legalStaticResources;
@DataPoints
public static IllegalValueModelAttributeValue[] illegalValueModelAttributeValues = {
new IllegalValueModelAttributeValue("{propertyX", ErrorMessage.SIMPLE_ERROR_MESSAGE),
new IllegalValueModelAttributeValue("propertyX", ErrorMessage.SUGGEST_CURLY_BRACES_ERROR_MESSAGE),
new IllegalValueModelAttributeValue("propertyX}", ErrorMessage.SIMPLE_ERROR_MESSAGE),
new IllegalValueModelAttributeValue("$${propertyX}", ErrorMessage.SIMPLE_ERROR_MESSAGE),
new IllegalValueModelAttributeValue("!{propertyX}", ErrorMessage.SIMPLE_ERROR_MESSAGE) };
@DataPoints
public static IllegalStaticResourceAttributeValue[] illegalStaticResourceAttributeValues = { new IllegalStaticResourceAttributeValue("{@layout/layoutX}",
ErrorMessage.SUGGEST_NOT_USING_CURLY_BRACES_FOR_STATIC_RESOURCES) };
private PropertyAttributeParser parser;
@Before
public void setUp() {
parser = new PropertyAttributeParser();
}
@Theory
public void whenParseLegalValueModelAttributeValue_thenReturnValueModelAttribute(LegalValueModelAttributeValue legalValueModelAttributeValue) {
AbstractPropertyAttribute attribute = parse(legalValueModelAttributeValue.value);
assertThat(attribute, instanceOf(ValueModelAttribute.class));
}
@Theory
public void whenParseLegalStaticResourceAttributeValue_thenReturnStaticResourceAttribute(LegalStaticResource legalStaticResourceAttributeValue) {
AbstractPropertyAttribute attribute = parse(legalStaticResourceAttributeValue.value);
assertThat(attribute, instanceOf(StaticResourceAttribute.class));
}
@Theory
public void whenParseIllegalAttributeValue_thenThrowException(AbstractIllegalAttributeValue illegalAttributeValue) {
try {
parse(illegalAttributeValue.value);
fail("Expect an exception thrown");
} catch (MalformedAttributeException e) {
assertThat(e.getMessage(), equalTo(illegalAttributeValue.getExpectedErrorMessage()));
}
}
private AbstractPropertyAttribute parse(String attributeValue) {
return parser.parse("name", attributeValue);
}
@Theory
public void givenLegalValueModelAttributeValue_whenParseAsValueModelAttribute_thenSuccessful(LegalValueModelAttributeValue legalValueModelAttributeValue) {
parseAsValueModelAttribute(legalValueModelAttributeValue.value);
}
@Theory
public void givenIllegalValueModelAttributeValue_whenParseAsValueModelAttribute_thenThrowException(
IllegalValueModelAttributeValue illegalValueModelAttributeValue) {
try {
parseAsValueModelAttribute(illegalValueModelAttributeValue.value);
fail("Expect an exception thrown");
} catch (MalformedAttributeException e) {
assertThat(e.getMessage(), equalTo(illegalValueModelAttributeValue.getExpectedErrorMessage()));
}
}
private ValueModelAttribute parseAsValueModelAttribute(String attributeValue) {
return parser.parseAsValueModelAttribute("name", attributeValue);
}
@Theory
public void givenLegalStaticResourceAttributeValue_whenParseAsValueModelAttribute_thenSuccessful(
LegalStaticResource legalStaticResourceAttributeValue) {
parseAsStaticResourceAttribute(legalStaticResourceAttributeValue.value);
}
@Theory
public void givenIllegalStaticResourceAttributeValue_whenParseAsStaticResourceAttribute_thenThrowException(
IllegalStaticResourceAttributeValue illegalStaticResourceAttributeValue) {
try {
parseAsStaticResourceAttribute(illegalStaticResourceAttributeValue.value);
fail("Expect an exception thrown");
} catch (MalformedAttributeException e) {
assertThat(e.getMessage(), equalTo(illegalStaticResourceAttributeValue.getExpectedErrorMessage()));
}
}
private StaticResourceAttribute parseAsStaticResourceAttribute(String attributeValue) {
return parser.parseAsStaticResourceAttribute("name", attributeValue);
}
public enum ErrorMessage {
SIMPLE_ERROR_MESSAGE, SUGGEST_CURLY_BRACES_ERROR_MESSAGE, SUGGEST_NOT_USING_CURLY_BRACES_FOR_STATIC_RESOURCES
}
private abstract static class AbstractIllegalAttributeValue {
final String value;
final ErrorMessage expectedErrorMessage;
public AbstractIllegalAttributeValue(String value, ErrorMessage expectedErrorMessage) {
this.value = value;
this.expectedErrorMessage = expectedErrorMessage;
}
public String getExpectedErrorMessage() {
switch (expectedErrorMessage) {
case SIMPLE_ERROR_MESSAGE:
return "Invalid binding syntax: '" + value + "'.";
case SUGGEST_CURLY_BRACES_ERROR_MESSAGE:
return "Invalid binding syntax: '" + value + "'.\n\nDid you mean '{" + value + "}' or '${" + value + "}'? (one/two-way binding)\n";
case SUGGEST_NOT_USING_CURLY_BRACES_FOR_STATIC_RESOURCES:
return "Invalid binding syntax: '" + value
+ "'.\n\nDid you mean to omit the curly braces? (Curly braces are for binding to a property on the presentation model,"
+ " not static resources)";
default:
throw new RuntimeException("should not reach here");
}
}
}
private static class IllegalValueModelAttributeValue extends AbstractIllegalAttributeValue {
public IllegalValueModelAttributeValue(String value, ErrorMessage expectedErrorMessage) {
super(value, expectedErrorMessage);
}
}
private static class IllegalStaticResourceAttributeValue extends AbstractIllegalAttributeValue {
public IllegalStaticResourceAttributeValue(String value, ErrorMessage expectedErrorMessage) {
super(value, expectedErrorMessage);
}
}
}