// Path: cfg4j-core/src/main/java/org/cfg4j/source/ConfigurationSource.java
// public interface ConfigurationSource {
// 
//   /**
//    * Get configuration set for a given {@code environment} from this source in a form of {@link Properties}.
//    * Provided {@link Environment} will be used to determine which environment to use.
//    *
//    * @param environment environment to use
//    * @return configuration set for {@code environment}
//    * @throws MissingEnvironmentException when requested environment couldn't be found
//    * @throws IllegalStateException       when unable to fetch configuration
//    */
//   Properties getConfiguration(Environment environment);
// 
//   /**
//    * Initialize this source. This method has to be called before any other method of this instance.
//    *
//    * @throws IllegalStateException        when source was improperly configured
//    * @throws SourceCommunicationException when unable to communicate with source
//    */
//   void init();
// }
// 
// Path: cfg4j-core/src/main/java/org/cfg4j/source/classpath/ClasspathConfigurationSource.java
// public class ClasspathConfigurationSource implements ConfigurationSource {
// 
//   private final ConfigFilesProvider configFilesProvider;
//   private final PropertiesProviderSelector propertiesProviderSelector;
// 
//   /**
//    * Construct {@link ConfigurationSource} backed by classpath files. Uses "application.properties" file
//    * located in the path specified by the {@link Environment} provided to {@link #getConfiguration(Environment)}
//    * calls (see corresponding javadoc for detail).
//    */
//   public ClasspathConfigurationSource() {
//     this(() -> Collections.singletonList(
//         Paths.get("application.properties")
//     ));
//   }
// 
//   /**
//    * Construct {@link ConfigurationSource} backed by classpath files. File paths should by provided by
//    * {@link ConfigFilesProvider} and will be treated as relative paths to the environment provided in
//    * {@link #getConfiguration(Environment)} calls (see corresponding javadoc for detail). Configuration
//    * file type is detected using file extension (see {@link PropertiesProviderSelector}).
//    *
//    * @param configFilesProvider {@link ConfigFilesProvider} supplying a list of configuration files to use
//    */
//   public ClasspathConfigurationSource(ConfigFilesProvider configFilesProvider) {
//     this(configFilesProvider, new PropertiesProviderSelector(
//         new PropertyBasedPropertiesProvider(), new YamlBasedPropertiesProvider(), new JsonBasedPropertiesProvider()
//     ));
//   }
// 
//   /**
//    * Construct {@link ConfigurationSource} backed by classpath files. File paths should by provided by
//    * {@link ConfigFilesProvider} and will be treated as relative paths to the environment provided in
//    * {@link #getConfiguration(Environment)} calls (see corresponding javadoc for detail).
//    *
//    * @param configFilesProvider        {@link ConfigFilesProvider} supplying a list of configuration files to use
//    * @param propertiesProviderSelector selector used for choosing {@link PropertiesProvider} based on a configuration file extension
//    */
//   public ClasspathConfigurationSource(ConfigFilesProvider configFilesProvider, PropertiesProviderSelector propertiesProviderSelector) {
//     this.configFilesProvider = requireNonNull(configFilesProvider);
//     this.propertiesProviderSelector = requireNonNull(propertiesProviderSelector);
//   }
// 
//   /**
//    * Get configuration from classpath. See the class-level javadoc for detail on environment resolution.
//    *
//    * @param environment environment to fetch configuration for
//    * @return configuration set for {@code environment}
//    * @throws MissingEnvironmentException when requested environment couldn't be found
//    * @throws IllegalStateException       when unable to fetch configuration
//    */
//   @Override
//   public Properties getConfiguration(Environment environment) {
//     Properties properties = new Properties();
// 
//     Path pathPrefix = Paths.get(environment.getName());
// 
//     URL url = getClass().getClassLoader().getResource(pathPrefix.toString());
//     if (url == null && !environment.getName().isEmpty()) {
//       throw new MissingEnvironmentException("Directory doesn't exist: " + environment.getName());
//     }
// 
//     List<Path> paths = new ArrayList<>();
//     for (Path path : configFilesProvider.getConfigFiles()) {
//       paths.add(pathPrefix.resolve(path));
//     }
// 
//     for (Path path : paths) {
//       try (InputStream input = getClass().getClassLoader().getResourceAsStream(path.toString())) {
// 
//         if (input == null) {
//           throw new IllegalStateException("Unable to load properties from classpath: " + path);
//         }
// 
//         PropertiesProvider provider = propertiesProviderSelector.getProvider(path.getFileName().toString());
//         properties.putAll(provider.getProperties(input));
// 
//       } catch (IOException e) {
//         throw new IllegalStateException("Unable to load properties from classpath: " + path, e);
//       }
//     }
// 
//     return properties;
//   }
// 
//   @Override
//   public void init() {
//     // NOP
//   }
// 
//   @Override
//   public String toString() {
//     return "ClasspathConfigurationSource{" +
//         "configFilesProvider=" + configFilesProvider +
//         '}';
//   }
// }


