11import { describe , it , expect } from 'vitest'
22import { parse } from './parse'
3- import { IDENTIFIER , NUMBER , DIMENSION , STRING , HASH , FUNCTION , OPERATOR , PARENTHESIS , URL , UNICODE_RANGE , VALUE } from './arena'
3+ import {
4+ IDENTIFIER ,
5+ NUMBER ,
6+ DIMENSION ,
7+ STRING ,
8+ HASH ,
9+ FUNCTION ,
10+ OPERATOR ,
11+ PARENTHESIS ,
12+ URL ,
13+ UNICODE_RANGE ,
14+ VALUE ,
15+ DECLARATION ,
16+ } from './arena'
417
518describe ( 'Value Node Types' , ( ) => {
619 // Helper to get first value node from a declaration
@@ -607,48 +620,48 @@ describe('Value Node Types', () => {
607620 } )
608621
609622 describe ( 'OPERATOR' , ( ) => {
610- it ( 'should parse comma operator' , ( ) => {
611- const root = parse ( 'body { font-family: Arial, sans-serif; }' )
612- const decl = root . first_child ?. first_child ?. next_sibling ?. first_child
623+ it ( 'should parse comma operator' , ( ) => {
624+ const root = parse ( 'body { font-family: Arial, sans-serif; }' )
625+ const decl = root . first_child ?. first_child ?. next_sibling ?. first_child
613626
614- expect ( decl ?. first_child ! . children [ 1 ] . type ) . toBe ( OPERATOR )
615- expect ( decl ?. first_child ! . children [ 1 ] . text ) . toBe ( ',' )
616- expect ( decl ?. first_child ! . children [ 1 ] . name ) . toBe ( undefined )
617- expect ( decl ?. first_child ! . children [ 1 ] . value ) . toBe ( ',' )
618- } )
627+ expect ( decl ?. first_child ! . children [ 1 ] . type ) . toBe ( OPERATOR )
628+ expect ( decl ?. first_child ! . children [ 1 ] . text ) . toBe ( ',' )
629+ expect ( decl ?. first_child ! . children [ 1 ] . name ) . toBe ( undefined )
630+ expect ( decl ?. first_child ! . children [ 1 ] . value ) . toBe ( ',' )
631+ } )
619632
620- it ( 'should parse calc operators' , ( ) => {
621- const root = parse ( 'body { width: calc(100% - 20px); }' )
622- const decl = root . first_child ?. first_child ?. next_sibling ?. first_child
623- const func = decl ?. first_child ! . children [ 0 ]
633+ it ( 'should parse calc operators' , ( ) => {
634+ const root = parse ( 'body { width: calc(100% - 20px); }' )
635+ const decl = root . first_child ?. first_child ?. next_sibling ?. first_child
636+ const func = decl ?. first_child ! . children [ 0 ]
624637
625- expect ( func ?. children [ 1 ] . type ) . toBe ( OPERATOR )
626- expect ( func ?. children [ 1 ] . text ) . toBe ( '-' )
627- expect ( func ?. children [ 1 ] . name ) . toBe ( undefined )
628- expect ( func ?. children [ 1 ] . value ) . toBe ( '-' )
629- } )
638+ expect ( func ?. children [ 1 ] . type ) . toBe ( OPERATOR )
639+ expect ( func ?. children [ 1 ] . text ) . toBe ( '-' )
640+ expect ( func ?. children [ 1 ] . name ) . toBe ( undefined )
641+ expect ( func ?. children [ 1 ] . value ) . toBe ( '-' )
642+ } )
630643
631- it ( 'should parse all calc operators' , ( ) => {
632- const root = parse ( 'body { width: calc(1px + 2px * 3px / 4px - 5px); }' )
633- const decl = root . first_child ?. first_child ?. next_sibling ?. first_child
634- const func = decl ?. first_child ! . children [ 0 ]
635-
636- const operators = func ?. children . filter ( ( n ) => n . type === OPERATOR )
637- expect ( operators ) . toHaveLength ( 4 )
638- expect ( operators ?. [ 0 ] . text ) . toBe ( '+' )
639- expect ( operators ?. [ 0 ] . name ) . toBe ( undefined )
640- expect ( operators ?. [ 0 ] . value ) . toBe ( '+' )
641- expect ( operators ?. [ 1 ] . text ) . toBe ( '*' )
642- expect ( operators ?. [ 1 ] . name ) . toBe ( undefined )
643- expect ( operators ?. [ 1 ] . value ) . toBe ( '*' )
644- expect ( operators ?. [ 2 ] . text ) . toBe ( '/' )
645- expect ( operators ?. [ 2 ] . name ) . toBe ( undefined )
646- expect ( operators ?. [ 2 ] . value ) . toBe ( '/' )
647- expect ( operators ?. [ 3 ] . text ) . toBe ( '-' )
648- expect ( operators ?. [ 3 ] . name ) . toBe ( undefined )
649- expect ( operators ?. [ 3 ] . value ) . toBe ( '-' )
644+ it ( 'should parse all calc operators' , ( ) => {
645+ const root = parse ( 'body { width: calc(1px + 2px * 3px / 4px - 5px); }' )
646+ const decl = root . first_child ?. first_child ?. next_sibling ?. first_child
647+ const func = decl ?. first_child ! . children [ 0 ]
648+
649+ const operators = func ?. children . filter ( ( n ) => n . type === OPERATOR )
650+ expect ( operators ) . toHaveLength ( 4 )
651+ expect ( operators ?. [ 0 ] . text ) . toBe ( '+' )
652+ expect ( operators ?. [ 0 ] . name ) . toBe ( undefined )
653+ expect ( operators ?. [ 0 ] . value ) . toBe ( '+' )
654+ expect ( operators ?. [ 1 ] . text ) . toBe ( '*' )
655+ expect ( operators ?. [ 1 ] . name ) . toBe ( undefined )
656+ expect ( operators ?. [ 1 ] . value ) . toBe ( '*' )
657+ expect ( operators ?. [ 2 ] . text ) . toBe ( '/' )
658+ expect ( operators ?. [ 2 ] . name ) . toBe ( undefined )
659+ expect ( operators ?. [ 2 ] . value ) . toBe ( '/' )
660+ expect ( operators ?. [ 3 ] . text ) . toBe ( '-' )
661+ expect ( operators ?. [ 3 ] . name ) . toBe ( undefined )
662+ expect ( operators ?. [ 3 ] . value ) . toBe ( '-' )
663+ } )
650664 } )
651- } )
652665
653666 describe ( 'PARENTHESIS' , ( ) => {
654667 it ( 'should parse parenthesized expressions in calc()' , ( ) => {
@@ -776,15 +789,36 @@ describe('Value Node Types', () => {
776789 expect ( decl ?. first_child ! . children [ 0 ] . value ) . toBe ( "'image.png'" )
777790 } )
778791
779- it ( 'should parse url() with base64 data URL' , ( ) => {
780- const root = parse ( 'body { background: url(data:image/png;base64,iVBORw0KGg); }' )
781- const decl = root . first_child ?. first_child ?. next_sibling ?. first_child
782- const func = decl ?. first_child ! . children [ 0 ]
783-
784- expect ( func ?. type ) . toBe ( URL )
785- expect ( func ?. name ) . toBe ( 'url' )
786- expect ( func ?. has_children ) . toBe ( false )
787- expect ( func ?. value ) . toBe ( 'data:image/png;base64,iVBORw0KGg' )
792+ describe . each ( [
793+ `data:image/png;base64,iVBORw0KGg` ,
794+ `data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgaGVpZ2h0PSIyNHB4IiB3aWR0aD0iMjRweCI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJsaW5lYXItZ3JhZGllbnQiIHgxPSIyMi4zMSIgeTE9IjIzLjYyIiB4Mj0iMy43MyIgeTI9IjMuMDUiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiNlOTM3MjIiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNmODZmMjUiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48dGl0bGU+TWFnbmlmaWVyPC90aXRsZT48cGF0aCBmaWxsPSJ1cmwoI2xpbmVhci1ncmFkaWVudCkiIGQ9Ik0yMy4zMyAyMC4xbC00LjczLTQuNzRhMTAuMDYgMTAuMDYgMCAxIDAtMy4yMyAzLjIzbDQuNzQgNC43NGEyLjI5IDIuMjkgMCAxIDAgMy4yMi0zLjIzem0tMTcuNDgtNS44NGE1Ljk0IDUuOTQgMCAxIDEgOC40MiAwIDYgNiAwIDAgMS04LjQyIDB6Ii8+PC9zdmc+` ,
795+ `'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 24 24"><path fill="rgba(0,0,0,0.5)" d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z"></path></svg>'` ,
796+ ] ) ( 'should parse url() with base64 data URL' , ( input ) => {
797+ test ( `parses value: ${ input . slice ( 0 , 40 ) } ` , ( ) => {
798+ const root = parse ( `body { background: url(${ input } ); }` )
799+ const decl = root . first_child ?. first_child ?. next_sibling ?. first_child
800+ const func = decl ?. first_child ! . children [ 0 ]
801+
802+ expect ( func ?. type ) . toBe ( URL )
803+ expect ( func ?. name ) . toBe ( 'url' )
804+ expect ( func ?. value ) . toBe ( input )
805+ } )
806+
807+ test ( 'does not break parsing declarations coming after' , ( ) => {
808+ const root = parse ( `
809+ body {
810+ background: url(${ input } );
811+ font-size: 1em;
812+ }
813+ ` )
814+ const block = root . first_child ?. first_child ?. next_sibling
815+
816+ expect ( block ?. children . length ) . toBe ( 2 )
817+ const [ with_data_url , declaration ] = block ! . children
818+
819+ expect ( with_data_url . type ) . toBe ( DECLARATION )
820+ expect ( declaration . type ) . toBe ( DECLARATION )
821+ } )
788822 } )
789823
790824 it ( 'should parse url() with inline SVG' , ( ) => {
@@ -801,7 +835,7 @@ describe('Value Node Types', () => {
801835 it ( 'should parse complex background value with url()' , ( ) => {
802836 const root = parse ( 'body { background: url("bg.png") no-repeat center center / cover; }' )
803837 const decl = root . first_child ?. first_child ?. next_sibling ?. first_child
804- expect ( decl ?. first_child ! . children . length ) . toBeGreaterThan ( 1 )
838+ expect ( decl ?. first_child ! . children . length ) . toBeGreaterThan ( 1 )
805839 expect ( decl ?. first_child ! . children [ 0 ] . type ) . toBe ( URL )
806840 expect ( decl ?. first_child ! . children [ 0 ] . name ) . toBe ( 'url' )
807841 expect ( decl ?. first_child ! . children [ 1 ] . type ) . toBe ( IDENTIFIER )
@@ -911,7 +945,7 @@ describe('Value Node Types', () => {
911945 const root = parse ( 'body { color: ; }' )
912946 const decl = root . first_child ?. first_child ?. next_sibling ?. first_child
913947
914- expect ( decl ?. first_child ! . type ) . toBe ( VALUE )
948+ expect ( decl ?. first_child ! . type ) . toBe ( VALUE )
915949 expect ( decl ?. first_child ! . children ) . toHaveLength ( 0 )
916950 } )
917951
0 commit comments