| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.sis.feature; |
| |
| import java.util.Map; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.Collection; |
| import org.opengis.util.NameFactory; |
| import org.opengis.util.InternationalString; |
| import org.apache.sis.internal.system.DefaultFactories; |
| import org.apache.sis.test.DependsOnMethod; |
| import org.apache.sis.test.DependsOn; |
| import org.apache.sis.test.TestCase; |
| import org.junit.Test; |
| |
| import static org.apache.sis.test.Assert.*; |
| import static org.apache.sis.test.TestUtilities.getSingleton; |
| import static java.util.Collections.singletonMap; |
| |
| |
| /** |
| * Tests {@link DefaultFeatureType}. |
| * |
| * @author Martin Desruisseaux (Geomatys) |
| * @version 0.8 |
| * @since 0.5 |
| * @module |
| */ |
| @DependsOn(DefaultAttributeTypeTest.class) |
| public final strictfp class DefaultFeatureTypeTest extends TestCase { |
| /** |
| * Convenience method returning the given name in a a property map |
| * to be given to {@link AbstractIdentifiedType} constructor. |
| */ |
| private static Map<String,?> name(final Object name) { |
| return singletonMap(AbstractIdentifiedType.NAME_KEY, name); |
| } |
| |
| /** |
| * Creates a simple feature type without super-types. |
| * The feature contains the following attributes: |
| * |
| * <ul> |
| * <li>{@code city} as a {@link String} (mandatory)</li> |
| * <li>{@code population} as an {@link Integer} (mandatory)</li> |
| * </ul> |
| * |
| * @return the feature for a city. |
| */ |
| public static DefaultFeatureType city() { |
| final Map<String,Object> identification = new HashMap<>(); |
| final DefaultAttributeType<String> city = DefaultAttributeTypeTest.city(identification); |
| final DefaultAttributeType<Integer> population = DefaultAttributeTypeTest.population(identification); |
| return new DefaultFeatureType(name("City"), false, null, city, population); |
| } |
| |
| /** |
| * Creates a sub-type of the "city" type with only one additional property, an arbitrary amount of strings. |
| * The feature contains the following attribute: |
| * |
| * <ul> |
| * <li>{@code city} as a {@link String} (mandatory)</li> |
| * <li>{@code population} as an {@link Integer} (mandatory)</li> |
| * <li>{@code universities} as an arbitrary amount of {@link String}</li> |
| * </ul> |
| * |
| * @return the feature for an university city. |
| */ |
| public static DefaultFeatureType universityCity() { |
| return new DefaultFeatureType(name("University city"), false, |
| new DefaultFeatureType[] {city()}, DefaultAttributeTypeTest.universities()); |
| } |
| |
| /** |
| * Creates a sub-type of the "city" type with only one additional property, a string giving the parliament name. |
| * The feature contains the following attribute: |
| * |
| * <ul> |
| * <li>{@code city} as a {@link String} (mandatory)</li> |
| * <li>{@code population} as an {@link Integer} (mandatory)</li> |
| * <li>{@code parliament} as a {@link String} (mandatory)</li> |
| * </ul> |
| * |
| * @return the feature for a capital. |
| */ |
| public static DefaultFeatureType capital() { |
| return new DefaultFeatureType(name("Capital"), false, |
| new DefaultFeatureType[] {city()}, DefaultAttributeTypeTest.parliament()); |
| } |
| |
| /** |
| * Creates a sub-type of the "city" type with two additional properties. |
| * The feature contains the following attribute: |
| * |
| * <ul> |
| * <li>{@code city} as a {@link String} (mandatory)</li> |
| * <li>{@code population} as an {@link Integer} (mandatory)</li> |
| * <li>{@code region} as a {@link CharSequence} (mandatory) — the region for which the city is a metropolis.</li> |
| * <li>{@code isGlobal} as a {@link Boolean} (mandatory) — whether the city has an effect on global affairs.</li> |
| * </ul> |
| * |
| * @return the feature for a metropolis. |
| */ |
| public static DefaultFeatureType metropolis() { |
| final Map<String,Object> identification = new HashMap<>(4); |
| assertNull(identification.put(DefaultFeatureType.NAME_KEY, "Metropolis")); |
| assertNull(identification.put(DefaultFeatureType.NAME_KEY + "_fr", "Métropole")); |
| return new DefaultFeatureType(identification, false, |
| new DefaultFeatureType[] {city()}, |
| new DefaultAttributeType<>(name("region"), CharSequence.class, 1, 1, null), |
| new DefaultAttributeType<>(name("isGlobal"), Boolean.class, 1, 1, null)); |
| } |
| |
| /** |
| * Creates a sub-type of the "metropolis" type with the "region" attribute overridden to |
| * {@link InternationalString} and an arbitrary amount of universities. |
| */ |
| static DefaultFeatureType worldMetropolis() { |
| return worldMetropolis(metropolis(), universityCity(), CharacteristicTypeMapTest.temperature(), InternationalString.class); |
| } |
| |
| /** |
| * Creates a sub-type of the "metropolis" type with the "region" attribute overridden to the given type. |
| * The given type should be {@link InternationalString}, but we allow other types for testing argument checks. |
| */ |
| private static DefaultFeatureType worldMetropolis(final DefaultFeatureType metropolis, |
| final DefaultFeatureType universityCity, final DefaultAttributeType<?> temperature, final Class<?> regionType) |
| { |
| return new DefaultFeatureType(name("World metropolis"), false, |
| new DefaultFeatureType[] { // Super types |
| metropolis, |
| universityCity |
| }, |
| new DefaultAttributeType<?>[] { // Properties |
| new DefaultAttributeType<>(name("region"), regionType, 1, 1, null), |
| temperature |
| }); |
| } |
| |
| /** |
| * Verifies that {@code DefaultFeatureType} methods returns unmodifiable collections. |
| * This method does <strong>not</strong> check recursively the properties. |
| */ |
| private static void assertUnmodifiable(final DefaultFeatureType feature) { |
| final Collection<?> superTypes = feature.getSuperTypes(); |
| final Collection<?> declaredProperties = feature.getProperties(false); |
| final Collection<?> allProperties = feature.getProperties(true); |
| if (!superTypes.isEmpty()) try { |
| superTypes.clear(); |
| fail("Super-types collection shall not be modifiable."); |
| } catch (UnsupportedOperationException e) { |
| assertFalse(superTypes.isEmpty()); |
| } |
| if (!declaredProperties.isEmpty()) try { |
| declaredProperties.clear(); |
| fail("Properties collection shall not be modifiable."); |
| } catch (UnsupportedOperationException e) { |
| assertFalse(declaredProperties.isEmpty()); |
| } |
| if (!allProperties.isEmpty()) try { |
| allProperties.clear(); |
| fail("Properties collection shall not be modifiable."); |
| } catch (UnsupportedOperationException e) { |
| assertFalse(allProperties.isEmpty()); |
| } |
| // Opportunist check. |
| assertTrue("'properties(true)' shall contain all 'properties(false)' elements.", |
| allProperties.containsAll(declaredProperties)); |
| } |
| |
| /** |
| * Asserts that the given feature contains the given properties, in the same order. |
| * This method tests the following {@code FeatureType} methods: |
| * |
| * <ul> |
| * <li>{@link DefaultFeatureType#getProperties(boolean)}</li> |
| * <li>{@link DefaultFeatureType#getProperty(String)}</li> |
| * </ul> |
| * |
| * @param feature the feature to verify. |
| * @param includeSuperTypes {@code true} for including the properties inherited from the super-types, or |
| * {@code false} for returning only the properties defined explicitly in the feature type. |
| * @param expected names of the expected properties. |
| */ |
| private static void assertPropertiesEquals(final DefaultFeatureType feature, final boolean includeSuperTypes, |
| final String... expected) |
| { |
| int index = 0; |
| for (final AbstractIdentifiedType property : feature.getProperties(includeSuperTypes)) { |
| assertTrue("Found more properties than expected.", index < expected.length); |
| final String name = expected[index++]; |
| assertNotNull(name, property); |
| assertEquals (name, property.getName().toString()); |
| assertSame (name, property, feature.getProperty(name)); |
| } |
| assertEquals("Unexpected number of properties.", expected.length, index); |
| try { |
| feature.getProperty("apple"); |
| fail("Shall not found a non-existent property."); |
| } catch (IllegalArgumentException e) { |
| final String message = e.getMessage(); |
| assertTrue(message, message.contains("apple")); |
| assertTrue(message, message.contains(feature.getName().toString())); |
| } |
| } |
| |
| /** |
| * Tests the construction of a simple feature without super-types. |
| * A feature is said "simple" if the multiplicity of all attributes is [1 … 1]. |
| * |
| * <p>Current implementation performs its tests on the {@link #city()} feature.</p> |
| */ |
| @Test |
| public void testSimple() { |
| final DefaultFeatureType simple = city(); |
| assertUnmodifiable(simple); |
| assertEquals("name", "City", simple.getName().toString()); |
| assertTrue ("superTypes", simple.getSuperTypes().isEmpty()); |
| assertFalse ("isAbstract", simple.isAbstract()); |
| assertFalse ("isSparse", simple.isSparse()); |
| assertTrue ("isSimple", simple.isSimple()); |
| assertTrue ("isAssignableFrom", simple.isAssignableFrom(simple)); |
| assertEquals("instanceSize", 2, simple.indices().size()); |
| assertPropertiesEquals(simple, false, "city", "population"); |
| } |
| |
| /** |
| * Tests the construction of a "complex" feature without super-types. |
| * A feature is said "complex" if it contains at least one attribute |
| * with a multiplicity different than [0 … 0] and [1 … 1]. |
| */ |
| @Test |
| @DependsOnMethod("testSimple") |
| public void testComplex() { |
| final Map<String,Object> identification = new HashMap<>(); |
| final DefaultAttributeType<String> city = DefaultAttributeTypeTest.city(identification); |
| final DefaultAttributeType<Integer> population = DefaultAttributeTypeTest.population(identification); |
| testComplex(city, population, 0, 0); // Simple |
| testComplex(city, population, 0, 1); |
| testComplex(city, population, 0, 2); |
| testComplex(city, population, 1, 2); |
| testComplex(city, population, 1, 1); // Simple |
| } |
| |
| /** |
| * Implementation of {@link #testComplex()} for the given minimum and maximum occurrences. |
| */ |
| private static void testComplex( |
| final DefaultAttributeType<String> city, |
| final DefaultAttributeType<Integer> population, |
| final int minimumOccurs, final int maximumOccurs) |
| { |
| final DefaultAttributeType<String> festival = new DefaultAttributeType<>( |
| name("festival"), String.class, minimumOccurs, maximumOccurs, null); |
| |
| final DefaultFeatureType complex = new DefaultFeatureType( |
| name("Festival"), false, null, city, population, festival); |
| |
| assertUnmodifiable(complex); |
| final Collection<AbstractIdentifiedType> properties = complex.getProperties(false); |
| final Iterator<AbstractIdentifiedType> it = properties.iterator(); |
| |
| assertEquals("name", "Festival", complex.getName().toString()); |
| assertTrue ("superTypes", complex.getSuperTypes().isEmpty()); |
| assertTrue ("isAssignableFrom", complex.isAssignableFrom(complex)); |
| assertFalse ("isAbstract", complex.isAbstract()); |
| assertFalse ("isSparse", complex.isSparse()); |
| assertEquals("isSimple", maximumOccurs == minimumOccurs, complex.isSimple()); |
| assertEquals("instanceSize", maximumOccurs == 0 ? 2 : 3, complex.indices().size()); |
| assertEquals("minimumOccurs", minimumOccurs, festival.getMinimumOccurs()); |
| assertEquals("maximumOccurs", maximumOccurs, festival.getMaximumOccurs()); |
| assertEquals("properties.size", 3, properties.size()); |
| assertSame ("properties[0]", city, it.next()); |
| assertSame ("properties[1]", population, it.next()); |
| assertSame ("properties[2]", festival, it.next()); |
| assertFalse (it.hasNext()); |
| } |
| |
| /** |
| * Ensures that we can not use two properties with the same name. |
| */ |
| @Test |
| @DependsOnMethod("testSimple") |
| public void testNameCollision() { |
| final DefaultAttributeType<String> city = new DefaultAttributeType<>(name("name"), String.class, 1, 1, null); |
| final DefaultAttributeType<Integer> cityId = new DefaultAttributeType<>(name("name"), Integer.class, 1, 1, null); |
| final DefaultAttributeType<Integer> population = new DefaultAttributeType<>(name("population"), Integer.class, 1, 1, null); |
| |
| try { |
| final Object t = new DefaultFeatureType(name("City"), false, null, city, population, cityId); |
| fail("Duplicated attribute names shall not be allowed:\n" + t); |
| } catch (IllegalArgumentException e) { |
| final String message = e.getMessage(); |
| assertTrue(message, message.contains("name")); // Property name. |
| assertTrue(message, message.contains("City")); // Feature name. |
| } |
| } |
| |
| /** |
| * Same than {@link #testNameCollision()}, but resolving collisions with usage of names |
| * of the form {@code "head:tip"}. |
| * |
| * @since 0.6 |
| */ |
| @Test |
| @DependsOnMethod("testNameCollision") |
| public void testQualifiedNames() { |
| final NameFactory factory = DefaultFactories.forBuildin(NameFactory.class); |
| final DefaultAttributeType<String> city = new DefaultAttributeType<>( |
| name(factory.createGenericName(null, "ns1", "name")), |
| String.class, 1, 1, null); |
| final DefaultAttributeType<Integer> cityId = new DefaultAttributeType<>( |
| name(factory.createGenericName(null, "ns2", "name")), |
| Integer.class, 1, 1, null); |
| final DefaultAttributeType<Integer> population = new DefaultAttributeType<>( |
| name(factory.createGenericName(null, "ns1", "population")), |
| Integer.class, 1, 1, null); |
| final DefaultFeatureType feature = new DefaultFeatureType( |
| name("City"), false, null, city, cityId, population); |
| |
| final Iterator<AbstractIdentifiedType> it = feature.getProperties(false).iterator(); |
| assertSame ("properties[0]", city, it.next()); |
| assertSame ("properties[1]", cityId, it.next()); |
| assertSame ("properties[2]", population, it.next()); |
| assertFalse(it.hasNext()); |
| |
| assertSame("Shall get from fully qualified name.", city, feature.getProperty("ns1:name")); |
| assertSame("Shall get from fully qualified name.", cityId, feature.getProperty("ns2:name")); |
| assertSame("Shall get from fully qualified name.", population, feature.getProperty("ns1:population")); |
| assertSame("Shall get from short alias.", population, feature.getProperty( "population")); |
| try { |
| feature.getProperty("name"); |
| fail("Expected no alias because of ambiguity."); |
| } catch (IllegalArgumentException e) { |
| final String message = e.getMessage(); |
| assertTrue(message, message.contains("name")); // Property name. |
| assertTrue(message, message.contains("ns1:name")); // Ambiguity 1. |
| assertTrue(message, message.contains("ns2:name")); // Ambiguity 2. |
| } |
| try { |
| feature.getProperty("other"); |
| fail("Expected no property."); |
| } catch (IllegalArgumentException e) { |
| final String message = e.getMessage(); |
| assertTrue(message, message.contains("other")); // Property name. |
| assertTrue(message, message.contains("City")); // Feature name. |
| } |
| } |
| |
| /** |
| * Tests two names having the same tip, but where only one of the two names have a namespace. |
| * |
| * @since 0.8 |
| */ |
| @Test |
| @DependsOnMethod("testQualifiedNames") |
| public void testQualifiedAndUnqualifiedNames() { |
| final NameFactory factory = DefaultFactories.forBuildin(NameFactory.class); |
| final DefaultAttributeType<String> a1 = new DefaultAttributeType<>( |
| name(factory.createGenericName(null, "sis", "identifier")), |
| String.class, 1, 1, null); |
| final DefaultAttributeType<String> a2 = new DefaultAttributeType<>( |
| name(factory.createGenericName(null, "identifier")), |
| String.class, 1, 1, null); |
| final DefaultFeatureType feature = new DefaultFeatureType( |
| name("City"), false, null, a1, a2); |
| |
| assertSame("sis:identifier", a1, feature.getProperty("sis:identifier")); |
| assertSame( "identifier", a2, feature.getProperty( "identifier")); |
| } |
| |
| /** |
| * Tests inclusion of a property of kind operation. |
| */ |
| @Test |
| public void testOperationProperty() { |
| final Map<String,?> featureName = name("Identified city"); |
| final Map<String,?> identifierName = name("identifier"); |
| final DefaultFeatureType[] parent = {city()}; |
| final DefaultFeatureType city = new DefaultFeatureType(featureName, false, |
| parent, new LinkOperation(identifierName, parent[0].getProperty("city"))); |
| assertPropertiesEquals(city, true, "city", "population", "identifier"); |
| /* |
| * Try to add an operation that depends on a non-existent property. |
| * Such construction shall not be allowed. |
| */ |
| final AbstractIdentifiedType parliament = new LinkOperation(identifierName, DefaultAttributeTypeTest.parliament()); |
| try { |
| final DefaultFeatureType illegal = new DefaultFeatureType(featureName, false, parent, parliament); |
| fail("Should not have been allowed to create this feature:\n" + illegal); |
| } catch (IllegalArgumentException e) { |
| final String message = e.getLocalizedMessage(); |
| assertTrue(message, message.contains("identifier")); |
| assertTrue(message, message.contains("parliament")); |
| assertTrue(message, message.contains("Identified city")); |
| } |
| } |
| |
| /** |
| * Tests a feature type which inherit from an other feature type, but without property overriding. |
| * |
| * <p>Current implementation performs its tests on the {@link #capital()} feature.</p> |
| */ |
| @Test |
| @DependsOnMethod({"testComplex", "testEquals"}) |
| public void testInheritance() { |
| final DefaultFeatureType city = city(); // Tested by 'testSimple()'. |
| final DefaultFeatureType capital = capital(); |
| assertUnmodifiable(capital); |
| assertEquals("name", "Capital", capital.getName().toString()); |
| assertEquals("superTypes", city, getSingleton(capital.getSuperTypes())); |
| assertFalse ("isAbstract", capital.isAbstract()); |
| assertFalse ("isSparse", capital.isSparse()); |
| assertTrue ("isSimple", capital.isSimple()); |
| assertEquals("instanceSize", 3, capital.indices().size()); |
| |
| assertPropertiesEquals(city, false, "city", "population"); |
| assertPropertiesEquals(capital, false, "parliament"); |
| assertPropertiesEquals(capital, true, "city", "population", "parliament"); |
| |
| // Check based only on name. |
| assertTrue ("maybeAssignableFrom", DefaultFeatureType.maybeAssignableFrom(city, capital)); |
| assertFalse("maybeAssignableFrom", DefaultFeatureType.maybeAssignableFrom(capital, city)); |
| |
| // Public API. |
| assertTrue ("isAssignableFrom", city.isAssignableFrom(capital)); |
| assertFalse("isAssignableFrom", capital.isAssignableFrom(city)); |
| } |
| |
| /** |
| * Tests the inheritance of 2 types having the same common parent. |
| */ |
| @Test |
| @DependsOnMethod("testInheritance") |
| public void testMultiInheritance() { |
| final DefaultFeatureType metropolis = metropolis(); |
| final DefaultFeatureType capital = capital(); // Tested by 'testComplex()'. |
| final DefaultFeatureType metroCapital = new DefaultFeatureType( |
| name("Metropolis and capital"), false, |
| new DefaultFeatureType[] {metropolis, capital}, |
| new DefaultAttributeType<>(name("country"), |
| String.class, 1, 1, null)); |
| |
| assertUnmodifiable(metroCapital); |
| assertEquals ("name", "Metropolis and capital", metroCapital.getName().toString()); |
| assertArrayEquals("superTypes", new Object[] {metropolis, capital}, metroCapital.getSuperTypes().toArray()); |
| assertFalse ("isAbstract", metroCapital.isAbstract()); |
| assertFalse ("isSparse", metroCapital.isSparse()); |
| assertTrue ("isSimple", metroCapital.isSimple()); |
| assertEquals ("instanceSize", 6, metroCapital.indices().size()); |
| |
| assertPropertiesEquals(metroCapital, false, "country"); |
| assertPropertiesEquals(metroCapital, true, "city", "population", "region", "isGlobal", "parliament", "country"); |
| assertEquals("property(“region”).valueClass", CharSequence.class, |
| ((DefaultAttributeType<?>) metroCapital.getProperty("region")).getValueClass()); |
| |
| // Check based only on name. |
| assertTrue ("maybeAssignableFrom", DefaultFeatureType.maybeAssignableFrom(capital, metroCapital)); |
| assertFalse("maybeAssignableFrom", DefaultFeatureType.maybeAssignableFrom(metroCapital, capital)); |
| assertTrue ("maybeAssignableFrom", DefaultFeatureType.maybeAssignableFrom(metropolis, metroCapital)); |
| assertFalse("maybeAssignableFrom", DefaultFeatureType.maybeAssignableFrom(metroCapital, metropolis)); |
| |
| // Public API. |
| assertTrue ("isAssignableFrom", capital.isAssignableFrom(metroCapital)); |
| assertFalse("isAssignableFrom", metroCapital.isAssignableFrom(capital)); |
| assertTrue ("isAssignableFrom", metropolis.isAssignableFrom(metroCapital)); |
| assertFalse("isAssignableFrom", metroCapital.isAssignableFrom(metropolis)); |
| } |
| |
| /** |
| * Tests inheritance with a property that override an other property with a more specific type. |
| */ |
| @Test |
| @DependsOnMethod({"testMultiInheritance", "testNameCollision"}) |
| public void testPropertyOverride() { |
| final DefaultFeatureType metropolis = metropolis(); |
| final DefaultFeatureType universityCity = universityCity(); |
| final DefaultAttributeType<?> temperature = CharacteristicTypeMapTest.temperature(); |
| try { |
| worldMetropolis(metropolis, universityCity, temperature, Integer.class); |
| fail("Shall not be allowed to override a 'CharSequence' attribute with an 'Integer' one."); |
| } catch (IllegalArgumentException e) { |
| final String message = e.getMessage(); |
| assertTrue(message, message.contains("region")); |
| assertTrue(message, message.contains("Metropolis")); |
| } |
| final DefaultFeatureType worldMetropolis = worldMetropolis(metropolis, universityCity, temperature, InternationalString.class); |
| assertUnmodifiable(worldMetropolis); |
| assertEquals ("name", "World metropolis", worldMetropolis.getName().toString()); |
| assertArrayEquals("superTypes", new Object[] {metropolis, universityCity}, worldMetropolis.getSuperTypes().toArray()); |
| assertFalse ("isAbstract", worldMetropolis.isAbstract()); |
| assertFalse ("isSparse", worldMetropolis.isSparse()); |
| assertFalse ("isSimple", worldMetropolis.isSimple()); // Because of the arbitrary amount of universities. |
| assertEquals ("instanceSize", 6, worldMetropolis.indices().size()); |
| |
| assertPropertiesEquals(worldMetropolis, false, "region", "temperature"); |
| assertPropertiesEquals(worldMetropolis, true, "city", "population", "region", "isGlobal", "universities", "temperature"); |
| assertEquals("property(“region”).valueClass", InternationalString.class, |
| ((DefaultAttributeType<?>) worldMetropolis.getProperty("region")).getValueClass()); |
| |
| // Check based only on name. |
| assertTrue ("maybeAssignableFrom", DefaultFeatureType.maybeAssignableFrom(metropolis, worldMetropolis)); |
| assertFalse("maybeAssignableFrom", DefaultFeatureType.maybeAssignableFrom(worldMetropolis, metropolis)); |
| |
| // Public API. |
| assertTrue ("isAssignableFrom", metropolis.isAssignableFrom(worldMetropolis)); |
| assertFalse("isAssignableFrom", worldMetropolis.isAssignableFrom(metropolis)); |
| } |
| |
| /** |
| * Tests the ommission of a property that duplicate a property already declared in the parent. |
| * This is a little bit different than {@link #testPropertyOverride()} since the duplicated property |
| * should be completely omitted. |
| */ |
| @Test |
| @DependsOnMethod("testPropertyOverride") |
| public void testPropertyDuplication() { |
| DefaultFeatureType city = city(); |
| city = new DefaultFeatureType(name("New-City"), |
| false, new DefaultFeatureType[] {city()}, city.getProperty("city")); |
| |
| assertPropertiesEquals(city, false); |
| assertPropertiesEquals(city, true, "city", "population"); |
| } |
| |
| /** |
| * Tests {@link DefaultFeatureType#equals(Object)}. |
| */ |
| @Test |
| @DependsOnMethod("testSimple") |
| public void testEquals() { |
| final DefaultFeatureType city = city(); |
| assertTrue (city.equals(city())); |
| assertFalse(city.equals(capital())); |
| } |
| |
| /** |
| * Tests serialization. |
| */ |
| @Test |
| @DependsOnMethod({"testInheritance", "testEquals"}) |
| public void testSerialization() { |
| assertPropertiesEquals(assertSerializedEquals(capital()), true, "city", "population", "parliament"); |
| } |
| } |