@@ -391,6 +391,40 @@ func TestParseSelector(t *testing.T) {
391391 formatted : path .Join ("linux(+erofs+unsorted)" , defaultArch , defaultVariant ),
392392 useV2Format : true ,
393393 },
394+ {
395+ input : "windows(10.0.17763%2Bbuild.42)" ,
396+ expected : specs.Platform {
397+ OS : "windows" ,
398+ OSVersion : "10.0.17763+build.42" ,
399+ Architecture : defaultArch ,
400+ Variant : defaultVariant ,
401+ },
402+ formatted : path .Join ("windows(10.0.17763%2Bbuild.42)" , defaultArch , defaultVariant ),
403+ useV2Format : true ,
404+ },
405+ {
406+ input : "windows(10.0.17763%2Bbuild.42+win32k)" ,
407+ expected : specs.Platform {
408+ OS : "windows" ,
409+ OSVersion : "10.0.17763+build.42" ,
410+ OSFeatures : []string {"win32k" },
411+ Architecture : defaultArch ,
412+ Variant : defaultVariant ,
413+ },
414+ formatted : path .Join ("windows(10.0.17763%2Bbuild.42+win32k)" , defaultArch , defaultVariant ),
415+ useV2Format : true ,
416+ },
417+ {
418+ input : "windows(50%25done)" ,
419+ expected : specs.Platform {
420+ OS : "windows" ,
421+ OSVersion : "50%done" ,
422+ Architecture : defaultArch ,
423+ Variant : defaultVariant ,
424+ },
425+ formatted : path .Join ("windows(50%25done)" , defaultArch , defaultVariant ),
426+ useV2Format : true ,
427+ },
394428 } {
395429 t .Run (testcase .input , func (t * testing.T ) {
396430 if testcase .skip {
@@ -446,6 +480,73 @@ func TestParseSelector(t *testing.T) {
446480 }
447481}
448482
483+ func TestFormatAllEncoding (t * testing.T ) {
484+ for _ , testcase := range []struct {
485+ platform specs.Platform
486+ expected string
487+ }{
488+ {
489+ platform : specs.Platform {OS : "windows" , OSVersion : "10.0.17763+build.42" , Architecture : "amd64" },
490+ expected : "windows(10.0.17763%2Bbuild.42)/amd64" ,
491+ },
492+ {
493+ platform : specs.Platform {OS : "windows" , OSVersion : "10.0.17763+build.42" , OSFeatures : []string {"win32k" }, Architecture : "amd64" },
494+ expected : "windows(10.0.17763%2Bbuild.42+win32k)/amd64" ,
495+ },
496+ {
497+ platform : specs.Platform {OS : "windows" , OSVersion : "50%done" , Architecture : "amd64" },
498+ expected : "windows(50%25done)/amd64" ,
499+ },
500+ {
501+ platform : specs.Platform {OS : "windows" , OSVersion : "1.0(beta)" , Architecture : "amd64" },
502+ expected : "windows(1.0%28beta%29)/amd64" ,
503+ },
504+ {
505+ platform : specs.Platform {OS : "windows" , OSVersion : "a/b" , Architecture : "amd64" },
506+ expected : "windows(a%2Fb)/amd64" ,
507+ },
508+ {
509+ // no special characters, no encoding needed
510+ platform : specs.Platform {OS : "windows" , OSVersion : "10.0.17763" , Architecture : "amd64" },
511+ expected : "windows(10.0.17763)/amd64" ,
512+ },
513+ {
514+ // feature with + in the name
515+ platform : specs.Platform {OS : "linux" , OSFeatures : []string {"feat+v2" }, Architecture : "amd64" },
516+ expected : "linux(+feat%2Bv2)/amd64" ,
517+ },
518+ {
519+ // feature with % in the name
520+ platform : specs.Platform {OS : "linux" , OSFeatures : []string {"100%gpu" }, Architecture : "amd64" },
521+ expected : "linux(+100%25gpu)/amd64" ,
522+ },
523+ {
524+ // version and feature both with special characters
525+ platform : specs.Platform {OS : "windows" , OSVersion : "10.0+build" , OSFeatures : []string {"feat+1" }, Architecture : "amd64" },
526+ expected : "windows(10.0%2Bbuild+feat%2B1)/amd64" ,
527+ },
528+ } {
529+ t .Run (testcase .expected , func (t * testing.T ) {
530+ formatted := FormatAll (testcase .platform )
531+ if formatted != testcase .expected {
532+ t .Fatalf ("unexpected format: %q != %q" , formatted , testcase .expected )
533+ }
534+
535+ // verify round-trip
536+ reparsed , err := Parse (formatted )
537+ if err != nil {
538+ t .Fatalf ("error parsing formatted output: %v" , err )
539+ }
540+ if reparsed .OSVersion != testcase .platform .OSVersion {
541+ t .Fatalf ("OSVersion did not survive round trip: %q != %q" , reparsed .OSVersion , testcase .platform .OSVersion )
542+ }
543+ if ! reflect .DeepEqual (reparsed .OSFeatures , testcase .platform .OSFeatures ) {
544+ t .Fatalf ("OSFeatures did not survive round trip: %v != %v" , reparsed .OSFeatures , testcase .platform .OSFeatures )
545+ }
546+ })
547+ }
548+ }
549+
449550func TestParseSelectorInvalid (t * testing.T ) {
450551 for _ , testcase := range []struct {
451552 input string
0 commit comments