@@ -891,4 +891,242 @@ describe('processBackgroundImage', () => {
891891 { color : processColor ( 'blue' ) , position : 40 } ,
892892 ] ) ;
893893 } ) ;
894+
895+ it ( 'should process radial gradient object syntax' , ( ) => {
896+ const input = [
897+ {
898+ type : 'radialGradient' ,
899+ shape : 'circle' ,
900+ colorStops : [
901+ { color : 'red' , positions : [ '10%' , 20 ] } ,
902+ { color : 'blue' , positions : [ '30%' , 40 ] } ,
903+ ] ,
904+ position : { top : '50%' , left : '50%' } ,
905+ size : 'closest-side' ,
906+ } ,
907+ {
908+ type : 'radialGradient' ,
909+ shape : 'circle' ,
910+ colorStops : [
911+ { color : 'red' , positions : [ '10%' , 20 ] } ,
912+ { color : 'blue' , positions : [ '30%' , 40 ] } ,
913+ ] ,
914+ position : { top : '50%' , left : 50 } ,
915+ size : {
916+ x : 100 ,
917+ y : 100 ,
918+ } ,
919+ } ,
920+ ] ;
921+ const result = processBackgroundImage ( input ) ;
922+ expect ( result [ 0 ] . colorStops ) . toEqual ( [
923+ { color : processColor ( 'red' ) , position : '10%' } ,
924+ { color : processColor ( 'red' ) , position : 20 } ,
925+ { color : processColor ( 'blue' ) , position : '30%' } ,
926+ { color : processColor ( 'blue' ) , position : 40 } ,
927+ ] ) ;
928+ expect ( result [ 0 ] . position ) . toEqual ( { top : '50%' , left : '50%' } ) ;
929+ expect ( result [ 0 ] . size ) . toEqual ( 'closest-side' ) ;
930+ expect ( result [ 0 ] . shape ) . toEqual ( 'circle' ) ;
931+ expect ( result [ 0 ] . type ) . toEqual ( 'radialGradient' ) ;
932+
933+ expect ( result [ 1 ] . size ) . toEqual ( {
934+ x : 100 ,
935+ y : 100 ,
936+ } ) ;
937+ } ) ;
938+
939+ it ( 'should process radial gradient without shape, size and position' , ( ) => {
940+ const input = 'radial-gradient(red, blue)' ;
941+ const result = processBackgroundImage ( input ) ;
942+ expect ( result [ 0 ] . colorStops ) . toEqual ( [
943+ { color : processColor ( 'red' ) , position : null } ,
944+ { color : processColor ( 'blue' ) , position : null } ,
945+ ] ) ;
946+ expect ( result [ 0 ] . position ) . toEqual ( { top : '50%' , left : '50%' } ) ;
947+ expect ( result [ 0 ] . size ) . toEqual ( 'farthest-corner' ) ;
948+ expect ( result [ 0 ] . shape ) . toEqual ( 'ellipse' ) ;
949+ expect ( result [ 0 ] . type ) . toEqual ( 'radialGradient' ) ;
950+ } ) ;
951+
952+ it ( 'should process radial gradient with shape circle' , ( ) => {
953+ const input = 'radial-gradient(circle, red, blue)' ;
954+ const result = processBackgroundImage ( input ) ;
955+ expect ( result [ 0 ] . colorStops ) . toEqual ( [
956+ { color : processColor ( 'red' ) , position : null } ,
957+ { color : processColor ( 'blue' ) , position : null } ,
958+ ] ) ;
959+ expect ( result [ 0 ] . position ) . toEqual ( { top : '50%' , left : '50%' } ) ;
960+ expect ( result [ 0 ] . size ) . toEqual ( 'farthest-corner' ) ;
961+ expect ( result [ 0 ] . shape ) . toEqual ( 'circle' ) ;
962+ expect ( result [ 0 ] . type ) . toEqual ( 'radialGradient' ) ;
963+ } ) ;
964+
965+ it ( 'should infer radial gradient circle shape from single length' , ( ) => {
966+ const input = 'radial-gradient(100px, red, blue)' ;
967+ const result = processBackgroundImage ( input ) ;
968+ expect ( result [ 0 ] . size ) . toEqual ( { x : 100 , y : 100 } ) ;
969+ expect ( result [ 0 ] . shape ) . toEqual ( 'circle' ) ;
970+ } ) ;
971+
972+ it ( 'should infer radial gradient ellipse shape from double length' , ( ) => {
973+ const input = 'radial-gradient(100px 50px, red, blue)' ;
974+ const result = processBackgroundImage ( input ) ;
975+ expect ( result [ 0 ] . size ) . toEqual ( { x : 100 , y : 50 } ) ;
976+ expect ( result [ 0 ] . shape ) . toEqual ( 'ellipse' ) ;
977+ } ) ;
978+
979+ it ( 'should handle radial gradient with explicit shape with size' , ( ) => {
980+ const input = 'radial-gradient(circle 100px at center, red, blue 80%)' ;
981+ const result = processBackgroundImage ( input ) ;
982+ expect ( result [ 0 ] . colorStops ) . toEqual ( [
983+ { color : processColor ( 'red' ) , position : null } ,
984+ { color : processColor ( 'blue' ) , position : '80%' } ,
985+ ] ) ;
986+ expect ( result [ 0 ] . position ) . toEqual ( { top : '50%' , left : '50%' } ) ;
987+ expect ( result [ 0 ] . size ) . toEqual ( { x : 100 , y : 100 } ) ;
988+ expect ( result [ 0 ] . shape ) . toEqual ( 'circle' ) ;
989+ expect ( result [ 0 ] . type ) . toEqual ( 'radialGradient' ) ;
990+ } ) ;
991+
992+ // 1. position syntax: [ left | center | right | top | bottom | <length-percentage> ]
993+ it ( 'should handle radial gradient position length syntax' , ( ) => {
994+ const input = 'radial-gradient(circle at 20px, red, blue)' ;
995+ const result = processBackgroundImage ( input ) ;
996+ expect ( result [ 0 ] . position ) . toEqual ( { left : 20 , top : '50%' } ) ;
997+ } ) ;
998+
999+ // 2. position syntax: [ left | center | right ] && [ top | center | bottom ]
1000+ it ( 'should handle radial gradient position keywords syntax' , ( ) => {
1001+ const input = 'radial-gradient(circle at left top, red, blue)' ;
1002+ const input1 = 'radial-gradient(circle at top left, red, blue)' ;
1003+ const result = processBackgroundImage ( input ) ;
1004+ const result1 = processBackgroundImage ( input1 ) ;
1005+ expect ( result [ 0 ] . position ) . toEqual ( { left : '0%' , top : '0%' } ) ;
1006+ expect ( result1 [ 0 ] . position ) . toEqual ( { left : '0%' , top : '0%' } ) ;
1007+ } ) ;
1008+
1009+ // 3. position syntax: [ left | center | right | <length-percentage> ] [ top | center | bottom | <length-percentage> ]
1010+ it ( 'should handle left position top position syntax' , ( ) => {
1011+ const input = 'radial-gradient(circle at left 20px, red, blue)' ;
1012+ const input1 = 'radial-gradient(circle at 20px 20px, red, blue)' ;
1013+ const input2 = 'radial-gradient(circle at right 50px, red, blue)' ;
1014+ const result = processBackgroundImage ( input ) ;
1015+ const result1 = processBackgroundImage ( input1 ) ;
1016+ const result2 = processBackgroundImage ( input2 ) ;
1017+ expect ( result [ 0 ] . position ) . toEqual ( { left : '0%' , top : 20 } ) ;
1018+ expect ( result1 [ 0 ] . position ) . toEqual ( { left : 20 , top : 20 } ) ;
1019+ expect ( result2 [ 0 ] . position ) . toEqual ( { left : '100%' , top : 50 } ) ;
1020+ } ) ;
1021+
1022+ // 4. position syntax: [ [ left | right ] <length-percentage> ] && [ [ top | bottom ] <length-percentage> ]
1023+ it ( 'should handle left position top position syntax' , ( ) => {
1024+ const input = 'radial-gradient(at top 0% right 10%, red, blue)' ;
1025+ const result = processBackgroundImage ( input ) ;
1026+ expect ( result [ 0 ] . position ) . toEqual ( { right : '10%' , top : '0%' } ) ;
1027+ } ) ;
1028+
1029+ it ( 'should handle color stops with transition hints in radial gradients' , ( ) => {
1030+ const input =
1031+ 'radial-gradient(circle, red 0%, 25%, blue 50%, 75%, green 100%)' ;
1032+ const result = processBackgroundImage ( input ) ;
1033+ expect ( result [ 0 ] . colorStops ) . toEqual ( [
1034+ { color : processColor ( 'red' ) , position : '0%' } ,
1035+ { color : null , position : '25%' } ,
1036+ { color : processColor ( 'blue' ) , position : '50%' } ,
1037+ { color : null , position : '75%' } ,
1038+ { color : processColor ( 'green' ) , position : '100%' } ,
1039+ ] ) ;
1040+ expect ( result [ 0 ] . shape ) . toEqual ( 'circle' ) ;
1041+ expect ( result [ 0 ] . type ) . toEqual ( 'radialGradient' ) ;
1042+ } ) ;
1043+
1044+ it ( 'should process multiple gradients with both radial and linear' , ( ) => {
1045+ const input = `
1046+ radial-gradient(circle at top left, red, blue),
1047+ linear-gradient(to bottom, green, yellow)
1048+ ` ;
1049+ const result = processBackgroundImage ( input ) ;
1050+ expect ( result ) . toHaveLength ( 2 ) ;
1051+ expect ( result [ 0 ] . type ) . toEqual ( 'radialGradient' ) ;
1052+ expect ( result [ 0 ] . shape ) . toEqual ( 'circle' ) ;
1053+ expect ( result [ 0 ] . position ) . toEqual ( { top : '0%' , left : '0%' } ) ;
1054+ expect ( result [ 0 ] . colorStops ) . toEqual ( [
1055+ { color : processColor ( 'red' ) , position : null } ,
1056+ { color : processColor ( 'blue' ) , position : null } ,
1057+ ] ) ;
1058+ expect ( result [ 1 ] . type ) . toEqual ( 'linearGradient' ) ;
1059+ expect ( result [ 1 ] . direction ) . toEqual ( {
1060+ type : 'angle' ,
1061+ value : 180 ,
1062+ } ) ;
1063+ expect ( result [ 1 ] . colorStops ) . toEqual ( [
1064+ { color : processColor ( 'green' ) , position : null } ,
1065+ { color : processColor ( 'yellow' ) , position : null } ,
1066+ ] ) ;
1067+ } ) ;
1068+
1069+ it ( 'should handle mixed case in radial gradient syntax' , ( ) => {
1070+ const input = 'RaDiAl-GrAdIeNt(CiRcLe ClOsEsT-sIdE aT cEnTeR, rEd, bLuE)' ;
1071+ const result = processBackgroundImage ( input ) ;
1072+ expect ( result [ 0 ] . colorStops ) . toEqual ( [
1073+ { color : processColor ( 'red' ) , position : null } ,
1074+ { color : processColor ( 'blue' ) , position : null } ,
1075+ ] ) ;
1076+ expect ( result [ 0 ] . position ) . toEqual ( { top : '50%' , left : '50%' } ) ;
1077+ expect ( result [ 0 ] . size ) . toEqual ( 'closest-side' ) ;
1078+ expect ( result [ 0 ] . shape ) . toEqual ( 'circle' ) ;
1079+ expect ( result [ 0 ] . type ) . toEqual ( 'radialGradient' ) ;
1080+ } ) ;
1081+
1082+ it ( 'should handle whitespace variations in radial gradients' , ( ) => {
1083+ const input =
1084+ 'radial-gradient( circle farthest-corner at 25% 75% , red 0% , blue 100% )' ;
1085+ const result = processBackgroundImage ( input ) ;
1086+ expect ( result [ 0 ] . colorStops ) . toEqual ( [
1087+ { color : processColor ( 'red' ) , position : '0%' } ,
1088+ { color : processColor ( 'blue' ) , position : '100%' } ,
1089+ ] ) ;
1090+ expect ( result [ 0 ] . position ) . toEqual ( { left : '25%' , top : '75%' } ) ;
1091+ expect ( result [ 0 ] . size ) . toEqual ( 'farthest-corner' ) ;
1092+ expect ( result [ 0 ] . shape ) . toEqual ( 'circle' ) ;
1093+ expect ( result [ 0 ] . type ) . toEqual ( 'radialGradient' ) ;
1094+ } ) ;
1095+
1096+ it ( 'should handle position keywords in different orders' , ( ) => {
1097+ const input1 = 'radial-gradient(circle at top left, red, blue)' ;
1098+ const input2 = 'radial-gradient(circle at left top, red, blue)' ;
1099+ const result1 = processBackgroundImage ( input1 ) ;
1100+ const result2 = processBackgroundImage ( input2 ) ;
1101+
1102+ expect ( result1 [ 0 ] . position ) . toEqual ( { top : '0%' , left : '0%' } ) ;
1103+ expect ( result2 [ 0 ] . position ) . toEqual ( { top : '0%' , left : '0%' } ) ;
1104+ } ) ;
1105+
1106+ it ( 'should handle invalid radial gradient syntax' , ( ) => {
1107+ const input = 'radial-gradient(circle at top leftt, red, blue, green)' ;
1108+ const input1 = 'radial-gradient(circle at, red, blue, green)' ;
1109+ const input2 = 'radial-gradient(ellipse 100px, red, blue, green)' ;
1110+ const input3 =
1111+ 'radial-gradient(ellipse at top 20% top 50%, red, blue, green)' ;
1112+ const result = processBackgroundImage ( input ) ;
1113+ const result1 = processBackgroundImage ( input1 ) ;
1114+ const result2 = processBackgroundImage ( input2 ) ;
1115+ const result3 = processBackgroundImage ( input3 ) ;
1116+ expect ( result ) . toEqual ( [ ] ) ;
1117+ expect ( result1 ) . toEqual ( [ ] ) ;
1118+ expect ( result2 ) . toEqual ( [ ] ) ;
1119+ expect ( result3 ) . toEqual ( [ ] ) ;
1120+ } ) ;
1121+
1122+ it ( 'should handle multiple color stops with radial gradient syntax' , ( ) => {
1123+ const input = 'radial-gradient(red 0%, yellow 30%, green 60%, blue 100%)' ;
1124+ const result = processBackgroundImage ( input ) ;
1125+ expect ( result [ 0 ] . colorStops ) . toEqual ( [
1126+ { color : processColor ( 'red' ) , position : '0%' } ,
1127+ { color : processColor ( 'yellow' ) , position : '30%' } ,
1128+ { color : processColor ( 'green' ) , position : '60%' } ,
1129+ { color : processColor ( 'blue' ) , position : '100%' } ,
1130+ ] ) ;
1131+ } ) ;
8941132} ) ;
0 commit comments