From d40ff897b7ca08c156cafbe24dd4bb4c3ea33f11 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 22 Dec 2015 16:42:35 -0600 Subject: [PATCH 1/6] Path reform! Make paths more configurable from the config.json, and try to use path.resolve and/or path.join rather than manual string concatenation to manipulate paths. Conflicts: builder/patternlab.js builder/pseudopattern_hunter.js test/engine_handlebars_tests.js test/pattern_assembler_tests.js --- builder/pattern_assembler.js | 10 +- builder/patternlab.js | 45 ++++---- builder/pseudopattern_hunter.js | 21 ++-- config.json | 21 ++-- test/engine_handlebars_tests.js | 165 +++++++++++++++++++++++++++++ test/pattern_assembler_tests.js | 72 +++++++++---- test/pseudopattern_hunter_tests.js | 9 +- 7 files changed, 276 insertions(+), 67 deletions(-) create mode 100644 test/engine_handlebars_tests.js diff --git a/builder/pattern_assembler.js b/builder/pattern_assembler.js index 608289495..957e35131 100644 --- a/builder/pattern_assembler.js +++ b/builder/pattern_assembler.js @@ -91,7 +91,7 @@ path = require('path'); //extract some information - var subdir = path.dirname(path.relative(patternlab.config.patterns.source, file)).replace('\\', '/'); + var subdir = path.dirname(path.relative(patternlab.config.paths.source.patterns, file)).replace('\\', '/'); var filename = path.basename(file); var ext = path.extname(filename); @@ -119,8 +119,8 @@ //look for a json file for this template try { - var jsonFilename = patternlab.config.patterns.source + currentPattern.subdir + '/' + currentPattern.fileName + ".json"; - currentPattern.jsonFileData = fs.readJSONSync(jsonFilename.substring(2)); + var jsonFilename = path.resolve(patternlab.config.paths.source.patterns, currentPattern.subdir, currentPattern.fileName + ".json"); + currentPattern.jsonFileData = fs.readJSONSync(jsonFilename); if(patternlab.config.debug){ console.log('found pattern-specific data.json for ' + currentPattern.key); } @@ -130,8 +130,8 @@ //look for a listitems.json file for this template try { - var listJsonFileName = patternlab.config.patterns.source + currentPattern.subdir + '/' + currentPattern.fileName + ".listitems.json"; - currentPattern.listitems = fs.readJSONSync(listJsonFileName.substring(2)); + var listJsonFileName = path.resolve(patternlab.config.paths.source.patterns, currentPattern.subdir,currentPattern.fileName + ".listitems.json"); + currentPattern.listitems = fs.readJSONSync(listJsonFileName); buildListItems(currentPattern); if(patternlab.config.debug){ console.log('found pattern-specific listitems.json for ' + currentPattern.key); diff --git a/builder/patternlab.js b/builder/patternlab.js index e24471737..1f4a5c1bf 100644 --- a/builder/patternlab.js +++ b/builder/patternlab.js @@ -27,6 +27,9 @@ var patternlab_engine = function () { patternlab.package = fs.readJSONSync('./package.json'); patternlab.config = fs.readJSONSync('./config.json'); + var paths = patternlab.config.paths; + + function getVersion() { console.log(patternlab.package.version); } @@ -55,10 +58,10 @@ var patternlab_engine = function () { } function buildPatterns(deletePatternDir){ - patternlab.data = fs.readJSONSync('./source/_data/data.json'); - patternlab.listitems = fs.readJSONSync('./source/_data/listitems.json'); - patternlab.header = fs.readFileSync('./source/_patternlab-files/pattern-header-footer/header.html', 'utf8'); - patternlab.footer = fs.readFileSync('./source/_patternlab-files/pattern-header-footer/footer.html', 'utf8'); + patternlab.data = fs.readJSONSync(path.resolve(paths.source.data, 'data.json')); + patternlab.listitems = fs.readJSONSync(path.resolve(paths.source.data, 'listitems.json')); + patternlab.header = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'pattern-header-footer/header.html'), 'utf8'); + patternlab.footer = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'pattern-header-footer/footer.html'), 'utf8'); patternlab.patterns = []; patternlab.partials = {}; patternlab.data.link = {}; @@ -66,7 +69,7 @@ var patternlab_engine = function () { var pattern_assembler = new pa(), entity_encoder = new he(), pattern_exporter = new pe(), - patterns_dir = './source/_patterns'; + patterns_dir = paths.source.patterns; pattern_assembler.combine_listItems(patternlab); @@ -87,7 +90,6 @@ var patternlab_engine = function () { console.log(err); return; } - pattern_assembler.process_pattern_iterative(file.substring(2), patternlab); }); @@ -113,13 +115,12 @@ var patternlab_engine = function () { console.log(err); return; } - pattern_assembler.process_pattern_recursive(file.substring(2), patternlab); }); //delete the contents of config.patterns.public before writing if(deletePatternDir){ - fs.emptyDirSync(patternlab.config.patterns.public); + fs.emptyDirSync(paths.public.patterns); } //render all patterns last, so lineageR works @@ -136,13 +137,13 @@ var patternlab_engine = function () { var patternFooter = pattern_assembler.renderPattern(patternlab.footer, pattern); //write the compiled template to the public patterns directory - fs.outputFileSync(patternlab.config.patterns.public + pattern.patternLink, patternlab.header + pattern.patternPartial + patternFooter); + fs.outputFileSync(paths.public.patterns + pattern.patternLink, patternlab.header + pattern.patternPartial + patternFooter); //write the mustache file too - fs.outputFileSync(patternlab.config.patterns.public + pattern.patternLink.replace('.html', '.mustache'), entity_encoder.encode(pattern.template)); + fs.outputFileSync(paths.public.patterns + pattern.patternLink.replace('.html', '.mustache'), entity_encoder.encode(pattern.template)); //write the encoded version too - fs.outputFileSync(patternlab.config.patterns.public + pattern.patternLink.replace('.html', '.escaped.html'), entity_encoder.encode(pattern.patternPartial)); + fs.outputFileSync(paths.public.patterns + pattern.patternLink.replace('.html', '.escaped.html'), entity_encoder.encode(pattern.patternPartial)); }); //export patterns if necessary @@ -164,7 +165,7 @@ var patternlab_engine = function () { media_hunter.find_media_queries('./source/css', patternlab); // check if patterns are excluded, if not add them to styleguidePatterns - if (styleGuideExcludes.length) { + if (styleGuideExcludes && styleGuideExcludes.length) { for (i = 0; i < patternlab.patterns.length; i++) { // skip underscore-prefixed files @@ -187,9 +188,9 @@ var patternlab_engine = function () { } //build the styleguide - var styleguideTemplate = fs.readFileSync('./source/_patternlab-files/styleguide.mustache', 'utf8'), + var styleguideTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'styleguide.mustache'), 'utf8'), styleguideHtml = pattern_assembler.renderPattern(styleguideTemplate, {partials: styleguidePatterns}); - fs.outputFileSync('./public/styleguide/html/styleguide.html', styleguideHtml); + fs.outputFileSync(path.resolve(paths.public.styleguide, 'html/styleguide.html'), styleguideHtml); //build the viewall pages var prevSubdir = '', @@ -228,14 +229,14 @@ var patternlab_engine = function () { } } - var viewAllTemplate = fs.readFileSync('./source/_patternlab-files/viewall.mustache', 'utf8'); + var viewAllTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'viewall.mustache'), 'utf8'); var viewAllHtml = pattern_assembler.renderPattern(viewAllTemplate, {partials: viewAllPatterns, patternPartial: patternPartial}); - fs.outputFileSync(patternlab.config.patterns.public + pattern.flatPatternPath + '/index.html', viewAllHtml); + fs.outputFileSync(paths.public.patterns + pattern.flatPatternPath + '/index.html', viewAllHtml); } } //build the patternlab website - var patternlabSiteTemplate = fs.readFileSync('./source/_patternlab-files/index.mustache', 'utf8'); + var patternlabSiteTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'index.mustache'), 'utf8'); //sort all patterns explicitly. patternlab.patterns = patternlab.patterns.sort(function(a,b){ @@ -415,20 +416,20 @@ var patternlab_engine = function () { //the patternlab site requires a lot of partials to be rendered. //patternNav - var patternNavTemplate = fs.readFileSync('./source/_patternlab-files/partials/patternNav.mustache', 'utf8'); + var patternNavTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials/patternNav.mustache'), 'utf8'); var patternNavPartialHtml = pattern_assembler.renderPattern(patternNavTemplate, patternlab); //ishControls - var ishControlsTemplate = fs.readFileSync('./source/_patternlab-files/partials/ishControls.mustache', 'utf8'); + var ishControlsTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials/ishControls.mustache'), 'utf8'); patternlab.config.mqs = patternlab.mediaQueries; var ishControlsPartialHtml = pattern_assembler.renderPattern(ishControlsTemplate, patternlab.config); //patternPaths - var patternPathsTemplate = fs.readFileSync('./source/_patternlab-files/partials/patternPaths.mustache', 'utf8'); + var patternPathsTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials/patternPaths.mustache'), 'utf8'); var patternPathsPartialHtml = pattern_assembler.renderPattern(patternPathsTemplate, {'patternPaths': JSON.stringify(patternlab.patternPaths)}); //viewAllPaths - var viewAllPathsTemplate = fs.readFileSync('./source/_patternlab-files/partials/viewAllPaths.mustache', 'utf8'); + var viewAllPathsTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'partials/viewAllPaths.mustache'), 'utf8'); var viewAllPathsPartialHtml = pattern_assembler.renderPattern(viewAllPathsTemplate, {'viewallpaths': JSON.stringify(patternlab.viewAllPaths)}); //render the patternlab template, with all partials @@ -438,7 +439,7 @@ var patternlab_engine = function () { 'patternPaths': patternPathsPartialHtml, 'viewAllPaths': viewAllPathsPartialHtml }); - fs.outputFileSync('./public/index.html', patternlabSiteHtml); + fs.outputFileSync(path.resolve(paths.public.root, 'index.html'), patternlabSiteHtml); } function addToPatternPaths(bucketName, pattern){ diff --git a/builder/pseudopattern_hunter.js b/builder/pseudopattern_hunter.js index 909dc38be..ebd652161 100644 --- a/builder/pseudopattern_hunter.js +++ b/builder/pseudopattern_hunter.js @@ -1,10 +1,10 @@ -/* - * patternlab-node - v1.0.1 - 2015 - * +/* + * patternlab-node - v1.0.1 - 2015 + * * Brian Muenzenmeyer, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. * */ @@ -20,15 +20,16 @@ pa = require('./pattern_assembler'), lh = require('./lineage_hunter'), of = require('./object_factory'), - mustache = require('mustache'); + path = require('path'); var pattern_assembler = new pa(); var lineage_hunter = new lh(); + var paths = patternlab.config.paths; //look for a pseudo pattern by checking if there is a file containing same name, with ~ in it, ending in .json var needle = currentPattern.subdir + '/' + currentPattern.fileName + '~*.json'; var pseudoPatterns = glob.sync(needle, { - cwd: patternlab.config.patterns.source + '/', + cwd: paths.source.patterns, debug: false, nodir: true, }); @@ -42,13 +43,13 @@ } //we want to do everything we normally would here, except instead read the pseudoPattern data - var variantFileData = fs.readJSONSync(patternlab.config.patterns.source + '/' + pseudoPatterns[i]); + var variantFileData = fs.readJSONSync(path.resolve(paths.source.patterns, pseudoPatterns[i])); //extend any existing data with variant data variantFileData = pattern_assembler.merge_data(currentPattern.jsonFileData, variantFileData); var variantName = pseudoPatterns[i].substring(pseudoPatterns[i].indexOf('~') + 1).split('.')[0]; - var variantFilePath = patternlab.config.patterns.source + '/' + currentPattern.subdir + '/' + currentPattern.fileName + '~' + variantName + '.json'; + var variantFilePath = path.resolve(paths.source.patterns, currentPattern.subdir, currentPattern.fileName + '~' + variantName + '.json'); var variantFileName = currentPattern.fileName + '-' + variantName + '.'; var patternVariant = new of.oPattern(variantFilePath, currentPattern.subdir, variantFileName, variantFileData); diff --git a/config.json b/config.json index 9ba9f591e..911eefcdd 100644 --- a/config.json +++ b/config.json @@ -1,8 +1,17 @@ - { - "patterns" : { - "source" : "./source/_patterns/", - "public" : "./public/patterns/" - }, +{ + "paths" : { + "source" : { + "root": "./source/", + "patterns" : "./source/_patterns/", + "data" : "./source/_data/", + "patternlabFiles" : "./source/_patternlab-files/" + }, + "public" : { + "root" : "./public/", + "patterns" : "./public/patterns/", + "styleguide" : "./public/styleguide/" + } + }, "styleGuideExcludes": [ "templates", "pages" @@ -30,7 +39,7 @@ "tools-docs": true }, "patternStates": { - "homepage-emergency" : "inprogress" + "homepage-emergency" : "inprogress" }, "patternExportKeys": [], "patternExportDirectory": "./pattern_exports/", diff --git a/test/engine_handlebars_tests.js b/test/engine_handlebars_tests.js new file mode 100644 index 000000000..191ce32f7 --- /dev/null +++ b/test/engine_handlebars_tests.js @@ -0,0 +1,165 @@ +(function () { + "use strict"; + + var path = require('path'); + var pa = require('../builder/pattern_assembler'); + var object_factory = require('../builder/object_factory'); + var testPatternsPath = path.resolve(__dirname, 'files', '_handlebars-test-patterns'); + + // fake pattern lab constructor: + // sets up a fake patternlab object, which is needed by the pattern processing + // apparatus. + function fakePatternLab() { + var fpl = { + partials: {}, + patterns: [], + footer: '', + header: '', + listitems: {}, + listItemArray: [], + data: { + link: {} + }, + config: require('../config.json'), + package: {} + }; + console.log(fpl.config); + + // patch the pattern source so the pattern assembler can correctly determine + // the "subdir" + fpl.config.paths.source.patterns = './test/files/_handlebars-test-patterns'; + + return fpl; + } + + + // function for testing sets of partials + function testFindPartials(test, partialTests) { + test.expect(partialTests.length + 1); + + // setup current pattern from what we would have during execution + // docs on partial syntax are here: + // http://patternlab.io/docs/pattern-including.html + var currentPattern = object_factory.oPattern.create( + '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.hbs', // abspath + '01-molecules\\00-testing', // subdir + '00-test-mol.hbs', // filename, + null, // data + { + template: partialTests.join() + } + ); + + // act + var results = currentPattern.findPartials(); + + // assert + test.equals(results.length, partialTests.length); + partialTests.forEach(function(testString, index) { + test.equals(results[index], testString); + }); + + test.done(); + } + + exports['engine_handlebars'] = { + 'hello world handlebars pattern renders': function (test) { + test.expect(1); + + var patternPath = path.resolve( + testPatternsPath, + '00-atoms', + '00-global', + '00-helloworld.hbs' + ); + + // do all the normal processing of the pattern + var patternlab = new fakePatternLab(); + var assembler = new pa(); + var helloWorldPattern = assembler.process_pattern_iterative(patternPath, patternlab); + assembler.process_pattern_recursive(patternPath, patternlab); + + test.equals(helloWorldPattern.render(), 'Hello world!\n'); + test.done(); + }, + 'hello worlds handlebars pattern can see the atoms-helloworld partial and renders it twice': function (test) { + test.expect(1); + + // pattern paths + var pattern1Path = path.resolve( + testPatternsPath, + '00-atoms', + '00-global', + '00-helloworld.hbs' + ); + var pattern2Path = path.resolve( + testPatternsPath, + '00-molecules', + '00-global', + '00-helloworlds.hbs' + ); + + // set up environment + var patternlab = new fakePatternLab(); // environment + var assembler = new pa(); + + // do all the normal processing of the pattern + assembler.process_pattern_iterative(pattern1Path, patternlab); + var helloWorldsPattern = assembler.process_pattern_iterative(pattern2Path, patternlab); + assembler.process_pattern_recursive(pattern1Path, patternlab); + assembler.process_pattern_recursive(pattern2Path, patternlab); + + // test + test.equals(helloWorldsPattern.render(), 'Hello world!\n and Hello world!\n\n'); + test.done(); + }, + 'find_pattern_partials finds partials': function(test){ + testFindPartials(test, [ + "{{> molecules-comment-header}}", + "{{> molecules-comment-header}}", + "{{> \n molecules-comment-header\n}}", + "{{> molecules-weird-spacing }}", + "{{> molecules-ba_d-cha*rs }}" + ]); + }, + 'find_pattern_partials finds verbose partials': function(test){ + testFindPartials(test, [ + '{{> 01-molecules/06-components/03-comment-header.hbs }}', + "{{> 01-molecules/06-components/02-single-comment.hbs(description: 'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.') }}", + '{{> molecules-single-comment:foo }}', + "{{>atoms-error(message: 'That\'s no moon...')}}", + "{{> atoms-error(message: 'That\'s no moon...') }}", + '{{> 00-atoms/00-global/06-test }}' + ]); + }, + 'find_pattern_partials finds simple partials with parameters': function(test){ + testFindPartials(test, [ + "{{> molecules-single-comment(description: 'A life isn\'t like a garden. Perfect moments can be had, but not preserved, except in memory.') }}", + '{{> molecules-single-comment(description:"A life is like a \"garden\". Perfect moments can be had, but not preserved, except in memory.") }}' + ]); + }, + 'find_pattern_partials finds simple partials with style modifiers': function(test){ + testFindPartials(test, [ + '{{> molecules-single-comment:foo }}' + ]); + }, + 'find_pattern_partials finds partials with handlebars parameters': function(test){ + testFindPartials(test, [ + '{{> atoms-title title="bravo" headingLevel="2" headingSize="bravo" position="left"}}', + '{{> atoms-title title="bravo"\n headingLevel="2"\n headingSize="bravo"\n position="left"}}', + '{{> atoms-title title="color  midnight blue" headingSize="charlie"}}', + '{{> atoms-input label="city" required=true}}', + '{{> organisms-product-filter filterData}}', + '{{> atoms-input email required=true}}', + '{{> molecules-storycard variants.flex }}', + '{{> myPartial name=../name }}' + ]); + }, + + 'find_pattern_partials finds handlebars block partials': function(test){ + testFindPartials(test, [ + '{{#> myPartial }}' + ]); + } + }; +})(); diff --git a/test/pattern_assembler_tests.js b/test/pattern_assembler_tests.js index f623e754b..183d73771 100644 --- a/test/pattern_assembler_tests.js +++ b/test/pattern_assembler_tests.js @@ -2,7 +2,8 @@ "use strict"; var pa = require('../builder/pattern_assembler'); - var object_factory = require('../builder/object_factory'); + var object_factory = require('../builder/object_factory'); + var path = require('path'); exports['pattern_assembler'] = { 'find_pattern_partials finds partials' : function(test){ @@ -209,11 +210,12 @@ var patterns_dir = './test/files/_patterns'; var patternlab = {}; patternlab.config = fs.readJSONSync('./config.json'); - patternlab.config.patterns = {source: patterns_dir}; - patternlab.data = fs.readJSONSync('./source/_data/data.json'); - patternlab.listitems = fs.readJSONSync('./source/_data/listitems.json'); - patternlab.header = fs.readFileSync('./source/_patternlab-files/pattern-header-footer/header.html', 'utf8'); - patternlab.footer = fs.readFileSync('./source/_patternlab-files/pattern-header-footer/footer.html', 'utf8'); + patternlab.config.paths.source.patterns = patterns_dir; + + patternlab.data = fs.readJSONSync(path.resolve(patternlab.config.paths.source.data, 'data.json')); + patternlab.listitems = fs.readJSONSync(path.resolve(patternlab.config.paths.source.data, 'listitems.json')); + patternlab.header = fs.readFileSync(path.resolve(patternlab.config.paths.source.patternlabFiles, 'pattern-header-footer/header.html'), 'utf8'); + patternlab.footer = fs.readFileSync(path.resolve(patternlab.config.paths.source.patternlabFiles, 'pattern-header-footer/footer.html'), 'utf8'); patternlab.patterns = []; patternlab.data.link = {}; patternlab.partials = {}; @@ -293,12 +295,17 @@ var patterns_dir = './test/files/_patterns'; var pl = {}; - pl.config = {}; + pl.config = { + paths: { + source: { + patterns: patterns_dir + } + } + }; pl.data = {}; pl.data.link = {}; pl.config.debug = false; pl.patterns = []; - pl.config.patterns = { source: patterns_dir}; var atomPattern = new object_factory.oPattern('test/files/_patterns/00-test/03-styled-atom.mustache', '00-test', '03-styled-atom.mustache'); atomPattern.template = fs.readFileSync(patterns_dir + '/00-test/03-styled-atom.mustache', 'utf8'); @@ -361,12 +368,17 @@ var patterns_dir = './test/files/_patterns'; var pl = {}; - pl.config = {}; + pl.config = { + paths: { + source: { + patterns: patterns_dir + } + } + }; pl.data = {}; pl.data.link = {}; pl.config.debug = false; pl.patterns = []; - pl.config.patterns = { source: patterns_dir}; var atomPattern = new object_factory.oPattern('test/files/_patterns/00-test/03-styled-atom.mustache', '00-test', '03-styled-atom.mustache'); atomPattern.template = fs.readFileSync(patterns_dir + '/00-test/03-styled-atom.mustache', 'utf8'); @@ -394,12 +406,17 @@ var patterns_dir = './test/files/_patterns'; var pl = {}; - pl.config = {}; + pl.config = { + paths: { + source: { + patterns: patterns_dir + } + } + }; pl.data = {}; pl.data.link = {}; pl.config.debug = false; pl.patterns = []; - pl.config.patterns = { source: patterns_dir}; var atomPattern = new object_factory.oPattern('test/files/_patterns/00-test/03-styled-atom.mustache', '00-test', '03-styled-atom.mustache'); atomPattern.template = fs.readFileSync(patterns_dir + '/00-test/03-styled-atom.mustache', 'utf8'); @@ -427,12 +444,17 @@ var patterns_dir = './test/files/_patterns'; var pl = {}; - pl.config = {}; + pl.config = { + paths: { + source: { + patterns: patterns_dir + } + } + }; pl.data = {}; pl.data.link = {}; pl.config.debug = false; pl.patterns = []; - pl.config.patterns = { source: patterns_dir}; var atomPattern = new object_factory.oPattern('test/files/_patterns/00-test/03-styled-atom.mustache', '00-test', '03-styled-atom.mustache'); atomPattern.template = fs.readFileSync(patterns_dir + '/00-test/03-styled-atom.mustache', 'utf8'); @@ -462,12 +484,17 @@ var patterns_dir = './test/files/_patterns'; var pl = {}; - pl.config = {}; + pl.config = { + paths: { + source: { + patterns: patterns_dir + } + } + }; pl.data = {}; pl.data.link = {}; pl.config.debug = false; pl.patterns = []; - pl.config.patterns = { source: patterns_dir}; var atomPattern = new object_factory.oPattern('test/files/_patterns/00-test/03-styled-atom.mustache', '00-test', '03-styled-atom.mustache'); atomPattern.template = fs.readFileSync(patterns_dir + '/00-test/03-styled-atom.mustache', 'utf8'); @@ -592,11 +619,11 @@ var patternlab = {}; //THIS IS BAD patternlab.config = fs.readJSONSync('./config.json'); - patternlab.config.patterns = {source: patterns_dir}; - patternlab.data = fs.readJSONSync('./source/_data/data.json'); - patternlab.listitems = fs.readJSONSync('./source/_data/listitems.json'); - patternlab.header = fs.readFileSync('./source/_patternlab-files/pattern-header-footer/header.html', 'utf8'); - patternlab.footer = fs.readFileSync('./source/_patternlab-files/pattern-header-footer/footer.html', 'utf8'); + patternlab.config.paths.source.patterns = patterns_dir; + patternlab.data = fs.readJSONSync(path.resolve(patternlab.config.paths.source.data, 'data.json')); + patternlab.listitems = fs.readJSONSync(path.resolve(patternlab.config.paths.source.data, 'listitems.json')); + patternlab.header = fs.readFileSync(path.resolve(patternlab.config.paths.source.patternlabFiles, 'pattern-header-footer/header.html'), 'utf8'); + patternlab.footer = fs.readFileSync(path.resolve(patternlab.config.paths.source.patternlabFiles, 'pattern-header-footer/footer.html'), 'utf8'); patternlab.patterns = []; patternlab.data.link = {}; patternlab.partials = {}; @@ -618,7 +645,7 @@ console.log(err); return; } - pattern_assembler.process_pattern_iterative(file.substring(2), patternlab); + pattern_assembler.process_pattern_iterative(file, patternlab); } ); @@ -633,6 +660,7 @@ pattern = patternlab.patterns[i]; } } + //assert before test.equals(pattern.jsonFileData.brad.url, "link.twitter-brad"); test.equals(pattern.jsonFileData.dave.url, "link.twitter-dave"); diff --git a/test/pseudopattern_hunter_tests.js b/test/pseudopattern_hunter_tests.js index 5a50dbcdd..2a9664e6e 100644 --- a/test/pseudopattern_hunter_tests.js +++ b/test/pseudopattern_hunter_tests.js @@ -14,12 +14,17 @@ var patterns_dir = './test/files/_patterns/'; var pl = {}; - pl.config = {}; + pl.config = { + paths: { + source: { + patterns: patterns_dir + } + } + }; pl.data = {}; pl.data.link = {}; pl.config.debug = false; pl.patterns = []; - pl.config.patterns = { source: patterns_dir}; pl.config.patternStates = {}; var atomPattern = new object_factory.oPattern('test/files/_patterns/00-test/03-styled-atom.mustache', '00-test', '03-styled-atom.mustache'); From d585257c44588fed0adc84c972e6ffcca58052b5 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Tue, 22 Dec 2015 16:44:53 -0600 Subject: [PATCH 2/6] some gulp cleanup --- builder/patternlab_gulp.js | 8 ++++---- gulpfile.js | 26 +++++++++++++------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/builder/patternlab_gulp.js b/builder/patternlab_gulp.js index 64b0800df..0c176d40a 100644 --- a/builder/patternlab_gulp.js +++ b/builder/patternlab_gulp.js @@ -21,16 +21,16 @@ module.exports = function(gulp) { gulp.task('patternlab:version', function(){ var patternlab = patternlab_engine(); patternlab.version(); - }) + }); gulp.task('patternlab:only_patterns', ['clean'], function(){ var patternlab = patternlab_engine(); patternlab.build_patterns_only(false); - }) + }); gulp.task('patternlab:help', function(){ var patternlab = patternlab_engine(); patternlab.help(); - }) + }); -} +}; diff --git a/gulpfile.js b/gulpfile.js index f0b66d3d7..b49631a40 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -27,7 +27,7 @@ gulp.loadTasks(__dirname+'/builder/patternlab_gulp.js'); gulp.task('clean', function(cb){ del.sync(['./public/patterns/*'], {force: true}); cb(); -}) +}); //build the banner gulp.task('banner', function(){ @@ -51,32 +51,32 @@ gulp.task('banner', function(){ today : new Date().getFullYear() } )) .pipe(gulp.dest('./builder')); -}) +}); //copy tasks gulp.task('cp:js', function(){ return gulp.src('**/*.js', {cwd:'./source/js'}) - .pipe(gulp.dest('./public/js')) + .pipe(gulp.dest('./public/js')); }); gulp.task('cp:img', function(){ return gulp.src( [ '**/*.gif', '**/*.png', '**/*.jpg', '**/*.jpeg' ], {cwd:'./source/images'} ) - .pipe(gulp.dest('./public/images')) + .pipe(gulp.dest('./public/images')); }); gulp.task('cp:font', function(){ return gulp.src('*', {cwd:'./source/fonts'}) - .pipe(gulp.dest('./public/fonts')) -}); + .pipe(gulp.dest('./public/fonts')); +});; gulp.task('cp:data', function(){ return gulp.src('annotations.js', {cwd:'./source/_data'}) - .pipe(gulp.dest('./public/data')) -}) + .pipe(gulp.dest('./public/data')); +}); gulp.task('cp:css', function(){ return gulp.src('./source/css/style.css') .pipe(gulp.dest('./public/css')) .pipe(browserSync.stream()); -}) +}); //server and watch tasks gulp.task('connect', ['lab'], function(){ @@ -99,13 +99,13 @@ gulp.task('connect', ['lab'], function(){ browserSync.reload(); }); -}) +}); //unit test gulp.task('nodeunit', function(){ return gulp.src('./test/**/*_tests.js') .pipe(nodeunit()); -}) +}); //sass tasks, turn on if you want to use // gulp.task('sass:style', function(){ @@ -130,12 +130,12 @@ gulp.task('nodeunit', function(){ gulp.task('lab-pipe', ['lab'], function(cb){ cb(); browserSync.reload(); -}) +}); gulp.task('default', ['lab']); gulp.task('assets', ['cp:js', 'cp:img', 'cp:font', 'cp:data', /*'sass:style', 'sass:styleguide'*/]); -gulp.task('prelab', ['clean', 'banner', 'assets']); +gulp.task('prelab', ['clean', 'assets']); gulp.task('lab', ['prelab', 'patternlab'], function(cb){cb();}); gulp.task('patterns', ['patternlab:only_patterns']); gulp.task('serve', ['lab', 'connect']); From 9dcfc63b99964757bcd9d085d39d87fd2e715e63 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Wed, 23 Dec 2015 13:18:20 -0600 Subject: [PATCH 3/6] make the gulpfile use the paths from the config JSON --- config.json | 13 +++++++++++-- gulpfile.js | 55 +++++++++++++++++++++++++++++++++-------------------- 2 files changed, 45 insertions(+), 23 deletions(-) diff --git a/config.json b/config.json index 911eefcdd..dfca6c756 100644 --- a/config.json +++ b/config.json @@ -4,12 +4,21 @@ "root": "./source/", "patterns" : "./source/_patterns/", "data" : "./source/_data/", - "patternlabFiles" : "./source/_patternlab-files/" + "patternlabFiles" : "./source/_patternlab-files/", + "js" : "./source/js", + "images" : "./source/images", + "fonts" : "./source/fonts", + "css" : "./source/css/" }, "public" : { "root" : "./public/", "patterns" : "./public/patterns/", - "styleguide" : "./public/styleguide/" + "data" : "./public/data/", + "styleguide" : "./public/styleguide/", + "js" : "./public/js", + "images" : "./public/images", + "fonts" : "./public/fonts", + "css" : "./public/css" } }, "styleGuideExcludes": [ diff --git a/gulpfile.js b/gulpfile.js index b49631a40..ba5529080 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -2,6 +2,7 @@ var pkg = require('./package.json'), gulp = require('gulp'), + path = require('path'), eol = require('os').EOL, del = require('del'), strip_banner = require('gulp-strip-banner'), @@ -20,12 +21,16 @@ var banner = [ '/** ', ' * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice.', ' * ', ' **/'].join(eol); +function paths () { + return require('./config.json').paths; +} + //load patternlab-node tasks gulp.loadTasks(__dirname+'/builder/patternlab_gulp.js'); //clean patterns dir gulp.task('clean', function(cb){ - del.sync(['./public/patterns/*'], {force: true}); + del.sync([path.resolve(paths().public.patterns, '*')], {force: true}); cb(); }); @@ -53,28 +58,34 @@ gulp.task('banner', function(){ .pipe(gulp.dest('./builder')); }); + //copy tasks + gulp.task('cp:js', function(){ - return gulp.src('**/*.js', {cwd:'./source/js'}) - .pipe(gulp.dest('./public/js')); + return gulp.src('**/*.js', {cwd:paths().source.js}) + .pipe(gulp.dest(paths().public.js)); }); + gulp.task('cp:img', function(){ return gulp.src( [ '**/*.gif', '**/*.png', '**/*.jpg', '**/*.jpeg' ], - {cwd:'./source/images'} ) - .pipe(gulp.dest('./public/images')); + {cwd:paths().source.images} ) + .pipe(gulp.dest(paths().public.images)); }); + gulp.task('cp:font', function(){ - return gulp.src('*', {cwd:'./source/fonts'}) - .pipe(gulp.dest('./public/fonts')); -});; + return gulp.src('*', {cwd:paths().source.fonts}) + .pipe(gulp.dest(paths().public.images)); +}); + gulp.task('cp:data', function(){ - return gulp.src('annotations.js', {cwd:'./source/_data'}) - .pipe(gulp.dest('./public/data')); + return gulp.src('annotations.js', {cwd:paths().source.data}) + .pipe(gulp.dest(paths().public.data)); }); + gulp.task('cp:css', function(){ - return gulp.src('./source/css/style.css') - .pipe(gulp.dest('./public/css')) + return gulp.src(path.resolve(paths().source.css, 'style.css')) + .pipe(gulp.dest(paths().public.css)) .pipe(browserSync.stream()); }); @@ -82,22 +93,24 @@ gulp.task('cp:css', function(){ gulp.task('connect', ['lab'], function(){ browserSync.init({ server: { - baseDir: './public/' + baseDir: paths().public.root } }); - gulp.watch('./source/css/style.css', ['cp:css']); + gulp.watch(path.resolve(paths().public.css, 'style.css'), ['cp:css']); //suggested watches if you use scss // gulp.watch('./source/css/**/*.scss', ['sass:style']); // gulp.watch('./public/styleguide/*.scss', ['sass:styleguide']); - gulp.watch([ - './source/_patterns/**/*.mustache', - './source/_patterns/**/*.json', - './source/_data/*.json' ], - ['lab-pipe'], function(){ - browserSync.reload(); - }); + gulp.watch( + [ + path.resolve(paths().source.patterns, '**/*.mustache'), + path.resolve(paths().source.patterns, '**/*.json'), + path.resolve(paths().source.data, '*.json') + ], + ['lab-pipe'], + function () { browserSync.reload(); } + ); }); From 57c130223aa5345956115db16d746ef0af827f99 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Wed, 23 Dec 2015 14:33:55 -0600 Subject: [PATCH 4/6] Nice comments in the gulpfile --- gulpfile.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gulpfile.js b/gulpfile.js index ba5529080..95a049ed7 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -59,13 +59,15 @@ gulp.task('banner', function(){ }); -//copy tasks +// COPY TASKS +// JS copy gulp.task('cp:js', function(){ return gulp.src('**/*.js', {cwd:paths().source.js}) .pipe(gulp.dest(paths().public.js)); }); +// Images copy gulp.task('cp:img', function(){ return gulp.src( [ '**/*.gif', '**/*.png', '**/*.jpg', '**/*.jpeg' ], @@ -73,16 +75,19 @@ gulp.task('cp:img', function(){ .pipe(gulp.dest(paths().public.images)); }); +// Fonts copy gulp.task('cp:font', function(){ return gulp.src('*', {cwd:paths().source.fonts}) .pipe(gulp.dest(paths().public.images)); }); +// Data copy gulp.task('cp:data', function(){ return gulp.src('annotations.js', {cwd:paths().source.data}) .pipe(gulp.dest(paths().public.data)); }); +// CSS Copy gulp.task('cp:css', function(){ return gulp.src(path.resolve(paths().source.css, 'style.css')) .pipe(gulp.dest(paths().public.css)) From 9177378d4ede635d130698a98cf74412692d79da Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Wed, 23 Dec 2015 15:33:16 -0600 Subject: [PATCH 5/6] we are not yet ready for handlebars unit tests, clearly --- test/engine_handlebars_tests.js | 165 -------------------------------- 1 file changed, 165 deletions(-) delete mode 100644 test/engine_handlebars_tests.js diff --git a/test/engine_handlebars_tests.js b/test/engine_handlebars_tests.js deleted file mode 100644 index 191ce32f7..000000000 --- a/test/engine_handlebars_tests.js +++ /dev/null @@ -1,165 +0,0 @@ -(function () { - "use strict"; - - var path = require('path'); - var pa = require('../builder/pattern_assembler'); - var object_factory = require('../builder/object_factory'); - var testPatternsPath = path.resolve(__dirname, 'files', '_handlebars-test-patterns'); - - // fake pattern lab constructor: - // sets up a fake patternlab object, which is needed by the pattern processing - // apparatus. - function fakePatternLab() { - var fpl = { - partials: {}, - patterns: [], - footer: '', - header: '', - listitems: {}, - listItemArray: [], - data: { - link: {} - }, - config: require('../config.json'), - package: {} - }; - console.log(fpl.config); - - // patch the pattern source so the pattern assembler can correctly determine - // the "subdir" - fpl.config.paths.source.patterns = './test/files/_handlebars-test-patterns'; - - return fpl; - } - - - // function for testing sets of partials - function testFindPartials(test, partialTests) { - test.expect(partialTests.length + 1); - - // setup current pattern from what we would have during execution - // docs on partial syntax are here: - // http://patternlab.io/docs/pattern-including.html - var currentPattern = object_factory.oPattern.create( - '/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.hbs', // abspath - '01-molecules\\00-testing', // subdir - '00-test-mol.hbs', // filename, - null, // data - { - template: partialTests.join() - } - ); - - // act - var results = currentPattern.findPartials(); - - // assert - test.equals(results.length, partialTests.length); - partialTests.forEach(function(testString, index) { - test.equals(results[index], testString); - }); - - test.done(); - } - - exports['engine_handlebars'] = { - 'hello world handlebars pattern renders': function (test) { - test.expect(1); - - var patternPath = path.resolve( - testPatternsPath, - '00-atoms', - '00-global', - '00-helloworld.hbs' - ); - - // do all the normal processing of the pattern - var patternlab = new fakePatternLab(); - var assembler = new pa(); - var helloWorldPattern = assembler.process_pattern_iterative(patternPath, patternlab); - assembler.process_pattern_recursive(patternPath, patternlab); - - test.equals(helloWorldPattern.render(), 'Hello world!\n'); - test.done(); - }, - 'hello worlds handlebars pattern can see the atoms-helloworld partial and renders it twice': function (test) { - test.expect(1); - - // pattern paths - var pattern1Path = path.resolve( - testPatternsPath, - '00-atoms', - '00-global', - '00-helloworld.hbs' - ); - var pattern2Path = path.resolve( - testPatternsPath, - '00-molecules', - '00-global', - '00-helloworlds.hbs' - ); - - // set up environment - var patternlab = new fakePatternLab(); // environment - var assembler = new pa(); - - // do all the normal processing of the pattern - assembler.process_pattern_iterative(pattern1Path, patternlab); - var helloWorldsPattern = assembler.process_pattern_iterative(pattern2Path, patternlab); - assembler.process_pattern_recursive(pattern1Path, patternlab); - assembler.process_pattern_recursive(pattern2Path, patternlab); - - // test - test.equals(helloWorldsPattern.render(), 'Hello world!\n and Hello world!\n\n'); - test.done(); - }, - 'find_pattern_partials finds partials': function(test){ - testFindPartials(test, [ - "{{> molecules-comment-header}}", - "{{> molecules-comment-header}}", - "{{> \n molecules-comment-header\n}}", - "{{> molecules-weird-spacing }}", - "{{> molecules-ba_d-cha*rs }}" - ]); - }, - 'find_pattern_partials finds verbose partials': function(test){ - testFindPartials(test, [ - '{{> 01-molecules/06-components/03-comment-header.hbs }}', - "{{> 01-molecules/06-components/02-single-comment.hbs(description: 'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.') }}", - '{{> molecules-single-comment:foo }}', - "{{>atoms-error(message: 'That\'s no moon...')}}", - "{{> atoms-error(message: 'That\'s no moon...') }}", - '{{> 00-atoms/00-global/06-test }}' - ]); - }, - 'find_pattern_partials finds simple partials with parameters': function(test){ - testFindPartials(test, [ - "{{> molecules-single-comment(description: 'A life isn\'t like a garden. Perfect moments can be had, but not preserved, except in memory.') }}", - '{{> molecules-single-comment(description:"A life is like a \"garden\". Perfect moments can be had, but not preserved, except in memory.") }}' - ]); - }, - 'find_pattern_partials finds simple partials with style modifiers': function(test){ - testFindPartials(test, [ - '{{> molecules-single-comment:foo }}' - ]); - }, - 'find_pattern_partials finds partials with handlebars parameters': function(test){ - testFindPartials(test, [ - '{{> atoms-title title="bravo" headingLevel="2" headingSize="bravo" position="left"}}', - '{{> atoms-title title="bravo"\n headingLevel="2"\n headingSize="bravo"\n position="left"}}', - '{{> atoms-title title="color  midnight blue" headingSize="charlie"}}', - '{{> atoms-input label="city" required=true}}', - '{{> organisms-product-filter filterData}}', - '{{> atoms-input email required=true}}', - '{{> molecules-storycard variants.flex }}', - '{{> myPartial name=../name }}' - ]); - }, - - 'find_pattern_partials finds handlebars block partials': function(test){ - testFindPartials(test, [ - '{{#> myPartial }}' - ]); - } - }; -})(); From cafd440f8c39c771fcda88c68b0924d8b3c882e6 Mon Sep 17 00:00:00 2001 From: Geoffrey Pursell Date: Wed, 23 Dec 2015 15:36:12 -0600 Subject: [PATCH 6/6] fix one unit test --- test/pattern_assembler_tests.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test/pattern_assembler_tests.js b/test/pattern_assembler_tests.js index 183d73771..a0d5cd4de 100644 --- a/test/pattern_assembler_tests.js +++ b/test/pattern_assembler_tests.js @@ -333,12 +333,17 @@ var patterns_dir = './test/files/_patterns'; var pl = {}; - pl.config = {}; + pl.config = { + paths: { + source: { + patterns: patterns_dir + } + } + }; pl.data = {}; pl.data.link = {}; pl.config.debug = false; pl.patterns = []; - pl.config.patterns = { source: patterns_dir}; var atomPattern = new object_factory.oPattern('test/files/_patterns/00-test/03-styled-atom.mustache', '00-test', '03-styled-atom.mustache'); atomPattern.template = fs.readFileSync(patterns_dir + '/00-test/03-styled-atom.mustache', 'utf8');