WebComponentExporter implements Serializable { private <P extends Serializable> PropertyConfiguration<C, P> addProperty( String name, Class<P> type, P defaultValue) { Objects.requireNonNull(name, "Parameter 'name' cannot be null!"); Objects.requireNonNull(type, "Parameter 'type' cannot be null!"); if (isConfigureInstanceCall) { throw new IllegalStateException( "The 'addProperty' method cannot be called within " + "the 'configureInstance' method. All properties have " + "to be configured in the " + getClass().getName() + " class constructor."); } if (!isSupportedType(type)) { throw new UnsupportedPropertyTypeException(String.format( "PropertyConfiguration " + "cannot handle type %s. Use any of %s instead.", type.getCanonicalName(), SUPPORTED_TYPES.stream().map(Class::getSimpleName) .collect(Collectors.joining(", ")))); } PropertyConfigurationImpl<C, P> propertyConfigurationImpl = new PropertyConfigurationImpl<>( getComponentClass(), name, type, defaultValue); propertyConfigurationMap.put(name, propertyConfigurationImpl); return propertyConfigurationImpl; } @SuppressWarnings("unchecked") protected  WebComponentExporter(String tag); final PropertyConfiguration<C, Integer> addProperty(String name,
            int defaultValue); final PropertyConfiguration<C, Double> addProperty(String name,
            double defaultValue); final PropertyConfiguration<C, String> addProperty(String name,
            String defaultValue); final PropertyConfiguration<C, Boolean> addProperty(String name,
            boolean defaultValue); final PropertyConfiguration<C, JsonValue> addProperty(String name,
            JsonValue defaultValue); final void preConfigure(); final void postConfigure(); final String getTag();  }
@Test public void addProperty_differentTypes() { exporter.addProperty("int", 1); exporter.addProperty("string", "string"); exporter.addProperty("boolean", true); exporter.addProperty("double", 1.0); assertProperty(config, "int", 1); assertProperty(config, "string", "string"); assertProperty(config, "boolean", true); assertProperty(config, "double", 1.0); Bean bean = new Bean(); bean.setInteger(5); JsonValue value = JsonSerializer.toJson(bean); exporter.addProperty("json", value); assertProperty(config, "json", value); }
@Test public void addProperty_propertyWithTheSameNameGetsOverwritten() { exporter.addProperty("int", 1); Assert.assertTrue(config.hasProperty("int")); exporter.addProperty("int", 2); Assert.assertEquals("Configuration should have one property", 1, config.getPropertyDataSet().size()); assertProperty(config, "int", 2); }
@Test public void configuration_getPropertyType_differentTypes() { exporter.addProperty("int", 1); exporter.addProperty("string", "string"); exporter.addProperty("boolean", true); exporter.addProperty("double", 1.0); Assert.assertEquals(Integer.class, config.getPropertyType("int")); Assert.assertEquals(String.class, config.getPropertyType("string")); Assert.assertEquals(Boolean.class, config.getPropertyType("boolean")); Assert.assertEquals(Double.class, config.getPropertyType("double")); }
@Test public void configuration_deliverPropertyUpdate() { exporter.addProperty("int", 0).onChange(MyComponent::update); WebComponentBinding<MyComponent> binding = config .createWebComponentBinding(new MockInstantiator(), mock(Element.class), Json.createObject()); Assert.assertNotNull(binding); binding.updateProperty("int", 1); Assert.assertEquals("Component should have been updated", 1, binding.getComponent().getValue()); }
@Test public void configuration_getPropertyDataSet() { exporter.addProperty("int", 1); exporter.addProperty("string", "string"); exporter.addProperty("boolean", true); exporter.addProperty("double", 1.0); Set<PropertyData<?>> set = config.getPropertyDataSet(); Assert.assertEquals(4, set.size()); }
@Test @SuppressWarnings("unchecked") public void configuration_createWebComponentBinding() { exporter = new MyComponentExporter() { @Override public void configureInstance( WebComponent<MyComponent> webComponent, MyComponent component) { component.flop(); } }; exporter.addProperty("value", 1).onChange(MyComponent::update); config = (WebComponentConfiguration<MyComponent>) new WebComponentExporter.WebComponentConfigurationFactory() .create(exporter); WebComponentBinding<MyComponent> binding = config .createWebComponentBinding(new MockInstantiator(), mock(Element.class), Json.createObject()); Assert.assertNotNull("Binding should not be null", binding); Assert.assertNotNull("Binding's component should not be null", binding.getComponent()); Assert.assertTrue("configureInstance() should have set 'flip' to true", binding.getComponent().getFlip()); Assert.assertEquals("value should be set to 1 by default", 1, binding.getComponent().value); }
@Test @SuppressWarnings("unchecked") public void configuration_createWebComponentBinding_overridesDefaultValues() { exporter.addProperty("value", 1).onChange(MyComponent::update); config = (WebComponentConfiguration<MyComponent>) new WebComponentExporter.WebComponentConfigurationFactory() .create(exporter); WebComponentBinding<MyComponent> binding = config .createWebComponentBinding(new MockInstantiator(), mock(Element.class), Json.parse("{\"value\":2}")); Assert.assertEquals("attribute should have set default value to two", 2, binding.getComponent().value); }
@Test public void configuration_hasProperty() { exporter.addProperty("int", 1); exporter.addProperty("string", "string"); exporter.addProperty("boolean", true); exporter.addProperty("double", 1.0); Assert.assertTrue(config.hasProperty("int")); Assert.assertTrue(config.hasProperty("string")); Assert.assertTrue(config.hasProperty("boolean")); Assert.assertTrue(config.hasProperty("double")); Assert.assertFalse(config.hasProperty("does-not-exist")); }