Skip to content

Commit 37fc443

Browse files
committed
chore: Refactor postcss processing for use in tests.
Extracted a method that invokes postcss with the bem converter plugin. The tests in plugin-test.ts have been rewritten to use this extracted method. This avoids a postcss warning because the filename is now provided during processing.
1 parent db25c26 commit 37fc443

File tree

2 files changed

+96
-80
lines changed

2 files changed

+96
-80
lines changed

packages/@css-blocks/bem-to-blocks/src/index.ts

+10-6
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,28 @@ type BlockToBemSelectorMap = Map<string, ElementToBemSelectorMap>;
1515
type BemToBlockClassMap = WeakMap<BemSelector, BlockClassSelector>;
1616

1717
const EMPTY_ELEMENT_PLACEHOLDER = "EMPTY-ELEMENT-PLACEHOLDER";
18-
const COMMON_PREFIXES_FOR_MODIFIERS = ["is"];
1918

2019
export async function convertBemToBlocks(files: Array<string>): Promise<void> {
2120
for (let file of files) {
2221
let fileName = path.relative(process.cwd(), file);
22+
let css = fs.readFileSync(file, "utf-8");
23+
let result = await processBEMContents(fileName, css);
24+
const parsedFilePath = path.parse(file);
25+
const blockFilePath = Object.assign(parsedFilePath, {ext: `.block${parsedFilePath.ext}`, base: undefined} );
26+
await fs.writeFile(path.format(blockFilePath), result);
27+
}
28+
}
29+
30+
export async function processBEMContents(fileName: string, css: string): Promise<string> {
2331
let processor = postcss([
2432
// Using postcss-simple-vars to pass the fileName to the plugin
2533
vars({
2634
variables: () => { return { fileName }; },
2735
}),
2836
bemToBlocksPlugin,
2937
]);
30-
let css = fs.readFileSync(file, "utf-8");
3138
let result = await processor.process(css, { from: fileName});
32-
const parsedFilePath = path.parse(file);
33-
const blockFilePath = Object.assign(parsedFilePath, {ext: `.block${parsedFilePath.ext}`, base: undefined} );
34-
await fs.writeFile(path.format(blockFilePath), result.toString());
35-
}
39+
return result.toString();
3640
}
3741

