NodeMap extends NodeFeature implements ReactiveValue { public MapProperty getProperty(String name) { MapProperty property = properties.get(name); if (property == null) { property = new MapProperty(name, this, "innerHTML".equals(name) && getId() == NodeFeatures.ELEMENT_PROPERTIES); properties.set(name, property); eventRouter.fireEvent(new MapPropertyAddEvent(this, property)); } return property; } NodeMap(int id, StateNode node); MapProperty getProperty(String name); boolean hasPropertyValue(String name); void forEachProperty(ForEachCallback<String, MapProperty> callback); JsArray<String> getPropertyNames(); @Override JsonValue getDebugJson(); @Override JsonValue convert(Function<Object, JsonValue> converter); @Override EventRemover addReactiveValueChangeListener(
            ReactiveValueChangeListener reactiveValueChangeListener); EventRemover addPropertyAddListener(
            MapPropertyAddListener listener);  }
@Test public void testPropertyCreation() { MapProperty property = map.getProperty("foo"); Assert.assertEquals("foo", property.getName()); Assert.assertSame(map, property.getMap()); List<MapProperty> properties = collectProperties(); Assert.assertEquals(Arrays.asList(property), properties); MapProperty getAgain = map.getProperty("foo"); Assert.assertSame(property, getAgain); Assert.assertEquals(properties, collectProperties()); }
@Test public void getProperty_returnPropertyWhichAlwaysUpdatesTheValue() { NodeMap map = new NodeMap(NodeFeatures.ELEMENT_PROPERTIES, new StateNode(0, new StateTree(null))); MapProperty property = map.getProperty("innerHTML"); AtomicReference<MapPropertyChangeEvent> capture = new AtomicReference<>(); property.addChangeListener(capture::set); property.setValue("foo"); Assert.assertNotNull(capture.get()); capture.set(null); property.setValue("foo"); Assert.assertNotNull(capture.get()); }