Skip to content

Commit

Permalink
Added more unit tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexSkrypnyk committed May 19, 2024
1 parent 65743b7 commit 3aec108
Show file tree
Hide file tree
Showing 10 changed files with 431 additions and 26 deletions.
46 changes: 21 additions & 25 deletions CustomizeCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -237,29 +237,25 @@ protected function process(array $answers): void {
*/
protected static function initIo(InputInterface $input, OutputInterface $output): SymfonyStyle {
$answers = getenv('CUSTOMIZER_ANSWERS');
$from_env = empty($answers);
$answers = $answers ?: $input->getOption('answers');

if ($answers && is_string($answers)) {
$answers = json_decode($answers, TRUE);

if (is_array($answers)) {
if ($from_env) {
$stream = fopen('php://memory', 'r+');
if ($stream === FALSE) {
throw new \RuntimeException('Failed to open memory stream');
}
foreach ($answers as $answer) {
fwrite($stream, $answer . \PHP_EOL);
}
rewind($stream);

$input = new ArgvInput($answers);
$input->setStream($stream);
$stream = fopen('php://memory', 'r+');
if ($stream === FALSE) {
// @codeCoverageIgnoreStart
throw new \RuntimeException('Failed to open memory stream');
// @codeCoverageIgnoreEnd
}
else {
$input = new ArgvInput($answers);
foreach ($answers as $answer) {
fwrite($stream, $answer . \PHP_EOL);
}
rewind($stream);

$input = new ArgvInput($answers);
$input->setStream($stream);
}
}

Expand All @@ -270,15 +266,15 @@ protected static function initIo(InputInterface $input, OutputInterface $output)
* Replace in path.
*
* @param string $path
* Path: directory or file.
* @param string|array<int, string> $search
* Search string or array of strings.
* @param string|array<int,string> $replace
* Replace string or array of strings.
* Directory or file path.
* @param string $search
* Search string.
* @param string $replace
* Replace string .
* @param bool $replace_line
* Replace for a whole line or only the occurrence.
*/
protected static function replaceInPath(string $path, string|array $search, string|array $replace, bool $replace_line = FALSE): void {
protected static function replaceInPath(string $path, string $search, string $replace, bool $replace_line = FALSE): void {
$dir = dirname($path);
$filename = basename($path);

Expand All @@ -290,7 +286,6 @@ protected static function replaceInPath(string $path, string|array $search, stri
$finder = Finder::create()
->ignoreVCS(TRUE)
->ignoreDotFiles(FALSE)
->depth(0)
->files()
->contains($search)
->in($dir);
Expand All @@ -304,10 +299,11 @@ protected static function replaceInPath(string $path, string|array $search, stri
$file_content = file_get_contents($file_path);
if ($file_content !== FALSE) {
if ($replace_line) {
$search = array_map(static fn($s): string => "/^.*{$s}.*\n/m", (array) $search);
$new_content = preg_replace(sprintf('/^.*%s.*/m', $search), $replace, $file_content);
}
else {
$new_content = str_replace($search, $replace, $file_content);
}

$new_content = str_replace($search, $replace, $file_content);

if ($new_content !== $file_content) {
file_put_contents($file_path, $new_content);
Expand Down
5 changes: 4 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,12 @@
"sort-packages": true
},
"scripts": {
"customize": [
"YourOrg\\YourPackage\\CustomizeCommand"
],
"lint": [
"phpcs",
"phpmd --exclude vendor,vendor-bin,node_modules . text phpmd.xml",
"phpmd --exclude vendor . text phpmd.xml",
"phpstan",
"rector --clear-cache --dry-run"
],
Expand Down
3 changes: 3 additions & 0 deletions tests/phpunit/Fixtures/dir1/file1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
First line of the first file
Unique string
non-unique string
2 changes: 2 additions & 0 deletions tests/phpunit/Fixtures/dir1/file2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
First line of the second file
non-unique string
2 changes: 2 additions & 0 deletions tests/phpunit/Fixtures/dir2/file3.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
First line of the third file
Second line with non-unique string in the middle
2 changes: 2 additions & 0 deletions tests/phpunit/Fixtures/dir2/file4.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
First line of the fourth file
End of file.
2 changes: 2 additions & 0 deletions tests/phpunit/Fixtures/file5.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
First line of the fifth file
Second line with non-unique string in the middle
10 changes: 10 additions & 0 deletions tests/phpunit/Functional/CreateProjectTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,14 @@ public function testCreateProjectNoInstall(): void {
$this->assertComposerCommandSuccessOutputContains('Project was customized');
}

public function testCreateProjectNoInstallCancel(): void {
$this->customizerSetAnswers([
'no',
]);

$this->composerCreateProject(['--no-install' => TRUE]);

$this->assertComposerCommandSuccessOutputContains('No changes were made.');
}

}
102 changes: 102 additions & 0 deletions tests/phpunit/Traits/ReflectionTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<?php

declare(strict_types=1);

namespace AlexSkrypnyk\Customizer\Tests\Traits;

/**
* Trait ReflectionTrait.
*
* Provides methods to work with class reflection.
*/
trait ReflectionTrait {

/**
* Call protected methods on the class.
*
* @param object|string $object
* Object or class name to use for a method call.
* @param string $name
* Method name. Method can be static.
* @param array $args
* Array of arguments to pass to the method. To pass arguments by reference,
* pass them by reference as an element of this array.
*
* @return mixed
* Method result.
*/
protected static function callProtectedMethod(object|string $object, string $name, array $args = []) {
$object_or_class = is_object($object) ? $object::class : $object;

if (!class_exists($object_or_class)) {
throw new \InvalidArgumentException(sprintf('Class %s does not exist', $object_or_class));
}

$class = new \ReflectionClass($object_or_class);

if (!$class->hasMethod($name)) {
throw new \InvalidArgumentException(sprintf('Method %s does not exist', $name));
}

$method = $class->getMethod($name);

$original_accessibility = $method->isPublic();

// Set method accessibility to true, so it can be invoked.
$method->setAccessible(TRUE);

// If the method is static, we won't pass an object instance to invokeArgs()
// Otherwise, we ensure to pass the object instance.
$invoke_object = $method->isStatic() ? NULL : (is_object($object) ? $object : NULL);

// Ensure we have an object for non-static methods.
if (!$method->isStatic() && $invoke_object === NULL) {
throw new \InvalidArgumentException("An object instance is required for non-static methods");
}

$result = $method->invokeArgs($invoke_object, $args);

// Reset the method's accessibility to its original state.
$method->setAccessible($original_accessibility);

return $result;
}

/**
* Set protected property value.
*
* @param object $object
* Object to set the value on.
* @param string $property
* Property name to set the value. Property should exists in the object.
* @param mixed $value
* Value to set to the property.
*/
protected static function setProtectedValue($object, $property, mixed $value): void {
$class = new \ReflectionClass($object::class);
$property = $class->getProperty($property);
$property->setAccessible(TRUE);

$property->setValue($object, $value);
}

/**
* Get protected value from the object.
*
* @param object $object
* Object to set the value on.
* @param string $property
* Property name to get the value. Property should exists in the object.
*
* @return mixed
* Protected property value.
*/
protected static function getProtectedValue($object, $property) {
$class = new \ReflectionClass($object::class);
$property = $class->getProperty($property);
$property->setAccessible(TRUE);

return $property->getValue($class);
}

}
Loading

0 comments on commit 3aec108

Please sign in to comment.