import static org.assertj.core.api.Assertions.assertThat;
import org.cfg4j.source.ConfigurationSource;
import org.cfg4j.source.classpath.ClasspathConfigurationSource;
import org.junit.jupiter.api.Test;
import java.nio.file.Paths;
import java.util.Collections;
/*
 * Copyright 2015-2018 Norbert Potocki (norbert.potocki@nort.pl)
 *
 * 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 org.cfg4j.provider;





class SimpleConfigurationProviderWithClasspathIntegrationTest {




  @Test
  void readsYamlBooleans() {
    String path = "org/cfg4j/provider/SimpleConfigurationProviderIntegrationTest_readsYamlBooleans.yaml";

    ConfigurationProvider provider = getConfigurationProvider(path);

    assertThat(provider.getProperty("someSetting", Boolean.class)).isTrue();
  }

  @Test
  void readsYamlIntegers() {
    String path = "org/cfg4j/provider/SimpleConfigurationProviderIntegrationTest_readsYamlIntegers.yaml";

    ConfigurationProvider provider = getConfigurationProvider(path);

    assertThat(provider.getProperty("someSetting", Integer.class)).isEqualTo(42);
  }

  private ConfigurationProvider getConfigurationProvider(final String path) {
// Path: cfg4j-core/src/main/java/org/cfg4j/source/ConfigurationSource.java
// public interface ConfigurationSource {
// 
//   /**
//    * Get configuration set for a given {@code environment} from this source in a form of {@link Properties}.
//    * Provided {@link Environment} will be used to determine which environment to use.
//    *
//    * @param environment environment to use
//    * @return configuration set for {@code environment}
//    * @throws MissingEnvironmentException when requested environment couldn't be found
//    * @throws IllegalStateException       when unable to fetch configuration
//    */
//   Properties getConfiguration(Environment environment);
// 
//   /**
//    * Initialize this source. This method has to be called before any other method of this instance.
//    *
//    * @throws IllegalStateException        when source was improperly configured
//    * @throws SourceCommunicationException when unable to communicate with source
//    */
//   void init();
// }
// 
// Path: cfg4j-core/src/main/java/org/cfg4j/source/classpath/ClasspathConfigurationSource.java
// public class ClasspathConfigurationSource implements ConfigurationSource {
// 
//   private final ConfigFilesProvider configFilesProvider;
//   private final PropertiesProviderSelector propertiesProviderSelector;
// 
//   /**
//    * Construct {@link ConfigurationSource} backed by classpath files. Uses "application.properties" file
//    * located in the path specified by the {@link Environment} provided to {@link #getConfiguration(Environment)}
//    * calls (see corresponding javadoc for detail).
//    */
//   public ClasspathConfigurationSource() {
//     this(() -> Collections.singletonList(
//         Paths.get("application.properties")
//     ));
//   }
// 
//   /**
//    * Construct {@link ConfigurationSource} backed by classpath files. File paths should by provided by
//    * {@link ConfigFilesProvider} and will be treated as relative paths to the environment provided in
//    * {@link #getConfiguration(Environment)} calls (see corresponding javadoc for detail). Configuration
//    * file type is detected using file extension (see {@link PropertiesProviderSelector}).
//    *
//    * @param configFilesProvider {@link ConfigFilesProvider} supplying a list of configuration files to use
//    */
//   public ClasspathConfigurationSource(ConfigFilesProvider configFilesProvider) {
//     this(configFilesProvider, new PropertiesProviderSelector(
//         new PropertyBasedPropertiesProvider(), new YamlBasedPropertiesProvider(), new JsonBasedPropertiesProvider()
//     ));
//   }
// 
//   /**
//    * Construct {@link ConfigurationSource} backed by classpath files. File paths should by provided by
//    * {@link ConfigFilesProvider} and will be treated as relative paths to the environment provided in
//    * {@link #getConfiguration(Environment)} calls (see corresponding javadoc for detail).
//    *
//    * @param configFilesProvider        {@link ConfigFilesProvider} supplying a list of configuration files to use
//    * @param propertiesProviderSelector selector used for choosing {@link PropertiesProvider} based on a configuration file extension
//    */
//   public ClasspathConfigurationSource(ConfigFilesProvider configFilesProvider, PropertiesProviderSelector propertiesProviderSelector) {
//     this.configFilesProvider = requireNonNull(configFilesProvider);
//     this.propertiesProviderSelector = requireNonNull(propertiesProviderSelector);
//   }
// 
//   /**
//    * Get configuration from classpath. See the class-level javadoc for detail on environment resolution.
//    *
//    * @param environment environment to fetch configuration for
//    * @return configuration set for {@code environment}
//    * @throws MissingEnvironmentException when requested environment couldn't be found
//    * @throws IllegalStateException       when unable to fetch configuration
//    */
//   @Override
//   public Properties getConfiguration(Environment environment) {
//     Properties properties = new Properties();
// 
//     Path pathPrefix = Paths.get(environment.getName());
// 
//     URL url = getClass().getClassLoader().getResource(pathPrefix.toString());
//     if (url == null && !environment.getName().isEmpty()) {
//       throw new MissingEnvironmentException("Directory doesn't exist: " + environment.getName());
//     }
// 
//     List<Path> paths = new ArrayList<>();
//     for (Path path : configFilesProvider.getConfigFiles()) {
//       paths.add(pathPrefix.resolve(path));
//     }
// 
//     for (Path path : paths) {
//       try (InputStream input = getClass().getClassLoader().getResourceAsStream(path.toString())) {
// 
//         if (input == null) {
//           throw new IllegalStateException("Unable to load properties from classpath: " + path);
//         }
// 
//         PropertiesProvider provider = propertiesProviderSelector.getProvider(path.getFileName().toString());
//         properties.putAll(provider.getProperties(input));
// 
//       } catch (IOException e) {
//         throw new IllegalStateException("Unable to load properties from classpath: " + path, e);
//       }
//     }
// 
//     return properties;
//   }
// 
//   @Override
//   public void init() {
//     // NOP
//   }
// 
//   @Override
//   public String toString() {
//     return "ClasspathConfigurationSource{" +
//         "configFilesProvider=" + configFilesProvider +
//         '}';
//   }
// }


