300 |
301 |
302 |
303 |
304 | `;
305 | return postcss([
306 | ]).process(html, {
307 | syntax: syntax,
308 | from: "react_inline_styles.html",
309 | }).then(result => {
310 | expect(result.root.nodes).to.be.lengthOf(0);
311 | });
312 | });
313 | });
314 |
--------------------------------------------------------------------------------
/test/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const expect = require("chai").expect;
4 | const syntax = require("../");
5 | describe("api", () => {
6 | it("default", () => {
7 | const root = syntax.parse("a{b:c}");
8 | expect(root.nodes).to.have.lengthOf(1);
9 | expect(root.first).to.have.property("type", "rule");
10 | expect(root.first).to.have.property("selector", "a");
11 | expect(root.first.nodes).to.have.lengthOf(1);
12 | expect(root.first.first).to.have.property("type", "decl");
13 | expect(root.first.first).to.have.property("prop", "b");
14 | expect(root.first.first).to.have.property("value", "c");
15 | });
16 |
17 | it("parse error", () => {
18 | const syntax = require("../syntax")(require("postcss-html/extract"))({
19 | css: {
20 | parse: () => {
21 | throw new Error("mock parse error");
22 | },
23 | },
24 | });
25 | expect(() => {
26 | syntax.parse("");
27 | }).to.throw(/^mock parse error$/);
28 | });
29 |
30 | it("loader return null", () => {
31 | const root = syntax({
32 | rules: [
33 | {
34 | test: /.*/,
35 | extract: "html",
36 | },
37 | ],
38 | }).parse(
39 | "\n".repeat(3)
40 | );
41 | expect(root.nodes).to.have.lengthOf(3);
42 | });
43 |
44 | it("loader opts", () => {
45 | let result;
46 | syntax({
47 | rules: [
48 | {
49 | test: /.*/,
50 | opts: {
51 | loaderOpts: "mock",
52 | },
53 | extract: (source, opts) => {
54 | result = opts;
55 | },
56 | },
57 | ],
58 | }).parse(
59 | "\n".repeat(3),
60 | {
61 | from: "mock.html",
62 | }
63 | );
64 | expect(result).to.have.property("from", "mock.html");
65 | expect(result).to.have.property("loaderOpts", "mock");
66 | });
67 |
68 | describe("standalone with syntax set by extension", () => {
69 | const opts = {
70 | rules: [],
71 | };
72 | [
73 | "css",
74 | "less",
75 | "sass",
76 | "scss",
77 | "sugarss",
78 | "stylus",
79 | ].forEach(lang => {
80 | opts[lang] = {
81 | parse: () => ({
82 | source: {},
83 | lang,
84 | }),
85 | };
86 | });
87 | const mockSyntax = syntax(opts);
88 | function lang (extension) {
89 | return mockSyntax.parse("", {
90 | from: "*." + extension,
91 | }).lang;
92 | }
93 |
94 | it("css", () => {
95 | expect(lang("css")).to.be.equal("css");
96 | });
97 | it("pcss", () => {
98 | expect(lang("pcss")).to.be.equal("css");
99 | });
100 | it("postcss", () => {
101 | expect(lang("postcss")).to.be.equal("css");
102 | });
103 | it("acss", () => {
104 | expect(lang("acss")).to.be.equal("css");
105 | });
106 | it("wxss", () => {
107 | expect(lang("wxss")).to.be.equal("css");
108 | });
109 | it("sass", () => {
110 | expect(lang("sass")).to.be.equal("sass");
111 | });
112 | it("scss", () => {
113 | expect(lang("scss")).to.be.equal("scss");
114 | });
115 | it("less", () => {
116 | expect(lang("less")).to.be.equal("less");
117 | });
118 | it("sugarss", () => {
119 | expect(lang("sss")).to.be.equal("sugarss");
120 | });
121 | it("stylus", () => {
122 | expect(lang("styl")).to.be.equal("stylus");
123 | });
124 | });
125 |
126 | describe("standalone with syntax set by rules", () => {
127 | const opts = {
128 | rules: [
129 | {
130 | test: /.*/,
131 | lang: "mockLang",
132 | },
133 | ],
134 | };
135 | opts.mockLang = {
136 | parse: () => ({
137 | source: {},
138 | lang: "mock lang",
139 | }),
140 | };
141 | const mockSyntax = syntax(opts);
142 | function lang (extension) {
143 | return mockSyntax.parse("", {
144 | from: "*." + extension,
145 | }).lang;
146 | }
147 |
148 | [
149 | "css",
150 | "pcss",
151 | "postcss",
152 | "acss",
153 | "wxss",
154 | "sass",
155 | "scss",
156 | "less",
157 | "sugarss",
158 | "stylus",
159 | ].forEach(extension => {
160 | it(extension, () => {
161 | expect(lang(extension)).to.be.equal("mock lang");
162 | });
163 | });
164 | });
165 | });
166 |
--------------------------------------------------------------------------------
/test/languages.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | const expect = require("chai").expect;
3 | const syntax = require("../");
4 |
5 | // https://github.com/Microsoft/vscode/blob/master/extensions/css/package.json
6 | // https://github.com/Microsoft/vscode/blob/master/extensions/less/package.json
7 |
8 | function testcase (lang, extensions, source) {
9 | describe(lang, () => {
10 | const code = "";
11 | extensions.forEach(ext => {
12 | const file = ext.replace(/^\.*/, "empty.");
13 | it(file, () => {
14 | const document = syntax.parse(code, {
15 | from: file,
16 | });
17 | expect(document.source).to.haveOwnProperty("lang", lang);
18 | expect(document.toString()).to.equal(code);
19 | });
20 | });
21 | if (!source) {
22 | return;
23 | }
24 | source.forEach(code => {
25 | it(JSON.stringify(code), () => {
26 | const document = syntax.parse(code, {
27 | from: undefined,
28 | });
29 | expect(document.source).to.haveOwnProperty("lang", lang);
30 | expect(document.toString()).to.equal(code);
31 | });
32 | });
33 | });
34 | }
35 |
36 | describe("language tests", () => {
37 | testcase("markdown", [
38 | // https://github.com/Microsoft/vscode/blob/master/extensions/markdown-basics/package.json
39 | ".md",
40 | ".mdown",
41 | ".markdown",
42 | ".markdn",
43 | // https://github.com/jshttp/mime-db/blob/master/db.json
44 | // text/x-markdown
45 | ".mkd",
46 | ], [
47 | "# asdadsad",
48 | "# asdadsad\n",
49 | "asdadsad\n====",
50 | "asdadsad\n====\n",
51 | ]);
52 |
53 | testcase("html", [
54 | // https://github.com/Microsoft/vscode/blob/master/extensions/html/package.json
55 | ".html",
56 | ".htm",
57 | ".shtml",
58 | ".xhtml",
59 | ".mdoc",
60 | ".jsp",
61 | ".asp",
62 | ".aspx",
63 | ".jshtm",
64 | ".volt",
65 | ".ejs",
66 | ".rhtml",
67 | // https://github.com/jshttp/mime-db/blob/master/db.json
68 | // application/xhtml+xml
69 | ".xht",
70 | // https://github.com/Microsoft/vscode/blob/master/extensions/xml/package.json
71 | ".xsl",
72 | ".xslt",
73 | // https://vue-loader.vuejs.org/spec.html
74 | // https://github.com/vuejs/vetur/blob/master/package.json
75 | ".vue",
76 | // https://doc.quickapp.cn/framework/source-file.html
77 | ".ux",
78 | // https://github.com/Tencent/wepy/blob/master/docs/md/doc.md#wpy文件说明
79 | ".wpy",
80 | // https://github.com/mblode/vscode-twig-language/blob/master/package.json
81 | ".twig",
82 | // https://github.com/GingerBear/vscode-liquid/blob/master/package.json
83 | ".liquid",
84 | // https://github.com/UnwrittenFun/svelte-vscode/blob/master/package.json
85 | ".svelte",
86 | // https://github.com/Microsoft/vscode/blob/master/extensions/php/package.json
87 | ".php",
88 | ".php4",
89 | ".php5",
90 | ".phtml",
91 | ".ctp",
92 | ], [
93 | "",
94 | "",
95 | "",
96 | "",
97 | "",
98 | "",
99 | "
",
100 | "
",
101 | "\n",
102 | "\n
\n",
103 | "\n
",
104 | "\n",
105 | "",
106 | "",
107 | "\n",
110 | ]);
111 |
112 | testcase("jsx", [
113 | // https://github.com/Microsoft/vscode/blob/master/extensions/javascript/package.json
114 | // javascript
115 | ".js",
116 | ".es6",
117 | ".mjs",
118 | ".cjs",
119 | ".pac",
120 | // javascriptreact
121 | ".jsx",
122 | // https://github.com/Microsoft/vscode/blob/master/extensions/typescript-basics/package.json
123 | // typescript
124 | ".ts",
125 | // typescriptreact
126 | ".tsx",
127 | // https://github.com/michaelgmcd/vscode-language-babel/blob/master/package.json
128 | ".babel",
129 | ".flow",
130 | ], [
131 | "#!/usr/bin/env node",
132 | "#!~/.nvm/versions/node/v8.9.1/bin/node",
133 | "#!/c/Program Files/nodejs/node.exe",
134 |
135 | "\"use strict\";",
136 | "'use strict';",
137 | "\"use strict\"",
138 | "'use strict'",
139 | "\"use strict\";\nalert(0)",
140 |
141 | "// @flow\n'use strict';",
142 | "/* @flow */\n'use strict';",
143 | "// @flow\n/* @flow */'use strict';",
144 |
145 | "// @flow\nrequire('flow');",
146 | "/* @flow */\nrequire('flow');",
147 | "// @flow\n/* @flow */require('flow');",
148 |
149 | "// @flow\nimport('flow');",
150 | "/* @flow */\nimport('flow');",
151 | "// @flow\n/* @flow */import('flow');",
152 |
153 | "import React from 'react'",
154 | "import defaultExport from \"module-name\";",
155 | "import * as name from \"module-name\";",
156 | "import { export } from \"module-name\";",
157 | "import { export as alias } from \"module-name\";",
158 | "import { export1 , export2 } from \"module-name\";",
159 | "import { export1 , export2 as alias2 , [...] } from \"module-name\";",
160 | "import defaultExport, { export [ , [...] ] } from \"module-name\";",
161 | "import defaultExport, * as name from \"module-name\";",
162 | "import \"module-name\";",
163 | "import styled from 'styled-components';export default styled.div`padding-left: 10px; padding: 20px`;",
164 |
165 | "const styled=require('styled-components');module.exports=styled.div`padding-left: 10px; padding: 20px`;",
166 | "require('a');",
167 | "var a = require('a');",
168 | "var a=require('a');",
169 | "import(\"a\");",
170 | "const a = import('a');",
171 | // https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export
172 | // https://github.com/tc39/proposal-export-default-from
173 | // https://www.npmjs.com/package/babel-plugin-transform-export-extensions
174 | "export var v;",
175 | "export default function f(){}",
176 | "export default function(){}",
177 | "export default class {}",
178 | "export default 42;",
179 | "export defaultExport from \"module-name\";",
180 | "export { named };",
181 | "export { named as alias };",
182 | "export { named } from \"module-name\";",
183 | "export { named as alias } from \"module-name\";",
184 | "export { named1, namedExport2 } from \"module-name\";",
185 | "export { named1, named2 as alias2, [...] } from \"module-name\";",
186 | "export * from \"module-name\"",
187 | "export * as defaultExport from \"module-name\"",
188 | "export defaultExport, { named1, named2 as alias2 } from \"module-name\";",
189 | ]);
190 |
191 | testcase("css", [
192 | // WXSS(WeiXin Style Sheets) See: https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxss.html
193 | // acss(AntFinancial Style Sheet) See: https://docs.alipay.com/mini/framework/acss
194 | // `*.pcss`, `*.postcss`
195 | ".css",
196 | ".pcss",
197 | ".postcss",
198 | ".acss",
199 | ".wxss",
200 | ".Unknown",
201 | ], [
202 | "",
203 | "a{b:c}",
204 | ]);
205 |
206 | testcase("xml", [
207 | // https://github.com/Microsoft/vscode/blob/master/extensions/xml/package.json
208 | ".xml",
209 | ".xsd",
210 | ".ascx",
211 | ".atom",
212 | ".axml",
213 | ".bpmn",
214 | ".config",
215 | ".cpt",
216 | ".csl",
217 | ".csproj",
218 | ".csproj.user",
219 | ".dita",
220 | ".ditamap",
221 | ".dtd",
222 | ".dtml",
223 | ".fsproj",
224 | ".fxml",
225 | ".iml",
226 | ".isml",
227 | ".jmx",
228 | ".launch",
229 | ".menu",
230 | ".mxml",
231 | ".nuspec",
232 | ".opml",
233 | ".owl",
234 | ".proj",
235 | ".props",
236 | ".pt",
237 | ".publishsettings",
238 | ".pubxml",
239 | ".pubxml.user",
240 | ".rdf",
241 | ".rng",
242 | ".rss",
243 | ".shproj",
244 | ".storyboard",
245 | ".svg",
246 | ".targets",
247 | ".tld",
248 | ".tmx",
249 | ".vbproj",
250 | ".vbproj.user",
251 | ".vcxproj",
252 | ".vcxproj.filters",
253 | ".wsdl",
254 | ".wxi",
255 | ".wxl",
256 | ".wxs",
257 | ".xaml",
258 | ".xbl",
259 | ".xib",
260 | ".xlf",
261 | ".xliff",
262 | ".xpdl",
263 | ".xul",
264 | ".xoml",
265 | ], [
266 | "",
267 | "",
268 | ]);
269 |
270 | testcase("stylus", [
271 | // https://github.com/d4rkr00t/language-stylus/blob/master/package.json
272 | ".styl",
273 | ".stylus",
274 | ]);
275 | });
276 |
--------------------------------------------------------------------------------
/test/load-syntax.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const expect = require("chai").expect;
4 | const postcss = require("postcss");
5 | const syntax = require("../syntax")(require("postcss-html/extract"));
6 |
7 | describe("load-syntax", () => {
8 | it("template value in quickapp", () => {
9 | return postcss().process([
10 | "",
11 | "\t{{notice.txt}}",
12 | "\t{{notice.txt}}",
13 | "",
14 | ].join("\n"), {
15 | syntax,
16 | from: "http://somehost.com/??quickapp.ax?v=102234",
17 | }).then(result => {
18 | expect(result.root.nodes).to.have.lengthOf(2);
19 | });
20 | });
21 | it("template value in quickapp with `postcss-safe-parser`", () => {
22 | return postcss().process([
23 | "",
24 | "\t{{notice.txt}}",
25 | "\t{{notice.txt}}",
26 | "",
27 | ].join("\n"), {
28 | syntax: syntax({
29 | css: require.resolve("postcss-safe-parser"),
30 | }),
31 | from: "quickapp.ax",
32 | }).then(result => {
33 | expect(result.root.nodes).to.have.lengthOf(2);
34 | });
35 | });
36 | });
37 |
--------------------------------------------------------------------------------
/test/markdown.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const expect = require("chai").expect;
4 | const syntax = require("../")({
5 | rules: [
6 | {
7 | test: /\.md$/,
8 | extract: require("postcss-markdown/extract"),
9 | },
10 | {
11 | test: /\.html$/,
12 | extract: require("postcss-html/extract"),
13 | },
14 | ],
15 | });
16 |
17 | describe("markdown tests", () => {
18 | it("CSS", () => {
19 | const md = [
20 | "---",
21 | "title: Something Special",
22 | "---",
23 | "Here is some text.",
24 | "```css",
25 | ".foo {}",
26 | "```",
27 | "And some other text.",
28 | "```css",
29 | " .foo { color: pink; }",
30 | " .bar {}",
31 | "```",
32 | "",
37 | "```scss",
38 | "// Parser-breaking comment",
39 | "$foo: bar;",
40 | ".foo {}",
41 | "```",
42 | "```js",
43 | "",
46 | "```",
47 | "```html",
48 | "",
51 | "```",
52 | "And the end.",
53 | ].join("\n");
54 | const root = syntax.parse(md, {
55 | from: "markdown.md",
56 | });
57 | expect(root.nodes).to.have.lengthOf(5);
58 | expect(root.toString()).to.equal(md);
59 | });
60 |
61 | it("empty code block", () => {
62 | const source = [
63 | "hi",
64 | "",
65 | "```css",
66 | "",
67 | "```",
68 | "",
69 | ].join("\n");
70 | const root = syntax.parse(source, {
71 | from: "empty_code_block.md",
72 | });
73 | expect(root.nodes).to.have.lengthOf(1);
74 | const css = root.first.source;
75 | expect(css.lang).equal("css");
76 | expect(css.input.css).equal("\n");
77 | expect(css.start.line).equal(4);
78 | expect(css.start.column).equal(1);
79 | });
80 |
81 | it("empty file", () => {
82 | const root = syntax.parse("", {
83 | from: "empty_file.md",
84 | });
85 | expect(root.nodes).have.lengthOf(0);
86 | expect(root.toString()).to.equal("");
87 | });
88 |
89 | it("without code blocks", () => {
90 | const root = syntax.parse("# Hi\n", {
91 | from: "without_code_blocks.md",
92 | });
93 | expect(root.nodes).to.have.lengthOf(0);
94 | expect(root.toString()).to.equal("# Hi\n");
95 | });
96 | });
97 |
--------------------------------------------------------------------------------
/test/parse-style.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | const parseStyle = require("../parse-style");
3 | const postcss = require("postcss");
4 | const expect = require("chai").expect;
5 |
6 | describe("parse-style", () => {
7 | it("style.ignoreErrors", () => {
8 | parseStyle("test", {}, [
9 | {
10 | syntax: {
11 | },
12 | ignoreErrors: true,
13 | },
14 | ]);
15 | });
16 |
17 | it("fix error.column", () => {
18 | let error;
19 | try {
20 | parseStyle("test", {}, [
21 | {
22 | startIndex: 9,
23 | content: "a {",
24 | syntax: postcss,
25 | },
26 | ]);
27 | } catch (ex) {
28 | error = ex;
29 | }
30 | expect(error.column).to.equal(10);
31 | });
32 |
33 | it("skipConvert error.column", () => {
34 | let error;
35 | try {
36 | parseStyle("test", {}, [
37 | {
38 | startIndex: 9,
39 | skipConvert: true,
40 | content: "a {",
41 | syntax: postcss,
42 | },
43 | ]);
44 | } catch (ex) {
45 | error = ex;
46 | }
47 | expect(error.column).to.equal(1);
48 | });
49 | });
50 |
--------------------------------------------------------------------------------
/test/safe.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const expect = require("chai").expect;
4 | const postcss = require("postcss");
5 | const syntax = require("../")({
6 | css: "postcss-safe-parser",
7 | });
8 |
9 | describe("postcss-safe-parser", () => {
10 | it("a{", () => {
11 | return postcss([
12 | root => {
13 | expect(root.nodes).to.have.lengthOf(1);
14 | },
15 | ]).process("a{", {
16 | syntax,
17 | from: "postcss-safe-parser.css",
18 | }).then(result => {
19 | expect(result.content).to.equal("a{}");
20 | });
21 | });
22 | });
23 |
--------------------------------------------------------------------------------
/test/sugarss.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const expect = require("chai").expect;
4 | const postcss = require("postcss");
5 | const syntax = require("../");
6 | const sugarss = require("sugarss");
7 |
8 | describe("SugarSS tests", () => {
9 | let sss = [
10 | ".one",
11 | "\tbackground: linear-gradient(rgba(0, 0, 0, 0), black)",
12 | "\t\tlinear-gradient(red, rgba(255, 0, 0, 0))",
13 | ];
14 | const css = [
15 | sss[0] + " {",
16 | sss[1],
17 | sss[2],
18 | "}",
19 | ].join("\n");
20 |
21 | sss = sss.join("\n");
22 |
23 | it("SugarSS to CSS, `syntax({ sugarss: { parse: sugarss.parse } })`", () => {
24 | return postcss([
25 | root => {
26 | expect(root.nodes).to.have.lengthOf(1);
27 | },
28 | ]).process(sss, {
29 | syntax: syntax({
30 | sugarss: {
31 | parse: sugarss.parse,
32 | },
33 | }),
34 | from: "SugarSS.sss",
35 | }).then(result => {
36 | expect(result.content).to.equal(css);
37 | });
38 | });
39 |
40 | it("SugarSS to CSS, `syntax({ sugarss: sugarss.parse })`", () => {
41 | return postcss([
42 | root => {
43 | expect(root.nodes).to.have.lengthOf(1);
44 | },
45 | ]).process(sss, {
46 | syntax: syntax({
47 | sugarss: sugarss.parse,
48 | }),
49 | from: "SugarSS.sss",
50 | }).then(result => {
51 | expect(result.content).to.equal(css);
52 | });
53 | });
54 |
55 | it("SugarSS toString()", () => {
56 | const root = syntax({
57 | sugarss: sugarss,
58 | }).parse(sss, {
59 | from: "SugarSS.sss",
60 | });
61 | expect(root.source).to.haveOwnProperty("lang", "sugarss");
62 | expect(root.toString()).to.be.equal(sss);
63 | expect(root.toString(root.source.syntax)).to.be.equal(sss);
64 | });
65 |
66 | it("SugarSS in vue", () => {
67 | const vue = [
68 | "",
71 | ].join("\n");
72 | return postcss([
73 | root => {
74 | expect(root.nodes).to.have.lengthOf(1);
75 | root.each(() => false);
76 | },
77 | ]).process(vue, {
78 | syntax,
79 | from: "sugarss.vue",
80 | }).then(result => {
81 | expect(result.root.first.source).to.haveOwnProperty("lang", "sugarss");
82 | expect(result.content).to.equal(vue);
83 | });
84 | });
85 | });
86 |
--------------------------------------------------------------------------------
/test/vue.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const expect = require("chai").expect;
4 | const syntax = require("../syntax")(require("postcss-html/extract"));
5 |
6 | describe("vue tests", () => {
7 | it("vue with empty ",
10 | "",
12 | ].join("\n");
13 | const root = syntax({
14 | "css": "css",
15 | }).parse(vue, {
16 | from: "empty.vue",
17 | });
18 | expect(root.first.source.lang).to.equal("css");
19 | expect(root.last.source.lang).to.equal("stylus");
20 | expect(root.nodes).to.have.lengthOf(2);
21 | root.nodes.forEach(root => {
22 | expect(root.nodes).to.have.lengthOf(0);
23 | });
24 | expect(root.toString()).to.equal(vue);
25 | });
26 |
27 | it("safe-parser", () => {
28 | const vue = [
29 | "",
30 | "",
32 | ].join("\n");
33 | const root = syntax({
34 | css: "postcss-safe-parser",
35 | }).parse(vue, {
36 | from: "empty.vue",
37 | });
38 | expect(root.first.source.lang).to.equal("css");
39 | expect(root.last.source.lang).to.equal("stylus");
40 | expect(root.nodes).to.have.lengthOf(2);
41 | root.nodes.forEach(root => {
42 | expect(root.nodes).to.have.lengthOf(0);
43 | });
44 | expect(root.toString()).to.equal(vue);
45 | });
46 |
47 | it("vue with lang(s)", () => {
48 | const vue = [
49 | "",
60 | "",
76 | ].join("\n");
77 | const root = syntax.parse(vue, {
78 | from: "lang.vue",
79 | });
80 | expect(root.nodes).to.have.lengthOf(2);
81 | expect(root.first.source.lang).to.equal("scss");
82 | expect(root.last.source.lang).to.equal("less");
83 | expect(root.toString()).to.equal(vue);
84 | });
85 |
86 | it("single line syntax error", () => {
87 | expect(() => {
88 | syntax.parse("", {
89 | from: "SyntaxError.vue",
90 | });
91 | }).to.throw(/SyntaxError.vue:1:8: Unclosed block\b/);
92 | });
93 | });
94 |
--------------------------------------------------------------------------------