Skip to content

Commit 29bffca

Browse files
committed
Refactor EOL Type detection
1 parent a89e6c5 commit 29bffca

File tree

9 files changed

+106
-103
lines changed

9 files changed

+106
-103
lines changed

src/EnvFile.php

+3-5
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,21 @@
66
use EnvEditor\EnvFile\Block\Variable as VariableBlock;
77
use EnvEditor\EnvFile\EOLType;
88
use EnvEditor\EnvFile\Visitor;
9+
use EnvEditor\Parser\EOLTypeDetector;
910

1011
class EnvFile
1112
{
1213

13-
public string $EOL = "\n";
14-
1514
/** @var Block[] */
1615
public array $blocks = [];
1716

18-
function __construct()
17+
function __construct(public string $EOL = EOLType::UNIX)
1918
{
20-
$this->EOL = EOLType::UNIX;
2119
}
2220

2321
public static function loadFrom(string $path): EnvFile
2422
{
25-
$parser = new Parser();
23+
$parser = new Parser(new EOLTypeDetector());
2624
$content = file_get_contents($path);
2725

2826
return $parser->parse($content);

src/EnvFile/EOLType.php

+1-11
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,5 @@ final class EOLType
77

88
const WINDOWS = "\r\n";
99
const UNIX = "\n";
10-
11-
public static function detect(string $content, string $default = EOLType::UNIX): string
12-
{
13-
if (str_contains($content, EOLType::WINDOWS)) {
14-
return EOLType::WINDOWS;
15-
} elseif (str_contains($content, EOLType::UNIX)) {
16-
return EOLType::UNIX;
17-
}
18-
19-
return $default;
20-
}
10+
2111
}

src/Parser.php

+11-6
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,32 @@
88
use EnvEditor\EnvFile\Block\Variable\Key as VariableKey;
99
use EnvEditor\EnvFile\Block\Variable\Value as VariableValue;
1010
use EnvEditor\EnvFile\EOLType;
11+
use EnvEditor\Parser\EOLTypeDetector;
1112

1213
class Parser
1314
{
1415

15-
public ?string $EOL = null;
16+
17+
public function __construct(private EOLTypeDetector $EOLTypeDetector)
18+
{
19+
}
1620

1721
public function parse(string $content): EnvFile
1822
{
1923

2024
$file = new EnvFile();
2125

22-
$file->EOL = $this->EOL ?? EOLType::detect($content);
26+
$file->EOL = $this->EOLTypeDetector->detect($content);
27+
$pregEOL = preg_quote($file->EOL);
2328

2429
$blockStart = "^";
25-
$blockEnd = "(?:{$file->EOL}|$)";
26-
$notEOLChar = "(?:(?!{$file->EOL}).)";
27-
$notEOLWhiteSpace = "(?:(?!{$file->EOL})\s)";
30+
$blockEnd = "(?:$pregEOL|$)";
31+
$notEOLChar = "(?:(?!$pregEOL).)";
32+
$notEOLWhiteSpace = "(?:(?!$pregEOL)\s)";
2833

2934
$comment = "#($notEOLChar*)";
3035

31-
$notEOLNotSingleQuote = "(?:(?!{$file->EOL})[^'])";
36+
$notEOLNotSingleQuote = "(?:(?!$pregEOL)[^'])";
3237
$notDoubleQuote = "[^\"]";
3338

3439
$variableKey = "[a-zA-Z0-9_.]+";

src/Parser/EOLTypeDetector.php

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace EnvEditor\Parser;
4+
5+
use EnvEditor\EnvFile\EOLType;
6+
7+
class EOLTypeDetector
8+
{
9+
public function __construct(private string $default = EOLType::UNIX)
10+
{
11+
}
12+
13+
public function detect(string $content): string
14+
{
15+
if (str_contains($content, EOLType::WINDOWS)) {
16+
return EOLType::WINDOWS;
17+
} elseif (str_contains($content, EOLType::UNIX)) {
18+
return EOLType::UNIX;
19+
}
20+
21+
return $this->default;
22+
}
23+
}

tests/Feature/Asset/example.env

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ AWS_SECRET_ACCESS_KEY=
4141
AWS_DEFAULT_REGION=us-east-1
4242
AWS_BUCKET=
4343

44+
4445
PUSHER_APP_ID=
4546
PUSHER_APP_KEY=
4647
PUSHER_APP_SECRET=

tests/Feature/ConsistencyTest.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@
55
use EnvEditor\Composer;
66
use EnvEditor\EnvFile;
77
use EnvEditor\Parser;
8+
use EnvEditor\Parser\EOLTypeDetector;
89
use Tests\TestCase;
910

1011
class ConsistencyTest extends TestCase
1112
{
1213

1314
public function testKeepEOL()
1415
{
15-
$parser = new Parser();
16+
$parser = new Parser(new EOLTypeDetector());
1617
$composer = new Composer();
1718

1819
$contentUnix = "#test\n#test";
@@ -28,7 +29,7 @@ public function testKeepEOL()
2829
public function testComplexFile()
2930
{
3031

31-
$parser = new Parser();
32+
$parser = new Parser(new EOLTypeDetector());
3233
$composer = new Composer();
3334

3435
$content = file_get_contents(__DIR__ . "/Asset/example.env");

tests/Unit/EnvFile/EOLTypeTest.php

-31
This file was deleted.
+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
namespace Tests\Unit\Parser;
4+
5+
use EnvEditor\EnvFile\EOLType;
6+
use EnvEditor\Parser\EOLTypeDetector;
7+
use Tests\TestCase;
8+
9+
class EOLTypeDetectorTest extends TestCase
10+
{
11+
12+
private EOLTypeDetector $detector;
13+
14+
private string $defaultEOL = '[DEFAULT_EOL]';
15+
16+
protected function setUp(): void
17+
{
18+
parent::setUp();
19+
20+
$this->detector = new EOLTypeDetector($this->defaultEOL);
21+
}
22+
23+
24+
public function testDetectUnix(): void
25+
{
26+
$unix = "#test\n#test";
27+
$this->assertEquals(EOLType::UNIX, $this->detector->detect($unix));
28+
}
29+
30+
public function testDetectWindows(): void
31+
{
32+
$win = "#test\r\n#test";
33+
$this->assertEquals(EOLType::WINDOWS, $this->detector->detect($win));
34+
}
35+
36+
public function testDetectDefault(): void
37+
{
38+
$empty = "";
39+
$this->assertEquals($this->defaultEOL, $this->detector->detect($empty));
40+
}
41+
}

tests/Unit/ParserTest.php

+23-48
Original file line numberDiff line numberDiff line change
@@ -2,66 +2,50 @@
22

33
namespace Tests\Unit;
44

5-
use EnvEditor\EnvFile\EOLType;
65
use EnvEditor\Parser;
76
use Tests\TestCase;
87

98
class ParserTest extends TestCase
109
{
11-
12-
public function testFileEOLType(): void
13-
{
14-
15-
$parser = new Parser();
16-
17-
$win = "#test\r\n#test";
18-
$unix = "#test\n#test";
1910

20-
$this->assertEquals(EOLType::WINDOWS, $parser->parse($win)->EOL);
21-
$this->assertEquals(EOLType::UNIX, $parser->parse($unix)->EOL);
11+
private Parser $parser;
2212

23-
$parser->EOL = EOLType::UNIX;
13+
private string $newLine = "[TEST_EOL]";
2414

25-
$this->assertEquals(EOLType::UNIX, $parser->parse($win)->EOL);
15+
protected function setUp(): void
16+
{
17+
parent::setUp();
2618

19+
$detector = $this->createMock(Parser\EOLTypeDetector::class);
20+
$detector->method('detect')->willReturn($this->newLine);
21+
$this->parser = new Parser($detector);
2722
}
2823

29-
/**
30-
* @depends testFileEOLType
31-
*/
3224
public function testSimpleBlockCount(): void
3325
{
34-
$parser = new Parser();
26+
$content = "#test{$this->newLine}#test";
3527

36-
$win = "#test\r\n#test";
37-
$unix = "#test\n#test";
38-
39-
$this->assertCount(2, $parser->parse($win)->blocks);
40-
$this->assertCount(2, $parser->parse($unix)->blocks);
28+
$this->assertCount(2, $this->parser->parse($content)->blocks);
4129
}
4230

4331
/**
4432
* @depends testSimpleBlockCount
4533
*/
4634
public function testComplexBlockCount(): void
4735
{
48-
$parser = new Parser();
49-
50-
$multilineString = "#test\nX=VALUE\nY='foo bar'\nZ=\"foo\nbar\"";
51-
$this->assertCount(4, $parser->parse($multilineString)->blocks);
36+
$multilineString = "#test{$this->newLine}X=VALUE{$this->newLine}Y='foo bar'{$this->newLine}Z=\"foo{$this->newLine}bar\"";
37+
$this->assertCount(4, $this->parser->parse($multilineString)->blocks);
5238

53-
$invalidValueString = "#test\nX=VALUE\nfoo bar";
54-
$this->assertCount(3, $parser->parse($invalidValueString)->blocks);
39+
$invalidValueString = "#test{$this->newLine}X=VALUE{$this->newLine}foo bar";
40+
$this->assertCount(3, $this->parser->parse($invalidValueString)->blocks);
5541
}
5642

5743
/**
5844
* @depends testSimpleBlockCount
5945
*/
6046
public function testCommentBlockText(): void
6147
{
62-
$parser = new Parser();
63-
64-
$blocks = $parser->parse("#test1\n#test2")->blocks;
48+
$blocks = $this->parser->parse("#test1{$this->newLine}#test2")->blocks;
6549

6650
$this->assertEquals("test1", $blocks[0]->text);
6751
$this->assertEquals("test2", $blocks[1]->text);
@@ -73,10 +57,8 @@ public function testCommentBlockText(): void
7357
*/
7458
public function testVariableBlockContent(): void
7559
{
76-
$parser = new Parser();
77-
78-
$multilineString = "X=VALUE\nY='foo bar'\nZ=\"foo\nbar\"";
79-
$blocks = $parser->parse($multilineString)->blocks;
60+
$multilineString = "X=VALUE{$this->newLine}Y='foo bar'{$this->newLine}Z=\"foo{$this->newLine}bar\"";
61+
$blocks = $this->parser->parse($multilineString)->blocks;
8062

8163
$this->assertEquals("X", $blocks[0]->key);
8264
$this->assertEquals("VALUE", $blocks[0]->value);
@@ -86,7 +68,7 @@ public function testVariableBlockContent(): void
8668
$this->assertEquals("'", $blocks[1]->value->quote);
8769

8870
$this->assertEquals("Z", $blocks[2]->key);
89-
$this->assertEquals("foo\nbar", $blocks[2]->value);
71+
$this->assertEquals("foo{$this->newLine}bar", $blocks[2]->value);
9072
$this->assertEquals('"', $blocks[2]->value->quote);
9173

9274
}
@@ -96,9 +78,7 @@ public function testVariableBlockContent(): void
9678
*/
9779
public function testVariableWhiteSpaces(): void
9880
{
99-
$parser = new Parser();
100-
101-
$blocks = $parser->parse("X =foo\n\tY = 'bar' ")->blocks;
81+
$blocks = $this->parser->parse("X =foo{$this->newLine}\tY = 'bar' ")->blocks;
10282

10383
$this->assertEquals("X", $blocks[0]->key);
10484
$this->assertEquals("foo", $blocks[0]->value);
@@ -122,8 +102,7 @@ public function testVariableWhiteSpaces(): void
122102
*/
123103
public function testUnknown(): void
124104
{
125-
$parser = new Parser();
126-
$blocks = $parser->parse("???")->blocks;
105+
$blocks = $this->parser->parse("???")->blocks;
127106
$this->assertEquals("???", $blocks[0]->content);
128107
}
129108

@@ -132,8 +111,7 @@ public function testUnknown(): void
132111
*/
133112
public function testEmpty(): void
134113
{
135-
$parser = new Parser();
136-
$blocks = $parser->parse("#test\n\n#test")->blocks;
114+
$blocks = $this->parser->parse("#test{$this->newLine}{$this->newLine}#test")->blocks;
137115
$this->assertEquals("", $blocks[1]->content);
138116
}
139117

@@ -142,16 +120,13 @@ public function testEmpty(): void
142120
*/
143121
public function testEmptyLast(): void
144122
{
145-
$parser = new Parser();
146-
$blocks = $parser->parse("#test\n")->blocks;
123+
$blocks = $this->parser->parse("#test{$this->newLine}")->blocks;
147124
$this->assertEquals("", $blocks[1]->content);
148125
}
149126

150127
public function testEmptyFile(): void
151128
{
152-
$parser = new Parser();
153-
154-
$blocks = $parser->parse("")->blocks;
129+
$blocks = $this->parser->parse("")->blocks;
155130

156131
$this->assertCount(1, $blocks);
157132
$this->assertEquals("", $blocks[0]->content);

0 commit comments

Comments
 (0)