Skip to content

Commit c5905ec

Browse files
committed
trump filename sort order with pattern.md frontmatter property "order"
unit tests to coverage scenario support is only for patterns at this time, not type / subtype documentation / directories part of #376
1 parent 027a26d commit c5905ec

File tree

5 files changed

+180
-39
lines changed

5 files changed

+180
-39
lines changed

core/lib/object_factory.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ var Pattern = function (relPath, data, patternlab) {
7171
this.lineageR = [];
7272
this.lineageRIndex = [];
7373
this.isPseudoPattern = false;
74+
this.order = Number.MAX_SAFE_INTEGER;
7475
this.engine = patternEngines.getEngineForPattern(this);
7576
};
7677

core/lib/patternlab.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* patternlab-node - v2.6.2 - 2016
2+
* patternlab-node - v2.7.0 - 2016
33
*
44
* Brian Muenzenmeyer, Geoff Pursell, and the web community.
55
* Licensed under the MIT license.

core/lib/ui_builder.js

Lines changed: 74 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ var ui_builder = function () {
115115
var docPattern = patternlab.subtypePatterns[pattern.patternGroup + (isSubtypePattern ? '-' + pattern.patternSubGroup : '')];
116116
if (docPattern) {
117117
docPattern.isDocPattern = true;
118+
docPattern.order = -Number.MAX_SAFE_INTEGER;
118119
return docPattern;
119120
}
120121

@@ -130,7 +131,8 @@ var ui_builder = function () {
130131
isPattern: false,
131132
engine: null,
132133
flatPatternPath: pattern.flatPatternPath,
133-
isDocPattern: true
134+
isDocPattern: true,
135+
order: -Number.MAX_SAFE_INTEGER
134136
},
135137
patternlab
136138
);
@@ -199,16 +201,16 @@ var ui_builder = function () {
199201
* @param pattern - the pattern to register
200202
*/
201203
function addPatternSubType(patternlab, pattern) {
204+
let newSubType = {
205+
patternSubtypeLC: pattern.patternSubGroup.toLowerCase(),
206+
patternSubtypeUC: pattern.patternSubGroup.charAt(0).toUpperCase() + pattern.patternSubGroup.slice(1),
207+
patternSubtype: pattern.patternSubType,
208+
patternSubtypeDash: pattern.patternSubGroup, //todo verify
209+
patternSubtypeItems: []
210+
};
202211
var patternType = getPatternType(patternlab, pattern);
203-
patternType.patternTypeItems.push(
204-
{
205-
patternSubtypeLC: pattern.patternSubGroup.toLowerCase(),
206-
patternSubtypeUC: pattern.patternSubGroup.charAt(0).toUpperCase() + pattern.patternSubGroup.slice(1),
207-
patternSubtype: pattern.patternSubType,
208-
patternSubtypeDash: pattern.patternSubGroup, //todo verify
209-
patternSubtypeItems: []
210-
}
211-
);
212+
let insertIndex = _.sortedIndexBy(patternType.patternTypeItems, newSubType, 'patternSubtype');
213+
patternType.patternTypeItems.splice(insertIndex, 0, newSubType);
212214
}
213215

214216
/**
@@ -230,7 +232,8 @@ var ui_builder = function () {
230232
patternName: pattern.patternName,
231233
patternState: pattern.patternState,
232234
patternSrcPath: encodeURI(pattern.subdir + '/' + pattern.fileName),
233-
patternPath: patternPath
235+
patternPath: patternPath,
236+
order: pattern.order
234237
};
235238
}
236239

@@ -242,23 +245,25 @@ var ui_builder = function () {
242245
* @param createViewAllVariant - whether or not to create the special view all item
243246
*/
244247
function addPatternSubTypeItem(patternlab, pattern, createSubtypeViewAllVarient) {
245-
var patternSubType = getPatternSubType(patternlab, pattern);
248+
let newSubTypeItem;
249+
246250
if (createSubtypeViewAllVarient) {
247-
patternSubType.patternSubtypeItems.push(
248-
{
249-
patternPartial: 'viewall-' + pattern.patternGroup + '-' + pattern.patternSubGroup,
250-
patternName: 'View All',
251-
patternPath: encodeURI(pattern.flatPatternPath + '/index.html'),
252-
patternType: pattern.patternType,
253-
patternSubtype: pattern.patternSubtype
254-
}
255-
);
251+
newSubTypeItem = {
252+
patternPartial: 'viewall-' + pattern.patternGroup + '-' + pattern.patternSubGroup,
253+
patternName: 'View All',
254+
patternPath: encodeURI(pattern.flatPatternPath + '/index.html'),
255+
patternType: pattern.patternType,
256+
patternSubtype: pattern.patternSubtype,
257+
order: 0
258+
};
256259
}
257260
else {
258-
patternSubType.patternSubtypeItems.push(
259-
createPatternSubTypeItem(pattern)
260-
);
261+
newSubTypeItem = createPatternSubTypeItem(pattern);
261262
}
263+
264+
let patternSubType = getPatternSubType(patternlab, pattern);
265+
patternSubType.patternSubtypeItems.push(newSubTypeItem);
266+
patternSubType.patternSubtypeItems = _.sortBy(patternSubType.patternSubtypeItems, ['order', 'name']);
262267
}
263268

264269
/**
@@ -284,13 +289,15 @@ var ui_builder = function () {
284289
patternType.patternItems.push({
285290
patternPartial: 'viewall-' + pattern.patternGroup + '-all',
286291
patternName: 'View All',
287-
patternPath: encodeURI(pattern.patternType + '/index.html')
292+
patternPath: encodeURI(pattern.patternType + '/index.html'),
293+
order: -Number.MAX_SAFE_INTEGER
288294
});
289295
}
290296

291297
} else {
292298
patternType.patternItems.push(createPatternSubTypeItem(pattern));
293299
}
300+
patternType.patternItems = _.sortBy(patternType.patternItems, ['order', 'name']);
294301
}
295302

296303
// function getPatternItems(patternlab, patternType) {
@@ -302,20 +309,54 @@ var ui_builder = function () {
302309
// }
303310

304311
/**
305-
* Sorts patterns based on name.
306-
* Will be expanded to use explicit order in the near future
312+
* Sorts patterns based on order property found within pattern markdown, falling back on name.
307313
* @param patternsArray - patterns to sort
308314
* @returns sorted patterns
309315
*/
310316
function sortPatterns(patternsArray) {
311317
return patternsArray.sort(function (a, b) {
312318

313-
if (a.name > b.name) {
314-
return 1;
319+
let aOrder = parseInt(a.order, 10);
320+
let bOrder = parseInt(b.order, 10);
321+
322+
if (aOrder === NaN) {
323+
aOrder = Number.MAX_SAFE_INTEGER;
324+
}
325+
326+
if (bOrder === NaN) {
327+
aOrder = Number.MAX_SAFE_INTEGER;
315328
}
316-
if (a.name < b.name) {
329+
330+
//alwasy return a docPattern first
331+
if (a.isDocPattern && !b.isDocPattern) {
317332
return -1;
318333
}
334+
335+
if (!a.isDocPattern && b.isDocPattern) {
336+
return 1;
337+
}
338+
339+
//use old alphabetical ordering if we have nothing else to use
340+
//pattern.order will be Number.MAX_SAFE_INTEGER if never defined by markdown, or markdown parsing fails
341+
if (aOrder === Number.MAX_SAFE_INTEGER && bOrder === Number.MAX_SAFE_INTEGER) {
342+
343+
if (a.name > b.name) {
344+
return 1;
345+
}
346+
if (a.name < b.name) {
347+
return -1;
348+
}
349+
}
350+
351+
//if we get this far, we can sort safely
352+
if (aOrder && bOrder) {
353+
if (aOrder > bOrder) {
354+
return 1;
355+
}
356+
if (aOrder < bOrder) {
357+
return -1;
358+
}
359+
}
319360
return 0;
320361
});
321362
}
@@ -330,7 +371,7 @@ var ui_builder = function () {
330371
patternGroups: {}
331372
};
332373

333-
_.forEach(sortPatterns(patternlab.patterns), function (pattern) {
374+
_.forEach(patternlab.patterns, function (pattern) {
334375

335376
//ignore patterns we can omit from rendering directly
336377
pattern.omitFromStyleguide = isPatternExcluded(pattern, patternlab);
@@ -459,8 +500,8 @@ var ui_builder = function () {
459500
//render the footer needed for the viewall template
460501
var footerHTML = buildFooterHTML(patternlab, 'viewall-' + patternPartial);
461502

462-
//render the viewall template
463-
var subtypePatterns = _.values(patternSubtypes);
503+
//render the viewall template by finding these smallest subtype-grouped patterns
504+
var subtypePatterns = sortPatterns(_.values(patternSubtypes));
464505

465506
//determine if we should write at this time by checking if these are flat patterns or grouped patterns
466507
p = _.find(subtypePatterns, function (pat) {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "patternlab-node",
33
"description": "Pattern Lab is a collection of tools to help you create atomic design systems. This is the node command line interface (CLI).",
4-
"version": "2.6.2",
4+
"version": "2.7.0",
55
"main": "./core/lib/patternlab.js",
66
"dependencies": {
77
"diveSync": "^0.3.0",

test/ui_builder_tests.js

Lines changed: 103 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
var tap = require('tap');
44
var rewire = require("rewire");
5+
var _ = require('lodash');
56
var eol = require('os').EOL;
67
var Pattern = require('../core/lib/object_factory').Pattern;
78
var extend = require('util')._extend;
@@ -120,8 +121,8 @@ tap.test('groupPatterns - creates pattern groups correctly', function (test) {
120121
});
121122

122123
patternlab.patterns.push(
123-
new Pattern('00-test/foo.mustache'),
124124
new Pattern('00-test/bar.mustache'),
125+
new Pattern('00-test/foo.mustache'),
125126
new Pattern('patternType1/patternSubType1/blue.mustache'),
126127
new Pattern('patternType1/patternSubType1/red.mustache'),
127128
new Pattern('patternType1/patternSubType1/yellow.mustache'),
@@ -134,22 +135,120 @@ tap.test('groupPatterns - creates pattern groups correctly', function (test) {
134135
//act
135136
var result = ui.groupPatterns(patternlab);
136137

137-
//assert
138138
test.equals(result.patternGroups.patternType1.patternSubType1.blue.patternPartial, 'patternType1-blue');
139139
test.equals(result.patternGroups.patternType1.patternSubType1.red.patternPartial, 'patternType1-red');
140140
test.equals(result.patternGroups.patternType1.patternSubType1.yellow.patternPartial, 'patternType1-yellow');
141141
test.equals(result.patternGroups.patternType1.patternSubType2.black.patternPartial, 'patternType1-black');
142142
test.equals(result.patternGroups.patternType1.patternSubType2.grey.patternPartial, 'patternType1-grey');
143143
test.equals(result.patternGroups.patternType1.patternSubType2.white.patternPartial, 'patternType1-white');
144144

145-
test.equals(patternlab.patternTypes[0].patternItems[0].patternPartial, 'test-bar');
146-
test.equals(patternlab.patternTypes[0].patternItems[1].patternPartial, 'test-foo');
145+
test.equals(patternlab.patternTypes[0].patternItems[0].patternPartial, 'test-bar', 'first pattern item should be test-bar');
146+
test.equals(patternlab.patternTypes[0].patternItems[1].patternPartial, 'test-foo', 'second pattern item should be test-foo');
147147

148148
//todo: patternlab.patternTypes[0].patternItems[1] looks malformed
149149

150150
test.end();
151151
});
152152

153+
tap.test('groupPatterns - orders patterns when provided from md', function (test) {
154+
//arrange
155+
var patternlab = createFakePatternLab({
156+
patterns: [],
157+
patternGroups: {},
158+
subtypePatterns: {}
159+
});
160+
161+
patternlab.patterns.push(
162+
new Pattern('patternType1/patternSubType1/blue.mustache'),
163+
new Pattern('patternType1/patternSubType1/red.mustache'),
164+
new Pattern('patternType1/patternSubType1/yellow.mustache')
165+
);
166+
ui.resetUIBuilderState(patternlab);
167+
168+
patternlab.patterns[1].order = 1;
169+
170+
//act
171+
ui.groupPatterns(patternlab);
172+
173+
let patternType = _.find(patternlab.patternTypes, ['patternType', 'patternType1']);
174+
let patternSubType = _.find(patternType.patternTypeItems, ['patternSubtype', 'patternSubType1']);
175+
var items = patternSubType.patternSubtypeItems;
176+
177+
//zero is viewall
178+
test.equals(items[1].patternPartial, 'patternType1-red');
179+
test.equals(items[2].patternPartial, 'patternType1-blue');
180+
test.equals(items[3].patternPartial, 'patternType1-yellow');
181+
182+
test.end();
183+
});
184+
185+
tap.test('groupPatterns - retains pattern order from name when order provided from md is malformed', function (test) {
186+
//arrange
187+
var patternlab = createFakePatternLab({
188+
patterns: [],
189+
patternGroups: {},
190+
subtypePatterns: {}
191+
});
192+
193+
patternlab.patterns.push(
194+
new Pattern('patternType1/patternSubType1/blue.mustache'),
195+
new Pattern('patternType1/patternSubType1/red.mustache'),
196+
new Pattern('patternType1/patternSubType1/yellow.mustache')
197+
);
198+
ui.resetUIBuilderState(patternlab);
199+
200+
patternlab.patterns[1].order = 'notanumber!';
201+
202+
//act
203+
ui.groupPatterns(patternlab);
204+
205+
let patternType = _.find(patternlab.patternTypes, ['patternType', 'patternType1']);
206+
let patternSubType = _.find(patternType.patternTypeItems, ['patternSubtype', 'patternSubType1']);
207+
var items = patternSubType.patternSubtypeItems;
208+
209+
//zero is viewall
210+
test.equals(items[1].patternPartial, 'patternType1-blue');
211+
test.equals(items[2].patternPartial, 'patternType1-red');
212+
test.equals(items[3].patternPartial, 'patternType1-yellow');
213+
214+
test.end();
215+
});
216+
217+
tap.test('groupPatterns - sorts viewall subtype pattern to the beginning', function (test) {
218+
//arrange
219+
var patternlab = createFakePatternLab({
220+
patterns: [],
221+
patternGroups: {},
222+
subtypePatterns: {}
223+
});
224+
225+
patternlab.patterns.push(
226+
new Pattern('patternType1/patternSubType1/blue.mustache'),
227+
new Pattern('patternType1/patternSubType1/red.mustache'),
228+
new Pattern('patternType1/patternSubType1/yellow.mustache')
229+
);
230+
ui.resetUIBuilderState(patternlab);
231+
232+
patternlab.patterns[0].order = 1;
233+
patternlab.patterns[1].order = 3;
234+
patternlab.patterns[2].order = 2;
235+
236+
//act
237+
ui.groupPatterns(patternlab);
238+
239+
let patternType = _.find(patternlab.patternTypes, ['patternType', 'patternType1']);
240+
let patternSubType = _.find(patternType.patternTypeItems, ['patternSubtype', 'patternSubType1']);
241+
var items = patternSubType.patternSubtypeItems;
242+
243+
//zero is viewall
244+
test.equals(items[0].patternPartial, 'viewall-patternType1-patternSubType1');
245+
test.equals(items[1].patternPartial, 'patternType1-blue');
246+
test.equals(items[2].patternPartial, 'patternType1-yellow');
247+
test.equals(items[3].patternPartial, 'patternType1-red');
248+
249+
test.end();
250+
});
251+
153252
tap.test('groupPatterns - creates documentation patterns for each type and subtype if not exists', function (test) {
154253
//arrange
155254
var patternlab = createFakePatternLab({

0 commit comments

Comments
 (0)