From e4a73114b81d08c52dd72ea36ba78e6a4fe96cd4 Mon Sep 17 00:00:00 2001 From: Ido Rosenthal Date: Wed, 20 Sep 2023 14:28:20 +0300 Subject: [PATCH] test: modify tests to new default --- .../core/test/features/css-general.spec.ts | 1 - .../test/features/css-pseudo-class.spec.ts | 424 ++++++++---------- .../test/features/css-pseudo-element.spec.ts | 126 +++--- .../test/features/st-custom-selector.spec.ts | 121 +++-- packages/core/test/features/st-global.spec.ts | 59 +-- packages/core/test/features/st-scope.spec.ts | 66 ++- .../test/stylable-transformer/general.spec.ts | 148 +++--- .../test/stylable-transformer/nesting.spec.ts | 64 +-- .../features/ls-css-pseudo-class.spec.ts | 5 +- .../lib/completions/custom-selectors.spec.ts | 35 +- 10 files changed, 493 insertions(+), 556 deletions(-) diff --git a/packages/core/test/features/css-general.spec.ts b/packages/core/test/features/css-general.spec.ts index 2970ce69a9..76ffd1e0fd 100644 --- a/packages/core/test/features/css-general.spec.ts +++ b/packages/core/test/features/css-general.spec.ts @@ -3,7 +3,6 @@ import { shouldReportNoDiagnostics, testStylableCore } from '@stylable/core-test describe('features/css-general', () => { describe('svg', () => { it('should preserve path value function quotes', () => { - // ToDo: remove once experimentalSelectorInference is the default const { sheets } = testStylableCore(` .path { diff --git a/packages/core/test/features/css-pseudo-class.spec.ts b/packages/core/test/features/css-pseudo-class.spec.ts index 299335807a..dc5fa1d85f 100644 --- a/packages/core/test/features/css-pseudo-class.spec.ts +++ b/packages/core/test/features/css-pseudo-class.spec.ts @@ -631,173 +631,143 @@ describe('features/css-pseudo-class', () => { }); }); describe('native selector nesting classes', () => { - describe('experimentalSelectorInference', () => { - it('should infer native selector nesting classes', () => { - const { sheets } = testStylableCore( - { - 'entry.st.css': ` - .x {/*no states*/} - .a { -st-states: shared } - .b { -st-states: shared } - .c { -st-states: shared } + it('should infer native selector nesting classes', () => { + const { sheets } = testStylableCore({ + 'entry.st.css': ` + .x {/*no states*/} + .a { -st-states: shared } + .b { -st-states: shared } + .c { -st-states: shared } - /* @rule(compound+nested) .entry__a:is(.entry__b).entry--shared */ - .a:is(.b):shared {} + /* @rule(compound+nested) .entry__a:is(.entry__b).entry--shared */ + .a:is(.b):shared {} - /* @rule(compound+nested) .entry__a:is(.entry__b, .entry__c).entry--shared */ - .a:is(.b, .c):shared {} + /* @rule(compound+nested) .entry__a:is(.entry__b, .entry__c).entry--shared */ + .a:is(.b, .c):shared {} - /* @compound+nested+comment- tested outside because of comment*/ - .a/**/:is(.b, .c):shared {} + /* @compound+nested+comment- tested outside because of comment*/ + .a/**/:is(.b, .c):shared {} - /* @rule(just nested) .entry__x :is(.entry__a, .entry__b).entry--shared */ - .x :is(.a, .b):shared {} + /* @rule(just nested) .entry__x :is(.entry__a, .entry__b).entry--shared */ + .x :is(.a, .b):shared {} - /* @rule(where) :where(.entry__a,.entry__b).entry--shared */ - :where(.a,.b):shared {} + /* @rule(where) :where(.entry__a,.entry__b).entry--shared */ + :where(.a,.b):shared {} - /* @rule(nth) :nth-child(2n + 1 of .entry__a,.entry__b).entry--shared */ - :nth-child(2n + 1 of .a,.b):shared {} + /* @rule(nth) :nth-child(2n + 1 of .entry__a,.entry__b).entry--shared */ + :nth-child(2n + 1 of .a,.b):shared {} - /* @rule(has - no infer) .entry__a:has(.entry__x).entry--shared */ - .a:has(.x):shared {} + /* @rule(has - no infer) .entry__a:has(.entry__x).entry--shared */ + .a:has(.x):shared {} - /* @rule(not - no infer) .entry__a:not(.entry__x).entry--shared */ - .a:not(.x):shared {} + /* @rule(not - no infer) .entry__a:not(.entry__x).entry--shared */ + .a:not(.x):shared {} - /* @rule(not - no infer 2) .entry__a:not(.entry__b).entry--shared */ - .a:not(.b):shared {} - `, - }, - { - stylableConfig: { - experimentalSelectorInference: true, - }, - } - ); + /* @rule(not - no infer 2) .entry__a:not(.entry__b).entry--shared */ + .a:not(.b):shared {} + `, + }); - const { meta } = sheets['/entry.st.css']; + const { meta } = sheets['/entry.st.css']; - const ruleWithComment = meta.targetAst?.nodes[9] as postcss.Rule; - expect(ruleWithComment.selector, 'compound+nested+comment').to.eql( - '.entry__a/**/:is(.entry__b, .entry__c).entry--shared' - ); + const ruleWithComment = meta.targetAst?.nodes[9] as postcss.Rule; + expect(ruleWithComment.selector, 'compound+nested+comment').to.eql( + '.entry__a/**/:is(.entry__b, .entry__c).entry--shared' + ); - shouldReportNoDiagnostics(meta); + shouldReportNoDiagnostics(meta); + }); + it('should filter out states after native selector nesting classes', () => { + const { sheets } = testStylableCore({ + 'entry.st.css': ` + .x {} + .y { -st-states: shared(string) } + .a { -st-states: shared } + .b { -st-states: shared } + + /* + @transform-error(compound missing) word(shared) ${cssPseudoClassDiagnostics.UNKNOWN_STATE_USAGE( + 'shared' + )} + @rule(compound missing) .entry__x:is(.entry__a, .entry__b):shared + */ + .x:is(.a, .b):shared {} + + /* + @transform-error(compound+nested+comment) word(shared) ${cssPseudoClassDiagnostics.UNKNOWN_STATE_USAGE( + 'shared' + )} + */ + .x/**/:is(.a, .b):shared {} + + /* + @transform-error(state type differ) word(shared) ${cssPseudoClassDiagnostics.UNKNOWN_STATE_USAGE( + 'shared' + )} + @rule(compound missing) .entry__y:is(.entry__a, .entry__b):shared + */ + .y:is(.a, .b):shared {} + `, }); - it('should filter out states after native selector nesting classes', () => { - const { sheets } = testStylableCore( - { - 'entry.st.css': ` - .x {} - .y { -st-states: shared(string) } - .a { -st-states: shared } - .b { -st-states: shared } - - /* - @transform-error(compound missing) word(shared) ${cssPseudoClassDiagnostics.UNKNOWN_STATE_USAGE( - 'shared' - )} - @rule(compound missing) .entry__x:is(.entry__a, .entry__b):shared - */ - .x:is(.a, .b):shared {} - - /* - @transform-error(compound+nested+comment) word(shared) ${cssPseudoClassDiagnostics.UNKNOWN_STATE_USAGE( - 'shared' - )} - */ - .x/**/:is(.a, .b):shared {} - - /* - @transform-error(state type differ) word(shared) ${cssPseudoClassDiagnostics.UNKNOWN_STATE_USAGE( - 'shared' - )} - @rule(compound missing) .entry__y:is(.entry__a, .entry__b):shared - */ - .y:is(.a, .b):shared {} - `, - }, - { - stylableConfig: { - experimentalSelectorInference: true, - }, - } - ); - const { meta } = sheets['/entry.st.css']; + const { meta } = sheets['/entry.st.css']; - const ruleWithComment = meta.targetAst?.nodes[7] as postcss.Rule; - expect(ruleWithComment.selector, 'compound+nested+comment').to.eql( - '.entry__x/**/:is(.entry__a, .entry__b):shared' - ); + const ruleWithComment = meta.targetAst?.nodes[7] as postcss.Rule; + expect(ruleWithComment.selector, 'compound+nested+comment').to.eql( + '.entry__x/**/:is(.entry__a, .entry__b):shared' + ); + }); + it('should infer complex states', () => { + testStylableCore({ + 'entry.st.css': ` + .a { -st-states: shared(string(contains(123))) } + .b { -st-states: shared(string(contains(123))) } + .cx { -st-states: shared(string(contains(456))) } + + /* @rule(match) .entry__a:is(.entry__b).entry---shared-5-x123x */ + .a:is(.b):shared(x123x) {} + + /* + @transform-error(compound missing) word(shared) ${cssPseudoClassDiagnostics.UNKNOWN_STATE_USAGE( + 'shared' + )} + @rule(match) .entry__a:is(.entry__x):shared(x123x) + */ + .a:is(.x):shared(x123x) {} + `, }); - it('should infer complex states', () => { - testStylableCore( - { - 'entry.st.css': ` - .a { -st-states: shared(string(contains(123))) } - .b { -st-states: shared(string(contains(123))) } - .cx { -st-states: shared(string(contains(456))) } - - /* @rule(match) .entry__a:is(.entry__b).entry---shared-5-x123x */ - .a:is(.b):shared(x123x) {} - - /* - @transform-error(compound missing) word(shared) ${cssPseudoClassDiagnostics.UNKNOWN_STATE_USAGE( - 'shared' - )} - @rule(match) .entry__a:is(.entry__x):shared(x123x) - */ - .a:is(.x):shared(x123x) {} + }); + it('should infer identical global states', () => { + const { sheets } = testStylableCore({ + 'a.st.css': ` + .root { + -st-states: + same('[shared]'), + sameWithParam('[$0]', enum(one, two)); + } `, - }, - { - stylableConfig: { - experimentalSelectorInference: true, - }, - } - ); - }); - it('should infer identical global states', () => { - const { sheets } = testStylableCore( - { - 'a.st.css': ` - .root { - -st-states: - same('[shared]'), - sameWithParam('[$0]', enum(one, two)); - } - `, - 'b.st.css': ` - .root { - -st-states: - same('[shared]'), - sameWithParam('[$0]', enum(one, two)); - } - `, - 'entry.st.css': ` - @st-import A from './a.st.css'; - @st-import B from './b.st.css'; - - /* @rule(global template) .entry__root :is(.a__root, .b__root)[shared] */ - .root :is(A, B):same {} - - /* @rule(global template+param) .entry__root :is(.a__root, .b__root)[two] */ - .root :is(A, B):sameWithParam(two) {} + 'b.st.css': ` + .root { + -st-states: + same('[shared]'), + sameWithParam('[$0]', enum(one, two)); + } `, - }, - { - stylableConfig: { - experimentalSelectorInference: true, - }, - } - ); + 'entry.st.css': ` + @st-import A from './a.st.css'; + @st-import B from './b.st.css'; - const { meta } = sheets['/entry.st.css']; + /* @rule(global template) .entry__root :is(.a__root, .b__root)[shared] */ + .root :is(A, B):same {} - shouldReportNoDiagnostics(meta); + /* @rule(global template+param) .entry__root :is(.a__root, .b__root)[two] */ + .root :is(A, B):sameWithParam(two) {} + `, }); + + const { meta } = sheets['/entry.st.css']; + + shouldReportNoDiagnostics(meta); }); }); describe(`st-var`, () => { @@ -873,99 +843,83 @@ describe('features/css-pseudo-class', () => { }); }); describe('st-custom-selector', () => { - describe('experimentalSelectorInference', () => { - it('should transform shared state', () => { - const { sheets } = testStylableCore( - { - 'base.st.css': ` - .root { - -st-states: shared; - } - .x { -st-extends: root; } - .y { -st-extends: root; } - @custom-selector :--innerMulti .x, .y; - `, - 'a.st.css': ` - @st-import Base from './base.st.css'; - .root { -st-extends: Base } - `, - 'b.st.css': ` - @st-import Base from './base.st.css'; - .root { -st-extends: Base } - `, - 'entry.st.css': ` - @st-import A from './a.st.css'; - @st-import B from './b.st.css'; - @custom-selector :--multi A, B; - - /* @rule(shared) .entry__root .a__root.base--shared,.entry__root .b__root.base--shared */ - .root::multi:shared {} - - /* @rule(2 levels) .entry__root .a__root .base__x.base--shared,.entry__root .b__root .base__x.base--shared,.entry__root .a__root .base__y.base--shared,.entry__root .b__root .base__y.base--shared */ - .root::multi::innerMulti:shared {} - `, - }, - { - stylableConfig: { - experimentalSelectorInference: true, - }, + it('should transform shared state', () => { + const { sheets } = testStylableCore({ + 'base.st.css': ` + .root { + -st-states: shared; } - ); + .x { -st-extends: root; } + .y { -st-extends: root; } + @custom-selector :--innerMulti .x, .y; + `, + 'a.st.css': ` + @st-import Base from './base.st.css'; + .root { -st-extends: Base } + `, + 'b.st.css': ` + @st-import Base from './base.st.css'; + .root { -st-extends: Base } + `, + 'entry.st.css': ` + @st-import A from './a.st.css'; + @st-import B from './b.st.css'; + @custom-selector :--multi A, B; + + /* @rule(shared) .entry__root .a__root.base--shared,.entry__root .b__root.base--shared */ + .root::multi:shared {} + + /* @rule(2 levels) .entry__root .a__root .base__x.base--shared,.entry__root .b__root .base__x.base--shared,.entry__root .a__root .base__y.base--shared,.entry__root .b__root .base__y.base--shared */ + .root::multi::innerMulti:shared {} + `, + }); - const { meta } = sheets['/entry.st.css']; + const { meta } = sheets['/entry.st.css']; - shouldReportNoDiagnostics(meta); - }); - it('should filter out states that do not exist or match', () => { - testStylableCore( - { - 'base.st.css': ` - .root { - -st-states: shared; - } - `, - 'a.st.css': ` - @st-import Base from './base.st.css'; - .root { - -st-extends: Base; - -st-states: unique, onlyInA; - } - `, - 'b.st.css': ` - @st-import Base from './base.st.css'; - .root { - -st-extends: Base; - -st-states: unique; - } - `, - 'entry.st.css': ` - @st-import A from './a.st.css'; - @st-import B from './b.st.css'; - @custom-selector :--multi A, B; - - /* - @transform-error(unique) word(unique) ${cssPseudoClassDiagnostics.UNKNOWN_STATE_USAGE( - 'unique' - )} - @rule(unique) .entry__root .a__root:unique,.entry__root .b__root:unique - */ - .root::multi:unique {} - - /* - @transform-error(only in 1) word(onlyInA) ${cssPseudoClassDiagnostics.UNKNOWN_STATE_USAGE( - 'onlyInA' - )} - @rule(only in 1) .entry__root .a__root:onlyInA,.entry__root .b__root:onlyInA - */ - .root::multi:onlyInA {} - `, - }, - { - stylableConfig: { - experimentalSelectorInference: true, - }, + shouldReportNoDiagnostics(meta); + }); + it('should filter out states that do not exist or match', () => { + testStylableCore({ + 'base.st.css': ` + .root { + -st-states: shared; + } + `, + 'a.st.css': ` + @st-import Base from './base.st.css'; + .root { + -st-extends: Base; + -st-states: unique, onlyInA; + } + `, + 'b.st.css': ` + @st-import Base from './base.st.css'; + .root { + -st-extends: Base; + -st-states: unique; } - ); + `, + 'entry.st.css': ` + @st-import A from './a.st.css'; + @st-import B from './b.st.css'; + @custom-selector :--multi A, B; + + /* + @transform-error(unique) word(unique) ${cssPseudoClassDiagnostics.UNKNOWN_STATE_USAGE( + 'unique' + )} + @rule(unique) .entry__root .a__root:unique,.entry__root .b__root:unique + */ + .root::multi:unique {} + + /* + @transform-error(only in 1) word(onlyInA) ${cssPseudoClassDiagnostics.UNKNOWN_STATE_USAGE( + 'onlyInA' + )} + @rule(only in 1) .entry__root .a__root:onlyInA,.entry__root .b__root:onlyInA + */ + .root::multi:onlyInA {} + `, }); }); }); diff --git a/packages/core/test/features/css-pseudo-element.spec.ts b/packages/core/test/features/css-pseudo-element.spec.ts index 9dedaed3b6..2961162dd7 100644 --- a/packages/core/test/features/css-pseudo-element.spec.ts +++ b/packages/core/test/features/css-pseudo-element.spec.ts @@ -250,79 +250,63 @@ describe('features/css-pseudo-element', () => { shouldReportNoDiagnostics(meta); }); - describe('experimentalSelectorInference', () => { - it('should transform multiple selector intersection', () => { - const { sheets } = testStylableCore( - { - 'base.st.css': ` - .shared {} - @custom-selector :--sharedMulti .x, .y; - `, - 'a.st.css': ` - @st-import Base from './base.st.css'; - .root { -st-extends: Base } - `, - 'b.st.css': ` - @st-import Base from './base.st.css'; - .root { -st-extends: Base } - `, - 'entry.st.css': ` - @st-import A from './a.st.css'; - @st-import B from './b.st.css'; - @custom-selector :--multi A, B; - - /* @rule(shared) .entry__root .a__root .base__shared,.entry__root .b__root .base__shared */ - .root::multi::shared {} - - /* @rule(shared-multi) .entry__root .a__root .base__x,.entry__root .b__root .base__x,.entry__root .a__root .base__y,.entry__root .b__root .base__y */ - .root::multi::sharedMulti {} - `, - }, - { - stylableConfig: { - experimentalSelectorInference: true, - }, - } - ); + it('should transform multiple selector intersection', () => { + const { sheets } = testStylableCore({ + 'base.st.css': ` + .shared {} + @custom-selector :--sharedMulti .x, .y; + `, + 'a.st.css': ` + @st-import Base from './base.st.css'; + .root { -st-extends: Base } + `, + 'b.st.css': ` + @st-import Base from './base.st.css'; + .root { -st-extends: Base } + `, + 'entry.st.css': ` + @st-import A from './a.st.css'; + @st-import B from './b.st.css'; + @custom-selector :--multi A, B; + + /* @rule(shared) .entry__root .a__root .base__shared,.entry__root .b__root .base__shared */ + .root::multi::shared {} + + /* @rule(shared-multi) .entry__root .a__root .base__x,.entry__root .b__root .base__x,.entry__root .a__root .base__y,.entry__root .b__root .base__y */ + .root::multi::sharedMulti {} + `, + }); - const { meta } = sheets['/entry.st.css']; + const { meta } = sheets['/entry.st.css']; - shouldReportNoDiagnostics(meta); - }); - it('should filter out elements that do not exist or match', () => { - testStylableCore( - { - 'base.st.css': ` - `, - 'a.st.css': ` - @st-import Base from './base.st.css'; - .root { -st-extends: Base } - .onlyInA {} - `, - 'b.st.css': ` - @st-import Base from './base.st.css'; - .root { -st-extends: Base } - `, - 'entry.st.css': ` - @st-import A from './a.st.css'; - @st-import B from './b.st.css'; - @custom-selector :--multi A, B; - - /* - @transform-error(exist in 1) word(onlyInA) ${transformerStringDiagnostics.UNKNOWN_PSEUDO_ELEMENT( - `onlyInA` - )} - @rule(exist in 1) .entry__root .a__root::onlyInA,.entry__root .b__root::onlyInA - */ - .root::multi::onlyInA {} - `, - }, - { - stylableConfig: { - experimentalSelectorInference: true, - }, - } - ); + shouldReportNoDiagnostics(meta); + }); + it('should filter out elements that do not exist or match', () => { + testStylableCore({ + 'base.st.css': ` + `, + 'a.st.css': ` + @st-import Base from './base.st.css'; + .root { -st-extends: Base } + .onlyInA {} + `, + 'b.st.css': ` + @st-import Base from './base.st.css'; + .root { -st-extends: Base } + `, + 'entry.st.css': ` + @st-import A from './a.st.css'; + @st-import B from './b.st.css'; + @custom-selector :--multi A, B; + + /* + @transform-error(exist in 1) word(onlyInA) ${transformerStringDiagnostics.UNKNOWN_PSEUDO_ELEMENT( + `onlyInA` + )} + @rule(exist in 1) .entry__root .a__root::onlyInA,.entry__root .b__root::onlyInA + */ + .root::multi::onlyInA {} + `, }); }); }); diff --git a/packages/core/test/features/st-custom-selector.spec.ts b/packages/core/test/features/st-custom-selector.spec.ts index 73a2fb9a0e..b7b67cc989 100644 --- a/packages/core/test/features/st-custom-selector.spec.ts +++ b/packages/core/test/features/st-custom-selector.spec.ts @@ -1,5 +1,5 @@ import chaiSubset from 'chai-subset'; -import { STCustomSelector, CSSType } from '@stylable/core/dist/features'; +import { STCustomSelector, CSSType, CSSPseudoClass } from '@stylable/core/dist/features'; import { testStylableCore, shouldReportNoDiagnostics, @@ -11,6 +11,7 @@ chai.use(chaiSubset); const customSelectorDiagnostics = diagnosticBankReportToStrings(STCustomSelector.diagnostics); const cssTypeDiagnostics = diagnosticBankReportToStrings(CSSType.diagnostics); +const pseudoClassDiagnostics = diagnosticBankReportToStrings(CSSPseudoClass.diagnostics); describe('features/st-custom-selector', () => { // ToDo: migrate to @st-part @@ -59,8 +60,6 @@ describe('features/st-custom-selector', () => { shouldReportNoDiagnostics(meta); }); it('should handle unknown custom selector', () => { - // ToDo: remove diagnostic once experimentalSelectorInference is the default - // it will fallback to pseudo-class transform and then to unknown pseudo-class testStylableCore(` /* @analyze-error(in custom) word(:--unknown) ${customSelectorDiagnostics.UNKNOWN_CUSTOM_SELECTOR( ':--unknown' @@ -68,8 +67,8 @@ describe('features/st-custom-selector', () => { @custom-selector :--x .before:--unknown.after; /* - @transform-error(in selector) word(:--unknown) ${customSelectorDiagnostics.UNKNOWN_CUSTOM_SELECTOR( - ':--unknown' + @transform-error(in selector) word(--unknown) ${pseudoClassDiagnostics.UNKNOWN_STATE_USAGE( + '--unknown' )} @rule .entry__before:--unknown.entry__after {} */ @@ -100,71 +99,55 @@ describe('features/st-custom-selector', () => { 'only a single unscoped diagnostic for span' ).to.eql(1); }); - describe('experimentalSelectorInference', () => { - it('should transform multiple selector intersection', () => { - const { sheets } = testStylableCore( - { - 'base.st.css': ` - .shared {} - @custom-selector :--xy .x, .y; - `, - 'a.st.css': ` - @st-import Base from './base.st.css'; - .root { -st-extends: Base } - `, - 'b.st.css': ` - @st-import Base from './base.st.css'; - .root { -st-extends: Base } - `, - 'entry.st.css': ` - @st-import A from './a.st.css'; - @st-import B from './b.st.css'; - @custom-selector :--ab A, B; - - /* @rule(shared-multi) .a__root .base__x, .b__root .base__x,.a__root .base__y, .b__root .base__y */ - :--ab::xy {} - `, - }, - { - stylableConfig: { - experimentalSelectorInference: true, - }, - } - ); - - const { meta } = sheets['/entry.st.css']; - - shouldReportNoDiagnostics(meta); + it('should transform multiple selector intersection', () => { + const { sheets } = testStylableCore({ + 'base.st.css': ` + .shared {} + @custom-selector :--xy .x, .y; + `, + 'a.st.css': ` + @st-import Base from './base.st.css'; + .root { -st-extends: Base } + `, + 'b.st.css': ` + @st-import Base from './base.st.css'; + .root { -st-extends: Base } + `, + 'entry.st.css': ` + @st-import A from './a.st.css'; + @st-import B from './b.st.css'; + @custom-selector :--ab A, B; + + /* @rule(shared-multi) .a__root .base__x, .b__root .base__x,.a__root .base__y, .b__root .base__y */ + :--ab::xy {} + `, }); - it('should filter out elements that do not exist or match', () => { - testStylableCore( - { - 'base.st.css': ` - `, - 'a.st.css': ` - @st-import Base from './base.st.css'; - .root { -st-extends: Base } - .onlyInA {} - `, - 'b.st.css': ` - @st-import Base from './base.st.css'; - .root { -st-extends: Base } - `, - 'entry.st.css': ` - @st-import A from './a.st.css'; - @st-import B from './b.st.css'; - @custom-selector :--ab A, B; - - /* @rule(exist in 1) .a__root::onlyInA, .b__root::onlyInA */ - :--ab::onlyInA {} - `, - }, - { - stylableConfig: { - experimentalSelectorInference: true, - }, - } - ); + + const { meta } = sheets['/entry.st.css']; + + shouldReportNoDiagnostics(meta); + }); + it('should filter out elements that do not exist or match', () => { + testStylableCore({ + 'base.st.css': ` + `, + 'a.st.css': ` + @st-import Base from './base.st.css'; + .root { -st-extends: Base } + .onlyInA {} + `, + 'b.st.css': ` + @st-import Base from './base.st.css'; + .root { -st-extends: Base } + `, + 'entry.st.css': ` + @st-import A from './a.st.css'; + @st-import B from './b.st.css'; + @custom-selector :--ab A, B; + + /* @rule(exist in 1) .a__root::onlyInA, .b__root::onlyInA */ + :--ab::onlyInA {} + `, }); }); }); diff --git a/packages/core/test/features/st-global.spec.ts b/packages/core/test/features/st-global.spec.ts index 3ce9688d68..b1bef94681 100644 --- a/packages/core/test/features/st-global.spec.ts +++ b/packages/core/test/features/st-global.spec.ts @@ -89,47 +89,48 @@ describe(`features/st-global`, () => { const expectedGlobalRules = collectAst(meta.sourceAst, ['global']); expect(actualGlobalRules).to.eql(expectedGlobalRules['global']); }); - it('should continue inferred selector after :global()', () => { - // ToDo: remove once experimentalSelectorInference is the default + it('should set wildcard inferred selector to context after :global()', () => { testStylableCore({ - 'comp.st.css': `.part {} `, + 'comp.st.css': ` .part {} `, 'entry.st.css': ` - @st-import Comp from './comp.st.css'; - .class { -st-states: state; } - /* @rule(state) .entry__class.g.entry--state */ - .class:global(.g):state {} + @st-import Comp from './comp.st.css'; + .class { -st-states: state('.class-state'); } - /* @rule(pseudo-element) .comp__root.g .comp__part */ - Comp:global(.g)::part {} + /* @rule(root state) .entry__class.g:state */ + .class:global(.g):state {} - /* @rule(unknown pseudo-element) .comp__root.g::class */ - Comp:global(.g)::class {} - `, + /* @rule(unknown comp pseudo-element) .comp__root.g::part */ + Comp:global(.g)::part {} + + /* @rule(unknown pseudo-element) .comp__root.g::class */ + Comp:global(.g)::class {} + + /* @rule(universal pseudo-element) .comp__root.g ::class */ + Comp:global(.g) ::class {} + `, }); }); - describe('experimentalSelectorInference', () => { - it('should set wildcard inferred selector to context after :global()', () => { + describe('experimentalSelectorInference=false', () => { + it('should continue inferred selector after :global()', () => { testStylableCore( { - 'comp.st.css': ` .part {} `, + 'comp.st.css': `.part {} `, 'entry.st.css': ` - @st-import Comp from './comp.st.css'; - .class { -st-states: state('.class-state'); } + @st-import Comp from './comp.st.css'; + .class { -st-states: state; } + /* @rule(state) .entry__class.g.entry--state */ + .class:global(.g):state {} - /* @rule(root state) .entry__class.g:state */ - .class:global(.g):state {} - - /* @rule(unknown comp pseudo-element) .comp__root.g::part */ - Comp:global(.g)::part {} + /* @rule(pseudo-element) .comp__root.g .comp__part */ + Comp:global(.g)::part {} - /* @rule(unknown pseudo-element) .comp__root.g::class */ - Comp:global(.g)::class {} - - /* @rule(universal pseudo-element) .comp__root.g ::class */ - Comp:global(.g) ::class {} - `, + /* @rule(unknown pseudo-element) .comp__root.g::class */ + Comp:global(.g)::class {} + `, }, - { stylableConfig: { experimentalSelectorInference: true } } + { + stylableConfig: { experimentalSelectorInference: false }, + } ); }); }); diff --git a/packages/core/test/features/st-scope.spec.ts b/packages/core/test/features/st-scope.spec.ts index 8441d17d58..f674a74f29 100644 --- a/packages/core/test/features/st-scope.spec.ts +++ b/packages/core/test/features/st-scope.spec.ts @@ -129,45 +129,37 @@ describe(`features/st-scope`, () => { expect(STGlobal.getGlobalRules(meta)).to.eql(actualGlobalRules['global']); }); }); - describe('experimentalSelectorInference', () => { - it('should infer nested selector', () => { - const { sheets } = testStylableCore( - ` - .a { - -st-states: shared; - } - .b { - -st-states: shared; - } - @st-scope .a, .b { - /* @rule(nest) .entry__a.entry--shared, .entry__b.entry--shared */ - &:shared {} - } - `, - { stylableConfig: { experimentalSelectorInference: true } } - ); + it('should infer nested selector', () => { + const { sheets } = testStylableCore(` + .a { + -st-states: shared; + } + .b { + -st-states: shared; + } + @st-scope .a, .b { + /* @rule(nest) .entry__a.entry--shared, .entry__b.entry--shared */ + &:shared {} + } + `); - const { meta } = sheets['/entry.st.css']; + const { meta } = sheets['/entry.st.css']; - shouldReportNoDiagnostics(meta); - }); - it('should infer default context as universal selector', () => { - testStylableCore( - ` - .a { - -st-states: shared; - } - .b { - -st-states: shared; - } - @st-scope .a, .b { - /* @rule(universal context) .entry__a ::b, .entry__b ::b */ - ::b {} - } - `, - { stylableConfig: { experimentalSelectorInference: true } } - ); - }); + shouldReportNoDiagnostics(meta); + }); + it('should infer default context as universal selector', () => { + testStylableCore(` + .a { + -st-states: shared; + } + .b { + -st-states: shared; + } + @st-scope .a, .b { + /* @rule(universal context) .entry__a ::b, .entry__b ::b */ + ::b {} + } + `); }); describe('stylable API', () => { it(`should get @st-scope for rule`, () => { diff --git a/packages/core/test/stylable-transformer/general.spec.ts b/packages/core/test/stylable-transformer/general.spec.ts index 1c79bace1d..dd7c08f6f9 100644 --- a/packages/core/test/stylable-transformer/general.spec.ts +++ b/packages/core/test/stylable-transformer/general.spec.ts @@ -52,99 +52,97 @@ describe('Stylable postcss transform (General)', () => { expect(rule2.nodes[0].toString(), 'color1').to.equal('color: red'); expect(rule2.nodes[1].toString(), 'color1').to.equal('color: blue'); }); - it('should continue inferred selector after combinator', () => { - // ToDo: remove once experimentalSelectorInference is the default - testStylableCore({ - 'comp.st.css': `.part {} `, - 'entry.st.css': ` - @st-import Comp from './comp.st.css'; + it('should set default inferred selector context to universal selector', () => { + testStylableCore( + ` + .root { -st-states: state; } .class { -st-states: state; } - - /* @rule(state) .entry__class .entry--state */ - .class :state {} - - /* @rule(pseudo-element) .comp__root .comp__part */ - Comp ::part {} - - /* @rule(unknown pseudo-element) .comp__root ::class */ - Comp ::class {} - `, - }); - }); - it('should continue inferred selector after universal', () => { - // ToDo: remove once experimentalSelectorInference is the default - testStylableCore(` - .root { -st-states: state; } - .part {} - - /* @rule(state) *.entry--state */ - *:state {} - /* @rule(element) * .entry__part */ - *::part {} - `); + /* + @transform-error(unknown state) ${cssPseudoClassDiagnostics.UNKNOWN_STATE_USAGE( + 'state' + )} + @rule(unknown state) :state + */ + :state {} + + /* + @transform-error(unknown pseudo-element) ${transformerStringDiagnostics.UNKNOWN_PSEUDO_ELEMENT( + `class` + )} + @rule(unknown pseudo-element) ::class + */ + ::class {} + ` + ); }); - - describe('experimentalSelectorInference', () => { - it('should set default inferred selector context to universal selector', () => { - testStylableCore( - ` - .root { -st-states: state; } + it('should reset inferred selector after combinator', () => { + testStylableCore({ + 'comp.st.css': ` .part {} `, + 'entry.st.css': ` + @st-import Comp from './comp.st.css'; .class { -st-states: state; } - /* - @transform-error(unknown state) ${cssPseudoClassDiagnostics.UNKNOWN_STATE_USAGE( - 'state' - )} - @rule(unknown state) :state - */ - :state {} + /* @rule(unknown state) .entry__class :state */ + .class :state {} + + /* @rule(unknown pseudo-element) .comp__root ::part */ + Comp ::part {} - /* - @transform-error(unknown pseudo-element) ${transformerStringDiagnostics.UNKNOWN_PSEUDO_ELEMENT( - `class` - )} - @rule(unknown pseudo-element) ::class - */ - ::class {} + /* @rule(standalone pseudo-element) .comp__root ::class */ + Comp ::class {} `, - { stylableConfig: { experimentalSelectorInference: true } } - ); }); - it('should reset inferred selector after combinator', () => { + }); + it('should set inferred selector after universal (to universal)', () => { + testStylableCore( + ` + .root { -st-states: state; } + .part {} + + /* @rule(state) *:state */ + *:state {} + + /* @rule(element) *::part */ + *::part {} + ` + ); + }); + describe('experimentalSelectorInference=false', () => { + it('should continue inferred selector after combinator', () => { testStylableCore( { - 'comp.st.css': ` .part {} `, + 'comp.st.css': `.part {} `, 'entry.st.css': ` - @st-import Comp from './comp.st.css'; - .class { -st-states: state; } + @st-import Comp from './comp.st.css'; + .class { -st-states: state; } + + /* @rule(state) .entry__class .entry--state */ + .class :state {} - /* @rule(unknown state) .entry__class :state */ - .class :state {} + /* @rule(pseudo-element) .comp__root .comp__part */ + Comp ::part {} - /* @rule(unknown pseudo-element) .comp__root ::part */ - Comp ::part {} - - /* @rule(standalone pseudo-element) .comp__root ::class */ - Comp ::class {} - `, + /* @rule(unknown pseudo-element) .comp__root ::class */ + Comp ::class {} + `, }, - { stylableConfig: { experimentalSelectorInference: true } } + { stylableConfig: { experimentalSelectorInference: false } } ); }); - it('should set inferred selector after universal (to universal)', () => { + it('should continue inferred selector after universal', () => { testStylableCore( ` - .root { -st-states: state; } - .part {} - - /* @rule(state) *:state */ - *:state {} - - /* @rule(element) *::part */ - *::part {} - `, - { stylableConfig: { experimentalSelectorInference: true } } + .root { -st-states: state; } + .part {} + + /* @rule(state) *.entry--state */ + *:state {} + + /* @rule(element) * .entry__part */ + *::part {} + `, + { stylableConfig: { experimentalSelectorInference: false } } ); }); }); diff --git a/packages/core/test/stylable-transformer/nesting.spec.ts b/packages/core/test/stylable-transformer/nesting.spec.ts index cd81e26adb..323516cacf 100644 --- a/packages/core/test/stylable-transformer/nesting.spec.ts +++ b/packages/core/test/stylable-transformer/nesting.spec.ts @@ -89,40 +89,48 @@ describe('transformer/nesting', () => { */ &:onlyX {} } - `, - { stylableConfig: { experimentalSelectorInference: true } } + ` ); }); - it('should infer to universal selector without nesting selector', () => { - testStylableCore(` - .root { - -st-states: x; - } - .part { - -st-states: x; - } + describe('experimentalSelectorInference=false', () => { + it('should infer to universal selector without nesting selector', () => { + testStylableCore( + ` + .root { + -st-states: x; + } + .part { + -st-states: x; + } - .part { - /* - @transform-error(first) ${cssPseudoClassDiagnostics.UNKNOWN_STATE_USAGE('x')} - @rule(first) :x - */ - :x {} + .part { + /* + @transform-error(first) ${cssPseudoClassDiagnostics.UNKNOWN_STATE_USAGE( + 'x' + )} + @rule(first) :x + */ + :x {} + + /* + @transform-error(after combinator) ${cssPseudoClassDiagnostics.UNKNOWN_STATE_USAGE( + 'x' + )} + @rule(after combinator) .entry__root :x + */ + .root :x {} + } /* - @transform-error(after combinator) ${cssPseudoClassDiagnostics.UNKNOWN_STATE_USAGE( - 'x' - )} - @rule(after combinator) .entry__root :x + legacy behavior without "experimentalSelectorInference" + @rule(after combinator) .entry__root .entry--x */ .root :x {} - } - - /* - legacy behavior without "experimentalSelectorInference" - @rule(after combinator) .entry__root .entry--x - */ - .root :x {} - `); + `, + { + stylableConfig: { experimentalSelectorInference: false }, + } + ); + }); }); }); diff --git a/packages/language-service/test/lib-new/features/ls-css-pseudo-class.spec.ts b/packages/language-service/test/lib-new/features/ls-css-pseudo-class.spec.ts index 7215ba238f..0da4fa2675 100644 --- a/packages/language-service/test/lib-new/features/ls-css-pseudo-class.spec.ts +++ b/packages/language-service/test/lib-new/features/ls-css-pseudo-class.spec.ts @@ -538,7 +538,6 @@ describe('LS: css-pseudo-class', () => { } } - /* currently nesting in non-& reset to root - this behavior might change */ .part { :hover { &^nestUnderNonAmp^ @@ -561,8 +560,8 @@ describe('LS: css-pseudo-class', () => { assertCompletions('/entry.st.css', ({ filePath, carets }) => ({ message: 'nestUnderNonAmp', actualList: service.onCompletion(filePath, carets.nestUnderNonAmp), - expectedList: [{ label: ':root-state' }], - unexpectedList: [{ label: ':part-state' }], + expectedList: [], + unexpectedList: [{ label: ':part-state' }, { label: ':root-state' }], })); }); }); diff --git a/packages/language-service/test/lib/completions/custom-selectors.spec.ts b/packages/language-service/test/lib/completions/custom-selectors.spec.ts index 09e764301a..ef3f34484b 100644 --- a/packages/language-service/test/lib/completions/custom-selectors.spec.ts +++ b/packages/language-service/test/lib/completions/custom-selectors.spec.ts @@ -300,9 +300,8 @@ describe('Custom Selectors', () => { asserter.suggested(exp); asserter.notSuggested(notExp); }); - it( - 'should not have states when custom selector is grouped, with prefix ' + + 'should have states when custom selector is grouped with the same inferred selector, with prefix ' + prefix + ' ', () => { @@ -311,10 +310,20 @@ describe('Custom Selectors', () => { 'custom-selectors/imported-selector-grouped.st.css', prefix ); + const exp: Array> = []; const notExp: Array> = []; - notExp.push(createCompletion(str3, rng, './top-import.st.css')); - notExp.push(createCompletion(str4, rng, './top-import.st.css')); - asserter.notSuggested(notExp); + if (!prefix || str3.indexOf(prefix) === 0) { + exp.push(createCompletion(str3, rng, './top-import.st.css')); + } else { + notExp.push(createCompletion(str3, rng, './top-import.st.css')); + } + if (!prefix || str4.indexOf(prefix) === 0) { + exp.push(createCompletion(str4, rng, './top-import.st.css')); + } else { + notExp.push(createCompletion(str4, rng, './top-import.st.css')); + } + + asserter.suggested(exp); } ); }); @@ -366,7 +375,7 @@ describe('Custom Selectors', () => { ); it( - 'should not have pseudo-elements when custom selector is grouped, with prefix ' + + 'should have pseudo-elements when custom selector is grouped with the same inferred selector, with prefix ' + prefix + ' ', () => { @@ -375,9 +384,19 @@ describe('Custom Selectors', () => { 'custom-selectors/imported-selector-grouped.st.css', prefix ); + const exp: Array> = []; const notExp: Array> = []; - notExp.push(createCompletion(str5, rng, './top-import.st.css')); - notExp.push(createCompletion(str6, rng, './top-import.st.css')); + if (!prefix || str5.indexOf(prefix) === 0) { + exp.push(createCompletion(str5, rng, './top-import.st.css')); + } else { + notExp.push(createCompletion(str5, rng, './top-import.st.css')); + } + if (!prefix || str6.indexOf(prefix) === 0) { + exp.push(createCompletion(str6, rng, './top-import.st.css')); + } else { + notExp.push(createCompletion(str6, rng, './top-import.st.css')); + } + asserter.suggested(exp); asserter.notSuggested(notExp); } );