Newer
Older

Adam G-H
committed
<?php
namespace Drupal\Tests\package_manager\Kernel;
use Drupal\Tests\package_manager\Traits\FixtureUtilityTrait;
use PHPUnit\Framework\AssertionFailedError;
/**
* @coversDefaultClass \Drupal\Tests\package_manager\Traits\FixtureUtilityTrait
*
* @group package_manager
*/
class FixtureUtilityTraitTest extends PackageManagerKernelTestBase {
use FixtureUtilityTrait;
/**
* The root directory of the virtual project.
*
* @var string
*/
private string $dir;
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->dir = $this->container->get('package_manager.path_locator')
->getProjectRoot();
$this->addPackage($this->dir, [
'name' => 'my/package',
]);

Adam G-H
committed
$this->addPackage($this->dir, [
'name' => 'my/dev-package',
'version' => '2.1.0',
'dev_requirement' => TRUE,
'install_path' => '../relative/path',

Adam G-H
committed
]);
}
/**
* @covers ::addPackage
*/
public function testAddPackage(): void {
// Packages cannot be added without a name.
try {
$this->addPackage($this->dir, ['type' => 'unknown']);
$this->fail('Adding an anonymous package should raise an error.');
}
catch (AssertionFailedError $e) {
$this->assertSame("Failed asserting that an array has the key 'name'.", $e->getMessage());
}
// We should not be able to add an existing package.
try {
$this->addPackage($this->dir, ['name' => 'my/package']);
$this->fail('Trying to add an existing package should raise an error.');
}
catch (AssertionFailedError $e) {
$this->assertStringContainsString("Expected package 'my/package' to not be installed, but it was.", $e->getMessage());
}
// We should not be able to add a package with an absolute installation
// path.
try {
$this->addPackage($this->dir, [
'name' => 'absolute/path',
'install_path' => '/absolute/path',
]);
}
catch (AssertionFailedError $e) {
$this->assertSame('Failed asserting that \'/absolute/path\' starts with "../".', $e->getMessage());
}

Adam G-H
committed
$expected_packages = [
'my/package' => [
'name' => 'my/package',
],
'my/dev-package' => [
'name' => 'my/dev-package',
'version' => '2.1.0',
'dev_requirement' => TRUE,
'install_path' => '../relative/path',

Adam G-H
committed
],
];
[$installed_json, $installed_php] = $this->getData();
$installed_json['packages'] = array_intersect_key($installed_json['packages'], $expected_packages);
$this->assertSame($expected_packages, $installed_json['packages']);
$this->assertContains('my/dev-package', $installed_json['dev-package-names']);
$this->assertNotContains('my/package', $installed_json['dev-package-names']);
// In installed.php, the relative installation path of my/dev-package should
// have been prefixed with the __DIR__ constant, which should be interpreted
// when installed.php is loaded by the PHP runtime.
$expected_packages['my/dev-package']['install_path'] = "$this->dir/vendor/composer/../relative/path";

Adam G-H
committed
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
$this->assertSame($expected_packages, $installed_php);
}
/**
* @covers ::modifyPackage
*/
public function testModifyPackage(): void {
// We should not be able to modify a non-existent package.
try {
$this->modifyPackage($this->dir, 'junk/drawer', ['type' => 'library']);
$this->fail('Modifying a non-existent package should raise an error.');
}
catch (AssertionFailedError $e) {
$this->assertStringContainsString("Expected package 'junk/drawer' to be installed, but it wasn't.", $e->getMessage());
}
// Add a key to an existing package.
$this->modifyPackage($this->dir, 'my/package', ['type' => 'metapackage']);
// Change a key in an existing package.
$this->modifyPackage($this->dir, 'my/dev-package', ['version' => '3.2.1']);
// Move an existing package to dev requirements.
$this->addPackage($this->dir, [
'name' => 'my/other-package',
'type' => 'library',
]);
$this->modifyPackage($this->dir, 'my/other-package', ['dev_requirement' => TRUE]);
$expected_packages = [
'my/package' => [
'name' => 'my/package',
'type' => 'metapackage',
],
'my/dev-package' => [
'name' => 'my/dev-package',
'version' => '3.2.1',
'dev_requirement' => TRUE,
'install_path' => '../relative/path',

Adam G-H
committed
],
'my/other-package' => [
'name' => 'my/other-package',
'type' => 'library',
'dev_requirement' => TRUE,
],
];
[$installed_json, $installed_php] = $this->getData();
$installed_json['packages'] = array_intersect_key($installed_json['packages'], $expected_packages);
$this->assertSame($expected_packages, $installed_json['packages']);
$this->assertContains('my/dev-package', $installed_json['dev-package-names']);
$this->assertContains('my/other-package', $installed_json['dev-package-names']);
$this->assertNotContains('my/package', $installed_json['dev-package-names']);
// @see ::testAddPackage()
$expected_packages['my/dev-package']['install_path'] = "$this->dir/vendor/composer/../relative/path";

Adam G-H
committed
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
$this->assertSame($expected_packages, $installed_php);
}
/**
* @covers ::removePackage
*/
public function testRemovePackage(): void {
// We should not be able to remove a package that's not installed.
try {
$this->removePackage($this->dir, 'junk/drawer');
$this->fail('Removing a non-existent package should raise an error.');
}
catch (AssertionFailedError $e) {
$this->assertStringContainsString("Expected package 'junk/drawer' to be installed, but it wasn't.", $e->getMessage());
}
$this->removePackage($this->dir, 'my/package');
$this->removePackage($this->dir, 'my/dev-package');
foreach (['json', 'php'] as $extension) {
$contents = file_get_contents("$this->dir/vendor/composer/installed.$extension");
$this->assertStringNotContainsString('my/package', $contents);
$this->assertStringNotContainsString('my/dev-package', $contents);
}
}
/**
* Returns the data from installed.php and installed.json.
*
* @return array[]
* An array of two arrays. The first array will be the contents of
* installed.json, with the `packages` array keyed by package name. The
* second array will be the `versions` array from installed.php.
*/
private function getData(): array {
$installed_json = file_get_contents("$this->dir/vendor/composer/installed.json");
$installed_json = json_decode($installed_json, TRUE, 512, JSON_THROW_ON_ERROR);
$keyed_packages = [];
foreach ($installed_json['packages'] as $package) {
$keyed_packages[$package['name']] = $package;
}
$installed_json['packages'] = $keyed_packages;
$installed_php = require "$this->dir/vendor/composer/installed.php";
return [
$installed_json,
$installed_php['versions'],
];
}
}