Skip to content

Commit

Permalink
Merge pull request #49 from BrianHenryIE/default-packages-2
Browse files Browse the repository at this point in the history
Default packages – 6-beta-2 bugfix
  • Loading branch information
coenjacobs authored Jun 2, 2020
2 parents 8d60334 + d842c28 commit 965d698
Show file tree
Hide file tree
Showing 3 changed files with 253 additions and 5 deletions.
4 changes: 2 additions & 2 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="replacers">
<directory>./tests/replacers/</directory>
<testsuite name="all">
<directory>./tests/</directory>
</testsuite>
</testsuites>
</phpunit>
29 changes: 26 additions & 3 deletions src/Console/Commands/Compose.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,26 @@ protected function execute(InputInterface $input, OutputInterface $output)
$workingDir = getcwd();
$this->workingDir = $workingDir;

$config = json_decode(file_get_contents($workingDir . '/composer.json'));
$config = $config->extra->mozart;
$composerFile = $workingDir . '/composer.json';
if (!file_exists($composerFile)) {
$output->write('No composer.json found at current directory: ' . $workingDir);
return 1;
}

$composer = json_decode(file_get_contents($composerFile));
// If the json was malformed.
if (!is_object($composer)) {
$output->write('Unable to parse composer.json read at: ' . $workingDir);
return 1;
}

// if `extra` is missing or not an object or if it does not have a `mozart` key which is an object.
if (!isset($composer->extra) || !is_object($composer->extra)
|| !isset($composer->extra->mozart) || !is_object($composer->extra->mozart)) {
$output->write('Mozart config not readable in composer.json at extra->mozart');
return 1;
}
$config = $composer->extra->mozart;

$config->dep_namespace = preg_replace("/\\\{2,}$/", "\\", "$config->dep_namespace\\");

Expand All @@ -47,7 +65,12 @@ protected function execute(InputInterface $input, OutputInterface $output)
$this->mover = new Mover($workingDir, $config);
$this->replacer = new Replacer($workingDir, $config);

$require = empty($config->packages) ? array_keys(get_object_vars($this->config->require)) : $config->packages;
$require = array();
if (isset($config->packages) && is_array($config->packages)) {
$require = $config->packages;
} elseif (isset($composer->require) && is_object($composer->require)) {
$require = array_keys(get_object_vars($composer->require));
}

$packages = $this->findPackages($require);

Expand Down
225 changes: 225 additions & 0 deletions tests/Console/Commands/ComposeTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
<?php
declare(strict_types=1);

