diff --git a/org.eclipse.scout.rt.dataobject.test/src/test/java/org/eclipse/scout/rt/dataobject/migration/DataObjectMigratorValueMigrationTest.java b/org.eclipse.scout.rt.dataobject.test/src/test/java/org/eclipse/scout/rt/dataobject/migration/DataObjectMigratorValueMigrationTest.java index 456e5f9d87f..18bc7f218e7 100644 --- a/org.eclipse.scout.rt.dataobject.test/src/test/java/org/eclipse/scout/rt/dataobject/migration/DataObjectMigratorValueMigrationTest.java +++ b/org.eclipse.scout.rt.dataobject.test/src/test/java/org/eclipse/scout/rt/dataobject/migration/DataObjectMigratorValueMigrationTest.java @@ -17,6 +17,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Map; import org.eclipse.scout.rt.dataobject.DoEntityBuilder; import org.eclipse.scout.rt.dataobject.IDoEntity; @@ -33,12 +34,15 @@ import org.eclipse.scout.rt.dataobject.migration.fixture.house.RoomFixtureDo; import org.eclipse.scout.rt.dataobject.migration.fixture.house.RoomSizeFixtureDoValueMigrationHandler_2; import org.eclipse.scout.rt.dataobject.migration.fixture.house.RoomTypeFixtureDoValueMigrationHandler_2; +import org.eclipse.scout.rt.dataobject.migration.fixture.house.RoomTypeFixtureStringId; +import org.eclipse.scout.rt.dataobject.migration.fixture.house.RoomTypesCollectionFixtureDo; import org.eclipse.scout.rt.dataobject.migration.fixture.house.RoomTypesFixture; import org.eclipse.scout.rt.dataobject.migration.fixture.version.CharlieFixtureTypeVersions.CharlieFixture_2; import org.eclipse.scout.rt.platform.BEANS; import org.eclipse.scout.rt.platform.BeanMetaData; import org.eclipse.scout.rt.platform.IBean; import org.eclipse.scout.rt.platform.util.CollectionUtility; +import org.eclipse.scout.rt.platform.util.ImmutablePair; import org.eclipse.scout.rt.testing.platform.BeanTestingHelper; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -49,6 +53,9 @@ */ public class DataObjectMigratorValueMigrationTest { + protected static final RoomTypeFixtureStringId ROOM_TYPE_STANDARD_ROOM = RoomTypeFixtureStringId.of("standard-room"); // 'standard-room' will be migrated to 'room' by RoomTypeFixtureDoValueMigrationHandler_2 + protected static final RoomTypeFixtureStringId ROOM_TYPE_SMALL_ROOM = RoomTypeFixtureStringId.of("small-room"); // 'small-room' will be migrated to 'room' by RoomTypeFixtureDoValueMigrationHandler_2 + private static final List> TEST_BEANS = new ArrayList<>(); private static DataObjectMigrationContext s_migrationContext; @@ -271,4 +278,93 @@ public void testStructureAndValueMigrations() { assertEqualsWithComparisonFailure(expected, result.getDataObject()); } + + /** + * Tests value migration for a DoList with duplicate values. + */ + @Test + public void testListValueMigration() { + RoomTypesCollectionFixtureDo original = BEANS.get(RoomTypesCollectionFixtureDo.class) + .withRoomTypesList( + RoomTypesFixture.ROOM, + RoomTypesFixture.LIVING_ROOM, + ROOM_TYPE_STANDARD_ROOM, // 'standard-room' will be migrated to 'room' by RoomTypeFixtureDoValueMigrationHandler_2 + ROOM_TYPE_SMALL_ROOM); // 'small-room' will be migrated to 'room' by RoomTypeFixtureDoValueMigrationHandler_2 + + DataObjectMigratorResult result = s_migrator.applyValueMigration(s_migrationContext, original); + + assertTrue(result.isChanged()); + + RoomTypesCollectionFixtureDo expected = BEANS.get(RoomTypesCollectionFixtureDo.class) + .withRoomTypesList( + RoomTypesFixture.ROOM, + RoomTypesFixture.LIVING_ROOM, + // Duplicate values in list are expected. Might be an inconsistent state depending on business logic, though. + RoomTypesFixture.ROOM, + RoomTypesFixture.ROOM); + + assertEqualsWithComparisonFailure(expected, result.getDataObject()); + } + + /** + * Tests value migration for a DoSet with duplicate values. + */ + @Test + public void testSetValueMigration() { + RoomTypesCollectionFixtureDo original = BEANS.get(RoomTypesCollectionFixtureDo.class) + .withRoomTypesSet( + RoomTypesFixture.ROOM, + RoomTypesFixture.LIVING_ROOM, + ROOM_TYPE_STANDARD_ROOM, // 'standard-room' will be migrated to 'room' by RoomTypeFixtureDoValueMigrationHandler_2 + ROOM_TYPE_SMALL_ROOM); // 'small-room' will be migrated to 'room' by RoomTypeFixtureDoValueMigrationHandler_2 + + DataObjectMigratorResult result = s_migrator.applyValueMigration(s_migrationContext, original); + + assertTrue(result.isChanged()); + + RoomTypesCollectionFixtureDo expected = BEANS.get(RoomTypesCollectionFixtureDo.class) + .withRoomTypesSet( + RoomTypesFixture.ROOM, // duplicate values in set have been removed + RoomTypesFixture.LIVING_ROOM); + + assertEqualsWithComparisonFailure(expected, result.getDataObject()); + } + + /** + * Tests value migration for a map with duplicate keys. + */ + @Test + public void testMapValueMigration() { + RoomFixtureDo room = BEANS.get(RoomFixtureDo.class) + .withName("room") + .withRoomType(RoomTypesFixture.ROOM); + RoomFixtureDo livingRoom = BEANS.get(RoomFixtureDo.class) + .withName("living room") + .withRoomType(RoomTypesFixture.LIVING_ROOM); + RoomFixtureDo standardRoom = BEANS.get(RoomFixtureDo.class) + .withName("standard room") + .withRoomType(ROOM_TYPE_STANDARD_ROOM); + RoomFixtureDo smallRoom = BEANS.get(RoomFixtureDo.class) + .withName("small room") + .withRoomType(ROOM_TYPE_SMALL_ROOM); + + RoomTypesCollectionFixtureDo original = BEANS.get(RoomTypesCollectionFixtureDo.class) + .withRoomTypesMap(CollectionUtility.hashMap( + ImmutablePair.of(RoomTypesFixture.ROOM, room), + ImmutablePair.of(RoomTypesFixture.LIVING_ROOM, livingRoom), + ImmutablePair.of(ROOM_TYPE_STANDARD_ROOM, standardRoom), // 'standard-room' will be migrated to 'room' by RoomTypeFixtureDoValueMigrationHandler_2 + ImmutablePair.of(ROOM_TYPE_SMALL_ROOM, smallRoom))); // 'small-room' will be migrated to 'room' by RoomTypeFixtureDoValueMigrationHandler_2 + + DataObjectMigratorResult result = s_migrator.applyValueMigration(s_migrationContext, original); + + assertTrue(result.isChanged()); + + Map resultMap = result.getDataObject().getRoomTypesMap(); + assertEquals(2, resultMap.size()); + assertEquals("living room", resultMap.get(RoomTypesFixture.LIVING_ROOM).getName()); + + // Merged keys result in a single, randomly selected value, depending on internal order of the original map and implementation details of AbstractReplacingDataObjectVisitor. + String roomName = resultMap.get(RoomTypesFixture.ROOM).getName(); + assertTrue("room".equals(roomName) || "standard room".equals(roomName) || "small room".equals(roomName)); + } } diff --git a/org.eclipse.scout.rt.dataobject.test/src/test/java/org/eclipse/scout/rt/dataobject/migration/fixture/house/RoomTypeFixtureDoValueMigrationHandler_2.java b/org.eclipse.scout.rt.dataobject.test/src/test/java/org/eclipse/scout/rt/dataobject/migration/fixture/house/RoomTypeFixtureDoValueMigrationHandler_2.java index 975fe5c44be..2ed37873505 100644 --- a/org.eclipse.scout.rt.dataobject.test/src/test/java/org/eclipse/scout/rt/dataobject/migration/fixture/house/RoomTypeFixtureDoValueMigrationHandler_2.java +++ b/org.eclipse.scout.rt.dataobject.test/src/test/java/org/eclipse/scout/rt/dataobject/migration/fixture/house/RoomTypeFixtureDoValueMigrationHandler_2.java @@ -18,7 +18,7 @@ import org.eclipse.scout.rt.platform.IgnoreBean; /** - * Rename room type value: standard-room -> room + * Rename room type values: standard-room -> room, small-room -> room */ @IgnoreBean public class RoomTypeFixtureDoValueMigrationHandler_2 extends AbstractDoValueMigrationHandler { @@ -37,6 +37,6 @@ public Class typeVersionClass() { @Override public RoomTypeFixtureStringId migrate(DataObjectMigrationContext ctx, RoomTypeFixtureStringId value) { - return "standard-room".equals(value.unwrap()) ? RoomTypesFixture.ROOM : value; + return "standard-room".equals(value.unwrap()) || "small-room".equals(value.unwrap()) ? RoomTypesFixture.ROOM : value; } } diff --git a/org.eclipse.scout.rt.dataobject.test/src/test/java/org/eclipse/scout/rt/dataobject/migration/fixture/house/RoomTypesCollectionFixtureDo.java b/org.eclipse.scout.rt.dataobject.test/src/test/java/org/eclipse/scout/rt/dataobject/migration/fixture/house/RoomTypesCollectionFixtureDo.java new file mode 100644 index 00000000000..0d3b2c1ed68 --- /dev/null +++ b/org.eclipse.scout.rt.dataobject.test/src/test/java/org/eclipse/scout/rt/dataobject/migration/fixture/house/RoomTypesCollectionFixtureDo.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2010-2021 BSI Business Systems Integration AG. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * BSI Business Systems Integration AG - initial API and implementation + */ +package org.eclipse.scout.rt.dataobject.migration.fixture.house; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.annotation.Generated; + +import org.eclipse.scout.rt.dataobject.DoEntity; +import org.eclipse.scout.rt.dataobject.DoList; +import org.eclipse.scout.rt.dataobject.DoSet; +import org.eclipse.scout.rt.dataobject.DoValue; +import org.eclipse.scout.rt.dataobject.TypeName; +import org.eclipse.scout.rt.dataobject.TypeVersion; +import org.eclipse.scout.rt.dataobject.migration.fixture.version.CharlieFixtureTypeVersions.CharlieFixture_1; + +/** + * Used for value migration tests for lists, sets and maps. + */ +@TypeName("charlieFixture.RoomTypesCollectionFixture") +@TypeVersion(CharlieFixture_1.class) +public class RoomTypesCollectionFixtureDo extends DoEntity { + + public DoList roomTypesList() { + return doList("roomTypesList"); + } + + public DoSet roomTypesSet() { + return doSet("roomTypesSet"); + } + + public DoValue> roomTypesMap() { + return doValue("roomTypesMap"); + } + + /* ************************************************************************** + * GENERATED CONVENIENCE METHODS + * *************************************************************************/ + + @Generated("DoConvenienceMethodsGenerator") + public RoomTypesCollectionFixtureDo withRoomTypesList(Collection roomTypesList) { + roomTypesList().updateAll(roomTypesList); + return this; + } + + @Generated("DoConvenienceMethodsGenerator") + public RoomTypesCollectionFixtureDo withRoomTypesList(RoomTypeFixtureStringId... roomTypesList) { + roomTypesList().updateAll(roomTypesList); + return this; + } + + @Generated("DoConvenienceMethodsGenerator") + public List getRoomTypesList() { + return roomTypesList().get(); + } + + @Generated("DoConvenienceMethodsGenerator") + public RoomTypesCollectionFixtureDo withRoomTypesSet(Collection roomTypesSet) { + roomTypesSet().updateAll(roomTypesSet); + return this; + } + + @Generated("DoConvenienceMethodsGenerator") + public RoomTypesCollectionFixtureDo withRoomTypesSet(RoomTypeFixtureStringId... roomTypesSet) { + roomTypesSet().updateAll(roomTypesSet); + return this; + } + + @Generated("DoConvenienceMethodsGenerator") + public Set getRoomTypesSet() { + return roomTypesSet().get(); + } + + @Generated("DoConvenienceMethodsGenerator") + public RoomTypesCollectionFixtureDo withRoomTypesMap(Map roomTypesMap) { + roomTypesMap().set(roomTypesMap); + return this; + } + + @Generated("DoConvenienceMethodsGenerator") + public Map getRoomTypesMap() { + return roomTypesMap().get(); + } +}