From 996fbad107b45e53d488e9acc9d68f4d60f76afc Mon Sep 17 00:00:00 2001 From: JBlond Date: Fri, 9 Dec 2022 12:13:48 +0100 Subject: [PATCH 1/5] Add file / EOL / EOF detection --- .gitattributes | 1 + lib/jblond/Diff/File.php | 75 +++++++++++++++++++++ tests/Diff/FileTest.php | 113 ++++++++++++++++++++++++++++++++ tests/resources/eol/mac.txt | 1 + tests/resources/eol/no-eol.txt | 1 + tests/resources/eol/unix.txt | 1 + tests/resources/eol/windows.txt | 1 + 7 files changed, 193 insertions(+) create mode 100644 lib/jblond/Diff/File.php create mode 100644 tests/Diff/FileTest.php create mode 100644 tests/resources/eol/mac.txt create mode 100644 tests/resources/eol/no-eol.txt create mode 100644 tests/resources/eol/unix.txt create mode 100644 tests/resources/eol/windows.txt diff --git a/.gitattributes b/.gitattributes index fdade2f..cf96c40 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,3 +2,4 @@ tests export-ignore .editorconfig export-ignore .gitattributes export-ignore phpcs.xml export-ignore +tests/resources/eol/*.txt binary diff --git a/lib/jblond/Diff/File.php b/lib/jblond/Diff/File.php new file mode 100644 index 0000000..27c7c70 --- /dev/null +++ b/lib/jblond/Diff/File.php @@ -0,0 +1,75 @@ +file = $file; + } + + /** + * @return false|mixed|string + */ + public function getLastLine() + { + $lines = file($this->file); + return end($lines); + } + + /** + * @return bool + */ + public function hasNewLineAtTheEnd(): bool + { + $lastLine = $this->getLastLine(); + if (strpos($lastLine, "\r\n") !== false) { + return true; + } + + if (strpos($lastLine, "\r") !== false) { + return true; + } + + if (strpos($lastLine, "\n") !== false) { + return true; + } + return false; + } + + /** + * @return string + */ + public function getEOLType(): string + { + $lastLine = $this->getLastLine(); + if (strpos($lastLine, "\r\n") !== false) { + return "EOL type is Windows (CRLF)"; + } + + if (strpos($lastLine, "\r") !== false) { + return "EOL type is Mac (CR)"; + } + + if (strpos($lastLine, "\n") !== false) { + return "EOL type is Unix (LF)"; + } + return "\ No newline at end of file"; + } +} diff --git a/tests/Diff/FileTest.php b/tests/Diff/FileTest.php new file mode 100644 index 0000000..a6fafbe --- /dev/null +++ b/tests/Diff/FileTest.php @@ -0,0 +1,113 @@ +assertEquals( + 'EOL type is Mac (CR)', + $mac->getEOLType() + ); + + $unix = new File('tests/resources/eol/unix.txt'); + $this->assertEquals( + 'EOL type is Unix (LF)', + $unix->getEOLType() + ); + + $noEol = new File('tests/resources/eol/no-eol.txt'); + $this->assertEquals( + '\ No newline at end of file', + $noEol->getEOLType() + ); + + $windows = new File('tests/resources/eol/windows.txt'); + $this->assertEquals( + 'EOL type is Windows (CRLF)', + $windows->getEOLType() + ); + } + + /** + * Bool test if the file has a line ending + */ + public function testHasNewLineAtTheEnd() + { + $mac = new File('tests/resources/eol/mac.txt'); + $this->assertEquals( + true, + $mac->hasNewLineAtTheEnd() + ); + + $unix = new File('tests/resources/eol/unix.txt'); + $this->assertEquals( + true, + $unix->hasNewLineAtTheEnd() + ); + + $noEol = new File('tests/resources/eol/no-eol.txt'); + $this->assertEquals( + false, + $noEol->hasNewLineAtTheEnd() + ); + + $windows = new File('tests/resources/eol/windows.txt'); + $this->assertEquals( + true, + $windows->hasNewLineAtTheEnd() + ); + } + + /** + * Test get the last string from a file + */ + public function testGetLastLine() + { + $mac = new File('tests/resources/eol/mac.txt'); + $this->assertEquals( + "Lorem ipsum\r", + $mac->getLastLine() + ); + + $unix = new File('tests/resources/eol/unix.txt'); + $this->assertEquals( + "Lorem ipsum\n", + $unix->getLastLine() + ); + + $noEol = new File('tests/resources/eol/no-eol.txt'); + $this->assertEquals( + "Lorem ipsum", + $noEol->getLastLine() + ); + + $windows = new File('tests/resources/eol/windows.txt'); + $this->assertEquals( + "Lorem ipsum\r\n", + $windows->getLastLine() + ); + } + + /** + * Test if the file exists + */ + public function test__construct() + { + $this->expectException(InvalidArgumentException::class); + $file = new File('foo.txt'); + } +} diff --git a/tests/resources/eol/mac.txt b/tests/resources/eol/mac.txt new file mode 100644 index 0000000..95b6a4b --- /dev/null +++ b/tests/resources/eol/mac.txt @@ -0,0 +1 @@ +Lorem ipsum \ No newline at end of file diff --git a/tests/resources/eol/no-eol.txt b/tests/resources/eol/no-eol.txt new file mode 100644 index 0000000..e5d3534 --- /dev/null +++ b/tests/resources/eol/no-eol.txt @@ -0,0 +1 @@ +Lorem ipsum \ No newline at end of file diff --git a/tests/resources/eol/unix.txt b/tests/resources/eol/unix.txt new file mode 100644 index 0000000..3be11c6 --- /dev/null +++ b/tests/resources/eol/unix.txt @@ -0,0 +1 @@ +Lorem ipsum diff --git a/tests/resources/eol/windows.txt b/tests/resources/eol/windows.txt new file mode 100644 index 0000000..2b3087b --- /dev/null +++ b/tests/resources/eol/windows.txt @@ -0,0 +1 @@ +Lorem ipsum From b1921ce19a38002ea20d9459779f7a5053595674 Mon Sep 17 00:00:00 2001 From: JBlond Date: Fri, 9 Dec 2022 12:18:30 +0100 Subject: [PATCH 2/5] Fix code formatting --- lib/jblond/Diff/File.php | 3 +-- tests/Diff/FileTest.php | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/jblond/Diff/File.php b/lib/jblond/Diff/File.php index 27c7c70..728d479 100644 --- a/lib/jblond/Diff/File.php +++ b/lib/jblond/Diff/File.php @@ -9,7 +9,6 @@ */ class File { - /** @var string $file */ protected $file; @@ -19,7 +18,7 @@ class File public function __construct(string $file) { if (!file_exists($file)) { - throw new InvalidArgumentException; + throw new InvalidArgumentException(); } $this->file = $file; } diff --git a/tests/Diff/FileTest.php b/tests/Diff/FileTest.php index a6fafbe..dbeb369 100644 --- a/tests/Diff/FileTest.php +++ b/tests/Diff/FileTest.php @@ -11,7 +11,6 @@ */ class FileTest extends TestCase { - /** * Test the type of EOF */ @@ -105,7 +104,7 @@ public function testGetLastLine() /** * Test if the file exists */ - public function test__construct() + public function testConstruct() { $this->expectException(InvalidArgumentException::class); $file = new File('foo.txt'); From 3d2ffe44a70b2e712417ed120f4da8f4ffc8d17e Mon Sep 17 00:00:00 2001 From: JBlond Date: Mon, 12 Dec 2022 12:54:07 +0100 Subject: [PATCH 3/5] Optimize: Make the File class more generic --- lib/jblond/Diff/File.php | 14 ++++++++++++-- tests/Diff/FileTest.php | 41 ++++++++++++++++++++++++++-------------- 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/lib/jblond/Diff/File.php b/lib/jblond/Diff/File.php index 728d479..80c9421 100644 --- a/lib/jblond/Diff/File.php +++ b/lib/jblond/Diff/File.php @@ -12,11 +12,18 @@ class File /** @var string $file */ protected $file; + /** - * @param string $file + * Add data + * @param string|array $file + * @return void */ - public function __construct(string $file) + public function setFile($file): void { + if (is_array($file)) { + $this->file = $file; + return; + } if (!file_exists($file)) { throw new InvalidArgumentException(); } @@ -24,6 +31,7 @@ public function __construct(string $file) } /** + * return the last line from the file array * @return false|mixed|string */ public function getLastLine() @@ -33,6 +41,7 @@ public function getLastLine() } /** + * Bool return if the file has a new line at the end * @return bool */ public function hasNewLineAtTheEnd(): bool @@ -53,6 +62,7 @@ public function hasNewLineAtTheEnd(): bool } /** + * Return the File Ending / EOL / EOF Type * @return string */ public function getEOLType(): string diff --git a/tests/Diff/FileTest.php b/tests/Diff/FileTest.php index dbeb369..7fbfcba 100644 --- a/tests/Diff/FileTest.php +++ b/tests/Diff/FileTest.php @@ -16,25 +16,29 @@ class FileTest extends TestCase */ public function testGetEOLType() { - $mac = new File('tests/resources/eol/mac.txt'); + $mac = new File(); + $mac->setFile('tests/resources/eol/mac.txt'); $this->assertEquals( 'EOL type is Mac (CR)', $mac->getEOLType() ); - $unix = new File('tests/resources/eol/unix.txt'); + $unix = new File(); + $unix->setFile('tests/resources/eol/unix.txt'); $this->assertEquals( 'EOL type is Unix (LF)', $unix->getEOLType() ); - $noEol = new File('tests/resources/eol/no-eol.txt'); + $noEol = new File(); + $noEol->setFile('tests/resources/eol/no-eol.txt'); $this->assertEquals( '\ No newline at end of file', $noEol->getEOLType() ); - $windows = new File('tests/resources/eol/windows.txt'); + $windows = new File(); + $windows->setFile('tests/resources/eol/windows.txt'); $this->assertEquals( 'EOL type is Windows (CRLF)', $windows->getEOLType() @@ -46,25 +50,29 @@ public function testGetEOLType() */ public function testHasNewLineAtTheEnd() { - $mac = new File('tests/resources/eol/mac.txt'); + $mac = new File(); + $mac->setFile('tests/resources/eol/mac.txt'); $this->assertEquals( true, $mac->hasNewLineAtTheEnd() ); - $unix = new File('tests/resources/eol/unix.txt'); + $unix = new File(); + $unix->setFile('tests/resources/eol/unix.txt'); $this->assertEquals( true, $unix->hasNewLineAtTheEnd() ); - $noEol = new File('tests/resources/eol/no-eol.txt'); + $noEol = new File(); + $noEol->setFile('tests/resources/eol/no-eol.txt'); $this->assertEquals( false, $noEol->hasNewLineAtTheEnd() ); - $windows = new File('tests/resources/eol/windows.txt'); + $windows = new File(); + $windows->setFile('tests/resources/eol/windows.txt'); $this->assertEquals( true, $windows->hasNewLineAtTheEnd() @@ -76,25 +84,29 @@ public function testHasNewLineAtTheEnd() */ public function testGetLastLine() { - $mac = new File('tests/resources/eol/mac.txt'); + $mac = new File(); + $mac->setFile('tests/resources/eol/mac.txt'); $this->assertEquals( "Lorem ipsum\r", $mac->getLastLine() ); - $unix = new File('tests/resources/eol/unix.txt'); + $unix = new File(); + $unix->setFile('tests/resources/eol/unix.txt'); $this->assertEquals( "Lorem ipsum\n", $unix->getLastLine() ); - $noEol = new File('tests/resources/eol/no-eol.txt'); + $noEol = new File(); + $noEol->setFile('tests/resources/eol/no-eol.txt'); $this->assertEquals( "Lorem ipsum", $noEol->getLastLine() ); - $windows = new File('tests/resources/eol/windows.txt'); + $windows = new File(); + $windows->setFile('tests/resources/eol/windows.txt'); $this->assertEquals( "Lorem ipsum\r\n", $windows->getLastLine() @@ -104,9 +116,10 @@ public function testGetLastLine() /** * Test if the file exists */ - public function testConstruct() + public function testSetFile() { $this->expectException(InvalidArgumentException::class); - $file = new File('foo.txt'); + $file = new File(); + $file->setFile('foo.txt'); } } From 431d1c0bf31fa4471cdc7b7a33ff6a2c8ff4c56b Mon Sep 17 00:00:00 2001 From: JBlond Date: Mon, 12 Dec 2022 13:57:52 +0100 Subject: [PATCH 4/5] Fix: Type Add: More Tests --- lib/jblond/Diff/File.php | 6 +++--- tests/Diff/FileTest.php | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/lib/jblond/Diff/File.php b/lib/jblond/Diff/File.php index 80c9421..81cb2e1 100644 --- a/lib/jblond/Diff/File.php +++ b/lib/jblond/Diff/File.php @@ -9,7 +9,7 @@ */ class File { - /** @var string $file */ + /** @var array $file */ protected $file; @@ -27,7 +27,7 @@ public function setFile($file): void if (!file_exists($file)) { throw new InvalidArgumentException(); } - $this->file = $file; + $this->file = file($file); } /** @@ -36,7 +36,7 @@ public function setFile($file): void */ public function getLastLine() { - $lines = file($this->file); + $lines = $this->file; return end($lines); } diff --git a/tests/Diff/FileTest.php b/tests/Diff/FileTest.php index 7fbfcba..4feb8d7 100644 --- a/tests/Diff/FileTest.php +++ b/tests/Diff/FileTest.php @@ -43,6 +43,13 @@ public function testGetEOLType() 'EOL type is Windows (CRLF)', $windows->getEOLType() ); + + $a = new File(); + $a->setFile('tests/resources/a.txt'); + $this->assertEquals( + 'EOL type is Unix (LF)', + $a->getEOLType() + ); } /** @@ -77,6 +84,20 @@ public function testHasNewLineAtTheEnd() true, $windows->hasNewLineAtTheEnd() ); + + $a = new File(); + $a->setFile('tests/resources/a.txt'); + $this->assertEquals( + true, + $a->hasNewLineAtTheEnd() + ); + + $b = new File(); + $b->setFile('tests/resources/b.txt'); + $this->assertEquals( + true, + $b->hasNewLineAtTheEnd() + ); } /** From dcbb76930db9263c0668fdb28f27fee7e338e843 Mon Sep 17 00:00:00 2001 From: JBlond Date: Mon, 27 Jan 2025 12:59:03 +0100 Subject: [PATCH 5/5] Update code --- lib/jblond/Diff/File.php | 47 +++++++++++++++------------------------- 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/lib/jblond/Diff/File.php b/lib/jblond/Diff/File.php index 81cb2e1..b14f575 100644 --- a/lib/jblond/Diff/File.php +++ b/lib/jblond/Diff/File.php @@ -27,17 +27,20 @@ public function setFile($file): void if (!file_exists($file)) { throw new InvalidArgumentException(); } - $this->file = file($file); + $file = file($file); + if ($file === false) { + throw new InvalidArgumentException(); + } + $this->file = $file; } /** * return the last line from the file array - * @return false|mixed|string + * @return false|mixed */ public function getLastLine() { - $lines = $this->file; - return end($lines); + return end($this->file); } /** @@ -46,19 +49,7 @@ public function getLastLine() */ public function hasNewLineAtTheEnd(): bool { - $lastLine = $this->getLastLine(); - if (strpos($lastLine, "\r\n") !== false) { - return true; - } - - if (strpos($lastLine, "\r") !== false) { - return true; - } - - if (strpos($lastLine, "\n") !== false) { - return true; - } - return false; + return (bool)preg_match('(\r\n|\r|\n)', $this->getLastLine()); } /** @@ -67,18 +58,16 @@ public function hasNewLineAtTheEnd(): bool */ public function getEOLType(): string { - $lastLine = $this->getLastLine(); - if (strpos($lastLine, "\r\n") !== false) { - return "EOL type is Windows (CRLF)"; - } - - if (strpos($lastLine, "\r") !== false) { - return "EOL type is Mac (CR)"; - } - - if (strpos($lastLine, "\n") !== false) { - return "EOL type is Unix (LF)"; + preg_match('(\r\n|\r|\n)', $this->getLastLine(), $matches); + switch ($matches[0] ?? '') { + case "\n": + return 'EOL type is Unix (LF)'; + case "\r": + return 'EOL type is Mac (CR)'; + case "\r\n": + return 'EOL type is Windows (CRLF)'; + default: + return '\ No newline at end of file'; } - return "\ No newline at end of file"; } }