use CoenJacobs\Mozart\Console\Commands\Compose;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class ComposeTest extends TestCase
{
static $cwd;

public static function setUpBeforeClass(): void
{
parent::setUpBeforeClass();
self::$cwd = getcwd();
}

/**
* Before each test ensure the current working directory is this one.
*
* Record the previous PHPUnit cwd to restore after.
*/
public function setUp(): void
{
parent::setUp();

chdir(dirname(__FILE__));
}

/**
* When composer.json is absent, instead of failing with:
* "failed to open stream: No such file or directory"
* a better message should be written to the OutputInterface.
*
* @test
*/
public function it_fails_gracefully_when_composer_json_absent(): void
{

$inputInterfaceMock = $this->createMock(InputInterface::class);
$outputInterfaceMock = $this->createMock(OutputInterface::class);

$outputInterfaceMock->expects($this->exactly(1))
->method('write');

$compose = new class( $inputInterfaceMock, $outputInterfaceMock ) extends Compose {
public function __construct($inputInterfaceMock, $outputInterfaceMock)
{
parent::__construct();

$this->execute($inputInterfaceMock, $outputInterfaceMock);
}
};
}

/**
* When json_decode fails, instead of
* "Trying to get property 'extra' of non-object"
* a better message should be written to the OutputInterface.
*
* @test
*/
public function it_handles_malformed_json_with_grace(): void
{

$badComposerJson = '{ "name": "coenjacobs/mozart", }';

file_put_contents(__DIR__ . '/composer.json', $badComposerJson);

$inputInterfaceMock = $this->createMock(InputInterface::class);
$outputInterfaceMock = $this->createMock(OutputInterface::class);

$outputInterfaceMock->expects($this->exactly(1))
->method('write');

$compose = new class( $inputInterfaceMock, $outputInterfaceMock ) extends Compose {
public function __construct($inputInterfaceMock, $outputInterfaceMock)
{
parent::__construct();

$this->execute($inputInterfaceMock, $outputInterfaceMock);
}
};
}

/**
* When composer.json->extra is absent, instead of
* "Undefined property: stdClass::$extra"
* a better message should be written to the OutputInterface.
*
* @test
*/
public function it_handles_absent_extra_config_with_grace(): void
{

$badComposerJson = '{ "name": "coenjacobs/mozart" }';

file_put_contents(__DIR__ . '/composer.json', $badComposerJson);

$inputInterfaceMock = $this->createMock(InputInterface::class);
$outputInterfaceMock = $this->createMock(OutputInterface::class);

$outputInterfaceMock->expects($this->exactly(1))
->method('write');

$compose = new class( $inputInterfaceMock, $outputInterfaceMock ) extends Compose {
public function __construct($inputInterfaceMock, $outputInterfaceMock)
{
parent::__construct();

$this->execute($inputInterfaceMock, $outputInterfaceMock);
}
};
}


/**
* When composer.json->extra is not an object, instead of
* "Trying to get property 'mozart' of non-object"
* a better message should be written to the OutputInterface.
*
* @test
*/
public function it_handles_malformed_extra_config_with_grace(): void
{

$badComposerJson = '{ "name": "coenjacobs/mozart", "extra": [] }';

file_put_contents(__DIR__ . '/composer.json', $badComposerJson);

$inputInterfaceMock = $this->createMock(InputInterface::class);
$outputInterfaceMock = $this->createMock(OutputInterface::class);

$outputInterfaceMock->expects($this->exactly(1))
->method('write');

$compose = new class( $inputInterfaceMock, $outputInterfaceMock ) extends Compose {
public function __construct($inputInterfaceMock, $outputInterfaceMock)
{
parent::__construct();

$this->execute($inputInterfaceMock, $outputInterfaceMock);
}
};
}

/**
* When composer.json->extra->mozart is absent, instead of
* "Undefined property: stdClass::$mozart"
* a better message should be written to the OutputInterface.
*
* @test
*/
public function it_handles_absent_mozart_config_with_grace(): void
{

$badComposerJson = '{ "name": "coenjacobs/mozart", "extra": { "moozart": {} } }';

file_put_contents(__DIR__ . '/composer.json', $badComposerJson);

$inputInterfaceMock = $this->createMock(InputInterface::class);
$outputInterfaceMock = $this->createMock(OutputInterface::class);

$outputInterfaceMock->expects($this->exactly(1))
->method('write');

$compose = new class( $inputInterfaceMock, $outputInterfaceMock ) extends Compose {
public function __construct($inputInterfaceMock, $outputInterfaceMock)
{
parent::__construct();

$this->execute($inputInterfaceMock, $outputInterfaceMock);
}
};
}

/**
* When composer.json->extra->mozart is malformed, instead of
* "Undefined property: stdClass::$mozart"
* a better message should be written to the OutputInterface.
*
* is_object() added.
*
* @test
*/
public function it_handles_malformed_mozart_config__with_grace(): void
{

$badComposerJson = '{ "name": "coenjacobs/mozart", "extra": { "mozart": [] } }';

file_put_contents(__DIR__ . '/composer.json', $badComposerJson);

$inputInterfaceMock = $this->createMock(InputInterface::class);
$outputInterfaceMock = $this->createMock(OutputInterface::class);

$outputInterfaceMock->expects($this->exactly(1))
->method('write');

$compose = new class( $inputInterfaceMock, $outputInterfaceMock ) extends Compose {
public function __construct($inputInterfaceMock, $outputInterfaceMock)
{
parent::__construct();

$this->execute($inputInterfaceMock, $outputInterfaceMock);
}
};
}

public function tearDown(): void
{
parent::tearDown();

$composer_json = __DIR__ . '/composer.json';
if (file_exists($composer_json)) {
unlink($composer_json);
}
}

public static function tearDownAfterClass(): void
{
parent::tearDownAfterClass();
chdir(self::$cwd);
}
}

0 comments on commit 965d698

Please sign in to comment.