3842
/**
Original file line numberDiff line numberDiff line change
@@ -1,139 +1,151 @@
1-
21
import { assert } from "chai";
32
import * as inquirer from "inquirer";
4-
import * as postcss from "postcss";
53
import * as sinon from "sinon";
64

7-
import { bemToBlocksPlugin } from "../src/index";
5+
import { processBEMContents } from "../src";
86

97
describe("converts BEM to blocks", () => {
108

119
it("converts simple classes to blocks", async () => {
12-
return postcss([bemToBlocksPlugin])
13-
.process(".jobs-entry__image--inverse-red {color: blue}").then((output) => {
14-
assert.equal(output.toString(), ".image[inverse-red] {color: blue}");
15-
});
10+
let result = await processBEMContents(
11+
"jobs-entry.css",
12+
".jobs-entry__image--inverse-red {color: blue}",
13+
);
14+
15+
assert.equal(result, ".image[inverse-red] {color: blue}");
1616
});
1717

1818
it("existing attributes remain unchanged", async () => {
19-
return postcss([bemToBlocksPlugin])
20-
.process(".jobs-entry__image[state=red] {color: blue}")
21-
.then(output => {
22-
assert.equal(output.toString(), ".image[state=red] {color: blue}");
23-
});
19+
let output = await processBEMContents(
20+
"test-existing-attributes.css",
21+
".jobs-entry__image[state=red] {color: blue}",
22+
);
23+
24+
assert.equal(output, ".image[state=red] {color: blue}");
2425
});
2526

2627
it("selector has attributes and a modifier", async () => {
27-
return postcss([bemToBlocksPlugin])
28-
.process(".jobs-entry__image--big[state=red] {color: blue}")
29-
.then(output => {
30-
assert.equal(output.toString(), ".image[big][state=red] {color: blue}");
31-
});
28+
let output = await processBEMContents(
29+
"attributes-with-modifier.css",
30+
".jobs-entry__image--big[state=red] {color: blue}",
31+
);
32+
33+
assert.equal(output, ".image[big][state=red] {color: blue}");
3234
});
3335

3436
it("comments are left as is", async () => {
35-
return postcss([bemToBlocksPlugin])
36-
.process(`/* adding a comment here */.jobs-entry__image--big[state=red] {color: blue}`)
37-
.then(output => {
38-
assert.equal(output.toString(), `/* adding a comment here */.image[big][state=red] {color: blue}`);
39-
});
37+
let output = await processBEMContents(
38+
"comments-test.css",
39+
"/* adding a comment here */.jobs-entry__image--big[state=red] {color: blue}",
40+
);
41+
42+
assert.equal(output, `/* adding a comment here */.image[big][state=red] {color: blue}`);
4043
});
4144

4245
it("respects pseudo selectors", async () => {
43-
return postcss([bemToBlocksPlugin])
44-
.process(".jobs-entry__image--big::before {color: blue}")
45-
.then(output => {
46-
assert.equal(output.toString(), ".image[big]::before {color: blue}");
47-
});
46+
let output = await processBEMContents(
47+
"pseudo-selectors.css",
48+
".jobs-entry__image--big::before {color: blue}",
49+
);
50+
51+
assert.equal(output, ".image[big]::before {color: blue}");
4852
});
4953

50-
it("respects sibling selectors", async () => {
51-
return postcss([bemToBlocksPlugin])
52-
.process(".jobs-entry__image--big>.jobs-entry__image--small {color: blue}")
53-
.then(output => {
54-
assert.equal(output.toString(), ".image[big]>.image[small] {color: blue}");
55-
});
54+
it("respects child selectors", async () => {
55+
let output = await processBEMContents(
56+
"sibling-selectors.css",
57+
".jobs-entry__image--big > .jobs-entry__image--small {color: blue}",
58+
);
59+
60+
assert.equal(output, ".image[big] > .image[small] {color: blue}");
5661
});
5762

5863
it("respects scss imports", async () => {
59-
return postcss([bemToBlocksPlugin])
60-
.process(`@import "restyle"; .jobs-entry__image--big[state=red] {color: blue}`)
61-
.then(output => {
62-
assert.equal(output.toString(), `@import "restyle"; .image[big][state=red] {color: blue}`);
63-
});
64+
let output = await processBEMContents(
65+
"imports.scss",
66+
`@import "restyle"; .jobs-entry__image--big[state=red] {color: blue}`,
67+
);
68+
69+
assert.equal(output, `@import "restyle"; .image[big][state=red] {color: blue}`);
6470
});
6571

6672
it.skip("respects scss nesting", async () => {
67-
return postcss([bemToBlocksPlugin])
68-
.process(`.jobs-entry__image { &--big {color: blue} }`)
69-
.then(output => {
70-
assert.equal(output.toString(), `.image { &[big] {color: blue} }`);
71-
});
73+
let output = await processBEMContents(
74+
"nesting.scss",
75+
`.jobs-entry__image { &--big {color: blue} }`,
76+
);
77+
78+
assert.equal(output, `.image { &[big] {color: blue} }`);
7279
});
7380

7481
it("other scss syntax", async () => {
75-
return postcss([bemToBlocksPlugin])
76-
.process(`
77-
@mixin artdeco-badge(){
78-
@keyframes artdecoBadgeAnimationIn1 {
82+
let output = await processBEMContents(
83+
"misc.scss",
84+
`
85+
@mixin animations() {
86+
@keyframes animation1 {
7987
from { transform: scale(0);}
8088
to { transform: scale(1.15); }
8189
}
8290
83-
@keyframes artdecoBadgeAnimationIn2 {
91+
@keyframes animation2 {
8492
from { transform: scale(1.15);}
8593
to { transform: scale(1); }
8694
}
87-
}`).then(output => {
88-
assert.equal(output.toString().trim(), `
89-
@mixin artdeco-badge(){
90-
@keyframes artdecoBadgeAnimationIn1 {
95+
}`,
96+
);
97+
98+
assert.equal(
99+
output.trim(),
100+
`@mixin animations() {
101+
@keyframes animation1 {
91102
from { transform: scale(0);}
92103
to { transform: scale(1.15); }
93104
}
94105
95-
@keyframes artdecoBadgeAnimationIn2 {
106+
@keyframes animation2 {
96107
from { transform: scale(1.15);}
97108
to { transform: scale(1); }
98109
}
99-
}`.trim());
100-
});
110+
}`.trim(),
111+
);
101112
});
102113

103114
it("replaces substates correctly", async () => {
104-
return postcss([bemToBlocksPlugin])
105-
.process(`.jobs-entry__image--size-big {color: blue}
106-
.jobs-entry__image--size-small {color: red}`)
107-
.then(output => {
108-
assert.equal(output.toString(), `.image[size="big"] {color: blue}
115+
let output = await processBEMContents(
116+
"substates.scss",
117+
`.jobs-entry__image--size-big {color: blue}
118+
.jobs-entry__image--size-small {color: red}`,
119+
);
120+
121+
assert.equal(output, `.image[size="big"] {color: blue}
109122
.image[size="small"] {color: red}`);
110-
});
111123
});
112124

113125
it("replaces substates correctly when the modifier is on the block", async () => {
114-
return postcss([bemToBlocksPlugin])
115-
.process(`.jobs-entry--size-big {color: blue}
116-
.jobs-entry--size-small {color: red}`)
117-
.then(output => {
118-
assert.equal(output.toString(), `:scope[size="big"] {color: blue}
126+
let output = await processBEMContents(
127+
"substates.scss",
128+
`.jobs-entry--size-big {color: blue}
129+
.jobs-entry--size-small {color: red}`,
130+
);
131+
132+
assert.equal(output, `:scope[size="big"] {color: blue}
119133
:scope[size="small"] {color: red}`);
120-
});
121134
});
122135

123136
it("calls inquirer for user input", async() => {
124-
125137
let stub = sinon.stub(inquirer, "prompt");
126138
// disabling the rule as it expects a Promise<unknown> & {ui:PromptUI}
127139
/* tslint:disable:prefer-unknown-to-any */
128140
stub.onCall(0).returns({block: "my-block"} as any);
129141
stub.onCall(1).returns({element: "my-elem"} as any);
130142
stub.onCall(2).returns({modifier: "my-mod"} as any);
131-
return postcss([bemToBlocksPlugin])
132-
.process(`.CLASSINCAPSTHATISNOTBEM {color: blue}`)
133-
.then((output) => {
134-
assert.equal(output.css, ".my-elem[my-mod] {color: blue}");
135-
assert.equal(stub.calledThrice, true);
143+
let output = await processBEMContents(
144+
"interactive-feedback.scss",
145+
`.CLASSINCAPSTHATISNOTBEM {color: blue}`,
146+
);
136147

137-
});
148+
assert.equal(output, `.my-elem[my-mod] {color: blue}`);
149+
assert.equal(stub.calledThrice, true);
138150
});
139151
});

0 commit comments

Comments
 (0)