/*
 * 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.commons.beanutils2;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import junit.framework.TestCase;

/**
 * Test class for {@code SuppressPropertiesBeanIntrospector}.
 *
 */
public class SuppressPropertiesBeanIntrospectorTestCase extends TestCase {
    /**
     * Tries to create an instance without properties.
     */
    public void testInitNoPropertyNames() {
        try {
            new SuppressPropertiesBeanIntrospector(null);
            fail("Missing properties not detected!");
        } catch (final IllegalArgumentException iaex) {
            // ok
        }
    }

    /**
     * Tests whether the expected properties have been removed during introspection.
     */
    public void testRemovePropertiesDuringIntrospection() throws IntrospectionException {
        final String[] properties = { "test", "other", "oneMore" };
        final SuppressPropertiesBeanIntrospector introspector = new SuppressPropertiesBeanIntrospector(
                Arrays.asList(properties));
        final IntrospectionContextTestImpl context = new IntrospectionContextTestImpl();

        introspector.introspect(context);
        assertEquals("Wrong number of removed properties", properties.length, context
                .getRemovedProperties().size());
        for (final String property : properties) {
            assertTrue("Property not removed: " + property, context
                    .getRemovedProperties().contains(property));
        }
    }

    /**
     * Tests that a defensive copy is created from the collection with properties to be
     * removed.
     */
    public void testPropertyNamesDefensiveCopy() throws IntrospectionException {
        final Collection<String> properties = new HashSet<>();
        properties.add("prop1");
        final SuppressPropertiesBeanIntrospector introspector = new SuppressPropertiesBeanIntrospector(
                properties);
        properties.add("prop2");
        final IntrospectionContextTestImpl context = new IntrospectionContextTestImpl();

        introspector.introspect(context);
        assertEquals("Wrong number of removed properties", 1, context
                .getRemovedProperties().size());
        assertTrue("Wrong removed property",
                context.getRemovedProperties().contains("prop1"));
    }

    /**
     * Tests that the set with properties to be removed cannot be modified.
     */
    public void testGetSuppressedPropertiesModify() {
        final SuppressPropertiesBeanIntrospector introspector = new SuppressPropertiesBeanIntrospector(
                Arrays.asList("p1", "p2"));
        final Set<String> properties = introspector.getSuppressedProperties();
        try {
            properties.add("anotherProperty");
            fail("Could modify properties");
        } catch (final UnsupportedOperationException uoex) {
            // ok
        }
    }

    /**
     * A test implementation of IntrospectionContext which collects the properties which
     * have been removed.
     */
    private static class IntrospectionContextTestImpl implements IntrospectionContext {
        /** Stores the names of properties which have been removed. */
        private final Set<String> removedProperties = new HashSet<>();

        /**
         * Returns the names of properties which have been removed.
         *
         * @return the set with removed properties
         */
        public Set<String> getRemovedProperties() {
            return removedProperties;
        }

        @Override
        public Class<?> getTargetClass() {
            throw new UnsupportedOperationException("Unexpected method call!");
        }

        @Override
        public void addPropertyDescriptor(final PropertyDescriptor desc) {
            throw new UnsupportedOperationException("Unexpected method call!");
        }

        @Override
        public void addPropertyDescriptors(final PropertyDescriptor[] descriptors) {
            throw new UnsupportedOperationException("Unexpected method call!");
        }

        @Override
        public boolean hasProperty(final String name) {
            throw new UnsupportedOperationException("Unexpected method call!");
        }

        @Override
        public PropertyDescriptor getPropertyDescriptor(final String name) {
            throw new UnsupportedOperationException("Unexpected method call!");
        }

        @Override
        public void removePropertyDescriptor(final String name) {
            removedProperties.add(name);
        }

        @Override
        public Set<String> propertyNames() {
            throw new UnsupportedOperationException("Unexpected method call!");
        }
    }
}
