Skip to content

Commit 711f964

Browse files
authored
Tests/prelude selector lenghts (#25)
found because of projectwallace/specificity#1
1 parent b08d04b commit 711f964

File tree

3 files changed

+385
-99
lines changed

3 files changed

+385
-99
lines changed

src/parse-atrule-prelude.test.ts

Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,4 +707,275 @@ describe('parse_atrule_prelude()', () => {
707707
expect(result.length).toBeGreaterThan(0)
708708
})
709709
})
710+
711+
describe('length property correctness (regression tests for commit 5c6e2cd)', () => {
712+
describe('At-rule prelude length', () => {
713+
test('@media prelude length should match text', () => {
714+
const css = '@media screen { }'
715+
const ast = parse(css)
716+
const atRule = ast.first_child
717+
718+
expect(atRule?.prelude).toBe('screen')
719+
expect(atRule?.prelude?.length).toBe(6)
720+
})
721+
722+
test('@media with feature prelude length', () => {
723+
const css = '@media (min-width: 768px) { }'
724+
const ast = parse(css)
725+
const atRule = ast.first_child
726+
727+
expect(atRule?.prelude).toBe('(min-width: 768px)')
728+
expect(atRule?.prelude?.length).toBe(18)
729+
})
730+
731+
test('@media complex prelude length', () => {
732+
const css = '@media screen and (min-width: 768px) { }'
733+
const ast = parse(css)
734+
const atRule = ast.first_child
735+
736+
expect(atRule?.prelude).toBe('screen and (min-width: 768px)')
737+
expect(atRule?.prelude?.length).toBe(29)
738+
})
739+
740+
test('@container prelude length', () => {
741+
const css = '@container (min-width: 768px) { }'
742+
const ast = parse(css)
743+
const atRule = ast.first_child
744+
745+
expect(atRule?.prelude).toBe('(min-width: 768px)')
746+
expect(atRule?.prelude?.length).toBe(18)
747+
})
748+
749+
test('@container with name prelude length', () => {
750+
const css = '@container sidebar (min-width: 400px) { }'
751+
const ast = parse(css)
752+
const atRule = ast.first_child
753+
754+
expect(atRule?.prelude).toBe('sidebar (min-width: 400px)')
755+
expect(atRule?.prelude?.length).toBe(26)
756+
})
757+
758+
test('@supports prelude length', () => {
759+
const css = '@supports (display: flex) { }'
760+
const ast = parse(css)
761+
const atRule = ast.first_child
762+
763+
expect(atRule?.prelude).toBe('(display: flex)')
764+
expect(atRule?.prelude?.length).toBe(15)
765+
})
766+
767+
test('@supports complex prelude length', () => {
768+
const css = '@supports (display: flex) and (color: red) { }'
769+
const ast = parse(css)
770+
const atRule = ast.first_child
771+
772+
expect(atRule?.prelude).toBe('(display: flex) and (color: red)')
773+
expect(atRule?.prelude?.length).toBe(32)
774+
})
775+
776+
test('@layer single name prelude length', () => {
777+
const css = '@layer utilities { }'
778+
const ast = parse(css)
779+
const atRule = ast.first_child
780+
781+
expect(atRule?.prelude).toBe('utilities')
782+
expect(atRule?.prelude?.length).toBe(9)
783+
})
784+
785+
test('@layer multiple names prelude length', () => {
786+
const css = '@layer base, components, utilities { }'
787+
const ast = parse(css)
788+
const atRule = ast.first_child
789+
790+
expect(atRule?.prelude).toBe('base, components, utilities')
791+
expect(atRule?.prelude?.length).toBe(27)
792+
})
793+
794+
test('@import url prelude length', () => {
795+
const css = '@import url("styles.css") screen;'
796+
const ast = parse(css)
797+
const atRule = ast.first_child
798+
799+
expect(atRule?.prelude).toBe('url("styles.css") screen')
800+
expect(atRule?.prelude?.length).toBe(24)
801+
})
802+
803+
test('@import with layer prelude length', () => {
804+
const css = '@import "styles.css" layer(utilities);'
805+
const ast = parse(css)
806+
const atRule = ast.first_child
807+
808+
expect(atRule?.prelude).toBe('"styles.css" layer(utilities)')
809+
expect(atRule?.prelude?.length).toBe(29)
810+
})
811+
812+
test('@import with supports prelude length', () => {
813+
const css = '@import url("styles.css") supports(display: flex);'
814+
const ast = parse(css)
815+
const atRule = ast.first_child
816+
817+
expect(atRule?.prelude).toBe('url("styles.css") supports(display: flex)')
818+
expect(atRule?.prelude?.length).toBe(41)
819+
})
820+
821+
test('@import complex prelude length', () => {
822+
const css = '@import url("a.css") layer(utilities) supports(display: flex) screen;'
823+
const ast = parse(css)
824+
const atRule = ast.first_child
825+
826+
expect(atRule?.prelude).toBe('url("a.css") layer(utilities) supports(display: flex) screen')
827+
expect(atRule?.prelude?.length).toBe(60)
828+
})
829+
})
830+
831+
describe('Prelude child node text length', () => {
832+
test('media query node text length', () => {
833+
const css = '@media screen and (min-width: 768px) { }'
834+
const ast = parse(css)
835+
const atRule = ast.first_child
836+
const children = atRule?.children || []
837+
838+
// First child should be media query
839+
const mediaQuery = children[0]
840+
expect(mediaQuery.type).toBe(NODE_PRELUDE_MEDIA_QUERY)
841+
expect(mediaQuery.text).toBe('screen and (min-width: 768px)')
842+
expect(mediaQuery.text.length).toBe(29)
843+
})
844+
845+
test('media type node text length', () => {
846+
const css = '@media screen { }'
847+
const ast = parse(css)
848+
const atRule = ast.first_child
849+
const children = atRule?.children || []
850+
const mediaQuery = children[0]
851+
const queryChildren = mediaQuery?.children || []
852+
853+
const mediaType = queryChildren.find((c) => c.type === NODE_PRELUDE_MEDIA_TYPE)
854+
expect(mediaType?.text).toBe('screen')
855+
expect(mediaType?.text.length).toBe(6)
856+
})
857+
858+
test('media feature node text length', () => {
859+
const css = '@media (min-width: 768px) { }'
860+
const ast = parse(css)
861+
const atRule = ast.first_child
862+
const children = atRule?.children || []
863+
const mediaQuery = children[0]
864+
const queryChildren = mediaQuery?.children || []
865+
866+
const mediaFeature = queryChildren.find((c) => c.type === NODE_PRELUDE_MEDIA_FEATURE)
867+
expect(mediaFeature?.text).toBe('(min-width: 768px)')
868+
expect(mediaFeature?.text.length).toBe(18)
869+
})
870+
871+
test('container query node text length', () => {
872+
const css = '@container sidebar (min-width: 400px) { }'
873+
const ast = parse(css)
874+
const atRule = ast.first_child
875+
const children = atRule?.children || []
876+
877+
const containerQuery = children.find((c) => c.type === NODE_PRELUDE_CONTAINER_QUERY)
878+
expect(containerQuery?.text).toBe('sidebar (min-width: 400px)')
879+
expect(containerQuery?.text.length).toBe(26)
880+
})
881+
882+
test('supports query node text length', () => {
883+
const css = '@supports (display: flex) { }'
884+
const ast = parse(css)
885+
const atRule = ast.first_child
886+
const children = atRule?.children || []
887+
888+
const supportsQuery = children.find((c) => c.type === NODE_PRELUDE_SUPPORTS_QUERY)
889+
expect(supportsQuery?.text).toBe('(display: flex)')
890+
expect(supportsQuery?.text.length).toBe(15)
891+
})
892+
893+
test('layer name node text length', () => {
894+
const css = '@layer utilities { }'
895+
const ast = parse(css)
896+
const atRule = ast.first_child
897+
const children = atRule?.children || []
898+
899+
const layerName = children.find((c) => c.type === NODE_PRELUDE_LAYER_NAME)
900+
expect(layerName?.text).toBe('utilities')
901+
expect(layerName?.text.length).toBe(9)
902+
})
903+
904+
test('import url node text length', () => {
905+
const css = '@import url("styles.css") screen;'
906+
const ast = parse(css)
907+
const atRule = ast.first_child
908+
const children = atRule?.children || []
909+
910+
const importUrl = children.find((c) => c.type === NODE_PRELUDE_IMPORT_URL)
911+
expect(importUrl?.text).toBe('url("styles.css")')
912+
expect(importUrl?.text.length).toBe(17)
913+
})
914+
915+
test('import layer node text length', () => {
916+
const css = '@import "styles.css" layer(utilities);'
917+
const ast = parse(css)
918+
const atRule = ast.first_child
919+
const children = atRule?.children || []
920+
921+
const importLayer = children.find((c) => c.type === NODE_PRELUDE_IMPORT_LAYER)
922+
expect(importLayer?.text).toBe('layer(utilities)')
923+
expect(importLayer?.text.length).toBe(16)
924+
})
925+
926+
test('import supports node text length', () => {
927+
const css = '@import url("a.css") supports(display: flex);'
928+
const ast = parse(css)
929+
const atRule = ast.first_child
930+
const children = atRule?.children || []
931+
932+
const importSupports = children.find((c) => c.type === NODE_PRELUDE_IMPORT_SUPPORTS)
933+
expect(importSupports?.text).toBe('supports(display: flex)')
934+
expect(importSupports?.text.length).toBe(23)
935+
})
936+
937+
test('operator node text length', () => {
938+
const css = '@media screen and (min-width: 768px) { }'
939+
const ast = parse(css)
940+
const atRule = ast.first_child
941+
const children = atRule?.children || []
942+
const mediaQuery = children[0]
943+
const queryChildren = mediaQuery?.children || []
944+
945+
const operator = queryChildren.find((c) => c.type === NODE_PRELUDE_OPERATOR)
946+
expect(operator?.text).toBe('and')
947+
expect(operator?.text.length).toBe(3)
948+
})
949+
})
950+
951+
describe('Edge cases and whitespace handling', () => {
952+
test('@media with extra whitespace prelude length', () => {
953+
const css = '@media screen and (min-width: 768px) { }'
954+
const ast = parse(css)
955+
const atRule = ast.first_child
956+
957+
// Whitespace is trimmed from start/end but preserved internally
958+
expect(atRule?.prelude).toBe('screen and (min-width: 768px)')
959+
expect(atRule?.prelude?.length).toBe(33)
960+
})
961+
962+
test('@layer with whitespace around commas', () => {
963+
const css = '@layer base , components , utilities { }'
964+
const ast = parse(css)
965+
const atRule = ast.first_child
966+
967+
expect(atRule?.prelude).toBe('base , components , utilities')
968+
expect(atRule?.prelude?.length).toBe(29)
969+
})
970+
971+
test('@import with newlines prelude length', () => {
972+
const css = '@import url("styles.css")\n screen;'
973+
const ast = parse(css)
974+
const atRule = ast.first_child
975+
976+
expect(atRule?.prelude).toBe('url("styles.css")\n screen')
977+
expect(atRule?.prelude?.length).toBe(26)
978+
})
979+
})
980+
})
710981
})

0 commit comments

Comments
 (0)