/*
 * 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.felix.ipojo.runtime.core.test.annotations;

import org.apache.felix.ipojo.ComponentInstance;
import org.apache.felix.ipojo.architecture.Architecture;
import org.junit.Test;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;

/**
 * Checks that a component setting a name and using the @Instantiate annotation creates the instance correctly.
 * It reproduce {@link https://issues.apache.org/jira/browse/FELIX-4052}
 */
public class TestInstantiatedComponent extends Common {

    @Test
    public void testInstanceCreation() {
        // This is the expected name.
        Architecture architecture = osgiHelper.getServiceObject(Architecture.class,
                "(architecture.instance=MyInstantiatedComponent-0)");

        assertNotNull(architecture);
        assertEquals(ComponentInstance.VALID, architecture.getInstanceDescription().getState());
    }

}