// Path: cfg4j-core/src/test/java/org/cfg4j/provider/SimpleConfigurationProviderWithClasspathIntegrationTest.java
import static org.assertj.core.api.Assertions.assertThat;
import org.cfg4j.source.ConfigurationSource;
import org.cfg4j.source.classpath.ClasspathConfigurationSource;
import org.junit.jupiter.api.Test;
import java.nio.file.Paths;
import java.util.Collections;

/*
 * Copyright 2015-2018 Norbert Potocki (norbert.potocki@nort.pl)
 *
 * 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 org.cfg4j.provider;





class SimpleConfigurationProviderWithClasspathIntegrationTest {




  @Test
  void readsYamlBooleans() {
    String path = "org/cfg4j/provider/SimpleConfigurationProviderIntegrationTest_readsYamlBooleans.yaml";

    ConfigurationProvider provider = getConfigurationProvider(path);

    assertThat(provider.getProperty("someSetting", Boolean.class)).isTrue();
  }

  @Test
  void readsYamlIntegers() {
    String path = "org/cfg4j/provider/SimpleConfigurationProviderIntegrationTest_readsYamlIntegers.yaml";

    ConfigurationProvider provider = getConfigurationProvider(path);

    assertThat(provider.getProperty("someSetting", Integer.class)).isEqualTo(42);
  }

  private ConfigurationProvider getConfigurationProvider(final String path) {
    ConfigurationSource source = new ClasspathConfigurationSource(() -> Collections.singleton(Paths.get(path)));