@@ -66,20 +66,92 @@ class ResourceLoader {
6666  } 
6767} 
6868
69+ class  StatusRule  { 
70+   constructor ( key ,  value ,  pattern  =  undefined )  { 
71+     this . key  =  key ; 
72+     this . requires  =  value . requires  ||  [ ] ; 
73+     this . fail  =  value . fail ; 
74+     this . skip  =  value . skip ; 
75+     if  ( pattern )  { 
76+       this . pattern  =  this . transformPattern ( pattern ) ; 
77+     } 
78+     // TODO(joyeecheung): implement this 
79+     this . scope  =  value . scope ; 
80+     this . comment  =  value . comment ; 
81+   } 
82+ 
83+   /** 
84+    * Transform a filename pattern into a RegExp 
85+    * @param  {string } pattern 
86+    * @returns  {RegExp } 
87+    */ 
88+   transformPattern ( pattern )  { 
89+     const  result  =  pattern . replace ( / [ - / \\ ^ $ + ? . ( ) | [ \] { } ] / g,  '\\$&' ) ; 
90+     return  new  RegExp ( result . replace ( '*' ,  '.*' ) ) ; 
91+   } 
92+ } 
93+ 
94+ class  StatusRuleSet  { 
95+   constructor ( )  { 
96+     // We use two sets of rules to speed up matching 
97+     this . exactMatch  =  { } ; 
98+     this . patternMatch  =  [ ] ; 
99+   } 
100+ 
101+   /** 
102+    * @param  {object } rules 
103+    */ 
104+   addRules ( rules )  { 
105+     for  ( const  key  of  Object . keys ( rules ) )  { 
106+       if  ( key . includes ( '*' ) )  { 
107+         this . patternMatch . push ( new  StatusRule ( key ,  rules [ key ] ,  key ) ) ; 
108+       }  else  { 
109+         this . exactMatch [ key ]  =  new  StatusRule ( key ,  rules [ key ] ) ; 
110+       } 
111+     } 
112+   } 
113+ 
114+   match ( file )  { 
115+     const  result  =  [ ] ; 
116+     const  exact  =  this . exactMatch [ file ] ; 
117+     if  ( exact )  { 
118+       result . push ( exact ) ; 
119+     } 
120+     for  ( const  item  of  this . patternMatch )  { 
121+       if  ( item . pattern . test ( file ) )  { 
122+         result . push ( item ) ; 
123+       } 
124+     } 
125+     return  result ; 
126+   } 
127+ } 
128+ 
69129class  WPTTest  { 
70130  /** 
71131   * @param  {string } mod 
72132   * @param  {string } filename 
73-    * @param  {string[] } requires 
74-    * @param  {string | undefined } failReason 
75-    * @param  {string | undefined } skipReason 
133+    * @param  {StatusRule[] } rules 
76134   */ 
77-   constructor ( mod ,  filename ,  requires ,   failReason ,   skipReason )  { 
135+   constructor ( mod ,  filename ,  rules )  { 
78136    this . module  =  mod ;  // name of the WPT module, e.g. 'url' 
79137    this . filename  =  filename ;   // name of the test file 
80-     this . requires  =  requires ; 
81-     this . failReason  =  failReason ; 
82-     this . skipReason  =  skipReason ; 
138+ 
139+     this . requires  =  new  Set ( ) ; 
140+     this . failReasons  =  [ ] ; 
141+     this . skipReasons  =  [ ] ; 
142+     for  ( const  item  of  rules )  { 
143+       if  ( item . requires . length )  { 
144+         for  ( const  req  of  item . requires )  { 
145+           this . requires . add ( req ) ; 
146+         } 
147+       } 
148+       if  ( item . fail )  { 
149+         this . failReasons . push ( item . fail ) ; 
150+       } 
151+       if  ( item . skip )  { 
152+         this . skipReasons . push ( item . skip ) ; 
153+       } 
154+     } 
83155  } 
84156
85157  getAbsolutePath ( )  { 
@@ -90,54 +162,37 @@ class WPTTest {
90162    return  fs . readFileSync ( this . getAbsolutePath ( ) ,  'utf8' ) ; 
91163  } 
92164
93-   shouldSkip ( )  { 
94-     return  this . failReason  ||  this . skipReason ; 
95-   } 
96- 
97165  requireIntl ( )  { 
98-     return  this . requires . includes ( 'intl' ) ; 
166+     return  this . requires . has ( 'intl' ) ; 
99167  } 
100168} 
101169
102170class  StatusLoader  { 
103171  constructor ( path )  { 
104172    this . path  =  path ; 
105173    this . loaded  =  false ; 
106-     this . status  =  null ; 
174+     this . rules  =  new   StatusRuleSet ( ) ; 
107175    /** @type  {WPTTest[] } */ 
108176    this . tests  =  [ ] ; 
109177  } 
110178
111-   loadTest ( file )  { 
112-     let  requires  =  [ ] ; 
113-     let  failReason ; 
114-     let  skipReason ; 
115-     if  ( this . status [ file ] )  { 
116-       requires  =  this . status [ file ] . requires  ||  [ ] ; 
117-       failReason  =  this . status [ file ] . fail ; 
118-       skipReason  =  this . status [ file ] . skip ; 
119-     } 
120-     return  new  WPTTest ( this . path ,  file ,  requires , 
121-                        failReason ,  skipReason ) ; 
122-   } 
123- 
124179  load ( )  { 
125180    const  dir  =  path . join ( __dirname ,  '..' ,  'wpt' ) ; 
126181    const  statusFile  =  path . join ( dir ,  'status' ,  `${ this . path }  .json` ) ; 
127182    const  result  =  JSON . parse ( fs . readFileSync ( statusFile ,  'utf8' ) ) ; 
128-     this . status   =   result ; 
183+     this . rules . addRules ( result ) ; 
129184
130185    const  list  =  fs . readdirSync ( fixtures . path ( 'wpt' ,  this . path ) ) ; 
131186
132187    for  ( const  file  of  list )  { 
133-       this . tests . push ( this . loadTest ( file ) ) ; 
188+       if  ( ! ( / \. \w + \. j s $ / . test ( file ) ) )  { 
189+         continue ; 
190+       } 
191+       const  match  =  this . rules . match ( file ) ; 
192+       this . tests . push ( new  WPTTest ( this . path ,  file ,  match ) ) ; 
134193    } 
135194    this . loaded  =  true ; 
136195  } 
137- 
138-   get  jsTests ( )  { 
139-     return  this . tests . filter ( ( test )  =>  test . filename . endsWith ( '.js' ) ) ; 
140-   } 
141196} 
142197
143198const  PASSED  =  1 ; 
@@ -156,7 +211,7 @@ class WPTRunner {
156211    this . status  =  new  StatusLoader ( path ) ; 
157212    this . status . load ( ) ; 
158213    this . tests  =  new  Map ( 
159-       this . status . jsTests . map ( ( item )  =>  [ item . filename ,  item ] ) 
214+       this . status . tests . map ( ( item )  =>  [ item . filename ,  item ] ) 
160215    ) ; 
161216
162217    this . results  =  new  Map ( ) ; 
@@ -171,7 +226,10 @@ class WPTRunner {
171226   */ 
172227  copyGlobalsFromObject ( obj ,  names )  { 
173228    for  ( const  name  of  names )  { 
174-       const  desc  =  Object . getOwnPropertyDescriptor ( global ,  name ) ; 
229+       const  desc  =  Object . getOwnPropertyDescriptor ( obj ,  name ) ; 
230+       if  ( ! desc )  { 
231+         assert . fail ( `${ name }   does not exist on the object` ) ; 
232+       } 
175233      this . globals . set ( name ,  desc ) ; 
176234    } 
177235  } 
@@ -328,8 +386,9 @@ class WPTRunner {
328386      for  ( const  item  of  items )  { 
329387        switch  ( item . type )  { 
330388          case  FAILED : { 
331-             if  ( test . failReason )  { 
389+             if  ( test . failReasons . length )  { 
332390              console . log ( `[EXPECTED_FAILURE] ${ item . test . name }  ` ) ; 
391+               console . log ( test . failReasons . join ( '; ' ) ) ; 
333392            }  else  { 
334393              console . log ( `[UNEXPECTED_FAILURE] ${ item . test . name }  ` ) ; 
335394              unexpectedFailures . push ( [ title ,  filename ,  item ] ) ; 
@@ -386,10 +445,10 @@ class WPTRunner {
386445    } ) ; 
387446  } 
388447
389-   skip ( filename ,  reason )  { 
448+   skip ( filename ,  reasons )  { 
390449    this . addResult ( filename ,  { 
391450      type : SKIPPED , 
392-       reason
451+       reason :  reasons . join ( '; ' ) 
393452    } ) ; 
394453  } 
395454
@@ -435,13 +494,13 @@ class WPTRunner {
435494    const  queue  =  [ ] ; 
436495    for  ( const  test  of  this . tests . values ( ) )  { 
437496      const  filename  =  test . filename ; 
438-       if  ( test . skipReason )  { 
439-         this . skip ( filename ,  test . skipReason ) ; 
497+       if  ( test . skipReasons . length   >   0 )  { 
498+         this . skip ( filename ,  test . skipReasons ) ; 
440499        continue ; 
441500      } 
442501
443502      if  ( ! common . hasIntl  &&  test . requireIntl ( ) )  { 
444-         this . skip ( filename ,  'missing Intl' ) ; 
503+         this . skip ( filename ,  [   'missing Intl'   ] ) ; 
445504        continue ; 
446505      } 
447506
0 commit comments