Skip to content

Commit 68866a1

Browse files
committed
merge with master
2 parents 0d6c50d + 9db891d commit 68866a1

File tree

2 files changed

+84
-18
lines changed

2 files changed

+84
-18
lines changed

__tests__/postcss-import-sub.test.js

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,11 @@ fs.__setMockFiles([
4949
]);
5050

5151
describe('postcss-import-sub', () => {
52+
5253
it ('relative `to` substitution', () => {
5354
const render = mockRender(sub([
5455
{
55-
id: new RegExp("red\.css"),
56+
id: /red\.css/,
5657
to: "blue.css"
5758
}
5859
]));
@@ -65,7 +66,7 @@ describe('postcss-import-sub', () => {
6566
it ('relative `to` substitution with dot', () => {
6667
const render = mockRender(sub([
6768
{
68-
id: new RegExp("red\.css"),
69+
id: /red\.css/,
6970
to: "./blue.css"
7071
}
7172
]));
@@ -78,7 +79,7 @@ describe('postcss-import-sub', () => {
7879
it ('absolute `to` substitution', () => {
7980
const render = mockRender(sub([
8081
{
81-
id: new RegExp("red\.css"),
82+
id: /red\.css/,
8283
to: "<root>/app/Components/Box/blue.css"
8384
}
8485
]));
@@ -91,7 +92,7 @@ describe('postcss-import-sub', () => {
9192
it ('relative `path` substitution with dot', () => {
9293
const render = mockRender(sub([
9394
{
94-
id: new RegExp("red\.css"),
95+
id: /red\.css/,
9596
path: "<root>/app/Theme/Components/Box/"
9697
}
9798
]));
@@ -104,7 +105,7 @@ describe('postcss-import-sub', () => {
104105
it ('relative `path` substitution with without ending slash', () => {
105106
const render = mockRender(sub([
106107
{
107-
id: new RegExp("red\.css"),
108+
id: /red\.css/,
108109
path: "<root>/app/Theme/Components/Box"
109110
}
110111
]));
@@ -117,7 +118,7 @@ describe('postcss-import-sub', () => {
117118
it ('absolute `to` substitution with alias', () => {
118119
const render = mockRender(sub([
119120
{
120-
id: new RegExp("red\.css"),
121+
id: /red\.css/,
121122
to: "<root>/app/Theme/Components/Box/<id>"
122123
}
123124
]));
@@ -130,7 +131,7 @@ describe('postcss-import-sub', () => {
130131
it ('absolute `to` substitution with alias', () => {
131132
const render = mockRender(sub([
132133
{
133-
id: new RegExp("red\.css"),
134+
id: /red\.css/,
134135
to: "<root>/app/Theme/Components/Box/<id>"
135136
}
136137
]));
@@ -143,7 +144,7 @@ describe('postcss-import-sub', () => {
143144
it ('relative `path` with custom aliases', () => {
144145
const render = mockRender(sub([
145146
{
146-
id: new RegExp("red\.css"),
147+
id: /red\.css/,
147148
base: /Components\/([a-z0-9]+)\//i,
148149
path: "<root>/app/Theme/Components/<base:$1>/"
149150
}
@@ -180,4 +181,34 @@ describe('postcss-import-sub', () => {
180181
expect(module[0]).toBe("app/Theme/Components/Box/red.css");
181182
});
182183
});
184+
185+
it ('append mode', () => {
186+
const render = mockRender(sub([
187+
{
188+
module: /\/([a-z0-9]+)\/([a-z0-9]+)\.css/i,
189+
to: "<root>/app/Theme/Components/<module:$1>/<module:$2>.css",
190+
append: true
191+
}
192+
]));
193+
return render("red.css", "app/Components/Box/")
194+
.then(function(module) {
195+
expect(module[0]).toBe("app/Components/Box/red.css");
196+
expect(module[1]).toBe("app/Theme/Components/Box/red.css");
197+
});
198+
});
199+
200+
it ('append mode unresolved', () => {
201+
const render = mockRender(sub([
202+
{
203+
module: /no.css/i,
204+
to: "<root>/app/Theme/Components/<module:$1>/<module:$2>.css",
205+
append: true
206+
}
207+
]));
208+
return render("red.css", "app/Components/Box/")
209+
.then(function(module) {
210+
expect(module[0]).toBe("red.css");
211+
expect(module.length).toBe(1);
212+
});
213+
});
183214
});

index.js

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ function sepToUnix(p) {
1616
* Test is file exists
1717
*/
1818
function testFileExists(filename) {
19-
return fs.existsSync(filename);
19+
return fs.existsSync(filename[0]);
2020
}
2121
/**
2222
* Simple replace string with key:value in holders
@@ -117,17 +117,37 @@ function resolveAsync(p, base) {
117117
}
118118
}
119119
/**
120+
* Select only rules witj extend property
121+
*/
122+
function ruleCheckAppend(rule) {
123+
return Object.prototype.hasOwnProperty.call(rule, 'append')&&rule.append;
124+
}
125+
/**
120126
* Search module in rules existing
121127
*/
122-
function isHasModule(rules) {
128+
function isHasModuleOrAppend(rules) {
123129
for (let i = 0; i < rules.length; ++i) {
124-
if (Object.prototype.hasOwnProperty.call(rules[i], 'module')) {
130+
if (
131+
Object.prototype.hasOwnProperty.call(rules[i], 'module') ||
132+
(Object.prototype.hasOwnProperty.call(rules[i], 'append') && rules[i].append)
133+
) {
125134
return true;
126135
}
127136
}
128137
return false;
129138
}
130-
139+
/**
140+
* Pick first value from Array<Array>
141+
*/
142+
function pickFirst(item) {
143+
return item[0];
144+
}
145+
/**
146+
* Pick second value from Array<Array>
147+
*/
148+
function pickSecond(item) {
149+
return item[1];
150+
}
131151
function sub(options) {
132152
/**
133153
* Support simple mode of rules definition
@@ -148,7 +168,7 @@ function sub(options) {
148168
/**
149169
* Search module testing rules
150170
*/
151-
const isModuleRequired = isHasModule(options.sub);
171+
const isModuleRequired = isHasModuleOrAppend(options.sub);
152172
/**
153173
* Define real options
154174
*/
@@ -193,6 +213,7 @@ function sub(options) {
193213
})
194214
.then(function(parcle) {
195215
return Promise.all(parcle[0].map(function(rule) {
216+
let resolver;
196217
/**
197218
* Match id
198219
*/
@@ -220,19 +241,33 @@ function sub(options) {
220241
* Parse aliases and resolve final path
221242
*/
222243
if (rule.to) {
223-
return resolveAsync(replace(rule.to, holders), base);
244+
resolver = resolveAsync(replace(rule.to, holders), base)
224245
} else {
225-
return resolveAsync(id, resolveSync(replace(rule.path, holders), base), importOptions);
246+
resolver = resolveAsync(id, resolveSync(replace(rule.path, holders), base), importOptions);
226247
}
227-
}));
248+
return resolver
249+
.then(function(file) {
250+
return [file, rule];
251+
});
252+
}))
253+
.then(function(files) {
254+
return [files, parcle[1]];
255+
});
228256
})
229-
.then(function(files) {
257+
.then(function(parcle) {
258+
const files = parcle[0];
259+
const module = parcle[1];
230260
const existsFiles = files.filter(testFileExists);
231261
/**
232262
* If at least one of file exists, we returns them
233263
*/
234264
if (existsFiles.length>0) {
235-
return existsFiles;
265+
const isAppendModule = (
266+
existsFiles
267+
.map(pickSecond)
268+
.filter(ruleCheckAppend).length>0
269+
);
270+
return (isAppendModule ? [module] : []).concat(existsFiles.map(pickFirst));
236271
}
237272
/**
238273
* On fail we must check for use resolve function to execute it

0 commit comments

Comments
 (0)