1 #!/usr/bin/perl -w 2 # 3 # Copyright (C) 2010 Chris Jerdonek (cjerdonek (at] webkit.org) 4 # 5 # Redistribution and use in source and binary forms, with or without 6 # modification, are permitted provided that the following conditions 7 # are met: 8 # 1. Redistributions of source code must retain the above copyright 9 # notice, this list of conditions and the following disclaimer. 10 # 2. Redistributions in binary form must reproduce the above copyright 11 # notice, this list of conditions and the following disclaimer in the 12 # documentation and/or other materials provided with the distribution. 13 # 14 # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND 15 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 # DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR 18 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 25 # Unit tests of parseGitDiffHeader(). 26 27 use strict; 28 use warnings; 29 30 use Test::More; 31 use VCSUtils; 32 33 # The array of test cases. 34 my @testCaseHashRefs = ( 35 { # New test 36 diffName => "Modified file", 37 inputText => <<'END', 38 diff --git a/foo.h b/foo.h 39 index f5d5e74..3b6aa92 100644 40 --- a/foo.h 41 +++ b/foo.h 42 @@ -1 +1 @@ 43 -file contents 44 +new file contents 45 END 46 expectedReturn => [ 47 { 48 svnConvertedText => <<'END', 49 Index: foo.h 50 index f5d5e74..3b6aa92 100644 51 --- foo.h 52 +++ foo.h 53 END 54 indexPath => "foo.h", 55 }, 56 "@@ -1 +1 @@\n"], 57 expectedNextLine => "-file contents\n", 58 }, 59 { # New test 60 diffName => "new file", 61 inputText => <<'END', 62 diff --git a/foo.h b/foo.h 63 new file mode 100644 64 index 0000000..3c9f114 65 --- /dev/null 66 +++ b/foo.h 67 @@ -0,0 +1,34 @@ 68 +<html> 69 END 70 expectedReturn => [ 71 { 72 svnConvertedText => <<'END', 73 Index: foo.h 74 new file mode 100644 75 index 0000000..3c9f114 76 --- foo.h 77 +++ foo.h 78 END 79 indexPath => "foo.h", 80 isNew => 1, 81 }, 82 "@@ -0,0 +1,34 @@\n"], 83 expectedNextLine => "+<html>\n", 84 }, 85 { # New test 86 diffName => "file deletion", 87 inputText => <<'END', 88 diff --git a/foo b/foo 89 deleted file mode 100644 90 index 1e50d1d..0000000 91 --- a/foo 92 +++ /dev/null 93 @@ -1,1 +0,0 @@ 94 -line1 95 diff --git a/configure.ac b/configure.ac 96 index d45dd40..3494526 100644 97 END 98 expectedReturn => [ 99 { 100 svnConvertedText => <<'END', 101 Index: foo 102 deleted file mode 100644 103 index 1e50d1d..0000000 104 --- foo 105 +++ foo 106 END 107 indexPath => "foo", 108 isDeletion => 1, 109 }, 110 "@@ -1,1 +0,0 @@\n"], 111 expectedNextLine => "-line1\n", 112 }, 113 { # New test 114 diffName => "using --no-prefix", 115 inputText => <<'END', 116 diff --git foo.h foo.h 117 index c925780..9e65c43 100644 118 --- foo.h 119 +++ foo.h 120 @@ -1,3 +1,17 @@ 121 +contents 122 END 123 expectedReturn => [ 124 { 125 svnConvertedText => <<'END', 126 Index: foo.h 127 index c925780..9e65c43 100644 128 --- foo.h 129 +++ foo.h 130 END 131 indexPath => "foo.h", 132 }, 133 "@@ -1,3 +1,17 @@\n"], 134 expectedNextLine => "+contents\n", 135 }, 136 #### 137 # Copy operations 138 ## 139 { # New test 140 diffName => "copy (with similarity index 100%)", 141 inputText => <<'END', 142 diff --git a/foo b/foo_new 143 similarity index 100% 144 copy from foo 145 copy to foo_new 146 diff --git a/bar b/bar 147 index d45dd40..3494526 100644 148 END 149 expectedReturn => [ 150 { 151 svnConvertedText => <<'END', 152 Index: foo_new 153 similarity index 100% 154 copy from foo 155 copy to foo_new 156 END 157 copiedFromPath => "foo", 158 indexPath => "foo_new", 159 }, 160 "diff --git a/bar b/bar\n"], 161 expectedNextLine => "index d45dd40..3494526 100644\n", 162 }, 163 { # New test 164 diffName => "copy (with similarity index < 100%)", 165 inputText => <<'END', 166 diff --git a/foo b/foo_new 167 similarity index 99% 168 copy from foo 169 copy to foo_new 170 diff --git a/bar b/bar 171 index d45dd40..3494526 100644 172 END 173 expectedReturn => [ 174 { 175 svnConvertedText => <<'END', 176 Index: foo_new 177 similarity index 99% 178 copy from foo 179 copy to foo_new 180 END 181 copiedFromPath => "foo", 182 indexPath => "foo_new", 183 isCopyWithChanges => 1, 184 }, 185 "diff --git a/bar b/bar\n"], 186 expectedNextLine => "index d45dd40..3494526 100644\n", 187 }, 188 { # New test 189 diffName => "rename (with similarity index 100%)", 190 inputText => <<'END', 191 diff --git a/foo b/foo_new 192 similarity index 100% 193 rename from foo 194 rename to foo_new 195 diff --git a/bar b/bar 196 index d45dd40..3494526 100644 197 END 198 expectedReturn => [ 199 { 200 svnConvertedText => <<'END', 201 Index: foo_new 202 similarity index 100% 203 rename from foo 204 rename to foo_new 205 END 206 copiedFromPath => "foo", 207 indexPath => "foo_new", 208 shouldDeleteSource => 1, 209 }, 210 "diff --git a/bar b/bar\n"], 211 expectedNextLine => "index d45dd40..3494526 100644\n", 212 }, 213 { # New test 214 diffName => "rename (with similarity index < 100%)", 215 inputText => <<'END', 216 diff --git a/foo b/foo_new 217 similarity index 99% 218 rename from foo 219 rename to foo_new 220 index 1e50d1d..1459d21 100644 221 --- a/foo 222 +++ b/foo_new 223 @@ -15,3 +15,4 @@ release r deployment dep deploy: 224 line1 225 line2 226 line3 227 +line4 228 diff --git a/bar b/bar 229 index d45dd40..3494526 100644 230 END 231 expectedReturn => [ 232 { 233 svnConvertedText => <<'END', 234 Index: foo_new 235 similarity index 99% 236 rename from foo 237 rename to foo_new 238 index 1e50d1d..1459d21 100644 239 --- foo_new 240 +++ foo_new 241 END 242 copiedFromPath => "foo", 243 indexPath => "foo_new", 244 isCopyWithChanges => 1, 245 shouldDeleteSource => 1, 246 }, 247 "@@ -15,3 +15,4 @@ release r deployment dep deploy:\n"], 248 expectedNextLine => " line1\n", 249 }, 250 { # New test 251 diffName => "rename (with executable bit change)", 252 inputText => <<'END', 253 diff --git a/foo b/foo_new 254 old mode 100644 255 new mode 100755 256 similarity index 100% 257 rename from foo 258 rename to foo_new 259 diff --git a/bar b/bar 260 index d45dd40..3494526 100644 261 END 262 expectedReturn => [ 263 { 264 svnConvertedText => <<'END', 265 Index: foo_new 266 old mode 100644 267 new mode 100755 268 similarity index 100% 269 rename from foo 270 rename to foo_new 271 END 272 copiedFromPath => "foo", 273 executableBitDelta => 1, 274 indexPath => "foo_new", 275 isCopyWithChanges => 1, 276 shouldDeleteSource => 1, 277 }, 278 "diff --git a/bar b/bar\n"], 279 expectedNextLine => "index d45dd40..3494526 100644\n", 280 }, 281 #### 282 # Binary file test cases 283 ## 284 { 285 # New test case 286 diffName => "New binary file", 287 inputText => <<'END', 288 diff --git a/foo.gif b/foo.gif 289 new file mode 100644 290 index 0000000000000000000000000000000000000000..64a9532e7794fcd791f6f12157406d9060151690 291 GIT binary patch 292 literal 7 293 OcmYex&reDa;sO8*F9L)B 294 295 literal 0 296 HcmV?d00001 297 298 END 299 expectedReturn => [ 300 { 301 svnConvertedText => <<'END', 302 Index: foo.gif 303 new file mode 100644 304 index 0000000000000000000000000000000000000000..64a9532e7794fcd791f6f12157406d9060151690 305 GIT binary patch 306 END 307 indexPath => "foo.gif", 308 isBinary => 1, 309 isNew => 1, 310 }, 311 "literal 7\n"], 312 expectedNextLine => "OcmYex&reDa;sO8*F9L)B\n", 313 }, 314 { 315 # New test case 316 diffName => "Deleted binary file", 317 inputText => <<'END', 318 diff --git a/foo.gif b/foo.gif 319 deleted file mode 100644 320 index 323fae0..0000000 321 GIT binary patch 322 literal 0 323 HcmV?d00001 324 325 literal 7 326 OcmYex&reDa;sO8*F9L)B 327 328 END 329 expectedReturn => [ 330 { 331 svnConvertedText => <<'END', 332 Index: foo.gif 333 deleted file mode 100644 334 index 323fae0..0000000 335 GIT binary patch 336 END 337 indexPath => "foo.gif", 338 isBinary => 1, 339 isDeletion => 1, 340 }, 341 "literal 0\n"], 342 expectedNextLine => "HcmV?d00001\n", 343 }, 344 #### 345 # Executable bit test cases 346 ## 347 { 348 # New test case 349 diffName => "Modified executable file", 350 inputText => <<'END', 351 diff --git a/foo b/foo 352 index d03e242..435ad3a 100755 353 --- a/foo 354 +++ b/foo 355 @@ -1 +1 @@ 356 -file contents 357 +new file contents 358 359 END 360 expectedReturn => [ 361 { 362 svnConvertedText => <<'END', 363 Index: foo 364 index d03e242..435ad3a 100755 365 --- foo 366 +++ foo 367 END 368 indexPath => "foo", 369 }, 370 "@@ -1 +1 @@\n"], 371 expectedNextLine => "-file contents\n", 372 }, 373 { 374 # New test case 375 diffName => "Making file executable (last diff)", 376 inputText => <<'END', 377 diff --git a/foo.exe b/foo.exe 378 old mode 100644 379 new mode 100755 380 END 381 expectedReturn => [ 382 { 383 svnConvertedText => <<'END', 384 Index: foo.exe 385 old mode 100644 386 new mode 100755 387 END 388 executableBitDelta => 1, 389 indexPath => "foo.exe", 390 }, 391 undef], 392 expectedNextLine => undef, 393 }, 394 { 395 # New test case 396 diffName => "Making file executable (not last diff)", 397 inputText => <<'END', 398 diff --git a/foo.exe b/foo.exe 399 old mode 100644 400 new mode 100755 401 diff --git a/another_file.txt b/another_file.txt 402 index d03e242..435ad3a 100755 403 END 404 expectedReturn => [ 405 { 406 svnConvertedText => <<'END', 407 Index: foo.exe 408 old mode 100644 409 new mode 100755 410 END 411 executableBitDelta => 1, 412 indexPath => "foo.exe", 413 }, 414 "diff --git a/another_file.txt b/another_file.txt\n"], 415 expectedNextLine => "index d03e242..435ad3a 100755\n", 416 }, 417 { 418 # New test case 419 diffName => "New executable file", 420 inputText => <<'END', 421 diff --git a/foo b/foo 422 new file mode 100755 423 index 0000000..d03e242 424 --- /dev/null 425 +++ b/foo 426 @@ -0,0 +1 @@ 427 +file contents 428 429 END 430 expectedReturn => [ 431 { 432 svnConvertedText => <<'END', 433 Index: foo 434 new file mode 100755 435 index 0000000..d03e242 436 --- foo 437 +++ foo 438 END 439 executableBitDelta => 1, 440 indexPath => "foo", 441 isNew => 1, 442 }, 443 "@@ -0,0 +1 @@\n"], 444 expectedNextLine => "+file contents\n", 445 }, 446 { 447 # New test case 448 diffName => "Deleted executable file", 449 inputText => <<'END', 450 diff --git a/foo b/foo 451 deleted file mode 100755 452 index d03e242..0000000 453 --- a/foo 454 +++ /dev/null 455 @@ -1 +0,0 @@ 456 -file contents 457 458 END 459 expectedReturn => [ 460 { 461 svnConvertedText => <<'END', 462 Index: foo 463 deleted file mode 100755 464 index d03e242..0000000 465 --- foo 466 +++ foo 467 END 468 executableBitDelta => -1, 469 indexPath => "foo", 470 isDeletion => 1, 471 }, 472 "@@ -1 +0,0 @@\n"], 473 expectedNextLine => "-file contents\n", 474 }, 475 ); 476 477 my $testCasesCount = @testCaseHashRefs; 478 plan(tests => 2 * $testCasesCount); # Total number of assertions. 479 480 foreach my $testCase (@testCaseHashRefs) { 481 my $testNameStart = "parseGitDiffHeader(): $testCase->{diffName}: comparing"; 482 483 my $fileHandle; 484 open($fileHandle, "<", \$testCase->{inputText}); 485 my $line = <$fileHandle>; 486 487 my @got = VCSUtils::parseGitDiffHeader($fileHandle, $line); 488 my $expectedReturn = $testCase->{expectedReturn}; 489 490 is_deeply(\@got, $expectedReturn, "$testNameStart return value."); 491 492 my $gotNextLine = <$fileHandle>; 493 is($gotNextLine, $testCase->{expectedNextLine}, "$testNameStart next read line."); 494 } 495