text: <?php
  
  /*
   * This file is part of Gush package.
   *
   * (c) Luis Cordova <cordoval@gmail.com>
   *
   * This source file is subject to the MIT license that is bundled
   * with this source code in the file LICENSE.
   */
  
  namespace Gush\Tests;
  
  use Gush\Config;
  
  class ConfigTest extends BaseTestCase
  {
      private $homedir;
  
      protected function setUp()
      {
          parent::setUp();
  
          $this->homedir = $this->getNewTmpDirectory('home');
      }
  
      public function testCreateEmptyConfigWithDefaults()
      {
          $config = $this->createConfig();
  
          $this->assertEquals(
              [
                  'adapters' => [],
                  'home' => $this->homedir.'/gush',
                  'home_config' => $this->homedir.'/gush/.gush.yml',
              ],
              $config->toArray(Config::CONFIG_ALL)
          );
  
          $this->assertEquals(
              [
                  'adapters' => [],
              ],
              $config->toArray(Config::CONFIG_SYSTEM)
          );
  
          $this->assertEquals([], $config->toArray(Config::CONFIG_LOCAL));
      }
  
      public function testCreateConfigWithLoaded()
      {
          $config = $this->createConfig(
              [
                  'adapters' => [
                      'github' => ['base_url' => 'url'],
                  ],
              ]
          );
  
          $this->assertEquals(
              [
                  'adapters' => [
                      'github' => ['base_url' => 'url'],
                  ],
                  'home' => $this->homedir.'/gush',
                  'home_config' => $this->homedir.'/gush/.gush.yml',
              ],
              $config->toArray(Config::CONFIG_ALL)
          );
  
          $this->assertEquals(
              [
                  'adapters' => [
                      'github' => ['base_url' => 'url'],
                  ],
              ],
              $config->toArray(Config::CONFIG_SYSTEM)
          );
  
          $this->assertEquals([], $config->toArray(Config::CONFIG_LOCAL));
      }
  
      public function testCreateConfigWithLoadedAndLocal()
      {
          $config = $this->createConfig(
              [
                  'adapters' => [
                      'github' => ['base_url' => 'url'],
                  ],
              ],
              [
                  'repo_adapter' => ['name' => 'github'],
              ]
          );
  
          $this->assertEquals(
              [
                  'adapters' => [
                      'github' => ['base_url' => 'url'],
                  ],
                  'home' => $this->homedir.'/gush',
                  'home_config' => $this->homedir.'/gush/.gush.yml',
                  'local' => $this->homedir.'/local-gush',
                  'local_config' => $this->homedir.'/local-gush/.gush.yml',
                  'repo_adapter' => ['name' => 'github'],
              ],
              $config->toArray(Config::CONFIG_ALL)
          );
  
          $this->assertEquals(
              [
                  'adapters' => [
                      'github' => ['base_url' => 'url'],
                  ],
              ],
              $config->toArray(Config::CONFIG_SYSTEM)
          );
  
          $this->assertEquals(
              [
                  'repo_adapter' => ['name' => 'github'],
              ],
              $config->toArray(Config::CONFIG_LOCAL)
          );
      }
  
      public function testGetConfigValueByKey()
      {
          $config = $this->createConfig();
  
          $this->assertEquals($this->homedir.'/gush', $config->get('home'));
          $this->assertEquals($this->homedir.'/gush/.gush.yml', $config->get('home_config'));
          $this->assertNull($config->get('no-key'));
  
          $this->assertEquals([], $config->get('adapters', Config::CONFIG_ALL));
          $this->assertEquals([], $config->get('adapters', Config::CONFIG_SYSTEM));
          $this->assertNull($config->get('adapters', Config::CONFIG_LOCAL));
      }
  
      public function testGetConfigValueByPath()
      {
          $config = $this->createConfig(
              [
                  'adapters' => [
                      'github' => ['base_url' => 'url'],
                  ],
              ]
          );
  
          $this->assertEquals($this->homedir.'/gush', $config->get('home'));
          $this->assertEquals(['base_url' => 'url'], $config->get(['adapters', 'github']));
          $this->assertEquals('url', $config->get(['adapters', 'github', 'base_url']));
          $this->assertNull($config->get(['no-key']));
  
          $this->assertEquals(
              ['github' => ['base_url' => 'url']],
              $config->get('adapters', Config::CONFIG_ALL)
          );
  
          $this->assertEquals(
              ['github' => ['base_url' => 'url']],
              $config->get(['adapters'], Config::CONFIG_SYSTEM)
          );
  
          $this->assertNull($config->get('adapters', Config::CONFIG_LOCAL));
      }
  
      public function testCannotGetConfigForUnsupportedSlot()
      {
          $config = $this->createConfig();
  
          $this->setExpectedException(
              'InvalidArgumentException',
              'Config slot "something" is not valid'
          );
  
          $config->get('adapters', 'something');
      }
  
      public function testSetConfigValue()
      {
          $config = $this->createConfig(['issue_trackers' => []]);
  
          $this->assertNull($config->get('repo_adapter'));
  
          $config->set('repo_adapter', 'github', Config::CONFIG_SYSTEM);
          $config->set('issue_adapter', 'github', Config::CONFIG_SYSTEM);
          $config->set('adapters', ['github' => ['base_url' => 'url']], Config::CONFIG_SYSTEM);
  
          $this->assertEquals('github', $config->get('repo_adapter'));
          $this->assertEquals('github', $config->get('issue_adapter'));
          $this->assertEquals(['github' => ['base_url' => 'url']], $config->get('adapters'));
          $this->assertTrue($config->has('issue_adapter', Config::CONFIG_SYSTEM));
  
          $this->assertNull($config->get('issue_adapter', Config::CONFIG_LOCAL));
          $this->assertFalse($config->has('issue_adapter', Config::CONFIG_LOCAL));
  
          // Ensure original options are not lost
          $this->assertEquals([], $config->get('issue_trackers', Config::CONFIG_ALL));
          $this->assertEquals([], $config->get('issue_trackers', Config::CONFIG_SYSTEM));
      }
  
      public function testCannotSetInvalidKey()
      {
          $config = $this->createConfig();
  
          $this->setExpectedException(
              'InvalidArgumentException',
              'Invalid configuration, cannot set nested configuration-key "[my_key]"'
          );
  
          $config->set('[my_key]', '/root', Config::CONFIG_SYSTEM);
      }
  
      public function testCannotSetConfigForAll()
      {
          $config = $this->createConfig();
  
          $this->setExpectedException(
              'InvalidArgumentException',
              'Config slot "'.Config::CONFIG_ALL.'" is not valid for setting "my_key"'
          );
  
          $config->set('my_key', '/root', Config::CONFIG_ALL);
      }
  
      /**
       * @dataProvider provideInvalidValues
       *
       * @param mixed $value
       */
      public function testCannotSetInvalidValue($value)
      {
          $config = $this->createConfig();
  
          $this->setExpectedException(
              'InvalidArgumentException',
              sprintf(
                  'Configuration can only a be scalar or an array, "%s" type given instead for "%s".',
                  gettype($value),
                  'my_key'
              )
          );
  
          $config->set('my_key', $value, Config::CONFIG_SYSTEM);
      }
  
      public static function provideInvalidValues()
      {
          return [
              [new \stdClass()],
              [imagecreate(1, 1)],
          ];
      }
  
      public function testCannotSetProtectedConfigKey()
      {
          $config = $this->createConfig();
  
          $this->setExpectedException(
              'InvalidArgumentException',
              'Configuration key "home" is protected and cannot be overwritten.'
          );
  
          $config->set('home', '/root', Config::CONFIG_SYSTEM);
      }
  
      public function testMergeConfigWithExisting()
      {
          $config = $this->createConfig();
  
          $config->merge(
              [
                  'repo_adapter' => 'github',
                  'issue_adapter' => 'github',
              ],
              Config::CONFIG_SYSTEM
          );
  
          $this->assertEquals('github', $config->get('repo_adapter'));
          $this->assertEquals('github', $config->get('issue_adapter'));
      }
  
      private function createConfig(array $config = [], array $localConfig = [])
      {
          $localHome = [] !== $localConfig ? $this->homedir.'/local-gush' : null;
  
          return new Config(
              $this->homedir.'/gush',
              $config,
              $localHome,
              $localConfig
          );
      }
  }
  