diff --git a/.travis.yml b/.travis.yml index ad1107b81..6d447035b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,6 @@ before_install: - phantomjs --version before_script: - - npm install -g grunt-cli - npm install patternengine-node-underscore - npm install patternengine-node-handlebars - npm install patternengine-node-twig diff --git a/core/lib/pattern_assembler.js b/core/lib/pattern_assembler.js index bb9d9e9d8..05df15e82 100644 --- a/core/lib/pattern_assembler.js +++ b/core/lib/pattern_assembler.js @@ -242,7 +242,7 @@ var pattern_assembler = function () { function processPatternIterative(relPath, patternlab) { - var relativeDepth = relPath.match(/\w(?=\\)|\w(?=\/)/g || []).length; + var relativeDepth = (relPath.match(/\w(?=\\)|\w(?=\/)/g) || []).length; if (relativeDepth > 2) { console.log(''); plutils.logOrange('Warning:'); diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index 0e53d594c..df3275f18 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -1,5 +1,5 @@ /* - * patternlab-node - v2.6.1 - 2016 + * patternlab-node - v2.6.2 - 2016 * * Brian Muenzenmeyer, Geoff Pursell, and the web community. * Licensed under the MIT license. diff --git a/core/lib/ui_builder.js b/core/lib/ui_builder.js index 4a0e87f0a..c8b5be431 100644 --- a/core/lib/ui_builder.js +++ b/core/lib/ui_builder.js @@ -6,8 +6,7 @@ var fs = require('fs-extra'); var ae = require('./annotation_exporter'); var of = require('./object_factory'); var Pattern = of.Pattern; -var pa = require('./pattern_assembler'); -var pattern_assembler = new pa(); +var pattern_assembler = require('./pattern_assembler')(); var plutils = require('./utilities'); var eol = require('os').EOL; var _ = require('lodash'); @@ -54,20 +53,6 @@ var ui_builder = function () { } } - /** - * Writes a file to disk, with an optional callback - * @param filePath - the path to write to with filename - * @param data - the file contents - * @param callback - an optional callback - */ - function writeFile(filePath, data, callback) { - if (callback) { - fs.outputFileSync(filePath, data, callback); - } else { - fs.outputFileSync(filePath, data); - } - } - /** * Returns whether or not the pattern should be excluded from direct rendering or navigation on the front end * @param pattern - the pattern to test for inclusion/exclusion @@ -468,7 +453,7 @@ var ui_builder = function () { //do not create a viewall page for flat patterns if (patternType === patternSubtype) { writeViewAllFile = false; - return false; + return; } //render the footer needed for the viewall template @@ -485,13 +470,12 @@ var ui_builder = function () { typePatterns = typePatterns.concat(subtypePatterns); var viewAllHTML = buildViewAllHTML(patternlab, subtypePatterns, patternPartial); - writeFile(paths.public.patterns + p.flatPatternPath + '/index.html', mainPageHeadHtml + viewAllHTML + footerHTML); - return true; //stop yelling at us eslint we know we know + fs.outputFileSync(paths.public.patterns + p.flatPatternPath + '/index.html', mainPageHeadHtml + viewAllHTML + footerHTML); }); //do not create a viewall page for flat patterns if (!writeViewAllFile || !p) { - return false; + return; } //render the footer needed for the viewall template @@ -507,7 +491,7 @@ var ui_builder = function () { //render the viewall template for the type var viewAllHTML = buildViewAllHTML(patternlab, typePatterns, patternType); - writeFile(paths.public.patterns + anyPatternOfType.patternType + '/index.html', mainPageHeadHtml + viewAllHTML + footerHTML); + fs.outputFileSync(paths.public.patterns + anyPatternOfType.patternType + '/index.html', mainPageHeadHtml + viewAllHTML + footerHTML); //determine if we should omit this patterntype completely from the viewall page var omitPatternType = styleGuideExcludes && styleGuideExcludes.length @@ -521,8 +505,6 @@ var ui_builder = function () { } else { patterns = patterns.concat(typePatterns); } - - return true; //stop yelling at us eslint we know we know }); return patterns; } @@ -561,12 +543,12 @@ var ui_builder = function () { output += 'var defaultPattern = "' + (patternlab.config.defaultPattern ? patternlab.config.defaultPattern : 'all') + '";' + eol; //write all output to patternlab-data - writeFile(path.resolve(paths.public.data, 'patternlab-data.js'), output); + fs.outputFileSync(path.resolve(paths.public.data, 'patternlab-data.js'), output); //annotations var annotationsJSON = annotation_exporter.gather(); var annotations = 'var comments = { "comments" : ' + JSON.stringify(annotationsJSON) + '};'; - writeFile(path.resolve(paths.public.annotations, 'annotations.js'), annotations); + fs.outputFileSync(path.resolve(paths.public.annotations, 'annotations.js'), annotations); } /** @@ -626,7 +608,7 @@ var ui_builder = function () { patternSection: patternlab.patternSection, patternSectionSubtype: patternlab.patternSectionSubType }); - writeFile(path.resolve(paths.public.styleguide, 'html/styleguide.html'), headerHTML + styleguideHtml + footerHTML); + fs.outputFileSync(path.resolve(paths.public.styleguide, 'html/styleguide.html'), headerHTML + styleguideHtml + footerHTML); //move the index file from its asset location into public root var patternlabSiteHtml; @@ -637,7 +619,7 @@ var ui_builder = function () { console.log("\nERROR: Could not load one or more styleguidekit assets from", paths.source.styleguide, '\n'); process.exit(1); } - writeFile(path.resolve(paths.public.root, 'index.html'), patternlabSiteHtml); + fs.outputFileSync(path.resolve(paths.public.root, 'index.html'), patternlabSiteHtml); //write out patternlab.data object to be read by the client exportData(patternlab); @@ -655,6 +637,9 @@ var ui_builder = function () { }, resetUIBuilderState: function (patternlab) { resetUIBuilderState(patternlab); + }, + buildViewAllPages: function (mainPageHeadHtml, patternlab, styleguidePatterns) { + return buildViewAllPages(mainPageHeadHtml, patternlab, styleguidePatterns); } }; diff --git a/package.json b/package.json index b7bfd5a5e..29cc5d61c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "patternlab-node", "description": "Pattern Lab is a collection of tools to help you create atomic design systems. This is the node command line interface (CLI).", - "version": "2.6.1", + "version": "2.6.2", "main": "./core/lib/patternlab.js", "dependencies": { "diveSync": "^0.3.0", @@ -17,6 +17,7 @@ }, "devDependencies": { "eslint": "^3.5.0", + "rewire": "^2.5.2", "tap": "^7.1.2" }, "keywords": [ diff --git a/test/ui_builder_tests.js b/test/ui_builder_tests.js index 3a111ffd8..b140452dd 100644 --- a/test/ui_builder_tests.js +++ b/test/ui_builder_tests.js @@ -1,10 +1,28 @@ "use strict"; var tap = require('tap'); - +var rewire = require("rewire"); var eol = require('os').EOL; var Pattern = require('../core/lib/object_factory').Pattern; var extend = require('util')._extend; +var uiModule = rewire('../core/lib/ui_builder'); + +//set up a global mocks - we don't want to be writing/rendering any files right now +var fsMock = { + outputFileSync: function (path, data, cb) { } +}; + +var patternAssemblerMock = { + renderPattern: function (template, data, partials) { return ''; } +}; + +//set our mocks in place of usual require() +uiModule.__set__({ + 'fs': fsMock, + 'pattern_assembler': patternAssemblerMock +}); + +var ui = uiModule(); function createFakePatternLab(customProps) { var pl = { @@ -24,13 +42,12 @@ function createFakePatternLab(customProps) { rawTemplate: '', markupOnly: '.markup-only' } - } + }, + data: {} }; return extend(pl, customProps); } -var ui = require('../core/lib/ui_builder')(); - tap.test('isPatternExcluded - returns true when pattern filename starts with underscore', function (test) { //arrange var patternlab = createFakePatternLab({}); @@ -246,3 +263,45 @@ tap.test('resetUIBuilderState - reset global objects', function (test) { test.end(); }); + +tap.test('buildViewAllPages - adds viewall page for each type and subtype', function (test) { + //arrange + let mainPageHeadHtml = ''; + let patternlab = createFakePatternLab({ + patterns: [], + patternGroups: {}, + subtypePatterns: {} + }); + + patternlab.patterns.push( + //this flat pattern is found and causes trouble for the rest of the crew + new Pattern('00-test/foo.mustache'), + new Pattern('patternType1/patternSubType1/blue.mustache'), + new Pattern('patternType1/patternSubType1/red.mustache'), + new Pattern('patternType1/patternSubType1/yellow.mustache'), + new Pattern('patternType1/patternSubType2/black.mustache'), + new Pattern('patternType1/patternSubType2/grey.mustache'), + new Pattern('patternType1/patternSubType2/white.mustache') + ); + ui.resetUIBuilderState(patternlab); + + let styleguidePatterns = ui.groupPatterns(patternlab); + + //act + var patterns = ui.buildViewAllPages(mainPageHeadHtml, patternlab, styleguidePatterns); + + //assert + //this was a nuanced one. buildViewAllPages() had return false; statements + //within _.forOwn(...) loops, causing premature termination of the entire loop + //when what was intended was a continue + //we expect 8 here because: + // - foo.mustache is flat and therefore does not have a viewall page + // - the colors.mustache files make 6 + // - patternSubType1 and patternSubType2 make 8 + //while most of that heavy lifting occurs inside groupPatterns and not buildViewAllPages, + //it's important to ensure that this method does not get prematurely terminated + //we choose to do that by checking it's return number of patterns + test.equals(patterns.length, 8, '2 viewall pages should be added'); + + test.end(); +});