@@ -435,12 +435,12 @@ pub(crate) struct TestPath<'a> {
435435 pub variant : Option < Cow < ' a , str > > ,
436436}
437437
438- const SCOPE_DIR_FX_PRIVATE_STR : & str = "testing/web-platform/mozilla" ;
439- const SCOPE_DIR_FX_PRIVATE_COMPONENTS : & [ & str ] = & [ "testing" , "web-platform" , "mozilla" ] ;
440- const SCOPE_DIR_FX_PUBLIC_STR : & str = "testing/web-platform" ;
441- const SCOPE_DIR_FX_PUBLIC_COMPONENTS : & [ & str ] = & [ "testing" , "web-platform" ] ;
442- const SCOPE_DIR_SERVO_PUBLIC_STR : & str = "tests/wpt/webgpu" ;
443- const SCOPE_DIR_SERVO_PUBLIC_COMPONENTS : & [ & str ] = & [ "tests" , "wpt" , "webgpu" ] ;
438+ const SCOPE_DIR_FX_MOZILLA_STR : & str = "testing/web-platform/mozilla" ;
439+ const SCOPE_DIR_FX_MOZILLA_COMPONENTS : & [ & str ] = & [ "testing" , "web-platform" , "mozilla" ] ;
440+ const SCOPE_DIR_FX_UPSTREAM_STR : & str = "testing/web-platform" ;
441+ const SCOPE_DIR_FX_UPSTREAM_COMPONENTS : & [ & str ] = & [ "testing" , "web-platform" ] ;
442+ const SCOPE_DIR_SERVO_WEBGPU_STR : & str = "tests/wpt/webgpu" ;
443+ const SCOPE_DIR_SERVO_WEBGPU_COMPONENTS : & [ & str ] = & [ "tests" , "wpt" , "webgpu" ] ;
444444
445445impl < ' a > TestPath < ' a > {
446446 pub fn from_execution_report (
@@ -449,23 +449,9 @@ impl<'a> TestPath<'a> {
449449 ) -> Result < Self , ExecutionReportPathError < ' a > > {
450450 let err = || ExecutionReportPathError { test_url_path } ;
451451
452- let try_strip_with = |prefix, visibility| {
453- test_url_path
454- . strip_prefix ( prefix)
455- . map ( |stripped| ( visibility, stripped) )
456- } ;
457- let vis_and_path = match browser {
458- Browser :: Firefox => try_strip_with ( "/_mozilla/" , TestVisibility :: Private ) ,
459- Browser :: Servo => try_strip_with ( "/_webgpu/" , TestVisibility :: Public ) ,
460- }
461- . or_else ( || try_strip_with ( "/" , TestVisibility :: Public ) ) ;
462- let Some ( ( visibility, path) ) = vis_and_path else {
463- return Err ( err ( ) ) ;
464- } ;
465- let scope = TestScope {
466- browser,
467- visibility,
468- } ;
452+ let ( scope, path) = browser
453+ . strip_scope_url_prefix ( test_url_path)
454+ . ok_or_else ( err) ?;
469455
470456 if path. contains ( '\\' ) {
471457 return Err ( err ( ) ) ;
@@ -510,21 +496,9 @@ impl<'a> TestPath<'a> {
510496 . ok_or ( err ( ) ) ?,
511497 ) ;
512498
513- let ( private_path, public_path) = match browser {
514- Browser :: Firefox => ( SCOPE_DIR_FX_PRIVATE_STR , SCOPE_DIR_FX_PUBLIC_STR ) ,
515- Browser :: Servo => ( SCOPE_DIR_FX_PRIVATE_STR , SCOPE_DIR_SERVO_PUBLIC_STR ) ,
516- } ;
517- let ( visibility, path) = if let Ok ( path) = rel_meta_file_path. strip_prefix ( private_path) {
518- ( TestVisibility :: Private , path)
519- } else if let Ok ( path) = rel_meta_file_path. strip_prefix ( public_path) {
520- ( TestVisibility :: Public , path)
521- } else {
522- return Err ( err ( ) ) ;
523- } ;
524- let scope = TestScope {
525- browser,
526- visibility,
527- } ;
499+ let ( scope, path) = browser
500+ . strip_scope_metadata_parent_path ( rel_meta_file_path)
501+ . map_err ( |_e| err ( ) ) ?;
528502
529503 let Ok ( path) = path. strip_prefix ( "meta/" ) else {
530504 return Err ( err ( ) ) ;
@@ -538,7 +512,7 @@ impl<'a> TestPath<'a> {
538512
539513 Ok ( Self {
540514 scope,
541- path : Utf8Path :: new ( path) . into ( ) ,
515+ path : path. into ( ) ,
542516 variant : variant. map ( Into :: into) ,
543517 } )
544518 }
@@ -591,17 +565,12 @@ impl<'a> TestPath<'a> {
591565 scope,
592566 } = self ;
593567 lazy_format ! ( move |f| {
594- let TestScope {
595- browser,
596- visibility,
597- } = scope;
598- let scope_prefix = match ( browser, visibility) {
599- ( Browser :: Firefox , TestVisibility :: Public ) => "" ,
600- ( Browser :: Firefox , TestVisibility :: Private ) => "_mozilla/" ,
601- ( Browser :: Servo , TestVisibility :: Public ) => "_webgpu/" ,
602- ( Browser :: Servo , TestVisibility :: Private ) => todo!( ) ,
603- } ;
604- write!( f, "{scope_prefix}{}" , path. components( ) . join_with( '/' ) ) ?;
568+ write!(
569+ f,
570+ "{}{}" ,
571+ scope. url_prefix( ) ,
572+ path. components( ) . join_with( '/' )
573+ ) ?;
605574 if let Some ( variant) = variant. as_ref( ) {
606575 write!( f, "{}" , variant) ?;
607576 }
@@ -616,24 +585,16 @@ impl<'a> TestPath<'a> {
616585 scope,
617586 } = self ;
618587
619- let TestScope {
620- browser,
621- visibility,
622- } = scope;
623- let scope_dir = match ( browser, visibility) {
624- ( Browser :: Firefox , TestVisibility :: Public ) => SCOPE_DIR_FX_PUBLIC_COMPONENTS ,
625- ( Browser :: Firefox , TestVisibility :: Private ) => SCOPE_DIR_FX_PRIVATE_COMPONENTS ,
626- ( Browser :: Servo , TestVisibility :: Public ) => SCOPE_DIR_SERVO_PUBLIC_COMPONENTS ,
627- ( Browser :: Servo , TestVisibility :: Private ) => todo ! ( ) ,
628- }
629- . iter ( )
630- . chain ( & [ "meta" ] )
631- . join_with ( std:: path:: MAIN_SEPARATOR ) ;
588+ let scope_dir = scope
589+ . metadata_parent_path_components ( )
590+ . chain ( [ "meta" ] . iter ( ) . cloned ( ) )
591+ . join_with ( std:: path:: MAIN_SEPARATOR ) ;
632592
633593 lazy_format ! ( move |f| { write!( f, "{scope_dir}{}{path}.ini" , std:: path:: MAIN_SEPARATOR ) } )
634594 }
635595}
636596
597+ /// An error encountered during [`TestPath::from_execution_report`].
637598#[ derive( Debug ) ]
638599pub struct ExecutionReportPathError < ' a > {
639600 test_url_path : & ' a str ,
@@ -653,6 +614,7 @@ impl Display for ExecutionReportPathError<'_> {
653614 }
654615}
655616
617+ /// An error encountered during [`TestPath::from_metadata_test`].
656618#[ derive( Debug ) ]
657619pub struct MetadataTestPathError < ' a > {
658620 rel_meta_file_path : & ' a Path ,
@@ -673,28 +635,114 @@ impl Display for MetadataTestPathError<'_> {
673635 }
674636}
675637
638+ /// A browser supported by [super::main], used for [`TestPath`]s.
676639#[ derive( Clone , Copy , Debug , Eq , Hash , Ord , PartialEq , PartialOrd , ValueEnum ) ]
677640pub ( crate ) enum Browser {
678641 Firefox ,
679642 Servo ,
680643}
681644
682- #[ derive( Copy , Clone , Debug , Eq , Hash , Ord , PartialEq , PartialOrd ) ]
683- pub ( crate ) enum TestVisibility {
645+ impl Browser {
646+ /// NOTE: Keep this implementation in sync with [`TestScope::url_prefix`].
647+ pub ( crate ) fn strip_scope_url_prefix < ' a > (
648+ & self ,
649+ url_path : & ' a str ,
650+ ) -> Option < ( TestScope , & ' a str ) > {
651+ let strip_prefix = |prefix, scope| {
652+ url_path
653+ . strip_prefix ( prefix)
654+ . map ( |stripped| ( scope, stripped) )
655+ } ;
656+ match self {
657+ Browser :: Firefox => strip_prefix ( "/_mozilla/" , FirefoxTestScope :: Mozilla . into ( ) )
658+ . or_else ( || strip_prefix ( "/" , FirefoxTestScope :: Upstream . into ( ) ) ) ,
659+ Browser :: Servo => strip_prefix ( "/_webgpu/" , ServoTestScope :: WebGpu . into ( ) ) ,
660+ }
661+ }
662+
663+ /// NOTE: Keep this implementation in sync with [`TestScope::metadata_parent_path_components`].
664+ pub ( crate ) fn strip_scope_metadata_parent_path < ' a > (
665+ & self ,
666+ path : & ' a Utf8Path ,
667+ ) -> Result < ( TestScope , & ' a Utf8Path ) , std:: path:: StripPrefixError > {
668+ let strip_prefix =
669+ |prefix, scope| path. strip_prefix ( prefix) . map ( |stripped| ( scope, stripped) ) ;
670+ match self {
671+ Browser :: Firefox => {
672+ strip_prefix ( SCOPE_DIR_FX_MOZILLA_STR , FirefoxTestScope :: Mozilla . into ( ) ) . or_else (
673+ |_| strip_prefix ( SCOPE_DIR_FX_UPSTREAM_STR , FirefoxTestScope :: Upstream . into ( ) ) ,
674+ )
675+ }
676+ Browser :: Servo => {
677+ strip_prefix ( SCOPE_DIR_SERVO_WEBGPU_STR , ServoTestScope :: WebGpu . into ( ) )
678+ }
679+ }
680+ }
681+ }
682+
683+ /// Symbolically represents a file root from which tests and metadata are based. Scopes are based
684+ /// on a specific [`Browser`].
685+ #[ derive( Clone , Debug , Eq , Hash , Ord , PartialEq , PartialOrd ) ]
686+ pub ( crate ) enum TestScope {
687+ Firefox ( FirefoxTestScope ) ,
688+ Servo ( ServoTestScope ) ,
689+ }
690+
691+ impl TestScope {
692+ /// NOTE: Keep this implementation in sync with [`Browser::strip_scope_url_prefix`].
693+ fn url_prefix ( & self ) -> & str {
694+ match self {
695+ TestScope :: Firefox ( scope) => match scope {
696+ FirefoxTestScope :: Upstream => "" ,
697+ FirefoxTestScope :: Mozilla => "_mozilla/" ,
698+ } ,
699+ TestScope :: Servo ( ServoTestScope :: WebGpu ) => "_webgpu/" ,
700+ }
701+ }
702+
703+ /// NOTE: Keep this implementation in sync with [`Browser::strip_scope_metadata_parent_path`].
704+ fn metadata_parent_path_components ( & self ) -> impl Iterator < Item = & str > + Clone {
705+ match self {
706+ TestScope :: Firefox ( scope) => match scope {
707+ FirefoxTestScope :: Upstream => SCOPE_DIR_FX_UPSTREAM_COMPONENTS ,
708+ FirefoxTestScope :: Mozilla => SCOPE_DIR_FX_MOZILLA_COMPONENTS ,
709+ } ,
710+ TestScope :: Servo ( ServoTestScope :: WebGpu ) => SCOPE_DIR_SERVO_WEBGPU_COMPONENTS ,
711+ }
712+ . iter ( )
713+ . cloned ( )
714+ }
715+ }
716+
717+ /// Subset of [`TestScope`] for [`Browser::Firefox`].
718+ #[ derive( Clone , Debug , Eq , Hash , Ord , PartialEq , PartialOrd ) ]
719+ pub ( crate ) enum FirefoxTestScope {
684720 /// A public test available at some point in the history of [WPT upstream]. Note that while
685721 /// a test may be public, metadata associated with it is in a private location.
686722 ///
687723 /// [WPT upstream]: https://github.com/web-platform-tests/wpt
688- Public ,
689- /// A private test specific to browser.
690- Private ,
724+ Upstream ,
725+ /// A private test specific to Firefox.
726+ Mozilla ,
727+ }
728+
729+ impl From < FirefoxTestScope > for TestScope {
730+ fn from ( value : FirefoxTestScope ) -> Self {
731+ Self :: Firefox ( value)
732+ }
691733}
692734
693- /// Symbolically represents a file root from which tests and metadata are based .
735+ /// Subset of [`TestScope`] for [`Browser::Servo`] .
694736#[ derive( Clone , Debug , Eq , Hash , Ord , PartialEq , PartialOrd ) ]
695- pub ( crate ) struct TestScope {
696- browser : Browser ,
697- visibility : TestVisibility ,
737+ pub ( crate ) enum ServoTestScope {
738+ /// A WebGPU CTS test vendored into Servo's source tree.
739+ WebGpu ,
740+ }
741+
742+ impl From < ServoTestScope > for TestScope {
743+ fn from ( value : ServoTestScope ) -> Self {
744+ Self :: Servo ( value)
745+ }
698746}
699747
700748#[ test]
@@ -707,10 +755,7 @@ fn parse_test_path() {
707755 )
708756 . unwrap( ) ,
709757 TestPath {
710- scope: TestScope {
711- browser: Browser :: Firefox ,
712- visibility: TestVisibility :: Private
713- } ,
758+ scope: FirefoxTestScope :: Mozilla . into( ) ,
714759 path: Utf8Path :: new( "blarg/cts.https.html" ) . into( ) ,
715760 variant: Some ( "?stuff=things" . into( ) ) ,
716761 }
@@ -724,10 +769,7 @@ fn parse_test_path() {
724769 )
725770 . unwrap( ) ,
726771 TestPath {
727- scope: TestScope {
728- browser: Browser :: Firefox ,
729- visibility: TestVisibility :: Public
730- } ,
772+ scope: FirefoxTestScope :: Upstream . into( ) ,
731773 path: Utf8Path :: new( "stuff/things/cts.https.html" ) . into( ) ,
732774 variant: None ,
733775 }
@@ -741,10 +783,7 @@ fn parse_test_path() {
741783 )
742784 . unwrap( ) ,
743785 TestPath {
744- scope: TestScope {
745- browser: Browser :: Servo ,
746- visibility: TestVisibility :: Public
747- } ,
786+ scope: ServoTestScope :: WebGpu . into( ) ,
748787 path: Utf8Path :: new( "webgpu/cts.https.html" ) . into( ) ,
749788 variant: Some ( "?stuff=things" . into( ) ) ,
750789 }
0 commit comments