@@ -330,6 +330,40 @@ fn simplified_search_handles_nil() -> crate::Result {
330
330
Ok ( ( ) )
331
331
}
332
332
333
+ #[ test]
334
+ fn longest_common_directory_no_prefix ( ) -> crate :: Result {
335
+ let search = gix_pathspec:: Search :: from_specs ( pathspecs ( & [ "tests/a/" , "tests/b/" , ":!*.sh" ] ) , None , Path :: new ( "" ) ) ?;
336
+ assert_eq ! ( search. common_prefix( ) , "tests/" ) ;
337
+ assert_eq ! ( search. prefix_directory( ) , Path :: new( "" ) ) ;
338
+ assert_eq ! (
339
+ search. longest_common_directory( ) . expect( "present" ) . to_string_lossy( ) ,
340
+ "tests/" ,
341
+ "trailing slashes are not stripped"
342
+ ) ;
343
+ Ok ( ( ) )
344
+ }
345
+
346
+ #[ test]
347
+ fn longest_common_directory_with_prefix ( ) -> crate :: Result {
348
+ let search = gix_pathspec:: Search :: from_specs (
349
+ pathspecs ( & [ "tests/a/" , "tests/b/" , ":!*.sh" ] ) ,
350
+ Some ( Path :: new ( "a/b" ) ) ,
351
+ Path :: new ( "" ) ,
352
+ ) ?;
353
+ assert_eq ! ( search. common_prefix( ) , "a/b/tests/" ) ;
354
+ assert_eq ! (
355
+ search. prefix_directory( ) . to_string_lossy( ) ,
356
+ "a/b" ,
357
+ "trailing slashes are not contained"
358
+ ) ;
359
+ assert_eq ! (
360
+ search. longest_common_directory( ) . expect( "present" ) . to_string_lossy( ) ,
361
+ "a/b/tests/" ,
362
+ "trailing slashes are present, they don't matter"
363
+ ) ;
364
+ Ok ( ( ) )
365
+ }
366
+
333
367
#[ test]
334
368
fn init_with_exclude ( ) -> crate :: Result {
335
369
let search = gix_pathspec:: Search :: from_specs ( pathspecs ( & [ "tests/" , ":!*.sh" ] ) , None , Path :: new ( "" ) ) ?;
@@ -339,6 +373,16 @@ fn init_with_exclude() -> crate::Result {
339
373
"re-orded so that excluded are first"
340
374
) ;
341
375
assert_eq ! ( search. common_prefix( ) , "tests" ) ;
376
+ assert_eq ! (
377
+ search. prefix_directory( ) ,
378
+ Path :: new( "" ) ,
379
+ "there was no prefix during initialization"
380
+ ) ;
381
+ assert_eq ! (
382
+ search. longest_common_directory( ) ,
383
+ Some ( Path :: new( "tests" ) . into( ) ) ,
384
+ "but this works here, and it should be tested"
385
+ ) ;
342
386
assert ! (
343
387
search. can_match_relative_path( "tests" . into( ) , Some ( true ) ) ,
344
388
"prefix matches"
@@ -388,40 +432,49 @@ fn prefixes_are_always_case_sensitive() -> crate::Result {
388
432
let path = gix_testtools:: scripted_fixture_read_only ( "match_baseline_files.sh" ) ?. join ( "paths" ) ;
389
433
let items = baseline:: parse_paths ( path) ?;
390
434
391
- for ( spec, prefix, common_prefix, expected) in [
392
- ( ":(icase)bar" , "FOO" , "FOO" , & [ "FOO/BAR" , "FOO/bAr" , "FOO/bar" ] as & [ _ ] ) ,
393
- ( ":(icase)bar" , "F" , "F" , & [ ] ) ,
394
- ( ":(icase)bar" , "FO" , "FO" , & [ ] ) ,
395
- ( ":(icase)../bar" , "fOo" , "" , & [ "BAR" , "bAr" , "bar" ] ) ,
396
- ( "../bar" , "fOo" , "bar" , & [ "bar" ] ) ,
397
- ( " " , "" , " " , & [ " " ] ) , // whitespace can match verbatim
398
- ( " hi*" , "" , " hi" , & [ " hi " ] ) , // whitespace can match with globs as well
399
- ( ":(icase)../bar" , "fO" , "" , & [ "BAR" , "bAr" , "bar" ] ) , // prefixes are virtual, and don't have to exist at all.
435
+ for ( spec, prefix, common_prefix, expected, expected_common_dir) in [
436
+ (
437
+ ":(icase)bar" ,
438
+ "FOO" ,
439
+ "FOO" ,
440
+ & [ "FOO/BAR" , "FOO/bAr" , "FOO/bar" ] as & [ _ ] ,
441
+ "FOO" ,
442
+ ) ,
443
+ ( ":(icase)bar" , "F" , "F" , & [ ] , "F" ) ,
444
+ ( ":(icase)bar" , "FO" , "FO" , & [ ] , "FO" ) ,
445
+ ( ":(icase)../bar" , "fOo" , "" , & [ "BAR" , "bAr" , "bar" ] , "" ) ,
446
+ ( "../bar" , "fOo" , "bar" , & [ "bar" ] , "" ) ,
447
+ ( " " , "" , " " , & [ " " ] , "" ) , // whitespace can match verbatim
448
+ ( " hi*" , "" , " hi" , & [ " hi " ] , "" ) , // whitespace can match with globs as well
449
+ ( ":(icase)../bar" , "fO" , "" , & [ "BAR" , "bAr" , "bar" ] , "" ) , // prefixes are virtual, and don't have to exist at all.
400
450
(
401
451
":(icase)../foo/bar" ,
402
452
"FOO" ,
403
453
"" ,
404
454
& [
405
455
"FOO/BAR" , "FOO/bAr" , "FOO/bar" , "fOo/BAR" , "fOo/bAr" , "fOo/bar" , "foo/BAR" , "foo/bAr" , "foo/bar" ,
406
456
] ,
457
+ "" ,
407
458
) ,
408
- ( "../foo/bar" , "FOO" , "foo/bar" , & [ "foo/bar" ] ) ,
459
+ ( "../foo/bar" , "FOO" , "foo/bar" , & [ "foo/bar" ] , "" ) ,
409
460
(
410
461
":(icase)../foo/../fOo/bar" ,
411
462
"FOO" ,
412
463
"" ,
413
464
& [
414
465
"FOO/BAR" , "FOO/bAr" , "FOO/bar" , "fOo/BAR" , "fOo/bAr" , "fOo/bar" , "foo/BAR" , "foo/bAr" , "foo/bar" ,
415
466
] ,
467
+ "" ,
416
468
) ,
417
- ( "../foo/../fOo/BAR" , "FOO" , "fOo/BAR" , & [ "fOo/BAR" ] ) ,
469
+ ( "../foo/../fOo/BAR" , "FOO" , "fOo/BAR" , & [ "fOo/BAR" ] , "" ) ,
418
470
] {
419
471
let mut search = gix_pathspec:: Search :: from_specs (
420
472
gix_pathspec:: parse ( spec. as_bytes ( ) , Default :: default ( ) ) ,
421
473
Some ( Path :: new ( prefix) ) ,
422
474
Path :: new ( "" ) ,
423
475
) ?;
424
476
assert_eq ! ( search. common_prefix( ) , common_prefix, "{spec} {prefix}" ) ;
477
+ assert_eq ! ( search. prefix_directory( ) , Path :: new( expected_common_dir) ) ;
425
478
let actual: Vec < _ > = items
426
479
. iter ( )
427
480
. filter ( |relative_path| {
@@ -453,13 +506,13 @@ fn prefixes_are_always_case_sensitive() -> crate::Result {
453
506
454
507
#[ test]
455
508
fn common_prefix ( ) -> crate :: Result {
456
- for ( specs, prefix, expected ) in [
457
- ( & [ "foo/bar" , ":(icase)foo/bar" ] as & [ _ ] , None , "" ) ,
458
- ( & [ "foo/bar" , "foo" ] , None , "foo" ) ,
459
- ( & [ "foo/bar/baz" , "foo/bar/" ] , None , "foo/bar" ) , // directory trailing slashes are ignored, but that prefix shouldn't care anyway
460
- ( & [ ":(icase)bar" , ":(icase)bart" ] , Some ( "foo" ) , "foo" ) , // only case-sensitive portions count
461
- ( & [ "bar" , "bart" ] , Some ( "foo" ) , "foo/bar" ) , // otherwise everything that matches counts
462
- ( & [ "bar" , "bart" , "ba" ] , Some ( "foo" ) , "foo/ba" ) ,
509
+ for ( specs, prefix, expected_common_prefix , expected_common_dir ) in [
510
+ ( & [ "foo/bar" , ":(icase)foo/bar" ] as & [ _ ] , None , "" , "" ) ,
511
+ ( & [ "foo/bar" , "foo" ] , None , "foo" , "" ) ,
512
+ ( & [ "foo/bar/baz" , "foo/bar/" ] , None , "foo/bar" , "" ) , // directory trailing slashes are ignored, but that prefix shouldn't care anyway
513
+ ( & [ ":(icase)bar" , ":(icase)bart" ] , Some ( "foo" ) , "foo" , "foo" ) , // only case-sensitive portions count
514
+ ( & [ "bar" , "bart" ] , Some ( "foo" ) , "foo/bar" , "foo" ) , // otherwise everything that matches counts
515
+ ( & [ "bar" , "bart" , "ba" ] , Some ( "foo" ) , "foo/ba" , "foo" ) ,
463
516
] {
464
517
let search = gix_pathspec:: Search :: from_specs (
465
518
specs
@@ -468,7 +521,12 @@ fn common_prefix() -> crate::Result {
468
521
prefix. map ( Path :: new) ,
469
522
Path :: new ( "" ) ,
470
523
) ?;
471
- assert_eq ! ( search. common_prefix( ) , expected, "{specs:?} {prefix:?}" ) ;
524
+ assert_eq ! ( search. common_prefix( ) , expected_common_prefix, "{specs:?} {prefix:?}" ) ;
525
+ assert_eq ! (
526
+ search. prefix_directory( ) ,
527
+ Path :: new( expected_common_dir) ,
528
+ "{specs:?} {prefix:?}"
529
+ ) ;
472
530
}
473
531
Ok ( ( ) )
474
532
}
0 commit comments