1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
/* |
6
|
|
|
* This file is part of Badcow DNS Library. |
7
|
|
|
* |
8
|
|
|
* (c) Samuel Williams <[email protected]> |
9
|
|
|
* |
10
|
|
|
* For the full copyright and license information, please view the LICENSE |
11
|
|
|
* file that was distributed with this source code. |
12
|
|
|
*/ |
13
|
|
|
|
14
|
|
|
namespace Badcow\DNS\Tests\Parser; |
15
|
|
|
|
16
|
|
|
use Badcow\DNS\Parser\Comments; |
17
|
|
|
use Badcow\DNS\Parser\Normaliser; |
18
|
|
|
use Badcow\DNS\Parser\ParseException; |
19
|
|
|
use PHPUnit\Framework\TestCase; |
20
|
|
|
|
21
|
|
|
class NormaliserTest extends TestCase |
22
|
|
|
{ |
23
|
|
|
/** |
24
|
|
|
* @var string |
25
|
|
|
*/ |
26
|
|
|
private $unbalancedBrackets = <<< TXT |
27
|
|
|
example.com. IN SOA ( |
28
|
|
|
example.com. ; MNAME |
29
|
|
|
post.example.com. ; RNAME |
30
|
|
|
2014110501 ; SERIAL |
31
|
|
|
3600 ; REFRESH |
32
|
|
|
14400 ; RETRY |
33
|
|
|
604800 ; EXPIRE |
34
|
|
|
3600 ; MINIMUM |
35
|
|
|
TXT; |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* @var string |
39
|
|
|
*/ |
40
|
|
|
private $commentsOptionsSample = <<< TXT |
41
|
|
|
; SOA Record |
42
|
|
|
example.com. IN SOA ( |
43
|
|
|
example.com. ; MNAME |
44
|
|
|
post.example.com. ; RNAME |
45
|
|
|
2014110501 ; SERIAL |
46
|
|
|
3600 ; REFRESH |
47
|
|
|
14400 ; RETRY |
48
|
|
|
604800 ; EXPIRE |
49
|
|
|
3600 ; MINIMUM |
50
|
|
|
);This is a Start of Authority |
51
|
|
|
TXT; |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* @throws ParseException|\Exception |
55
|
|
|
*/ |
56
|
|
View Code Duplication |
public function testRemovesComments(): void |
|
|
|
|
57
|
|
|
{ |
58
|
|
|
$zone = self::readFile(__DIR__.'/Resources/testClearComments_sample.txt'); |
59
|
|
|
$expectation = self::readFile(__DIR__.'/Resources/testClearComments_expectation.txt'); |
60
|
|
|
|
61
|
|
|
$this->assertEquals($expectation, Normaliser::normalise($zone)); |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* Multi-line records collapse onto single line. |
66
|
|
|
* |
67
|
|
|
* @throws ParseException|\Exception |
68
|
|
|
*/ |
69
|
|
View Code Duplication |
public function testMultilineRecordsCollapseOntoSingleLine(): void |
|
|
|
|
70
|
|
|
{ |
71
|
|
|
$zone = self::readFile(__DIR__.'/Resources/testCollapseMultilines_sample.txt'); |
72
|
|
|
$expectation = self::readFile(__DIR__.'/Resources/testCollapseMultilines_expectation.txt'); |
73
|
|
|
|
74
|
|
|
$this->assertEquals($expectation, Normaliser::normalise($zone)); |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* Unbalanced brackets cause ParseException. |
79
|
|
|
* |
80
|
|
|
* @throws ParseException |
81
|
|
|
*/ |
82
|
|
|
public function testUnbalancedBracketsCauseParseException(): void |
83
|
|
|
{ |
84
|
|
|
$this->expectException(ParseException::class); |
85
|
|
|
$this->expectExceptionMessage('End of file reached. Unclosed bracket.'); |
86
|
|
|
Normaliser::normalise($this->unbalancedBrackets); |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
/** |
90
|
|
|
* Unbalanced quotation marks cause ParseException. |
91
|
|
|
* |
92
|
|
|
* @throws ParseException |
93
|
|
|
*/ |
94
|
|
|
public function testUnbalancedQuotationMarksCauseParseException(): void |
95
|
|
|
{ |
96
|
|
|
$string = 'mail IN TXT "Some string'; |
97
|
|
|
|
98
|
|
|
$this->expectException(ParseException::class); |
99
|
|
|
$this->expectExceptionMessage('Unbalanced double quotation marks. End of file reached.'); |
100
|
|
|
Normaliser::normalise($string); |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
/** |
104
|
|
|
* Line feed inside quotation marks cause exception. |
105
|
|
|
* |
106
|
|
|
* @throws ParseException |
107
|
|
|
*/ |
108
|
|
|
public function testLineFeedInsideQuotationMarksCauseException(): void |
109
|
|
|
{ |
110
|
|
|
$string = "www IN CNAME @\n mail IN TXT \"Some \nstring\""; |
111
|
|
|
|
112
|
|
|
$this->expectException(ParseException::class); |
113
|
|
|
$this->expectExceptionMessage('Line Feed found within double quotation marks context. [Line no: 2]'); |
114
|
|
|
Normaliser::normalise($string); |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
/** |
118
|
|
|
* @throws \Exception |
119
|
|
|
*/ |
120
|
|
View Code Duplication |
public function testCommentsAreRetained(): void |
|
|
|
|
121
|
|
|
{ |
122
|
|
|
$zone = self::readFile(__DIR__.'/Resources/testClearComments_sample.txt'); |
123
|
|
|
$expectation = self::readFile(__DIR__.'/Resources/testKeepComments_expectation.txt'); |
124
|
|
|
$normalisedZone = Normaliser::normalise($zone, Comments::END_OF_ENTRY); |
125
|
|
|
|
126
|
|
|
$this->assertEquals($expectation, $normalisedZone); |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
/** |
130
|
|
|
* @throws \Exception |
131
|
|
|
*/ |
132
|
|
|
public function testMultilineCommentsAreRetained(): void |
133
|
|
|
{ |
134
|
|
|
$zone = self::readFile(__DIR__.'/Resources/testCollapseMultilines_sample.txt'); |
135
|
|
|
$expectation = self::readFile(__DIR__.'/Resources/testCollapseMultilinesWithComments_expectation.txt'); |
136
|
|
|
$normalisedZone = Normaliser::normalise($zone, Comments::END_OF_ENTRY | Comments::MULTILINE | Comments::ORPHAN); |
137
|
|
|
|
138
|
|
|
$this->assertEquals($expectation, $normalisedZone); |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
/** |
142
|
|
|
* @throws \Exception |
143
|
|
|
*/ |
144
|
|
View Code Duplication |
public function testMultilineTxtRecords(): void |
|
|
|
|
145
|
|
|
{ |
146
|
|
|
$zone = self::readFile(__DIR__.'/Resources/testMultilineTxtRecords_sample.txt'); |
147
|
|
|
$expectation = self::readFile(__DIR__.'/Resources/testMultilineTxtRecords_expectation.txt'); |
148
|
|
|
$normalisedZone = Normaliser::normalise($zone, Comments::END_OF_ENTRY); |
149
|
|
|
|
150
|
|
|
$this->assertEquals($expectation, $normalisedZone); |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
/** |
154
|
|
|
* @throws \Exception |
155
|
|
|
*/ |
156
|
|
View Code Duplication |
public function testKeepCommentsWithoutLinefeedAtEnd(): void |
|
|
|
|
157
|
|
|
{ |
158
|
|
|
$zone = self::readFile(__DIR__.'/Resources/testKeepCommentsWithoutLinefeedAtEnd_sample.txt'); |
159
|
|
|
$expectation = self::readFile(__DIR__.'/Resources/testKeepCommentsWithoutLinefeedAtEnd_expectation.txt'); |
160
|
|
|
$normalisedZone = Normaliser::normalise($zone, Comments::END_OF_ENTRY); |
161
|
|
|
|
162
|
|
|
$this->assertEquals($expectation, $normalisedZone); |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
/** |
166
|
|
|
* @throws \Exception |
167
|
|
|
*/ |
168
|
|
|
public function testCommentOptions(): void |
169
|
|
|
{ |
170
|
|
|
$option_1 = Comments::END_OF_ENTRY; |
171
|
|
|
$expectation_1 = 'example.com. IN SOA example.com. post.example.com. 2014110501 3600 14400'. |
172
|
|
|
' 604800 3600;This is a Start of Authority'; |
173
|
|
|
|
174
|
|
|
$option_2 = Comments::MULTILINE; |
175
|
|
|
$expectation_2 = 'example.com. IN SOA example.com. post.example.com. 2014110501 3600 14400'. |
176
|
|
|
' 604800 3600;MNAME RNAME SERIAL REFRESH RETRY EXPIRE MINIMUM'; |
177
|
|
|
|
178
|
|
|
$option_3 = Comments::END_OF_ENTRY | Comments::MULTILINE; |
179
|
|
|
$expectation_3 = 'example.com. IN SOA example.com. post.example.com. 2014110501 3600 14400'. |
180
|
|
|
' 604800 3600;MNAME RNAME SERIAL REFRESH RETRY EXPIRE MINIMUMThis is a Start of Authority'; |
181
|
|
|
|
182
|
|
|
$option_4 = Comments::ORPHAN; |
183
|
|
|
$expectation_4 = ";SOA Record\nexample.com. IN SOA example.com. post.example.com. 2014110501 3600 14400". |
184
|
|
|
' 604800 3600'; |
185
|
|
|
|
186
|
|
|
$option_5 = Comments::ORPHAN | Comments::END_OF_ENTRY; |
187
|
|
|
$expectation_5 = ";SOA Record\nexample.com. IN SOA example.com. post.example.com. 2014110501 3600 14400". |
188
|
|
|
' 604800 3600;This is a Start of Authority'; |
189
|
|
|
|
190
|
|
|
$option_6 = Comments::ORPHAN | Comments::MULTILINE; |
191
|
|
|
$expectation_6 = ";SOA Record\nexample.com. IN SOA example.com. post.example.com. 2014110501 3600 14400". |
192
|
|
|
' 604800 3600;MNAME RNAME SERIAL REFRESH RETRY EXPIRE MINIMUM'; |
193
|
|
|
|
194
|
|
|
$option_7 = Comments::ALL; |
195
|
|
|
$expectation_7 = ";SOA Record\nexample.com. IN SOA example.com. post.example.com. 2014110501 3600 14400". |
196
|
|
|
' 604800 3600;MNAME RNAME SERIAL REFRESH RETRY EXPIRE MINIMUMThis is a Start of Authority'; |
197
|
|
|
|
198
|
|
|
$this->assertEquals($expectation_1, Normaliser::normalise($this->commentsOptionsSample, $option_1)); |
199
|
|
|
$this->assertEquals($expectation_2, Normaliser::normalise($this->commentsOptionsSample, $option_2)); |
200
|
|
|
$this->assertEquals($expectation_3, Normaliser::normalise($this->commentsOptionsSample, $option_3)); |
201
|
|
|
$this->assertEquals($expectation_4, Normaliser::normalise($this->commentsOptionsSample, $option_4)); |
202
|
|
|
$this->assertEquals($expectation_5, Normaliser::normalise($this->commentsOptionsSample, $option_5)); |
203
|
|
|
$this->assertEquals($expectation_6, Normaliser::normalise($this->commentsOptionsSample, $option_6)); |
204
|
|
|
$this->assertEquals($expectation_7, Normaliser::normalise($this->commentsOptionsSample, $option_7)); |
205
|
|
|
} |
206
|
|
|
|
207
|
|
|
/** |
208
|
|
|
* @throws \Exception |
209
|
|
|
*/ |
210
|
|
|
public static function readFile(string $filename): string |
211
|
|
|
{ |
212
|
|
|
$file = file_get_contents($filename); |
213
|
|
|
|
214
|
|
|
if (false === $file) { |
215
|
|
|
throw new \Exception(sprintf('Unable to read file "%s".', $filename)); |
216
|
|
|
} |
217
|
|
|
|
218
|
|
|
//Remove Windows carriage returns. |
219
|
|
|
$file = str_replace("\r", '', $file); |
220
|
|
|
|
221
|
|
|
return $file; |
222
|
|
|
} |
223
|
|
|
} |
224
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.