@@ -20,17 +20,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2020SOFTWARE.
2121*/
2222
23- import path from 'node:path'
24-
25- import { glob } from 'fast-glob'
2623import { describe , expect , it } from 'vitest'
2724
28- import { readJson } from '@socketsecurity/registry/lib/fs'
29- import {
30- isObject ,
31- toSortedObjectFromEntries ,
32- } from '@socketsecurity/registry/lib/objects'
33-
3425import {
3526 testInvalidParam ,
3627 testInvalidStringParam ,
@@ -90,17 +81,6 @@ function getNpmId(purl: any) {
9081 return `${ namespace ?. length > 0 ? `${ namespace } /` : '' } ${ name } `
9182}
9283
93- function toUrlSearchParams ( search : any ) {
94- const searchParams = new URLSearchParams ( )
95- const entries = search . split ( '&' )
96- for ( let i = 0 , { length } = entries ; i < length ; i += 1 ) {
97- const pairs = entries [ i ] . split ( '=' )
98- const value = decodeURIComponent ( pairs . at ( 1 ) ?? '' )
99- searchParams . append ( pairs [ 0 ] , value )
100- }
101- return searchParams
102- }
103-
10484describe ( 'PackageURL' , ( ) => {
10585 describe ( 'KnownQualifierNames' , ( ) => {
10686 it . each ( [
@@ -538,165 +518,6 @@ describe('PackageURL', () => {
538518 } )
539519 } )
540520
541- describe ( 'test-suite-data' , async ( ) => {
542- // Tests from the official purl-spec test suite (data/*.json files)
543- const TEST_FILES = (
544- await Promise . all (
545- (
546- await glob ( [ '**/**.json' ] , {
547- absolute : true ,
548- cwd : path . join ( __dirname , 'data' ) ,
549- } )
550- ) . map ( p => readJson ( p ) ) ,
551- )
552- )
553- . filter ( Boolean )
554- . flatMap ( ( o : any ) => o . tests ?? [ ] )
555-
556- for ( const obj of TEST_FILES ) {
557- const { expected_failure, expected_output, test_type } = obj
558-
559- const inputObj = isObject ( obj . input ) ? obj . input : undefined
560-
561- const inputStr = typeof obj . input === 'string' ? obj . input : undefined
562-
563- if ( ! inputObj && ! inputStr ) {
564- continue
565- }
566-
567- const expectedObj = isObject ( expected_output )
568- ? expected_output
569- : undefined
570-
571- const expectedStr =
572- typeof expected_output === 'string' ? expected_output : undefined
573-
574- if ( ! expectedObj && ! expectedStr ) {
575- continue
576- }
577-
578- describe ( obj . description , ( ) => {
579- if ( expected_failure ) {
580- if ( test_type === 'parse' && inputStr ) {
581- // Tests expected parse failures from test suite
582- it ( `should not be possible to parse invalid ${ expectedObj ?. type ?? 'type' } PackageURLs` , ( ) => {
583- expect ( ( ) => PackageURL . fromString ( inputStr ) ) . toThrow (
584- / m i s s i n g t h e r e q u i r e d | I n v a l i d p u r l / ,
585- )
586- } )
587- }
588- if ( test_type === 'build' && inputObj ) {
589- // Tests expected constructor failures from test suite
590- it ( `should not be possible to create invalid ${ inputObj . type ?? 'type' } PackageURLs` , ( ) => {
591- expect (
592- ( ) =>
593- new PackageURL (
594- inputObj . type ,
595- inputObj . namespace ,
596- inputObj . name ,
597- inputObj . version ,
598- inputObj . qualifiers ,
599- inputObj . subpath ,
600- ) ,
601- ) . toThrow ( / i s a r e q u i r e d | I n v a l i d p u r l / )
602- } )
603- }
604- } else if ( test_type === 'parse' && inputStr && expectedObj ) {
605- // Tests successful parsing from test suite
606- it ( `should be able to parse valid ${ expectedObj . type ?? 'type' } PackageURLs` , ( ) => {
607- const purl = PackageURL . fromString ( inputStr )
608- expect ( purl . type ) . toBe ( expectedObj . type )
609- expect ( purl . name ) . toBe ( expectedObj . name )
610- expect ( purl . namespace ) . toBe ( expectedObj . namespace ?? undefined )
611- expect ( purl . version ) . toBe ( expectedObj . version ?? undefined )
612- expect ( purl . qualifiers ) . toStrictEqual (
613- expectedObj . qualifiers
614- ? { __proto__ : null , ...expectedObj . qualifiers }
615- : undefined ,
616- )
617- expect ( purl . subpath ) . toBe ( expectedObj . subpath ?? undefined )
618- } )
619- } else if ( test_type === 'build' && inputObj && expectedStr ) {
620- // Tests toString() output from test suite
621- it ( `should be able to convert valid ${ inputObj . type ?? 'type' } PackageURLs to a string` , ( ) => {
622- const purl = new PackageURL (
623- inputObj . type ,
624- inputObj . namespace ,
625- inputObj . name ,
626- inputObj . version ,
627- inputObj . qualifiers ,
628- inputObj . subpath ,
629- )
630- const purlToStr = purl . toString ( )
631- if ( purl . qualifiers ) {
632- const markIndex = expectedStr . indexOf ( '?' )
633- const beforeMarkToStr = purlToStr . slice ( 0 , markIndex )
634- const beforeExpectedStr = expectedStr . slice ( 0 , markIndex )
635- expect ( beforeMarkToStr ) . toBe ( beforeExpectedStr )
636-
637- const afterMarkToStr = purlToStr . slice ( markIndex + 1 )
638- const afterExpectedStr = expectedStr . slice ( markIndex + 1 )
639- const actualParams = toSortedObjectFromEntries (
640- toUrlSearchParams ( afterMarkToStr ) . entries ( ) ,
641- )
642- const expectedParams = toSortedObjectFromEntries (
643- toUrlSearchParams ( afterExpectedStr ) . entries ( ) ,
644- )
645- expect ( actualParams ) . toStrictEqual ( expectedParams )
646- } else {
647- expect ( purlToStr ) . toBe ( expectedStr )
648- }
649- } )
650- } else if ( test_type === 'roundtrip' && inputStr && expectedStr ) {
651- it ( `should roundtrip ${ expectedStr . split ( '/' ) [ 1 ] ?. split ( '@' ) [ 0 ] ?? 'purl' } ` , ( ) => {
652- const purl = PackageURL . fromString ( inputStr )
653- const purlToStr = purl . toString ( )
654-
655- // Special case: The test suite has a known issue where it expects
656- // unencoded + in subpaths for roundtrip, but that's not correct.
657- // We normalize to the canonical form with %2B per URL encoding rules.
658- let normalizedExpected = expectedStr
659- if (
660- expectedStr . includes ( '#' ) &&
661- expectedStr . includes ( '+' ) &&
662- inputStr === 'pkg:cocoapods/[email protected] #NSData+zlib' 663- ) {
664- normalizedExpected = expectedStr . replace (
665- '#NSData+zlib' ,
666- '#NSData%2Bzlib' ,
667- )
668- }
669-
670- if ( purl . qualifiers ) {
671- const markIndex = normalizedExpected . indexOf ( '?' )
672- const beforeMarkToStr = purlToStr . slice ( 0 , markIndex )
673- const beforeExpectedStr = normalizedExpected . slice ( 0 , markIndex )
674- expect ( beforeMarkToStr ) . toBe ( beforeExpectedStr )
675-
676- const afterMarkToStr = purlToStr . slice ( markIndex + 1 )
677- const afterExpectedStr = normalizedExpected . slice ( markIndex + 1 )
678- const actualParams = toSortedObjectFromEntries (
679- toUrlSearchParams ( afterMarkToStr ) . entries ( ) ,
680- )
681- const expectedParams = toSortedObjectFromEntries (
682- toUrlSearchParams ( afterExpectedStr ) . entries ( ) ,
683- )
684- expect ( actualParams ) . toStrictEqual ( expectedParams )
685- } else {
686- expect ( purlToStr ) . toBe ( normalizedExpected )
687- }
688- } )
689- } else {
690- it ( `should handle test case: ${ test_type } ` , ( ) => {
691- throw new Error (
692- `Unhandled test case: test_type=${ test_type } , has inputStr=${ ! ! inputStr } , has inputObj=${ ! ! inputObj } , has expectedStr=${ ! ! expectedStr } , has expectedObj=${ ! ! expectedObj } , expected_failure=${ expected_failure } ` ,
693- )
694- } )
695- }
696- } )
697- }
698- } )
699-
700521 describe ( 'npm' , ( ) => {
701522 it ( "should allow legacy names to be mixed case, match a builtin, or contain ~'!()* characters" , ( ) => {
702523 // Tests npm legacy package exceptions (historical packages with special names)
0 commit comments