diff --git a/.gitignore b/.gitignore index e5a709278..d1ddc139e 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ source/css/style.css.map public !test/patterns/public/.gitkeep !test/patterns/testDependencyGraph.json +.nyc_output/ diff --git a/README.md b/README.md index 58bd30c02..942921085 100644 --- a/README.md +++ b/README.md @@ -1,47 +1,98 @@ +![Pattern Lab Logo](/patternlab.png "Pattern Lab Logo") + [![Build Status](https://travis-ci.org/pattern-lab/patternlab-node.svg?branch=master)](https://travis-ci.org/pattern-lab/patternlab-node) ![current release](https://img.shields.io/github/release/pattern-lab/patternlab-node.svg) ![license](https://img.shields.io/github/license/pattern-lab/patternlab-node.svg) [![Join the chat at Gitter](https://badges.gitter.im/pattern-lab/node.svg)](https://gitter.im/pattern-lab/node) # Pattern Lab Node Core -This repository contains the core functionality for Pattern Lab Node. Pattern Lab Core is designed to be included as a dependency within [Node Editions](https://github.com/pattern-lab?utf8=%E2%9C%93&query=edition-node). -If this looks **REALLY DIFFERENT** from what you expected, check out the [ChangeLog](https://github.com/pattern-lab/patternlab-node/wiki/ChangeLog). +This repository contains the core functionality for Pattern Lab Node. Pattern Lab helps you and your team build thoughtful, pattern-driven user interfaces using atomic design principles. + +[Online Demo of Pattern Lab Output](http://demo.patternlab.io/) + +## Support for Pattern Lab Node + +Pattern Lab Node wouldn't be what it is today without the support of the community. It will always be free and open source. Continued development is made possible in part from the support of [these wonderful project supporters](https://github.com/pattern-lab/patternlab-node/wiki/Thanks). If you want to learn more about supporting the project, visit the [Pattern Lab Node Patreon page](https://www.patreon.com/patternlab). + +**:100: Thanks for support from the following:** + +* **[Brad Frost](http://bradfrost.com/)** +* Marcos Peebles + +## Installation + +Pattern Lab Node Core is designed to be consumed, and by default is included as a dependency within two example [Node Editions](https://github.com/pattern-lab?utf8=%E2%9C%93&query=edition-node). + * [Pattern Lab/Node: Gulp Edition](https://github.com/pattern-lab/edition-node-gulp) contains info how to get started within a Gulp task running environment. * [Pattern Lab/Node: Grunt Edition](https://github.com/pattern-lab/edition-node-grunt) contains info how to get started within a Grunt task running environment. -## Core Team +![Pattern Lab Ecosystem](http://patternlab.io/assets/pattern-lab-2-image_18-large-opt.png) -* [@bmuenzenmeyer](https://github.com/bmuenzenmeyer) - Lead Maintainer -* [@geoffp](https://github.com/geoffp) - Core Contributor -* [@raphaelokon](https://github.com/raphaelokon) - CLI Contributor -* [@tburny](https://github.com/tburny) - Core Contributor +Core, and Editions, are part of the [Pattern Lab Ecosystem](http://patternlab.io/docs/advanced-ecosystem-overview.html). With this architecture, we encourage people to write and maintain their own editions. + +## Usage + +``` javascript +const config = require('./patternlab-config.json'); +const patternlab = require('patternlab-node')(config); +patternlab.build(doneCallBack, boolCleanOutputDir); +``` + +* Read more about configuration via `patternlab-config.json`: https://github.com/pattern-lab/patternlab-node/wiki/Configuration +* The rest of the [api / command line interface](https://github.com/pattern-lab/patternlab-node/wiki/Command-Line-Interface) is documented in the wiki, and already implemented for you within [Node Editions](https://github.com/pattern-lab?utf8=%E2%9C%93&query=edition-node). +A [full-featured command line interface](https://github.com/pattern-lab/patternlab-node-cli) is in the works, courtesy of [@raphaelokon](https://github.com/raphaelokon). + + +## Development Installation / Workflow + +If you are interested in [contributing to Pattern Lab](https://github.com/pattern-lab/patternlab-node/blob/master/.github/CONTRIBUTING.md), it's suggested to install an Edition of your choice and then run a local copy of this repository via [`npm link`](https://docs.npmjs.com/cli/link). + +``` bash +mkdir /patternlab-node +cd /patternlab-node +git clone https://github.com/pattern-lab/patternlab-node.git +npm install +npm link +cd location/of/edition +npm link patternlab-node +``` + +The above is a bit verbose, but illustrates: + +1. how to clone this repository to an arbitrary location +2. install all dependencies (run `npm install --dev` if your NODE_ENV is production for some reason) +3. setup the `npm link` to your local copy +4. use the local copy of patternlab-node in your edition + +> Make sure to change to whichever branch you intend to hack on or test within your cloned repository, such as `dev` or `bugfix/fixes-broken-unittest` ## Upgrading If you find yourself here and are looking to upgrade, check out how to upgrade from version to version of Pattern Lab Node here: [https://github.com/pattern-lab/patternlab-node/wiki/Upgrading](https://github.com/pattern-lab/patternlab-node/wiki/Upgrading) -## Command Line Interface - -The rudimentary [command line interface](https://github.com/pattern-lab/patternlab-node/wiki/Command-Line-Interface) is documented in the wiki, and already implemented for you within [Node Editions](https://github.com/pattern-lab?utf8=%E2%9C%93&query=edition-node). -A [full-featured command line interface](https://github.com/pattern-lab/patternlab-node-cli) is in the works, courtesy of [@raphaelokon](https://github.com/raphaelokon). +View the [ChangeLog](https://github.com/pattern-lab/patternlab-node/wiki/ChangeLog) for the latest Pattern Lab Node updates. ## Contributing If you'd like to contribute to Pattern Lab Node, please do so! There is always a lot of ground to cover and something for your wheelhouse. -No pull request is too small. Check out any [up for grabs issues](https://github.com/pattern-lab/patternlab-node/labels/help%20wanted%20%2F%20up%20for%20grabs) as a good way to get your feet wet, or add some more unit tests. +Please read the guidelines: https://github.com/pattern-lab/patternlab-node/blob/master/.github/CONTRIBUTING.md -## Guidelines -1. Please keep your pull requests concise and limited to **ONE** substantive change at a time. This makes reviewing and testing so much easier. -2. _ALWAYS_ submit pull requests against the [dev branch](https://github.com/pattern-lab/patternlab-node/tree/dev). If this does not occur, I will first, try to redirect you gently, second, port over your contribution manually if time allows, and/or third, close your pull request. If you have a major feature to stabilize over time, talk to @bmuenzenmeyer about making a dedicated `feature-branch` -3. If you can, add some unit tests using the existing patterns in the `./test` directory -4. To help hack on core from an edition, read [this wiki page](https://github.com/pattern-lab/patternlab-node/wiki/Running-an-Edition-Against-Local-Core) -## Coding style -Two files combine within the project to define and maintain our coding style. +## Core Team -* The `.editorconfig` controls spaces / tabs within supported editors. Check out their [site](http://editorconfig.org/). -* The `.eslintrc` defines our javascript standards. Some editors will evaluate this real-time - otherwise it's run using `grunt|gulp build` +* [@bmuenzenmeyer](https://github.com/bmuenzenmeyer) - Lead Maintainer +* [@geoffp](https://github.com/geoffp) - Core Contributor +* [@raphaelokon](https://github.com/raphaelokon) - CLI Contributor +* [@tburny](https://github.com/tburny) - Core Contributor -## Gitter +## Community The Pattern Lab Node team uses [our gitter.im channel, pattern-lab/node](https://gitter.im/pattern-lab/node) to keep in sync, share updates, and talk shop. Please stop by to say hello or as a first place to turn if stuck. Other channels in the Pattern Lab organization can be found on gitter too. + +There is also a dedicated Pattern Lab channel on the [design system slack](designsystems.herokuapp.com) run by [@jina](https://twitter.com/jina). + +Ask or answer Pattern Lab questions on Stack Overflow: http://stackoverflow.com/questions/tagged/patternlab.io + +## License + +[MIT](https://github.com/pattern-lab/patternlab-node/blob/master/LICENSE) diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index f05ef9d57..6ee8d5d44 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -1,5 +1,5 @@ /* - * patternlab-node - v2.8.0 - 2017 + * patternlab-node - v2.9.2 - 2017 * * Brian Muenzenmeyer, Geoff Pursell, Raphael Okon, tburny and the web community. * Licensed under the MIT license. @@ -22,6 +22,10 @@ var diveSync = require('diveSync'), packageInfo = require('../../package.json'), plutils = require('./utilities'), jsonCopy = require('./json_copy'), + ui = require('./ui_builder'), + ui_builder = new ui(), + pe = require('./pattern_exporter'), + pattern_exporter = new pe(), PatternGraph = require('./pattern_graph').PatternGraph; //register our log events @@ -148,9 +152,7 @@ var patternlab_engine = function (config) { 'use strict'; var pa = require('./pattern_assembler'), - pe = require('./pattern_exporter'), lh = require('./lineage_hunter'), - ui = require('./ui_builder'), sm = require('./starterkit_manager'), Pattern = require('./object_factory').Pattern, CompileState = require('./object_factory').CompileState, @@ -159,7 +161,6 @@ var patternlab_engine = function (config) { patternlab.engines = patternEngines; var pattern_assembler = new pa(), - pattern_exporter = new pe(), lineage_hunter = new lh(); patternlab.package = fs.readJSONSync(path.resolve(__dirname, '../../package.json')); @@ -528,6 +529,10 @@ var patternlab_engine = function (config) { patternlab.events.emit('patternlab-pattern-iteration-end', patternlab); + //now that all the main patterns are known, look for any links that might be within data and expand them + //we need to do this before expanding patterns & partials into extendedTemplates, otherwise we could lose the data -> partial reference + pattern_assembler.parse_data_links(patternlab); + //diveSync again to recursively include partials, filling out the //extendedTemplate property of the patternlab.patterns elements // TODO we can reduce the time needed by only processing changed patterns and their partials @@ -537,10 +542,6 @@ var patternlab_engine = function (config) { processHeadPattern(); processFootPattern(); - //now that all the main patterns are known, look for any links that might be within data and expand them - //we need to do this before expanding patterns & partials into extendedTemplates, otherwise we could lose the data -> partial reference - pattern_assembler.parse_data_links(patternlab); - //cascade any patternStates lineage_hunter.cascade_pattern_states(patternlab); @@ -580,7 +581,6 @@ var patternlab_engine = function (config) { } } - //render all patterns last, so lineageR works patternsToBuild.forEach(pattern => renderSinglePattern(pattern, head)); @@ -606,7 +606,7 @@ var patternlab_engine = function (config) { } patternlab.isBusy = true; buildPatterns(deletePatternDir); - new ui().buildFrontend(patternlab); + ui_builder.buildFrontend(patternlab); printDebug(); patternlab.isBusy = false; callback(); diff --git a/package.json b/package.json index 46f0d0fa8..8c856442d 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.8.0", + "version": "2.9.2", "main": "./core/lib/patternlab.js", "dependencies": { "chalk": "^1.1.3", diff --git a/patternlab.png b/patternlab.png new file mode 100644 index 000000000..80edf70ad Binary files /dev/null and b/patternlab.png differ diff --git a/test/files/_data/listitems.json b/test/files/_data/listitems.json index efcd8b4f1..3187a7a8d 100644 --- a/test/files/_data/listitems.json +++ b/test/files/_data/listitems.json @@ -1,4 +1,11 @@ { - "test_list_item" : "izzn thizzle" + "1": { + "title": "Nullizzle shizznit velizzle, hizzle, suscipit own yo', gravida vizzle, arcu." + }, + "2": { + "title": "Veggies sunt bona vobis, proinde vos postulo" + }, + "3": { + "title": "Bacon ipsum dolor sit amet turducken strip steak beef ribs shank" + } } - diff --git a/test/files/_meta/_00-head.mustache b/test/files/_meta/_00-head.mustache new file mode 100644 index 000000000..e69de29bb diff --git a/test/files/_meta/_01-foot.mustache b/test/files/_meta/_01-foot.mustache new file mode 100644 index 000000000..e69de29bb diff --git a/test/files/_patterns/00-test/paramMiddle.mustache b/test/files/_patterns/00-test/paramMiddle.mustache new file mode 100644 index 000000000..31169fb7e --- /dev/null +++ b/test/files/_patterns/00-test/paramMiddle.mustache @@ -0,0 +1,3 @@ +
+ {{> test-link }} +
diff --git a/test/files/_patterns/00-test/paramParent.json b/test/files/_patterns/00-test/paramParent.json new file mode 100644 index 000000000..d913cc535 --- /dev/null +++ b/test/files/_patterns/00-test/paramParent.json @@ -0,0 +1,3 @@ +{ + "url" : "link.test-foo" +} diff --git a/test/files/_patterns/00-test/paramParent.mustache b/test/files/_patterns/00-test/paramParent.mustache new file mode 100644 index 000000000..bf4e84562 --- /dev/null +++ b/test/files/_patterns/00-test/paramParent.mustache @@ -0,0 +1 @@ +{{> test-paramMiddle(styleModifier: "foo") }} diff --git a/test/files/partials/general-footer.mustache b/test/files/partials/general-footer.mustache new file mode 100644 index 000000000..e69de29bb diff --git a/test/files/partials/general-header.mustache b/test/files/partials/general-header.mustache new file mode 100644 index 000000000..e69de29bb diff --git a/test/files/partials/patternSection.mustache b/test/files/partials/patternSection.mustache new file mode 100644 index 000000000..e69de29bb diff --git a/test/files/partials/patternSectionSubtype.mustache b/test/files/partials/patternSectionSubtype.mustache new file mode 100644 index 000000000..e69de29bb diff --git a/test/files/viewall.mustache b/test/files/viewall.mustache new file mode 100644 index 000000000..e69de29bb diff --git a/test/patternlab_tests.js b/test/patternlab_tests.js index 84eb81d2f..0ea02de9b 100644 --- a/test/patternlab_tests.js +++ b/test/patternlab_tests.js @@ -1,15 +1,73 @@ 'use strict'; -var tap = require('tap'); +const tap = require('tap'); +const rewire = require("rewire"); +const _ = require('lodash'); +const fs = require('fs-extra'); +var config = require('./util/patternlab-config.json'); + +var plEngineModule = rewire('../core/lib/patternlab'); + +//set up a global mocks - we don't want to be writing/rendering any files right now +const uiBuilderMock = { + buildFrontend: function (patternlab) { } +}; + +const fsMock = { + outputFileSync: function (path, content) { /* INTENTIONAL NOOP */}, + readJSONSync: function(path, encoding) { + return fs.readJSONSync(path, encoding); + }, + removeSync: function(path) { fs.removeSync(path); }, + emptyDirSync: function(path) { fs.emptyDirSync(path); }, + readFileSync: function(path, encoding) { return fs.readFileSync(path, encoding); }, +} + +//set our mocks in place of usual require() +plEngineModule.__set__({ + 'ui_builder': uiBuilderMock, + 'fs': fsMock +}); tap.test('buildPatternData - should merge all JSON files in the data folder except listitems', function(test){ - var fs = require('fs-extra'); - var plMain = require('../core/lib/patternlab'); var data_dir = './test/files/_data/'; - var dataResult = plMain.build_pattern_data(data_dir, fs); + var dataResult = plEngineModule.build_pattern_data(data_dir, fs); test.equals(dataResult.data, "test"); test.equals(dataResult.foo, "bar"); test.equals(dataResult.test_list_item, undefined); test.end(); }); + +tap.test('buildPatterns - should replace data link even when pattern parameter present', function(test) { + //arrange + + var patternExporterMock = { + /* + In this test, we actually take advantage of the pattern export functionality post-build to inspect what + the contents of the patterns look like. This, coupled with a mocking of fs and the ui_builder, allow us to focus + only on the order of events within build. + */ + export_patterns: function (patternlab) { + var pattern = _.find(patternlab.patterns, (pattern) => { + return pattern.patternPartial === 'test-paramParent'; + }); + //assert + test.equals(pattern.patternPartialCode.indexOf('00-test-00-foo.rendered.html') > -1, true, 'data link should be replaced properly'); + } + }; + + plEngineModule.__set__({ + 'pattern_exporter': patternExporterMock + }); + + config.patternExportPatternPartials = ['test-paramParent']; + var pl = new plEngineModule(config); + + //act + pl.build(function() { + test.end(); + }, true); + + +}); diff --git a/test/util/patternlab-config.json b/test/util/patternlab-config.json new file mode 100644 index 000000000..d13f33508 --- /dev/null +++ b/test/util/patternlab-config.json @@ -0,0 +1,67 @@ +{ + "paths" : { + "source" : { + "root": "./test/files/", + "patterns" : "./test/files/_patterns/", + "data" : "./test/files/_data/", + "meta": "./test/files/_meta/", + "styleguide" : "./test/files/styleguide/", + "patternlabFiles" : "./test/files/", + "js" : "./test/files/js", + "images" : "./test/files/images", + "fonts" : "./test/files/fonts", + "css" : "./test/files/css/" + }, + "public" : { + "root" : "./test/public/", + "patterns" : "./test/public/patterns/", + "data" : "./test/public/data/", + "styleguide" : "./test/public/styleguide/", + "js" : "./test/public/js", + "images" : "./test/public/images", + "fonts" : "./test/public/fonts", + "css" : "./test/public/css" + } + }, + "styleGuideExcludes": [ + "templates", + "pages" + ], + "defaultPattern": "all", + "ignored-extensions" : ["scss", "DS_Store", "less"], + "ignored-directories" : ["scss"], + "debug": false, + "ishControlsHide": { + "s": false, + "m": false, + "l": false, + "full": false, + "random": false, + "disco": false, + "hay": true, + "mqs": false, + "find": false, + "views-all": false, + "views-annotations": false, + "views-code": false, + "views-new": false, + "tools-all": false, + "tools-docs": false + }, + "ishMinimum": "240", + "ishMaximum": "2600", + "patternStateCascade": ["inprogress", "inreview", "complete"], + "patternStates": { + }, + "patternExportPatternPartials": [], + "patternExportDirectory": "./pattern_exports/", + "cacheBust": true, + "outputFileSuffixes": { + "rendered": ".rendered", + "rawTemplate": "", + "markupOnly": ".markup-only" + }, + "cleanOutputHtml": true, + "exportToGraphViz": false, + "cleanPublic": true +}