From 3bacebb8762d049637297124eda935ea7303b13e Mon Sep 17 00:00:00 2001 From: Rene Schneider Date: Fri, 8 Jul 2016 15:31:32 +0200 Subject: [PATCH 1/2] fixed #115: Map entries aren't sorted when maps are converted to Strings --- .../java/other/AbstractMapToString.java | 24 +++++-- ...bitraryParametersWithStringIdentifiers.xml | 58 ++++++++-------- ...basic.beans.beanToMapTestMapInVariable.xml | 66 +++++++++---------- 3 files changed, 81 insertions(+), 67 deletions(-) diff --git a/de.gebit.integrity.dsl/src/de/gebit/integrity/parameter/conversion/conversions/java/other/AbstractMapToString.java b/de.gebit.integrity.dsl/src/de/gebit/integrity/parameter/conversion/conversions/java/other/AbstractMapToString.java index 34d8e25d2..ab6d418d9 100644 --- a/de.gebit.integrity.dsl/src/de/gebit/integrity/parameter/conversion/conversions/java/other/AbstractMapToString.java +++ b/de.gebit.integrity.dsl/src/de/gebit/integrity/parameter/conversion/conversions/java/other/AbstractMapToString.java @@ -10,6 +10,8 @@ import java.util.Hashtable; import java.util.Map; import java.util.Map.Entry; +import java.util.SortedMap; +import java.util.TreeMap; import de.gebit.integrity.comparator.MapComparisonResult; import de.gebit.integrity.parameter.conversion.Conversion; @@ -51,7 +53,7 @@ public abstract class AbstractMapToString extends Conversion { * the conversion context * @return the resulting string */ - protected FormattedString convertToFormattedString(Map aSource, ConversionContext aConversionContext) + protected FormattedString convertToFormattedString(Map aSource, ConversionContext aConversionContext) throws ConversionFailedException { String tempParentMapPath = (String) aConversionContext.getProperty(MAP_PATH_PROPERTY); @@ -66,16 +68,28 @@ protected FormattedString convertToFormattedString(Map aSource, ConversionContex } nestedObjectDepthMap.put(Thread.currentThread(), tempDepth); + // In order to provide a consistent ordering of map entries in the string, we want to sort the map by natural + // key ordering + SortedMap tempSortedSource = null; + if (aSource instanceof SortedMap) { + // Either our source map is already sorted... + tempSortedSource = (SortedMap) aSource; + } else { + // ...or we need to sort it by creating a TreeMap and filling it + tempSortedSource = new TreeMap<>(aSource); + } + try { boolean tempFirst = true; - for (Entry tempEntry : ((Map) aSource).entrySet()) { + for (Entry tempEntry : ((Map) tempSortedSource).entrySet()) { String tempCurrentMapPath = (tempParentMapPath != null ? tempParentMapPath + "." : "") + tempEntry.getKey(); aConversionContext.withProperty(MAP_PATH_PROPERTY, tempCurrentMapPath); - boolean tempCurrentPathFailed = (aConversionContext.getComparisonResult() instanceof MapComparisonResult) - && ((MapComparisonResult) aConversionContext.getComparisonResult()).getFailedPaths().contains( - tempCurrentMapPath); + boolean tempCurrentPathFailed = (aConversionContext + .getComparisonResult() instanceof MapComparisonResult) + && ((MapComparisonResult) aConversionContext.getComparisonResult()).getFailedPaths() + .contains(tempCurrentMapPath); FormattedString[] tempConvertedValues = convertValueToFormattedStringArrayRecursive( tempEntry.getValue(), aConversionContext); diff --git a/de.gebit.integrity.tests/results/integrity.basic.arbitraryParameters.arbitraryParametersWithStringIdentifiers.xml b/de.gebit.integrity.tests/results/integrity.basic.arbitraryParameters.arbitraryParametersWithStringIdentifiers.xml index b5dae5c3a..9545251e0 100644 --- a/de.gebit.integrity.tests/results/integrity.basic.arbitraryParameters.arbitraryParametersWithStringIdentifiers.xml +++ b/de.gebit.integrity.tests/results/integrity.basic.arbitraryParameters.arbitraryParametersWithStringIdentifiers.xml @@ -1,29 +1,29 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/de.gebit.integrity.tests/results/integrity.basic.beans.beanToMapTestMapInVariable.xml b/de.gebit.integrity.tests/results/integrity.basic.beans.beanToMapTestMapInVariable.xml index 00ba9cc0f..a4ea83b24 100644 --- a/de.gebit.integrity.tests/results/integrity.basic.beans.beanToMapTestMapInVariable.xml +++ b/de.gebit.integrity.tests/results/integrity.basic.beans.beanToMapTestMapInVariable.xml @@ -1,33 +1,33 @@ - - - - - - - - - - - - - - - - This should succeed as well, because it's the same as the example before, but just using a map stored in a variable - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + This should succeed as well, because it's the same as the example before, but just using a map stored in a variable + + + + + + + + + + + + + + + + + From c485d713ae6712e0197a71d63b079e76010b0856 Mon Sep 17 00:00:00 2001 From: Rene Schneider Date: Fri, 8 Jul 2016 16:51:42 +0200 Subject: [PATCH 2/2] fixed #114: Complex objects inside maps are ignored by value conversion --- .../AbstractModularValueConverter.java | 91 +++++++----- .../DefaultModularValueConverter.java | 2 + .../conversions/java/other/MapToMap.java | 136 ++++++++++++++++++ .../integrity/fixtures/BeanFixture.integrity | 9 ++ .../basic/beans/mapInsideBeanTest.integrity | 57 ++++++++ .../junit/basic/beans/MapInsideBeanTest.java | 73 ++++++++++ ...egrity.basic.beans.mapInsideBeanSimple.xml | 24 ++++ ....basic.beans.mapInsideBeanWithMapInMap.xml | 24 ++++ ...y.basic.beans.mapInsideBeanWithTreeMap.xml | 24 ++++ .../fixtures/basic/beans/BeanFixture.java | 15 ++ .../fixtures/basic/beans/MapTestBean.java | 49 +++++++ .../basic/beans/MapTestBeanWithMapInMap.java | 56 ++++++++ .../basic/beans/MapTestBeanWithTreeMap.java | 48 +++++++ 13 files changed, 569 insertions(+), 39 deletions(-) create mode 100644 de.gebit.integrity.dsl/src/de/gebit/integrity/parameter/conversion/conversions/java/other/MapToMap.java create mode 100644 de.gebit.integrity.tests/integrity/suites/basic/beans/mapInsideBeanTest.integrity create mode 100644 de.gebit.integrity.tests/junit/de/gebit/integrity/tests/junit/basic/beans/MapInsideBeanTest.java create mode 100644 de.gebit.integrity.tests/results/integrity.basic.beans.mapInsideBeanSimple.xml create mode 100644 de.gebit.integrity.tests/results/integrity.basic.beans.mapInsideBeanWithMapInMap.xml create mode 100644 de.gebit.integrity.tests/results/integrity.basic.beans.mapInsideBeanWithTreeMap.xml create mode 100644 de.gebit.integrity.tests/src/de/gebit/integrity/tests/fixtures/basic/beans/MapTestBean.java create mode 100644 de.gebit.integrity.tests/src/de/gebit/integrity/tests/fixtures/basic/beans/MapTestBeanWithMapInMap.java create mode 100644 de.gebit.integrity.tests/src/de/gebit/integrity/tests/fixtures/basic/beans/MapTestBeanWithTreeMap.java diff --git a/de.gebit.integrity.dsl/src/de/gebit/integrity/parameter/conversion/AbstractModularValueConverter.java b/de.gebit.integrity.dsl/src/de/gebit/integrity/parameter/conversion/AbstractModularValueConverter.java index fd49b3413..8aec5943a 100644 --- a/de.gebit.integrity.dsl/src/de/gebit/integrity/parameter/conversion/AbstractModularValueConverter.java +++ b/de.gebit.integrity.dsl/src/de/gebit/integrity/parameter/conversion/AbstractModularValueConverter.java @@ -8,6 +8,7 @@ package de.gebit.integrity.parameter.conversion; import java.lang.reflect.Array; +import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; @@ -174,8 +175,8 @@ public Object convertValue(Class aTargetType, Class aParameterizedType, Ob * @throws InstantiationException */ public Object convertValue(Class aTargetType, Class aParameterizedType, Object aValue, - ConversionContext aConversionContext, Set someVisitedObjects) throws UnresolvableVariableException, - UnexecutableException { + ConversionContext aConversionContext, Set someVisitedObjects) + throws UnresolvableVariableException, UnexecutableException { ConversionContext tempConversionContext = safeguardConversionContext(aConversionContext); if (someVisitedObjects.contains(aValue)) { @@ -194,8 +195,8 @@ public Object convertValue(Class aTargetType, Class aParameterizedType, Ob return convertEncapsulatedConstantValueToTargetType(aTargetType, aParameterizedType, (ConstantValue) aValue, tempConversionContext, someVisitedObjects); } else { - return convertPlainValueToTargetType(aTargetType, aParameterizedType, aValue, - tempConversionContext, someVisitedObjects); + return convertPlainValueToTargetType(aTargetType, aParameterizedType, aValue, tempConversionContext, + someVisitedObjects); } } finally { someVisitedObjects.remove(aValue); @@ -253,20 +254,14 @@ protected Object convertPlainValueToTargetType(Class aTargetType, Class aP // both are arrays tempResultArray = Array.newInstance(tempActualParamType, Array.getLength(aValue)); for (int i = 0; i < Array.getLength(aValue); i++) { - Array.set( - tempResultArray, - i, - convertPlainValueToTargetType(tempActualParamType, aParameterizedType, - Array.get(aValue, i), aConversionContext, someVisitedValues)); + Array.set(tempResultArray, i, convertPlainValueToTargetType(tempActualParamType, aParameterizedType, + Array.get(aValue, i), aConversionContext, someVisitedValues)); } } else { // target is an array, but value is a single value tempResultArray = Array.newInstance(tempActualParamType, 1); - Array.set( - tempResultArray, - 0, - convertPlainValueToTargetType(tempActualParamType, aParameterizedType, aValue, - aConversionContext, someVisitedValues)); + Array.set(tempResultArray, 0, convertPlainValueToTargetType(tempActualParamType, aParameterizedType, + aValue, aConversionContext, someVisitedValues)); } return tempResultArray; } else { @@ -338,18 +333,37 @@ private Object convertSingleValueToTargetType(Class aTargetType, Class aPa Class tempSourceType = transformPrimitiveTypes(aValue.getClass()); String tempSourceTypeName = tempSourceType.getName(); - // No conversion necessary if target type is a superclass or the same as the current type - if (tempTargetType != null && tempTargetType.isAssignableFrom(tempSourceType)) { - // ...except if the source type is one of Integritys' internal types, which shouldn't generally been given - // to fixtures in an unconverted state. - if (!tempSourceTypeName.startsWith("de.gebit.integrity.dsl.")) { - return aValue; + if (Map.class.isAssignableFrom(tempSourceType)) { + // Maps need special attention: we may have to convert their contents. Therefore we perform a Map-to-Map + // conversion in this case, which iterates over inner value and ensures those are also converted, if + // necessary. + // In order to do this, we need to specify a concrete map target type. + if (tempTargetType == null) { + tempTargetType = HashMap.class; // HashMap is a good default + } else if (Map.class.isAssignableFrom(tempTargetType)) { + // If the target type is also a map, see whether the target is an abstract type + if ((tempTargetType.getModifiers() & Modifier.ABSTRACT) != 0) { + // If it is, just use the source value type as target. This basically performs no conversion of the + // map object itself, but it nevertheless results in an execution of the Map-to-Map conversion, + // which triggers conversion of inner values + tempTargetType = tempSourceType; + } + } + } else { + // No conversion necessary if target type is a superclass or the same as the current type + if (tempTargetType != null && tempTargetType.isAssignableFrom(tempSourceType)) { + // ...except if the source type is one of Integritys' internal types, which shouldn't generally been + // given + // to fixtures in an unconverted state. + if (!tempSourceTypeName.startsWith("de.gebit.integrity.dsl.")) { + return aValue; + } } - } - if (tempTargetType == null && tempSourceTypeName.startsWith("java.")) { - // Java types generally have themselves as "default type" and don't need to be converted to anything - return aValue; + if (tempTargetType == null && tempSourceTypeName.startsWith("java.")) { + // Java types generally have themselves as "default type" and don't need to be converted to anything + return aValue; + } } try { @@ -372,8 +386,8 @@ private Object convertSingleValueToTargetType(Class aTargetType, Class aPa throw exc; // SUPPRESS CHECKSTYLE IllegalCatch } catch (Throwable exc) { - throw new ConversionFailedException(aValue.getClass(), tempTargetType, - "Unexpected error during conversion", exc); + throw new ConversionFailedException(aValue.getClass(), tempTargetType, "Unexpected error during conversion", + exc); } } @@ -502,8 +516,8 @@ protected Object convertEncapsulatedConstantValueToTargetType(Class aTargetTy } else if (((Constant) aValue).getName().eContainer() instanceof ConstantDefinition) { // Without the variable manager, we can still attempt to resolve statically. try { - return parameterResolver.resolveStatically((ConstantDefinition) ((Constant) aValue).getName() - .eContainer(), null); + return parameterResolver + .resolveStatically((ConstantDefinition) ((Constant) aValue).getName().eContainer(), null); } catch (ClassNotFoundException exc) { exc.printStackTrace(); } catch (InstantiationException exc) { @@ -580,8 +594,8 @@ protected Object convertEncapsulatedValueCollectionToTargetType(Class aTarget // this is actually an array Object tempResultArray = Array.newInstance(tempTargetArrayType, aCollection.getMoreValues().size() + 1); for (int i = 0; i < aCollection.getMoreValues().size() + 1; i++) { - ValueOrEnumValueOrOperation tempValue = (i == 0 ? aCollection.getValue() : aCollection.getMoreValues() - .get(i - 1)); + ValueOrEnumValueOrOperation tempValue = (i == 0 ? aCollection.getValue() + : aCollection.getMoreValues().get(i - 1)); Object tempResultValue = convertEncapsulatedValueToTargetType(tempTargetType, aParameterizedType, tempValue, aConversionContext, someVisitedValues); Array.set(tempResultArray, i, tempResultValue); @@ -720,9 +734,8 @@ public FormattedString[] convertValueToStringArray(Object aValue, ConversionCont FormattedString[] tempResult; try { if (aValue instanceof ValueOrEnumValueOrOperationCollection) { - tempResult = (FormattedString[]) convertEncapsulatedValueCollectionToTargetType( - FormattedString[].class, null, (ValueOrEnumValueOrOperationCollection) aValue, - tempConversionContext, someVisitedValues); + tempResult = (FormattedString[]) convertEncapsulatedValueCollectionToTargetType(FormattedString[].class, + null, (ValueOrEnumValueOrOperationCollection) aValue, tempConversionContext, someVisitedValues); } else if (aValue instanceof ValueOrEnumValueOrOperation) { tempResult = (FormattedString[]) convertEncapsulatedValueToTargetType(FormattedString[].class, null, (ValueOrEnumValueOrOperation) aValue, tempConversionContext, someVisitedValues); @@ -958,8 +971,8 @@ public String toString() { * @throws IllegalAccessException */ protected Conversion findAndInstantiateConversion(Class aSourceType, Class aTargetType, - Set someVisitedValues, ConversionContext aConversionContext) throws InstantiationException, - IllegalAccessException { + Set someVisitedValues, ConversionContext aConversionContext) + throws InstantiationException, IllegalAccessException { Class> tempConversionClass = findConversion(aSourceType, aTargetType, someVisitedValues, aConversionContext); @@ -1034,8 +1047,8 @@ public String toString() { * @return a conversion class, or null if none was found */ protected Class> searchDerivedConversionMap(Class aSourceType, Class aTargetType) { - List>> tempList = derivedConversions.get(new ConversionKey(aSourceType, - aTargetType)); + List>> tempList = derivedConversions + .get(new ConversionKey(aSourceType, aTargetType)); if (tempList != null && !tempList.isEmpty()) { return tempList.get(0); } @@ -1173,8 +1186,8 @@ public String toString() { * @throws IllegalAccessException */ @SuppressWarnings({ "rawtypes", "unchecked" }) - protected C createConversionInstance(Class aConversionClass, Set someVisitedValues) - throws InstantiationException, IllegalAccessException { + protected C createConversionInstance(Class aConversionClass, + Set someVisitedValues) throws InstantiationException, IllegalAccessException { if (aConversionClass == null) { return null; } diff --git a/de.gebit.integrity.dsl/src/de/gebit/integrity/parameter/conversion/DefaultModularValueConverter.java b/de.gebit.integrity.dsl/src/de/gebit/integrity/parameter/conversion/DefaultModularValueConverter.java index 9f1448951..529a4e930 100644 --- a/de.gebit.integrity.dsl/src/de/gebit/integrity/parameter/conversion/DefaultModularValueConverter.java +++ b/de.gebit.integrity.dsl/src/de/gebit/integrity/parameter/conversion/DefaultModularValueConverter.java @@ -124,6 +124,7 @@ import de.gebit.integrity.parameter.conversion.conversions.java.other.EnumToString; import de.gebit.integrity.parameter.conversion.conversions.java.other.MapToBean; import de.gebit.integrity.parameter.conversion.conversions.java.other.MapToFormattedString; +import de.gebit.integrity.parameter.conversion.conversions.java.other.MapToMap; import de.gebit.integrity.parameter.conversion.conversions.java.other.MapToString; import de.gebit.integrity.parameter.conversion.conversions.java.other.ObjectToFormattedString; import de.gebit.integrity.parameter.conversion.conversions.java.other.ObjectToMap; @@ -209,6 +210,7 @@ protected void initializeConversions() { addConversion(MapToBean.class); addConversion(MapToString.class); addConversion(MapToFormattedString.class); + addConversion(MapToMap.class); addConversion(ObjectToMap.class); addConversion(EnumToString.class); addConversion(EnumToFormattedString.class); diff --git a/de.gebit.integrity.dsl/src/de/gebit/integrity/parameter/conversion/conversions/java/other/MapToMap.java b/de.gebit.integrity.dsl/src/de/gebit/integrity/parameter/conversion/conversions/java/other/MapToMap.java new file mode 100644 index 000000000..e0b58cce4 --- /dev/null +++ b/de.gebit.integrity.dsl/src/de/gebit/integrity/parameter/conversion/conversions/java/other/MapToMap.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * Copyright (c) 2016 Rene Schneider, GEBIT Solutions GmbH and others. + * 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 + *******************************************************************************/ +package de.gebit.integrity.parameter.conversion.conversions.java.other; + +import java.util.Map; +import java.util.Map.Entry; + +import de.gebit.integrity.operations.UnexecutableException; +import de.gebit.integrity.parameter.conversion.Conversion; +import de.gebit.integrity.parameter.conversion.ConversionContext; +import de.gebit.integrity.parameter.conversion.ConversionFailedException; +import de.gebit.integrity.utils.ParameterUtil.UnresolvableVariableException; + +/** + * A default Integrity conversion. + * + * + * @author Rene Schneider - initial API and implementation + * + */ +@SuppressWarnings("rawtypes") +@de.gebit.integrity.parameter.conversion.Conversion.Priority(Integer.MIN_VALUE) +public class MapToMap extends Conversion { + + @SuppressWarnings("unchecked") + @Override + public Map convert(Map aSource, Class aTargetType, ConversionContext aConversionContext) + throws ConversionFailedException { + + try { + Map tempTargetInstance = aTargetType.newInstance(); + + Class tempTargetValueType = null; + if (aTargetType.getTypeParameters().length >= 2) { + tempTargetValueType = aTargetType.getTypeParameters()[1].getGenericDeclaration().getComponentType(); + } + + for (Entry tempEntry : ((Map) aSource).entrySet()) { + // // find setter + // Method tempWriteMethod = new PropertyDescriptor(tempEntry.getKey(), aTargetType).getWriteMethod(); + // if (tempWriteMethod == null || tempWriteMethod.getParameterTypes().length != 1) { + // throw new ConversionFailedException(aSource.getClass(), aTargetType, + // "No accessible standards-compliant setter found for '" + tempEntry.getKey() + "'"); + // } + // + // aTargetType.getp + // Class tempTargetType = tempWriteMethod.getParameterTypes()[0]; + // Class tempParameterizedType = null; + // + // // See whether we can find a generic type parameter for the given target class + // Class tempClassInFocus = aTargetType; + // while (tempClassInFocus != null) { + // try { + // Field tempField = tempClassInFocus.getDeclaredField(tempEntry.getKey()); + // Type tempGenericType = tempField.getGenericType(); + // if (tempGenericType instanceof ParameterizedType) { + // Type tempInnerType = ((ParameterizedType) tempGenericType).getActualTypeArguments()[0]; + // if (tempInnerType instanceof WildcardType) { + // if (((WildcardType) tempInnerType).getUpperBounds() == null) { + // tempParameterizedType = null; + // } else { + // Type tempUpperBound = ((WildcardType) tempInnerType).getUpperBounds()[0]; + // if (tempUpperBound instanceof ParameterizedType) { + // tempParameterizedType = (Class) ((ParameterizedType) tempUpperBound) + // .getRawType(); + // } else { + // tempParameterizedType = (Class) tempUpperBound; + // } + // } + // // lower bounds not currently supported! + // + // } else { + // if (tempInnerType instanceof ParameterizedType) { + // tempParameterizedType = (Class) ((ParameterizedType) tempInnerType).getRawType(); + // } else { + // tempParameterizedType = (Class) tempInnerType; + // } + // } + // } + // break; + // } catch (SecurityException exc) { + // // don't care, just continue + // } catch (NoSuchFieldException exc) { + // // don't care, just continue + // } + // tempClassInFocus = tempClassInFocus.getSuperclass(); + // } + + Object tempConvertedValue; + // if (tempEntry.getValue() instanceof Map) { // map itself + // // case for only one element within an array type + // Class tempOriginalClass = tempWriteMethod.getParameterTypes()[0]; + // Class tempClass = tempOriginalClass; + // if (tempOriginalClass.isArray()) { + // tempClass = tempClass.getComponentType(); + // } + // + // tempConvertedValue = convert(((Map) tempEntry.getValue()), tempClass, aConversionContext); + // + // if (tempOriginalClass.isArray()) { + // Object tempCopy = tempConvertedValue; + // tempConvertedValue = Array.newInstance(tempClass, 1); + // Array.set(tempConvertedValue, 0, tempCopy); + // } + // } else { // value + tempConvertedValue = convertValueRecursive(tempTargetValueType, null, tempEntry.getValue(), + aConversionContext); + // } + tempTargetInstance.put(tempEntry.getKey(), tempConvertedValue); + } + return tempTargetInstance; + } catch ( + + InstantiationException exc) { + throw new ConversionFailedException(aSource.getClass(), aTargetType, null, exc); + } catch (IllegalAccessException exc) { + throw new ConversionFailedException(aSource.getClass(), aTargetType, null, exc); + } catch (UnresolvableVariableException exc) { + throw new ConversionFailedException(aSource.getClass(), aTargetType, null, exc); + } catch (ClassNotFoundException exc) { + throw new ConversionFailedException(aSource.getClass(), aTargetType, null, exc); + } catch (UnexecutableException exc) { + throw new ConversionFailedException(aSource.getClass(), aTargetType, null, exc); + } catch (IllegalArgumentException exc) { + throw new ConversionFailedException(aSource.getClass(), aTargetType, null, exc); + } catch (SecurityException exc) { + throw new ConversionFailedException(aSource.getClass(), aTargetType, null, exc); + } + } + +} diff --git a/de.gebit.integrity.tests/integrity/fixtures/BeanFixture.integrity b/de.gebit.integrity.tests/integrity/fixtures/BeanFixture.integrity index 67a4d660b..5acc8180c 100644 --- a/de.gebit.integrity.tests/integrity/fixtures/BeanFixture.integrity +++ b/de.gebit.integrity.tests/integrity/fixtures/BeanFixture.integrity @@ -30,5 +30,14 @@ packagedef integrity.fixtures.basic.beans with testdef createTransientTestBean uses de.gebit.integrity.tests.fixtures.basic.beans.BeanFixture#createTransientTestBean calldef createTransientTestBeanCall uses de.gebit.integrity.tests.fixtures.basic.beans.BeanFixture#createTransientTestBean + + testdef createMapTestBean uses de.gebit.integrity.tests.fixtures.basic.beans.BeanFixture#createMapTestBean + calldef createMapTestBeanCall uses de.gebit.integrity.tests.fixtures.basic.beans.BeanFixture#createMapTestBean + + testdef createMapTestBeanWithMapInMap uses de.gebit.integrity.tests.fixtures.basic.beans.BeanFixture#createMapTestBeanWithMapInMap + calldef createMapTestBeanWithMapInMapCall uses de.gebit.integrity.tests.fixtures.basic.beans.BeanFixture#createMapTestBeanWithMapInMap + + testdef createMapTestBeanWithTreeMap uses de.gebit.integrity.tests.fixtures.basic.beans.BeanFixture#createMapTestBeanWithTreeMap + calldef createMapTestBeanWithTreeMapCall uses de.gebit.integrity.tests.fixtures.basic.beans.BeanFixture#createMapTestBeanWithTreeMap packageend \ No newline at end of file diff --git a/de.gebit.integrity.tests/integrity/suites/basic/beans/mapInsideBeanTest.integrity b/de.gebit.integrity.tests/integrity/suites/basic/beans/mapInsideBeanTest.integrity new file mode 100644 index 000000000..bcd9f370f --- /dev/null +++ b/de.gebit.integrity.tests/integrity/suites/basic/beans/mapInsideBeanTest.integrity @@ -0,0 +1,57 @@ +import integrity.fixtures.basic.beans.* +import integrity.operations.default.* +import integrity.basic.beans.* + +packagedef integrity.basic.beans with + + suitedef mapInsideBeanSimple with + test createMapTestBean = { + mapParameter: { + key1: { + innerParameter: "foo" + } + key2: { + innerParameter: "bar" + } + } + } + suiteend + + suitedef mapInsideBeanWithMapInMap with + test createMapTestBeanWithMapInMap = { + mapInMapParameter: { + outerKey1: { + innerKey1: { + innerParameter: "foo" + } + innerKey2: { + innerParameter: "bar" + } + } + outerKey2: { + innerKey1: { + innerParameter: "bar" + } + innerKey2: { + innerParameter: "foo" + } + } + } + } + suiteend + + suitedef mapInsideBeanWithTreeMap with + test createMapTestBean = { + mapParameter: { + key1: { + innerParameter: "foo" + } + key2: { + innerParameter: "bar" + } + } + } + suiteend + + +packageend \ No newline at end of file diff --git a/de.gebit.integrity.tests/junit/de/gebit/integrity/tests/junit/basic/beans/MapInsideBeanTest.java b/de.gebit.integrity.tests/junit/de/gebit/integrity/tests/junit/basic/beans/MapInsideBeanTest.java new file mode 100644 index 000000000..2fee4f6cb --- /dev/null +++ b/de.gebit.integrity.tests/junit/de/gebit/integrity/tests/junit/basic/beans/MapInsideBeanTest.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2013 Rene Schneider, GEBIT Solutions GmbH and others. + * 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 + *******************************************************************************/ +package de.gebit.integrity.tests.junit.basic.beans; + +import java.io.IOException; + +import org.jdom.Document; +import org.jdom.JDOMException; +import org.junit.Test; + +import de.gebit.integrity.runner.exceptions.ModelLoadException; +import de.gebit.integrity.tests.junit.IntegrityJUnitTest; + +/** + * JUnit test which checks bean to map conversion operation and result string creation in such cases. + * + * + * @author Rene Schneider - initial API and implementation + * + */ +public class MapInsideBeanTest extends IntegrityJUnitTest { + + /** + * Performs a suite which does fixture calls with bean values and checks the resulting XML document. + * + * @throws ModelLoadException + * @throws IOException + * @throws JDOMException + */ + @Test + public void testMapInsideBeanSimple() throws ModelLoadException, IOException, JDOMException { + Document tempResult = executeIntegritySuite( + new String[] { "integrity/suites/basic/beans/mapInsideBeanTest.integrity" }, + "integrity.basic.beans.mapInsideBeanSimple", null); + assertDocumentMatchesReference(tempResult); + } + + /** + * Performs a suite which does fixture calls with bean values and checks the resulting XML document. + * + * @throws ModelLoadException + * @throws IOException + * @throws JDOMException + */ + @Test + public void testMapInsideBeanWithMapInMap() throws ModelLoadException, IOException, JDOMException { + Document tempResult = executeIntegritySuite( + new String[] { "integrity/suites/basic/beans/mapInsideBeanTest.integrity" }, + "integrity.basic.beans.mapInsideBeanWithMapInMap", null); + assertDocumentMatchesReference(tempResult); + } + + /** + * Performs a suite which does fixture calls with bean values and checks the resulting XML document. + * + * @throws ModelLoadException + * @throws IOException + * @throws JDOMException + */ + @Test + public void testMapInsideBeanWithTreeMap() throws ModelLoadException, IOException, JDOMException { + Document tempResult = executeIntegritySuite( + new String[] { "integrity/suites/basic/beans/mapInsideBeanTest.integrity" }, + "integrity.basic.beans.mapInsideBeanWithTreeMap", null); + assertDocumentMatchesReference(tempResult); + } + +} diff --git a/de.gebit.integrity.tests/results/integrity.basic.beans.mapInsideBeanSimple.xml b/de.gebit.integrity.tests/results/integrity.basic.beans.mapInsideBeanSimple.xml new file mode 100644 index 000000000..5844e6721 --- /dev/null +++ b/de.gebit.integrity.tests/results/integrity.basic.beans.mapInsideBeanSimple.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/de.gebit.integrity.tests/results/integrity.basic.beans.mapInsideBeanWithMapInMap.xml b/de.gebit.integrity.tests/results/integrity.basic.beans.mapInsideBeanWithMapInMap.xml new file mode 100644 index 000000000..7b7355b78 --- /dev/null +++ b/de.gebit.integrity.tests/results/integrity.basic.beans.mapInsideBeanWithMapInMap.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/de.gebit.integrity.tests/results/integrity.basic.beans.mapInsideBeanWithTreeMap.xml b/de.gebit.integrity.tests/results/integrity.basic.beans.mapInsideBeanWithTreeMap.xml new file mode 100644 index 000000000..2220e32be --- /dev/null +++ b/de.gebit.integrity.tests/results/integrity.basic.beans.mapInsideBeanWithTreeMap.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/de.gebit.integrity.tests/src/de/gebit/integrity/tests/fixtures/basic/beans/BeanFixture.java b/de.gebit.integrity.tests/src/de/gebit/integrity/tests/fixtures/basic/beans/BeanFixture.java index d5b8d90e8..c217be079 100644 --- a/de.gebit.integrity.tests/src/de/gebit/integrity/tests/fixtures/basic/beans/BeanFixture.java +++ b/de.gebit.integrity.tests/src/de/gebit/integrity/tests/fixtures/basic/beans/BeanFixture.java @@ -141,4 +141,19 @@ public Object createSimpleBeanUntypedEmpty() { public Object createTransientTestBean() { return new TransientTestBean(); } + + @FixtureMethod(description = "creates a map test bean and returns it") + public MapTestBean createMapTestBean() { + return new MapTestBean(); + } + + @FixtureMethod(description = "creates a map test bean and returns it") + public MapTestBeanWithMapInMap createMapTestBeanWithMapInMap() { + return new MapTestBeanWithMapInMap(); + } + + @FixtureMethod(description = "creates a map test bean and returns it") + public MapTestBeanWithTreeMap createMapTestBeanWithTreeMap() { + return new MapTestBeanWithTreeMap(); + } } diff --git a/de.gebit.integrity.tests/src/de/gebit/integrity/tests/fixtures/basic/beans/MapTestBean.java b/de.gebit.integrity.tests/src/de/gebit/integrity/tests/fixtures/basic/beans/MapTestBean.java new file mode 100644 index 000000000..20b92708b --- /dev/null +++ b/de.gebit.integrity.tests/src/de/gebit/integrity/tests/fixtures/basic/beans/MapTestBean.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2013 Rene Schneider, GEBIT Solutions GmbH and others. + * 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 + *******************************************************************************/ +package de.gebit.integrity.tests.fixtures.basic.beans; + +import java.util.HashMap; +import java.util.Map; + +//SUPPRESS CHECKSTYLE LONG Javadoc +public class MapTestBean { + + private Map mapParameter = new HashMap<>(); + + public MapTestBean() { + mapParameter.put("key1", new InnerBean("foo")); + mapParameter.put("key2", new InnerBean("bar")); + } + + public Map getMapParameter() { + return mapParameter; + } + + public void setMapParameter(Map mapParameter) { + this.mapParameter = mapParameter; + } + + public static class InnerBean { + + private String innerParameter; + + private InnerBean(String aParameter) { + innerParameter = aParameter; + } + + public String getInnerParameter() { + return innerParameter; + } + + public void setInnerParameter(String innerParameter) { + this.innerParameter = innerParameter; + } + + } + +} diff --git a/de.gebit.integrity.tests/src/de/gebit/integrity/tests/fixtures/basic/beans/MapTestBeanWithMapInMap.java b/de.gebit.integrity.tests/src/de/gebit/integrity/tests/fixtures/basic/beans/MapTestBeanWithMapInMap.java new file mode 100644 index 000000000..fc19225b6 --- /dev/null +++ b/de.gebit.integrity.tests/src/de/gebit/integrity/tests/fixtures/basic/beans/MapTestBeanWithMapInMap.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2013 Rene Schneider, GEBIT Solutions GmbH and others. + * 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 + *******************************************************************************/ +package de.gebit.integrity.tests.fixtures.basic.beans; + +import java.util.HashMap; +import java.util.Map; + +//SUPPRESS CHECKSTYLE LONG Javadoc +public class MapTestBeanWithMapInMap { + + private Map> mapInMapParameter = new HashMap<>(); + + public MapTestBeanWithMapInMap() { + Map tempInnerMap = new HashMap<>(); + tempInnerMap.put("innerKey1", new InnerBean("foo")); + tempInnerMap.put("innerKey2", new InnerBean("bar")); + mapInMapParameter.put("outerKey1", tempInnerMap); + + tempInnerMap = new HashMap<>(); + tempInnerMap.put("innerKey1", new InnerBean("bar")); + tempInnerMap.put("innerKey2", new InnerBean("foo")); + mapInMapParameter.put("outerKey2", tempInnerMap); + } + + public Map> getMapInMapParameter() { + return mapInMapParameter; + } + + public void setMapInMapParameter(Map> mapInMapParameter) { + this.mapInMapParameter = mapInMapParameter; + } + + public static class InnerBean { + + private String innerParameter; + + private InnerBean(String aParameter) { + innerParameter = aParameter; + } + + public String getInnerParameter() { + return innerParameter; + } + + public void setInnerParameter(String innerParameter) { + this.innerParameter = innerParameter; + } + + } + +} diff --git a/de.gebit.integrity.tests/src/de/gebit/integrity/tests/fixtures/basic/beans/MapTestBeanWithTreeMap.java b/de.gebit.integrity.tests/src/de/gebit/integrity/tests/fixtures/basic/beans/MapTestBeanWithTreeMap.java new file mode 100644 index 000000000..abaaee3a4 --- /dev/null +++ b/de.gebit.integrity.tests/src/de/gebit/integrity/tests/fixtures/basic/beans/MapTestBeanWithTreeMap.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2013 Rene Schneider, GEBIT Solutions GmbH and others. + * 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 + *******************************************************************************/ +package de.gebit.integrity.tests.fixtures.basic.beans; + +import java.util.TreeMap; + +//SUPPRESS CHECKSTYLE LONG Javadoc +public class MapTestBeanWithTreeMap { + + private TreeMap treeMapParameter = new TreeMap<>(); + + public MapTestBeanWithTreeMap() { + treeMapParameter.put("key1", new InnerBean("foo")); + treeMapParameter.put("key2", new InnerBean("bar")); + } + + public TreeMap getTreeMapParameter() { + return treeMapParameter; + } + + public void setTreeMapParameter(TreeMap treeMapParameter) { + this.treeMapParameter = treeMapParameter; + } + + public static class InnerBean { + + private String innerParameter; + + private InnerBean(String aParameter) { + innerParameter = aParameter; + } + + public String getInnerParameter() { + return innerParameter; + } + + public void setInnerParameter(String innerParameter) { + this.innerParameter = innerParameter; + } + + } + +}