package org.robobinding.binder;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.robobinding.binder.PendingAttributesForViewBuilder.aPendingAttributesForView;
import java.util.Collection;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robobinding.AttributeResolutionException;
import org.robobinding.PendingAttributesForView;
import org.robobinding.ViewResolutionErrorsException;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import android.content.Context;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ListView;
/**
*
* @since 1.0
* @version $Revision: 1.0 $
* @author Robert Taylor
*/
@Config(manifest = Config.NONE)
@RunWith(RobolectricTestRunner.class)
public class ResolutionTest {
private BindingAttributeResolver bindingAttributeResolver;
private Context context = RuntimeEnvironment.application;
@Before
public void setUp() {
bindingAttributeResolver = new BindingAttributeResolverBuilder().build();
}
@Test
public void givenASingleView_whenResolvingValidBindingAttributes_thenReturnResolvedBindingAttributes() {
ResolvedBindingAttributesForView resolvedBindingAttributes = resolveBindingAttributes(aPendingAttributesForEditText().withAttribute("text", "${name}")
.withAttribute("onTextChanged", "onNameChanged").build());
assertNotNull(resolvedBindingAttributes);
}
@Test(expected = ViewResolutionErrorsException.class)
public void givenASingleView_whenResolvingUnsupportedBindingAttributes_thenThrowException() {
resolveBindingAttributes(aPendingAttributesForEditText().withAttribute("tex", "${name}").build());
}
@Test(expected = ViewResolutionErrorsException.class)
public void givenASingleView_whenResolvingMalformedPropertyBindingAttributes_thenThrowException() {
resolveBindingAttributes(aPendingAttributesForEditText().withAttribute("text", "${name").build());
}
@Test(expected = ViewResolutionErrorsException.class)
public void givenASingleView_whenResolvingMalformedCommandBindingAttributes_thenThrowException() {
resolveBindingAttributes(aPendingAttributesForEditText().withAttribute("onTextChanged", "{nameChanged}").build());
}
@Test
public void givenASingleView_whenResolvingMissingGroupBindingAttributes_thenThrowExceptionReferencingView() {
PendingAttributesForView pendingAttributesForAdapterView = aPendingAttributesForAdapterView().withAttribute("source", "{names}").build();
try {
resolveBindingAttributes(pendingAttributesForAdapterView);
fail("Expected exception to be thrown");
} catch (ViewResolutionErrorsException e) {
assertThat(e.getView(), equalTo(pendingAttributesForAdapterView.getView()));
assertThat(e.getMissingRequiredAttributeErrors().size(), is(1));
}
}
@Test
public void givenASingleView_whenResolvingMultipleMalformedAndUnsupportedBindingAttributes_thenThrowExceptionReferringToEachOne() {
try {
resolveBindingAttributes(aPendingAttributesForEditText().withAttribute("text", "${name").withAttribute("onTextChanged", "{nameChanged}")
.withAttribute("tex", "${name}").build());
fail("Expected exception to be thrown");
} catch (ViewResolutionErrorsException e) {
assertHasAttributeError(e, "text");
assertHasAttributeError(e, "onTextChanged");
assertHasAttributeError(e, "tex");
assertThat(e.numErrors(), is(3));
}
}
@Test
public void givenASingleView_whenResolvingMultipleMalformedAndUnsupportedBindingAttributesFromTheSameAttributeGroup_thenThrowExceptionReferringToEachOne() {
try {
resolveBindingAttributes(aPendingAttributesForAdapterView().withAttribute("itemLayout", "invalid").withAttribute("source", "{invalid").build());
fail("Expected exception to be thrown");
} catch (ViewResolutionErrorsException e) {
assertHasAttributeError(e, "itemLayout");
assertHasAttributeError(e, "source");
assertThat(e.numErrors(), is(2));
}
}
@Test
public void givenAViewWithSubViewAttributes_whenResolvingMultipleMalformedBindingAttributes_thenThrowExceptionReferringToEachOne() {
try {
resolveBindingAttributes(aPendingAttributesForAdapterView().withAttribute("itemLayout", "@layout/some_resource")
.withAttribute("source", "{dateSource}").withAttribute("footerLayout", "invalid").withAttribute("footerVisibility", "{invalid")
.withAttribute("footerPresentationModel", "{invalid").build());
fail("Expected exception to be thrown");
} catch (ViewResolutionErrorsException e) {
assertHasAttributeError(e, "footerLayout");
assertHasAttributeError(e, "footerVisibility");
assertHasAttributeError(e, "footerPresentationModel");
assertThat(e.numErrors(), is(3));
}
}
private void assertHasAttributeError(ViewResolutionErrorsException e, String attribute) {
Collection<AttributeResolutionException> attributeErrors = e.getAttributeErrors();
for (AttributeResolutionException attributeError : attributeErrors) {
if (attributeError.getAttributeName().equals(attribute)) {
return;
}
}
fail("Resolution error for " + attribute + " was not reported");
}
private PendingAttributesForViewBuilder aPendingAttributesForEditText() {
EditText editText = new EditText(context);
return aPendingAttributesForView(editText);
}
private PendingAttributesForViewBuilder aPendingAttributesForAdapterView() {
AdapterView<?> adapterView = new ListView(context);
return aPendingAttributesForView(adapterView);
}
private ResolvedBindingAttributesForView resolveBindingAttributes(PendingAttributesForView pendingAttributesForView) {
ViewResolutionResult resolutionResult = bindingAttributeResolver.resolve(pendingAttributesForView);
resolutionResult.assertNoErrors();
return resolutionResult.getResolvedBindingAttributes();
}
}