/*
* Copyright (C) 2016 Red Hat, Inc. and/or its affiliates.
*
* 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.
*/
package org.jboss.errai.databinding.client.test;
import static org.jboss.errai.databinding.client.components.ListComponent.forIsWidgetComponent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jboss.errai.databinding.client.BindableListWrapper;
import org.jboss.errai.databinding.client.BindableProxy;
import org.jboss.errai.databinding.client.DataBindingModuleBootstrapper;
import org.jboss.errai.databinding.client.MapPropertyType;
import org.jboss.errai.databinding.client.NonExistingPropertyException;
import org.jboss.errai.databinding.client.PropertyType;
import org.jboss.errai.databinding.client.TestModel;
import org.jboss.errai.databinding.client.api.Convert;
import org.jboss.errai.databinding.client.api.DataBinder;
import org.jboss.errai.databinding.client.components.ListComponent;
import com.google.gwt.junit.client.GWTTestCase;
import com.google.gwt.user.client.ui.IntegerBox;
import com.google.gwt.user.client.ui.TextBox;
/**
* Tests binding to lists with the {@link DataBinder}.
*
* @author Max Barkley <mbarkley@redhat.com>
*/
public class MapBindingIntegrationTest extends GWTTestCase {
@Override
public String getModuleName() {
return "org.jboss.errai.databinding.DataBindingTestModule";
}
@Override
protected void gwtSetUp() throws Exception {
new DataBindingModuleBootstrapper().run();
}
public void testMapWithNonBindableProperties() throws Exception {
final Map<String, PropertyType> propertyTypes = new HashMap<>();
propertyTypes.put("str", new PropertyType(String.class));
propertyTypes.put("num", new PropertyType(Integer.class));
final DataBinder<Map<String, Object>> binder = DataBinder.forMap(propertyTypes);
final TextBox strTextBox = new TextBox();
final IntegerBox numIntBox = new IntegerBox();
binder
.bind(strTextBox, "str")
.bind(numIntBox, "num");
final Map<String, Object> map = binder.getModel();
assertNotNull(map);
map.put("str", "foo");
assertEquals("foo", strTextBox.getValue());
map.put("num", 42);
assertEquals(Integer.valueOf(42), numIntBox.getValue());
}
public void testMapWithBindableProperties() throws Exception {
final Map<String, PropertyType> propertyTypes = new HashMap<>();
propertyTypes.put("list", new PropertyType(List.class, false, true));
propertyTypes.put("bindable", new PropertyType(TestModel.class, true, false));
final DataBinder<Map<String, Object>> binder = DataBinder.forMap(propertyTypes);
final IntegerBox ageIntBox = new IntegerBox();
final ListComponent<String, TextBox> component = forIsWidgetComponent(TextBox::new, c -> {}).inDiv();
binder
.bind(component, "list", Convert.identityConverter(List.class))
.bind(ageIntBox, "bindable.age");
final Map<String, Object> map = binder.getModel();
assertNotNull(map);
map.put("bindable", new TestModel());
final TestModel model = (TestModel) map.get("bindable");
model.setAge(99);
assertTrue("TestModel is not proxied.", model instanceof BindableProxy);
assertEquals(Integer.valueOf(99), ageIntBox.getValue());
map.put("list", new ArrayList<>());
final List<String> list = (List<String>) map.get("list");
assertTrue("List value was not proxied.", list instanceof BindableListWrapper);
list.add("moogah");
try {
assertEquals("moogah", component.getComponent(0).getValue());
} catch (final AssertionError ae) {
throw ae;
} catch (final Throwable t) {
throw new AssertionError("Component not added for list entry.", t);
}
}
public void testMapWithBindableMap() throws Exception {
final Map<String, PropertyType> innerMapPropertyTypes = new HashMap<>();
innerMapPropertyTypes.put("str", new PropertyType(String.class));
innerMapPropertyTypes.put("num", new PropertyType(Integer.class));
final Map<String, PropertyType> outerMapPropertyTypes = new HashMap<>();
outerMapPropertyTypes.put("map", new MapPropertyType(innerMapPropertyTypes));
final DataBinder<Map<String, Object>> binder = DataBinder.forMap(outerMapPropertyTypes);
final TextBox strTextBox = new TextBox();
final IntegerBox numIntBox = new IntegerBox();
binder
.bind(strTextBox, "map.str")
.bind(numIntBox, "map.num");
final Map<String, Object> outerMap = binder.getModel();
assertNotNull(outerMap);
outerMap.put("map", new HashMap<>());
final Map<String, Object> innerMap = (Map<String, Object>) outerMap.get("map");
innerMap.put("str", "foo");
assertEquals("foo", strTextBox.getValue());
innerMap.put("num", 42);
assertEquals(Integer.valueOf(42), numIntBox.getValue());
}
public void testPutAllUpdatesWidgets() throws Exception {
final Map<String, PropertyType> propertyTypes = new HashMap<>();
propertyTypes.put("str", new PropertyType(String.class));
propertyTypes.put("num", new PropertyType(Integer.class));
final DataBinder<Map<String, Object>> binder = DataBinder.forMap(propertyTypes);
final TextBox strTextBox = new TextBox();
final IntegerBox numIntBox = new IntegerBox();
binder
.bind(strTextBox, "str")
.bind(numIntBox, "num");
final Map<String, Object> map = binder.getModel();
assertNotNull(map);
final Map<String, Object> otherMap = new HashMap<>();
otherMap.put("str", "foo");
otherMap.put("num", 42);
map.putAll(otherMap);
assertEquals("foo", strTextBox.getValue());
assertEquals(Integer.valueOf(42), numIntBox.getValue());
}
public void testPutAllThrowsErrorForUnrecognizedProperties() throws Exception {
final Map<String, PropertyType> propertyTypes = new HashMap<>();
propertyTypes.put("str", new PropertyType(String.class));
propertyTypes.put("num", new PropertyType(Integer.class));
final DataBinder<Map<String, Object>> binder = DataBinder.forMap(propertyTypes);
final TextBox strTextBox = new TextBox();
final IntegerBox numIntBox = new IntegerBox();
binder
.bind(strTextBox, "str")
.bind(numIntBox, "num");
final Map<String, Object> map = binder.getModel();
assertNotNull(map);
final Map<String, Object> otherMap = new HashMap<>();
otherMap.put("nonexistent", "foible");
try {
map.putAll(otherMap);
fail("Putting non-existent property into map did not cause an exception.");
} catch (final NonExistingPropertyException ex) {
// success
} catch (final AssertionError ae) {
throw ae;
} catch (final Throwable t) {
throw new AssertionError("Wrong exception thrown: " + t.getMessage(), t);
}
}
}