diff --git a/packages/node-sass-magic-importer/src/functions/parse-node-filters.spec.ts b/packages/node-sass-magic-importer/src/functions/parse-node-filters.spec.ts index e6ac116..014263f 100644 --- a/packages/node-sass-magic-importer/src/functions/parse-node-filters.spec.ts +++ b/packages/node-sass-magic-importer/src/functions/parse-node-filters.spec.ts @@ -7,12 +7,21 @@ describe(`parseNodeFilters()`, () => { expect(typeof parseNodeFilters).toBe(`function`); }); - test(`It should return an empty array if no filters were found.`, () => { + test(`It should return an empty array if there is no filter divider.`, () => { const parseNodeFilters = parseNodeFiltersFactory(); - const urlWithoutFilters = `style.scss`; + const nodeFilters = parseNodeFilters(urlWithoutFilters); + const expectedResult: any[] = []; + expect(nodeFilters).toEqual(expectedResult); + }); + + test(`It should return an empty array if no filters were found.`, () => { + const parseNodeFilters = parseNodeFiltersFactory(); + const urlWithoutFilters = `{ .some-thing } from style.scss`; + + const nodeFilters = parseNodeFilters(urlWithoutFilters); const expectedResult: any[] = []; expect(nodeFilters).toEqual(expectedResult); @@ -20,13 +29,49 @@ describe(`parseNodeFilters()`, () => { test(`It should return node filters from URL.`, () => { const parseNodeFilters = parseNodeFiltersFactory(); - const urlWithFilters = `[at-rules, mixins] from style.scss`; + + const nodeFilters = parseNodeFilters(urlWithFilters); + const expectedResult = [ + `at-rules`, + `mixins`, + ]; + + expect(nodeFilters).toEqual(expectedResult); + }); + + test(`It should ignore brackets used in a glob pattern.`, () => { + const parseNodeFilters = parseNodeFiltersFactory(); + const urlWithGlobPattern = `[!_]style.scss`; + + const nodeFilters = parseNodeFilters(urlWithGlobPattern); + const expectedResult: any[] = []; + + expect(nodeFilters).toEqual(expectedResult); + }); + + test(`It should return node filters from URL with glob pattern.`, () => { + const parseNodeFilters = parseNodeFiltersFactory(); + const urlWithFilters = `[at-rules, mixins] from [!_]style.scss`; + const nodeFilters = parseNodeFilters(urlWithFilters); + const expectedResult = [ + `at-rules`, + `mixins`, + ]; + + expect(nodeFilters).toEqual(expectedResult); + }); + test(`It should return node filters when filter contains \`from\`.`, () => { + const parseNodeFilters = parseNodeFiltersFactory(); + const urlWithFilters = `[at-rules, mixins, from] from style.scss`; + + const nodeFilters = parseNodeFilters(urlWithFilters); const expectedResult = [ `at-rules`, `mixins`, + `from`, ]; expect(nodeFilters).toEqual(expectedResult); @@ -34,13 +79,12 @@ describe(`parseNodeFilters()`, () => { test(`It should trim empty filter from multi line URL.`, () => { const parseNodeFilters = parseNodeFiltersFactory(); - const urlWithFilters = `[ at-rules, mixins, ] from style.scss`; - const nodeFilters = parseNodeFilters(urlWithFilters); + const nodeFilters = parseNodeFilters(urlWithFilters); const expectedResult = [ `at-rules`, `mixins`, diff --git a/packages/node-sass-magic-importer/src/functions/parse-node-filters.ts b/packages/node-sass-magic-importer/src/functions/parse-node-filters.ts index 1c815f2..f230467 100644 --- a/packages/node-sass-magic-importer/src/functions/parse-node-filters.ts +++ b/packages/node-sass-magic-importer/src/functions/parse-node-filters.ts @@ -2,7 +2,14 @@ import { IFilterParser } from '../interfaces/IFilterParser'; export function parseNodeFiltersFactory(): IFilterParser { return (url: string) => { + const filterDivider = /[\n\r\s]+from[\n\r\s]+/; + + if (!filterDivider.test(url)) { + return []; + } + const nodeFiltersMatch = url + .split(filterDivider)[0] .replace(/{.*?\/.*?\/.*?}/, ``) .match(/\[([\s\S]*)\]/); diff --git a/packages/node-sass-magic-importer/src/functions/parse-selector-filters.spec.ts b/packages/node-sass-magic-importer/src/functions/parse-selector-filters.spec.ts index d7fe324..6e4e198 100644 --- a/packages/node-sass-magic-importer/src/functions/parse-selector-filters.spec.ts +++ b/packages/node-sass-magic-importer/src/functions/parse-selector-filters.spec.ts @@ -27,13 +27,26 @@ describe(`parseSelectorFilters()`, () => { expect(typeof parseSelectorFilters).toBe(`function`); }); + test(`It should return an empty array if there is no filter divider.`, () => { + const parseSelectorFilters = parseSelectorFiltersFactory( + dependencies.processRawSelectorFilters, + dependencies.splitSelectorFilter, + ); + const urlWithoutFilters = `style.scss`; + + const selectorFilters = parseSelectorFilters(urlWithoutFilters); + const expectedResult: any[] = []; + + expect(selectorFilters).toEqual(expectedResult); + }); + test(`It should return an empty array if no filters were found.`, () => { const parseSelectorFilters = parseSelectorFiltersFactory( dependencies.processRawSelectorFilters, dependencies.splitSelectorFilter, ); + const urlWithoutFilters = `[some-thing] from style.scss`; - const urlWithoutFilters = `style.scss`; const selectorFilters = parseSelectorFilters(urlWithoutFilters); const expectedResult: any[] = []; @@ -45,8 +58,8 @@ describe(`parseSelectorFilters()`, () => { dependencies.processRawSelectorFilters, dependencies.splitSelectorFilter, ); - const urlWithFilters = `{ .btn, .btn-alert } from style.scss`; + const selectorFilters = parseSelectorFilters(urlWithFilters); const expectedResult = [ { @@ -67,8 +80,8 @@ describe(`parseSelectorFilters()`, () => { dependencies.processRawSelectorFilters, dependencies.splitSelectorFilter, ); - const urlWithFilters = `{ .btn as .button, .btn-alert as .button-alert } from style.scss`; + const selectorFilters = parseSelectorFilters(urlWithFilters); const expectedResult = [ { @@ -84,13 +97,74 @@ describe(`parseSelectorFilters()`, () => { expect(selectorFilters).toEqual(expectedResult); }); - test(`It should handle special characters.`, () => { + test(`It should ignore curly brackets used in a glob pattern.`, () => { + const parseSelectorFilters = parseSelectorFiltersFactory( + dependencies.processRawSelectorFilters, + dependencies.splitSelectorFilter, + ); + const urlWithFilters = `style{1}.scss`; + + const selectorFilters = parseSelectorFilters(urlWithFilters); + const expectedResult: any[] = []; + + expect(selectorFilters).toEqual(expectedResult); + }); + + test(`It should return selector filters from URL with glob pattern.`, () => { const parseSelectorFilters = parseSelectorFiltersFactory( dependencies.processRawSelectorFilters, dependencies.splitSelectorFilter, ); + const urlWithFilters = `{ .btn, .btn-alert } from style{1}.scss`; + const selectorFilters = parseSelectorFilters(urlWithFilters); + const expectedResult = [ + { + replacement: undefined, + selector: `.btn`, + }, + { + replacement: undefined, + selector: `.btn-alert`, + }, + ]; + + expect(selectorFilters).toEqual(expectedResult); + }); + + test(`It should return selector filters when filter contains \`from\`.`, () => { + const parseSelectorFilters = parseSelectorFiltersFactory( + dependencies.processRawSelectorFilters, + dependencies.splitSelectorFilter, + ); + const urlWithFilters = `{ .btn, .btn-alert, .from } from style.scss`; + + const selectorFilters = parseSelectorFilters(urlWithFilters); + const expectedResult = [ + { + replacement: undefined, + selector: `.btn`, + }, + { + replacement: undefined, + selector: `.btn-alert`, + }, + { + replacement: undefined, + selector: `.from`, + }, + ]; + + expect(selectorFilters).toEqual(expectedResult); + }); + + test(`It should handle special characters.`, () => { + const parseSelectorFilters = parseSelectorFiltersFactory( + dependencies.processRawSelectorFilters, + dependencies.splitSelectorFilter, + ); const urlWithFilters = `{ .btn@m as .button@m } from style.scss`; + const selectorFilters = parseSelectorFilters(urlWithFilters); const expectedResult = [ { @@ -107,8 +181,8 @@ describe(`parseSelectorFilters()`, () => { dependencies.processRawSelectorFilters, dependencies.splitSelectorFilter, ); - const urlWithFilters = `{ /^\\.btn(.*)/i as .button$1 } from style.scss`; + const selectorFilters = parseSelectorFilters(urlWithFilters); const expectedResult = [ { diff --git a/packages/node-sass-magic-importer/src/functions/parse-selector-filters.ts b/packages/node-sass-magic-importer/src/functions/parse-selector-filters.ts index 2584559..f5cb75e 100644 --- a/packages/node-sass-magic-importer/src/functions/parse-selector-filters.ts +++ b/packages/node-sass-magic-importer/src/functions/parse-selector-filters.ts @@ -7,7 +7,15 @@ export function parseSelectorFiltersFactory( splitSelectorFilter: ISplitSelectorFilter, ): IParseSelectorFilters { return (url: string) => { - const selectorFiltersMatch = url.match(/{([\s\S]*)}/); + const filterDivider = /[\n\r\s]+from[\n\r\s]+/; + + if (!filterDivider.test(url)) { + return []; + } + + const selectorFiltersMatch = url + .split(filterDivider)[0] + .match(/{([\s\S]*)}/); if (!selectorFiltersMatch) { return [];