/*
 * Copyright (C) 2006 Google Inc.
 *
 * Licensed 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 com.google.inject.spring;

import static com.google.inject.spring.SpringIntegration.fromSpring;

import com.google.inject.AbstractModule;
import com.google.inject.CreationException;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.name.Names;
import junit.framework.TestCase;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;

/** @author crazybob@google.com (Bob Lee) */
public class SpringIntegrationTest extends TestCase {

  public void testBindFromSpring() throws CreationException {
    final DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

    RootBeanDefinition singleton = new RootBeanDefinition(Singleton.class);
    beanFactory.registerBeanDefinition("singleton", singleton);

    RootBeanDefinition prototype = new RootBeanDefinition(Prototype.class);
    prototype.setScope(BeanDefinition.SCOPE_PROTOTYPE);
    beanFactory.registerBeanDefinition("prototype", prototype);

    Injector injector =
        Guice.createInjector(
            new AbstractModule() {
              @Override
              protected void configure() {
                bind(BeanFactory.class).toInstance(beanFactory);
                bind(Singleton.class).toProvider(fromSpring(Singleton.class, "singleton"));
                bind(Prototype.class).toProvider(fromSpring(Prototype.class, "prototype"));
              }
            });

    assertNotNull(injector.getInstance(Singleton.class));
    assertSame(injector.getInstance(Singleton.class), injector.getInstance(Singleton.class));

    assertNotNull(injector.getInstance(Prototype.class));
    assertNotSame(injector.getInstance(Prototype.class), injector.getInstance(Prototype.class));
  }

  public void testBindAll() throws CreationException {
    final DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

    RootBeanDefinition singleton = new RootBeanDefinition(Singleton.class);
    beanFactory.registerBeanDefinition("singleton", singleton);

    RootBeanDefinition prototype = new RootBeanDefinition(Prototype.class);
    prototype.setScope(BeanDefinition.SCOPE_PROTOTYPE);
    beanFactory.registerBeanDefinition("prototype", prototype);

    Injector injector =
        Guice.createInjector(
            new AbstractModule() {
              @Override
              protected void configure() {
                SpringIntegration.bindAll(binder(), beanFactory);
              }
            });

    Key<Singleton> singletonKey = Key.get(Singleton.class, Names.named("singleton"));
    Key<Prototype> prototypeKey = Key.get(Prototype.class, Names.named("prototype"));

    assertNotNull(injector.getInstance(singletonKey));
    assertSame(injector.getInstance(singletonKey), injector.getInstance(singletonKey));

    assertNotNull(injector.getInstance(prototypeKey));
    assertNotSame(injector.getInstance(prototypeKey), injector.getInstance(prototypeKey));
  }

  static class Singleton {}

  static class Prototype {}
}
