package fr.openwide.core.test.wicket.more.bindable; import static org.junit.Assert.assertSame; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import org.junit.Test; import fr.openwide.core.wicket.more.bindable.model.BindableModel; import fr.openwide.core.wicket.more.bindable.model.IBindableModel; public class TestBindableModel extends AbstractTestBindableModel { @Test public void readAccessToProperties() { SimplePropertyValue expectedPropertyValue = new SimplePropertyValue(); rootValue.setSimpleProperty(expectedPropertyValue); doReturn(rootValue).when(rootModel).getObject(); IBindableModel<RootValue> bindableModel = new BindableModel<>(rootModel); IBindableModel<SimplePropertyValue> propertyModel = bindableModel.bind(rootBinding().simpleProperty()); assertSame(propertyModel.getObject(), expectedPropertyValue); verify(rootValue, times(1)).getSimpleProperty(); } @Test public void writeAccessToProperties() { doReturn(rootValue).when(rootModel).getObject(); IBindableModel<RootValue> bindableModel = new BindableModel<>(rootModel); IBindableModel<SimplePropertyValue> propertyModel = bindableModel.bind(rootBinding().simpleProperty()); SimplePropertyValue newExpectedPropertyValue = new SimplePropertyValue(); propertyModel.setObject(newExpectedPropertyValue); verify(rootValue, times(1)).setSimpleProperty(newExpectedPropertyValue); } @Test public void alwaysReturnsSameModelInstance() { doReturn(rootValue).when(rootModel).getObject(); IBindableModel<RootValue> bindableModel = new BindableModel<>(rootModel); IBindableModel<?> firstCall = bindableModel.bind(rootBinding().simpleProperty()); IBindableModel<?> secondCall = bindableModel.bind(rootBinding().simpleProperty()); assertSame(firstCall, secondCall); IBindableModel<?> thirdCall = bindableModel.bindWithCache(rootBinding().simpleProperty(), new StubModel<SimplePropertyValue>()); assertSame(firstCall, thirdCall); } @Test public void alwaysReturnsSameModelInstanceEvenIfChained() { doReturn(rootValue).when(rootModel).getObject(); IBindableModel<RootValue> bindableModel = new BindableModel<>(rootModel); IBindableModel<?> directCall = bindableModel.bind(rootBinding().compositeProperty().simpleProperty()); IBindableModel<?> chainedCall = bindableModel.bind(rootBinding().compositeProperty()).bind(rootBinding().simpleProperty()); assertSame(directCall, chainedCall); IBindableModel<?> chainedCallWithCache = bindableModel.bind(rootBinding().compositeProperty()) .bindWithCache(rootBinding().simpleProperty(), new StubModel<SimplePropertyValue>()); assertSame(directCall, chainedCallWithCache); } @Test public void simpleCacheUsage() { SimplePropertyValue firstExpectedValue = new SimplePropertyValue(); SimplePropertyValue secondExpectedValue = new SimplePropertyValue(); rootValue.setSimpleProperty(firstExpectedValue); doReturn(rootValue).when(rootModel).getObject(); IBindableModel<RootValue> bindableModel = new BindableModel<>(rootModel); IBindableModel<SimplePropertyValue> propertyModel = bindableModel.bindWithCache( rootBinding().simpleProperty(), new StubModel<SimplePropertyValue>() ); assertSame(firstExpectedValue, propertyModel.getObject()); verify(rootValue).getSimpleProperty(); // Cache was initialized rootValue.setSimpleProperty(secondExpectedValue); propertyModel.readAll(); verify(rootValue, times(2)).getSimpleProperty(); // The value was fetched assertSame(secondExpectedValue, propertyModel.getObject()); // The cache was updated verify(rootValue, times(2)).getSimpleProperty(); // Only the cache was touched when calling getObject(), no the actual value SimplePropertyValue valueToSet = new SimplePropertyValue(); assertSame(secondExpectedValue, rootValue.getSimpleProperty()); propertyModel.setObject(valueToSet); assertSame(secondExpectedValue, rootValue.getSimpleProperty()); // Only the cache was touched, not the actual value (which was only initialized at the start of this test) assertSame(valueToSet, propertyModel.getObject()); propertyModel.writeAll(); assertSame(valueToSet, rootValue.getSimpleProperty()); assertSame(valueToSet, propertyModel.getObject()); } @Test public void cacheUpdatePropagation() { SimplePropertyValue firstExpectedValue = new SimplePropertyValue(); SimplePropertyValue secondExpectedValue = new SimplePropertyValue(); rootValue.setSimpleProperty(firstExpectedValue); doReturn(rootValue).when(rootModel).getObject(); IBindableModel<RootValue> bindableModel = new BindableModel<>(rootModel); IBindableModel<SimplePropertyValue> propertyModel = bindableModel.bindWithCache( rootBinding().simpleProperty(), new StubModel<SimplePropertyValue>() ); assertSame(firstExpectedValue, propertyModel.getObject()); verify(rootValue).getSimpleProperty(); // Cache was initialized rootValue.setSimpleProperty(secondExpectedValue); bindableModel.readAll(); verify(rootValue, times(2)).getSimpleProperty(); // The value was fetched assertSame(secondExpectedValue, propertyModel.getObject()); // The cache was updated verify(rootValue, times(2)).getSimpleProperty(); // Only the cache was touched when calling getObject(), no the actual value SimplePropertyValue valueToSet = new SimplePropertyValue(); assertSame(secondExpectedValue, rootValue.getSimpleProperty()); propertyModel.setObject(valueToSet); assertSame(secondExpectedValue, rootValue.getSimpleProperty()); // Only the cache was touched, not the actual value (which was only initialized at the start of this test) assertSame(valueToSet, propertyModel.getObject()); bindableModel.writeAll(); assertSame(valueToSet, rootValue.getSimpleProperty()); assertSame(valueToSet, propertyModel.getObject()); } }