Skip to content

Commit befb62b

Browse files
committed
Files/FileList: adding the same file twice should not increment FileList::$numFiles
This commit fixes the `FileList::__construct()` and `FileList::addFile()` methods to ensure that, when there is an attempt to add the same file twice, the `FileList::$numFiles` variable is not incremented. The code was already handling duplicates correctly in the sense that duplicated files were not added to `FileList::$files`. However, `FileList::$numFiles` was being incorrectly incremented. There is some duplicated logic in `FileList::__construct()` and `FileList::addFile()`. I considered refactoring the duplicated code to a private method before adding the check that is added in this commit. I decided not to do it as there are some subtle differences between the logic in the two methods. `FileList::__construct()` always sets the value of an entry in the `FileList::$files` to `null` and the key to whatever is returned by `SplFileInfo::getPathname()`. While `FileList::addFile()` sets the value of an entry in the `FileList::$files` to `null` or an object passed to the method and the key to the path passed to the method. I decided to leave this refactor to remove the duplication to the future and focus this commit on fixing the issue with handling duplicated files.
1 parent a134f89 commit befb62b

File tree

3 files changed

+67
-4
lines changed

3 files changed

+67
-4
lines changed

src/Files/FileList.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,14 @@ public function __construct(Config $config, Ruleset $ruleset)
9191
$iterator = new RecursiveIteratorIterator($filter);
9292

9393
foreach ($iterator as $file) {
94-
$this->files[$file->getPathname()] = null;
94+
$pathname = $file->getPathname();
95+
96+
if (array_key_exists($pathname, $this->files) === true) {
97+
// The path has already been added.
98+
continue;
99+
}
100+
101+
$this->files[$pathname] = null;
95102
$this->numFiles++;
96103
}
97104
} else {
@@ -132,6 +139,11 @@ public function addFile($path, $file=null)
132139
$iterator = new RecursiveIteratorIterator($filter);
133140

134141
foreach ($iterator as $path) {
142+
if (array_key_exists($path, $this->files) === true) {
143+
// The path has already been added.
144+
continue;
145+
}
146+
135147
$this->files[$path] = $file;
136148
$this->numFiles++;
137149
}

tests/Core/Files/FileList/AddFileTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,36 @@ public static function dataAddFile()
102102
}//end dataAddFile()
103103

104104

105+
/**
106+
* Test that it is not possible to add the same file twice.
107+
*
108+
* @return void
109+
*/
110+
public function testAddFileShouldNotAddTheSameFileTwice()
111+
{
112+
$file1 = 'test1.php';
113+
$file2 = 'test2.php';
114+
$expectedFiles = [
115+
$file1,
116+
$file2,
117+
];
118+
119+
// Add $file1 once.
120+
$this->fileList->addFile($file1);
121+
$this->assertCount(1, $this->fileList);
122+
$this->assertSame([$file1], array_keys(iterator_to_array($this->fileList)));
123+
124+
// Try to add $file1 again. Should be ignored.
125+
$this->fileList->addFile($file1);
126+
$this->assertCount(1, $this->fileList);
127+
$this->assertSame([$file1], array_keys(iterator_to_array($this->fileList)));
128+
129+
// Add $file2. Should be added.
130+
$this->fileList->addFile($file2);
131+
$this->assertCount(2, $this->fileList);
132+
$this->assertSame($expectedFiles, array_keys(iterator_to_array($this->fileList)));
133+
134+
}//end testAddFileShouldNotAddTheSameFileTwice()
135+
136+
105137
}//end class

tests/Core/Files/FileList/ConstructTest.php

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,11 @@ public static function dataConstruct()
100100
$fixturesDir = __DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR;
101101

102102
return [
103-
'No files' => [
103+
'No files' => [
104104
'files' => [],
105105
'expectedFiles' => [],
106106
],
107-
'Two files' => [
107+
'Two files' => [
108108
'files' => [
109109
'file1.php',
110110
'file2.php',
@@ -114,13 +114,32 @@ public static function dataConstruct()
114114
'file2.php',
115115
],
116116
],
117-
'A directory' => [
117+
'A directory' => [
118118
'files' => [$fixturesDir],
119119
'expectedFiles' => [
120120
$fixturesDir.'file1.php',
121121
$fixturesDir.'file2.php',
122122
],
123123
],
124+
'Same file twice' => [
125+
'files' => [
126+
'file1.php',
127+
'file1.php',
128+
],
129+
'expectedFiles' => [
130+
'file1.php',
131+
],
132+
],
133+
'File and then directory containing that file' => [
134+
'files' => [
135+
$fixturesDir.'file1.php',
136+
$fixturesDir,
137+
],
138+
'expectedFiles' => [
139+
$fixturesDir.'file1.php',
140+
$fixturesDir.'file2.php',
141+
],
142+
],
124143
];
125144

126145
}//end dataConstruct()

0 commit comments

Comments
 (0)