From 1ac77a75153ce667598163540300dfc42de99e71 Mon Sep 17 00:00:00 2001 From: Brian Muenzenmeyer Date: Fri, 19 Jan 2018 14:43:36 -0600 Subject: [PATCH] feat(list_item_hunter): Re-work algorithm Now list_item_hunter does almost nothing, transforming the spec syntax into a friendly single value (rather than nested with a period), so that we can ALSO transform listItem data into the same structure - meaning `2` in the json becomes `listItem-two` - which can very easily by looped over by mustache. this change should be further vetted --- core/lib/buildListItems.js | 40 +- core/lib/list_item_hunter.js | 246 +--------- core/lib/patternlab.js | 18 +- test/buildListItems_tests.js | 85 ++++ test/files/_data/listitems.json | 12 +- .../00-test/553-repeatedListItems.mustache | 2 + .../00-test/listWithListItems.listitems.json | 11 + .../00-test/listWithListItems.mustache | 3 + .../00-test/listWithPartial.mustache | 3 + test/files/_patterns/00-test/mirror.mustache | 1 + test/index_tests.js | 76 +++ test/list_item_hunter_tests.js | 451 ++---------------- test/processRecursive_tests.js | 42 -- 13 files changed, 288 insertions(+), 702 deletions(-) create mode 100644 test/buildListItems_tests.js create mode 100644 test/files/_patterns/00-test/553-repeatedListItems.mustache create mode 100644 test/files/_patterns/00-test/listWithListItems.listitems.json create mode 100644 test/files/_patterns/00-test/listWithListItems.mustache create mode 100644 test/files/_patterns/00-test/listWithPartial.mustache create mode 100644 test/files/_patterns/00-test/mirror.mustache diff --git a/core/lib/buildListItems.js b/core/lib/buildListItems.js index a8aebbcda..af9ba783d 100644 --- a/core/lib/buildListItems.js +++ b/core/lib/buildListItems.js @@ -1,6 +1,30 @@ 'use strict'; -const _ = require('lodash'); +let _ = require('lodash'); //eslint-disable-line prefer-const + +const items = [ + 'zero', + 'one', + 'two', + 'three', + 'four', + 'five', + 'six', + 'seven', + 'eight', + 'nine', + 'ten', + 'eleven', + 'twelve', + 'thirteen', + 'fourteen', + 'fifteen', + 'sixteen', + 'seventeen', + 'eighteen', + 'nineteen', + 'twenty', +]; module.exports = function(container) { //combine all list items into one structure @@ -10,17 +34,19 @@ module.exports = function(container) { list.push(container.listitems[item]); } } - container.listItemArray = _.shuffle(list); + const listItemArray = _.shuffle(list); - for (let i = 1; i <= container.listItemArray.length; i++) { + for (let i = 1; i <= listItemArray.length; i++) { const tempItems = []; if (i === 1) { - tempItems.push(container.listItemArray[0]); - container.listitems['' + i] = tempItems; + tempItems.push(listItemArray[0]); + container.listitems['listItems-' + items[i]] = tempItems; + delete container.listitems[i]; } else { for (let c = 1; c <= i; c++) { - tempItems.push(container.listItemArray[c - 1]); - container.listitems['' + i] = tempItems; + tempItems.push(listItemArray[c - 1]); + container.listitems['listItems-' + items[i]] = tempItems; + delete container.listitems[i]; } } } diff --git a/core/lib/list_item_hunter.js b/core/lib/list_item_hunter.js index 49ac87f70..167c8e55c 100644 --- a/core/lib/list_item_hunter.js +++ b/core/lib/list_item_hunter.js @@ -1,244 +1,38 @@ 'use strict'; const list_item_hunter = function() { - const extend = require('util')._extend; - const _ = require('lodash'); - const smh = require('./style_modifier_hunter'); - const jsonCopy = require('./json_copy'); - const Pattern = require('./object_factory').Pattern; - const logger = require('./log'); - const parseLink = require('./parseLink'); - const getPartial = require('./get'); - const render = require('./render'); - - const style_modifier_hunter = new smh(); - const items = [ - 'zero', - 'one', - 'two', - 'three', - 'four', - 'five', - 'six', - 'seven', - 'eight', - 'nine', - 'ten', - 'eleven', - 'twelve', - 'thirteen', - 'fourteen', - 'fifteen', - 'sixteen', - 'seventeen', - 'eighteen', - 'nineteen', - 'twenty', - ]; - function processListItemPartials(pattern, patternlab) { + function processListItemPartials(pattern) { //find any listitem blocks const matches = pattern.findListItems(); if (matches !== null) { - return matches.reduce((previousMatchPromise, liMatch) => { + return matches.reduce((previousMatchPromise, liMatchStart) => { return previousMatchPromise.then(() => { logger.debug( - `found listItem of size ${liMatch} inside ${pattern.patternPartial}` + `found listItem of size ${liMatchStart} inside ${ + pattern.patternPartial + }` ); - //find the boundaries of the block - const loopNumberString = liMatch - .split('.')[1] - .split('}')[0] - .trim(); - const end = liMatch.replace('#', '/'); - const patternBlock = pattern.template - .substring( - pattern.template.indexOf(liMatch) + liMatch.length, - pattern.template.indexOf(end) - ) - .trim(); - - //build arrays that repeat the block, however large we need to - const repeatedBlockTemplate = []; - - //what we will eventually replace our template's listitems block with - let repeatedBlockHtml = ''; - - for (let i = 0; i < items.indexOf(loopNumberString); i++) { - logger.debug( - `list item(s) in pattern ${ - pattern.patternPartial - }, adding ${patternBlock} to repeatedBlockTemplate` - ); - repeatedBlockTemplate.push(patternBlock); - } - - //check for a local listitems.json file - let listData; - try { - listData = jsonCopy( - patternlab.listitems, - 'config.paths.source.data listitems' - ); - } catch (err) { - logger.warning( - `There was an error parsing JSON for ${pattern.relPath}` - ); - logger.warning(err); - } - - listData = _.merge(listData, pattern.listitems); - listData = parseLink( - patternlab, - listData, - 'listitems.json + any pattern listitems.json' + //we found a listitem match + //replace it's beginning listitems.number with -number + const newStart = liMatchStart.replace('.', '-'); + pattern.extendedTemplate = pattern.extendedTemplate.replace( + liMatchStart, + newStart ); - //iterate over each copied block, rendering its contents - const allBlocks = repeatedBlockTemplate.reduce( - (previousPromise, currentBlockTemplate, index) => { - let thisBlockTemplate = currentBlockTemplate; - - return previousPromise - .then(() => { - //combine listItem data with pattern data with global data - const itemData = - listData['' + items.indexOf(loopNumberString)]; //this is a property like "2" - let globalData; - let localData; - try { - globalData = jsonCopy( - patternlab.data, - 'config.paths.source.data global data' - ); - localData = jsonCopy( - pattern.jsonFileData, - `${pattern.patternPartial} data` - ); - } catch (err) { - logger.warning( - `There was an error parsing JSON for ${pattern.relPath}` - ); - logger.warning(err); - } - - let allData = _.merge(globalData, localData); - allData = _.merge( - allData, - itemData !== undefined ? itemData[index] : {} - ); //itemData could be undefined if the listblock contains no partial, just markup - allData.link = extend({}, patternlab.data.link); - - //check for partials within the repeated block - const foundPartials = Pattern.createEmpty({ - template: thisBlockTemplate, - }).findPartials(); - - let renderPromise = undefined; - - if (foundPartials && foundPartials.length > 0) { - for (let j = 0; j < foundPartials.length; j++) { - //get the partial - const partialName = foundPartials[j].match( - /([\w\-\.\/~]+)/g - )[0]; - const partialPattern = getPartial( - partialName, - patternlab - ); - - //create a copy of the partial so as to not pollute it after the get_pattern_by_key call. - let cleanPartialPattern; - try { - cleanPartialPattern = JSON.parse( - JSON.stringify(partialPattern) - ); - cleanPartialPattern = jsonCopy( - partialPattern, - `partial pattern ${partialName}` - ); - } catch (err) { - logger.warning( - `There was an error parsing JSON for ${ - pattern.relPath - }` - ); - logger.warning(err); - } - - //if we retrieved a pattern we should make sure that its extendedTemplate is reset. looks to fix #356 - cleanPartialPattern.extendedTemplate = - cleanPartialPattern.template; - - //if partial has style modifier data, replace the styleModifier value - if (foundPartials[j].indexOf(':') > -1) { - style_modifier_hunter.consume_style_modifier( - cleanPartialPattern, - foundPartials[j], - patternlab - ); - } - - //replace its reference within the block with the extended template - thisBlockTemplate = thisBlockTemplate.replace( - foundPartials[j], - cleanPartialPattern.extendedTemplate - ); - } - - //render with data - renderPromise = render( - Pattern.createEmpty({ template: thisBlockTemplate }), - allData, - patternlab.partials - ); - } else { - //just render with mergedData - renderPromise = render( - Pattern.createEmpty({ template: thisBlockTemplate }), - allData, - patternlab.partials - ); - } - - return renderPromise - .then(thisBlockHTML => { - //add the rendered HTML to our string - repeatedBlockHtml = repeatedBlockHtml + thisBlockHTML; - }) - .catch(reason => { - logger.error(reason); - }); - }) - .catch(reason => { - logger.error(reason); - }); - }, - Promise.resolve() + //replace it's ending listitems.number with -number + const liMatchEnd = liMatchStart.replace('#', '/'); + const newEnd = liMatchEnd.replace('.', '-'); + pattern.extendedTemplate = pattern.extendedTemplate.replace( + liMatchEnd, + newEnd ); - return allBlocks - .then(() => { - //replace the block with our generated HTML - const repeatingBlock = pattern.extendedTemplate.substring( - pattern.extendedTemplate.indexOf(liMatch), - pattern.extendedTemplate.indexOf(end) + end.length - ); - pattern.extendedTemplate = pattern.extendedTemplate.replace( - repeatingBlock, - repeatedBlockHtml - ); - - //update the extendedTemplate in the partials object in case this pattern is consumed later - patternlab.partials[pattern.patternPartial] = - pattern.extendedTemplate; - }) - .catch(reason => { - logger.error(reason); - }); + return Promise.resolve(); }); }, Promise.resolve()); } else { @@ -247,8 +41,8 @@ const list_item_hunter = function() { } return { - process_list_item_partials: function(pattern, patternlab) { - return processListItemPartials(pattern, patternlab); + process_list_item_partials: function(pattern) { + return processListItemPartials(pattern); }, }; }; diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index 39cf984ba..3f8662141 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -11,6 +11,7 @@ const packageInfo = require('../../package.json'); const buildListItems = require('./buildListItems'); const dataLoader = require('./data_loader')(); const logger = require('./log'); +const parseLink = require('./parseLink'); const processIterative = require('./processIterative'); const processRecursive = require('./processRecursive'); const jsonCopy = require('./json_copy'); @@ -363,13 +364,16 @@ module.exports = class PatternLab { //render the pattern, but first consolidate any data we may have let allData; - try { - allData = jsonCopy(this.data, 'config.paths.source.data global data'); - } catch (err) { - logger.info('There was an error parsing JSON for ' + pattern.relPath); - logger.info(err); - } - allData = _.merge(allData, pattern.jsonFileData); + + let allListItems = _.merge({}, this.listitems, pattern.listitems); + allListItems = parseLink( + this, + allListItems, + 'listitems.json + any pattern listitems.json' + ); + + allData = _.merge({}, this.data, pattern.jsonFileData); + allData = _.merge({}, allData, allListItems); allData.cacheBuster = this.cacheBuster; /////////////// diff --git a/test/buildListItems_tests.js b/test/buildListItems_tests.js new file mode 100644 index 000000000..97a78d256 --- /dev/null +++ b/test/buildListItems_tests.js @@ -0,0 +1,85 @@ +'use strict'; + +const tap = require('tap'); +const rewire = require('rewire'); + +const listItems = require('./files/_data/listItems.json'); +const buildlistItems = rewire('../core/lib/buildListItems'); + +const _Mock = { + shuffle: function(list) { + return list; + }, +}; + +//set our mocks in place of usual require() +buildlistItems.__set__({ + _: _Mock, +}); + +tap.test( + 'buildlistItems transforms container of listItems with one value', + test => { + // do this to avoid the shuffling for now + const container = Object.assign({}, { listitems: { '1': listItems['1'] } }); + buildlistItems(container); + test.same(container.listitems, { + 'listItems-one': [ + { + title: 'tA', + description: 'dA', + message: 'mA', + }, + ], + }); + test.end(); + } +); + +tap.test( + 'buildlistItems transforms container of listItems with three values', + test => { + // do this to avoid the shuffling for now + const container = { listitems: listItems }; + buildlistItems(container); + test.same(container.listitems, { + 'listItems-one': [ + { + title: 'tA', + description: 'dA', + message: 'mA', + }, + ], + 'listItems-two': [ + { + title: 'tA', + description: 'dA', + message: 'mA', + }, + { + title: 'tB', + description: 'dB', + message: 'mB', + }, + ], + 'listItems-three': [ + { + title: 'tA', + description: 'dA', + message: 'mA', + }, + { + title: 'tB', + description: 'dB', + message: 'mB', + }, + { + title: 'tC', + description: 'dC', + message: 'mC', + }, + ], + }); + test.end(); + } +); diff --git a/test/files/_data/listitems.json b/test/files/_data/listitems.json index 3187a7a8d..0cb4c328d 100644 --- a/test/files/_data/listitems.json +++ b/test/files/_data/listitems.json @@ -1,11 +1,17 @@ { "1": { - "title": "Nullizzle shizznit velizzle, hizzle, suscipit own yo', gravida vizzle, arcu." + "title": "tA", + "description": "dA", + "message": "mA" }, "2": { - "title": "Veggies sunt bona vobis, proinde vos postulo" + "title": "tB", + "description": "dB", + "message": "mB" }, "3": { - "title": "Bacon ipsum dolor sit amet turducken strip steak beef ribs shank" + "title": "tC", + "description": "dC", + "message": "mC" } } diff --git a/test/files/_patterns/00-test/553-repeatedListItems.mustache b/test/files/_patterns/00-test/553-repeatedListItems.mustache new file mode 100644 index 000000000..8362b6d31 --- /dev/null +++ b/test/files/_patterns/00-test/553-repeatedListItems.mustache @@ -0,0 +1,2 @@ +{{# listItems.three }}A{{/ listItems.three }} +{{# listItems.three }}B{{/ listItems.three }} diff --git a/test/files/_patterns/00-test/listWithListItems.listitems.json b/test/files/_patterns/00-test/listWithListItems.listitems.json new file mode 100644 index 000000000..01497948f --- /dev/null +++ b/test/files/_patterns/00-test/listWithListItems.listitems.json @@ -0,0 +1,11 @@ +{ + "1": { + "title": "tX" + }, + "2": { + "title": "tY" + }, + "3": { + "title": "tZ" + } +} diff --git a/test/files/_patterns/00-test/listWithListItems.mustache b/test/files/_patterns/00-test/listWithListItems.mustache new file mode 100644 index 000000000..34699f54e --- /dev/null +++ b/test/files/_patterns/00-test/listWithListItems.mustache @@ -0,0 +1,3 @@ +{{#listItems.three}} + {{> test-mirror }} +{{/listItems.three}} diff --git a/test/files/_patterns/00-test/listWithPartial.mustache b/test/files/_patterns/00-test/listWithPartial.mustache new file mode 100644 index 000000000..5a734227a --- /dev/null +++ b/test/files/_patterns/00-test/listWithPartial.mustache @@ -0,0 +1,3 @@ +{{#listItems.two}} +{{> test-comment }} +{{/listItems.two}} diff --git a/test/files/_patterns/00-test/mirror.mustache b/test/files/_patterns/00-test/mirror.mustache new file mode 100644 index 000000000..31ea13421 --- /dev/null +++ b/test/files/_patterns/00-test/mirror.mustache @@ -0,0 +1 @@ +{{title}}{{description}} diff --git a/test/index_tests.js b/test/index_tests.js index 4d95a58a6..12b2e5b03 100644 --- a/test/index_tests.js +++ b/test/index_tests.js @@ -127,6 +127,82 @@ tap.test('buildPatterns', function() { test.end(); }); + tap.test('uses global listItem property', test => { + var pattern = get('test-listWithPartial', patternlab); + console.log(pattern.patternPartialCode); + let assertionCount = 0; + ['dA', 'dB', 'dC'].forEach(d => { + if (pattern.patternPartialCode.indexOf(d) > -1) { + assertionCount++; + } + }); + test.ok(assertionCount === 2); + test.end(); + }); + + tap.test( + 'overwrites listItem property if that property is in local .listitem.json', + test => { + var pattern = get('test-listWithListItems', patternlab); + test.ok(pattern.patternPartialCode.indexOf('tX') > -1); + test.ok(pattern.patternPartialCode.indexOf('tY') > -1); + test.ok(pattern.patternPartialCode.indexOf('tZ') > -1); + + test.end(); + } + ); + + tap.test( + 'uses global listItem property after merging local .listitem.json', + test => { + var pattern = get('test-listWithListItems', patternlab); + test.ok(pattern.patternPartialCode.indexOf('dA') > -1); + test.ok(pattern.patternPartialCode.indexOf('dB') > -1); + test.ok(pattern.patternPartialCode.indexOf('dC') > -1); + test.end(); + } + ); + + tap.test( + 'correctly ignores bookended partials without a style modifier when the same partial has a style modifier between', + test => { + var pattern = get('test-bookend-listitem', patternlab); + test.equals( + util.sanitized(pattern.extendedTemplate), + util.sanitized(`
+ {{#listItems-two}} + + {{message}} + + + + {{message}} + + + + {{message}} + + + {{/listItems-two}} +
+ `) + ); + test.end(); + } + ); + + tap.test( + 'listItems keys (`one` through `twelve`) can be used more than once per pattern', + test => { + var pattern = get('test-repeatedListItems', patternlab); + test.equals( + util.sanitized(pattern.patternPartialCode), + util.sanitized(`AAA BBB`) + ); + test.end(); + } + ); + /////////////// FAILING /////////////////// // todo // From issue #145 https://github.com/pattern-lab/patternlab-node/issues/145 diff --git a/test/list_item_hunter_tests.js b/test/list_item_hunter_tests.js index b77c76c20..77ad449ef 100644 --- a/test/list_item_hunter_tests.js +++ b/test/list_item_hunter_tests.js @@ -1,389 +1,40 @@ 'use strict'; const tap = require('tap'); -const extend = require('util')._extend; +const path = require('path'); -const Pattern = require('../core/lib/object_factory').Pattern; -const PatternGraph = require('../core/lib/pattern_graph').PatternGraph; const lih = require('../core/lib/list_item_hunter'); const list_item_hunter = new lih(); const util = require('./util/test_utils.js'); -const processRecursive = require('../core/lib/processRecursive'); +const loadPattern = require('../core/lib/loadPattern'); + +const testPatternsPath = path.resolve(__dirname, 'files', '_patterns'); const config = require('./util/patternlab-config.json'); const engineLoader = require('../core/lib/pattern_engines'); engineLoader.loadAllEngines(config); -// fake pattern creators -function createFakeListPattern(customProps) { - var inputs = { - relPath: '01-molecules/01-lists/00-list.mustache', - data: {}, - }; - var pattern = new Pattern(inputs.relPath); - - return extend(pattern, customProps); -} - -function createFakePatternLab(customProps) { - //NOTE: These listitems are faked so that buildListItems has already clobbered them. - var pl = { - graph: PatternGraph.empty(), - listitems: { - '1': [ - { - title: 'Foo', - message: 'FooM', - }, - ], - '2': [ - { - title: 'Foo', - message: 'FooM', - }, - { - title: 'Bar', - message: 'BarM', - }, - ], - '3': [ - { - title: 'Foo', - message: 'FooM', - }, - { - title: 'Bar', - message: 'BarM', - }, - { - title: 'Baz', - message: 'BazM', - }, - ], - }, - data: { - link: {}, - partials: [], - }, - config: { - logLevel: 'quiet', - paths: { - source: { - patterns: './test/files/_patterns', - }, - }, - outputFileSuffixes: { - rendered: '', - }, - }, - partials: {}, - patterns: [], - }; - - return extend(pl, customProps); -} - -tap.test( - 'process_list_item_partials finds and outputs basic repeating blocks', - function(test) { - //arrange - //setup current pattern from what we would have during execution - var currentPattern = createFakeListPattern({ - template: '{{#listItems.two}}{{ title }}{{/listItems.two}}', - extendedTemplate: '{{#listItems.two}}{{ title }}{{/listItems.two}}', - }); - var patternlab = createFakePatternLab(); - - //act - list_item_hunter - .process_list_item_partials(currentPattern, patternlab) - .then(() => { - //assert - test.equals(currentPattern.extendedTemplate, 'FooBar'); - test.end(); - }); - } -); - -tap.test('process_list_item_partials listitems with lowercase name', function( - test -) { - //arrange - //setup current pattern from what we would have during execution - var currentPattern = createFakeListPattern({ - template: '{{#listitems.two}}{{ title }}{{/listitems.two}}', - extendedTemplate: '{{#listitems.two}}{{ title }}{{/listitems.two}}', - }); - var patternlab = createFakePatternLab(); - - //act - list_item_hunter - .process_list_item_partials(currentPattern, patternlab) - .then(() => { - //assert - test.equals(currentPattern.extendedTemplate, 'FooBar'); - test.end(); - }); -}); - -tap.test( - 'process_list_item_partials finds partials and outputs repeated renders', - function(test) { - //arrange - //setup current pattern from what we would have during execution - var currentPattern = createFakeListPattern({ - template: '{{#listItems.two}}{{ title }}{{/listItems.two}}', - extendedTemplate: - '{{#listItems.two}}{{> test-simple }}{{/listItems.two}}', - }); - - var patternlab = createFakePatternLab({ - patterns: [ - { - template: '{{ title }}', - extendedTemplate: '{{ title }}', - patternPartial: 'test-simple', - jsonFileData: {}, - }, - ], - }); - - //act - list_item_hunter - .process_list_item_partials(currentPattern, patternlab) - .then(() => { - //assert - test.equals(currentPattern.extendedTemplate, 'FooBar'); - test.end(); - }); - } -); - -tap.test( - 'process_list_item_partials finds verbose partials and outputs repeated renders', - function(test) { - var pattern1 = createFakeListPattern({ - template: - '{{#listItems.one}}{{> 00-test/00-foo.mustache }}{{/listItems.one}}', - extendedTemplate: - '{{#listItems.one}}{{> 00-test/00-foo.mustache }}{{/listItems.one}}', - patternPartial: 'test-patternName1', - relPath: '00-test/02-patternName1.mustache', - }); - - var pattern2 = createFakeListPattern({ - template: - '{{#listItems.two}}{{> 00-test/00-bar.mustache }}{{/listItems.two}}', - extendedTemplate: - '{{#listItems.two}}{{> 00-test/00-bar.mustache }}{{/listItems.two}}', - patternPartial: 'test-patternName2', - relPath: '00-test/03-patternName2.mustache', - }); - - var patternlab = createFakePatternLab({ - patterns: [ - Pattern.create('00-test/00-foo.mustache', null, { - template: '{{ title }}', - extendedTemplate: '{{ title }}', - relPath: '00-test/00-foo.mustache', - }), - Pattern.create('00-test/00-bar.mustache', null, { - template: '{{ title }}', - extendedTemplate: '{{ title }}', - relPath: '00-test/00-bar.mustache', - }), - ], - }); - - //act - list_item_hunter - .process_list_item_partials(pattern1, patternlab) - .then(() => { - list_item_hunter - .process_list_item_partials(pattern2, patternlab) - .then(() => { - //assert - test.equals(pattern1.extendedTemplate, 'Foo'); - test.equals(pattern2.extendedTemplate, 'FooBar'); - test.end(); - }); - }); - } -); - -tap.test( - 'process_list_item_partials overwrites listItem property if that property is in local .listitem.json', - function(test) { - //arrange - //setup current pattern from what we would have during execution - var currentPattern = createFakeListPattern({ - template: '{{#listItems.two}}{{ title }}{{/listItems.two}}', - extendedTemplate: - '{{#listItems.two}}{{> test-simple }}{{/listItems.two}}', - key: 'test-patternName', - jsonFileData: {}, - listitems: { - '2': [{ title: 'One' }, { title: 'Two' }], - }, - }); - var patternlab = createFakePatternLab({ - patterns: [ - createFakeListPattern({ - template: '{{ title }}', - extendedTemplate: '{{ title }}', - patternPartial: 'test-simple', - jsonFileData: {}, - }), - ], - }); - - //act - list_item_hunter - .process_list_item_partials(currentPattern, patternlab) - .then(() => { - //assert - test.equals(currentPattern.extendedTemplate, 'OneTwo'); - test.end(); - }); - } -); - -tap.test( - 'process_list_item_partials keeps listItem property if that property is not in local .listitem.json', - function(test) { - //arrange - //setup current pattern from what we would have during execution - var currentPattern = createFakeListPattern({ - template: '{{#listItems.one}}{{ title }}{{/listItems.one}}', - extendedTemplate: - '{{#listItems.one}}{{> test-simple }}{{/listItems.one}}', - key: 'test-patternName', - jsonFileData: {}, - listitems: { - '2': [{ title: 'One' }, { title: 'Two' }], - }, - }); - var patternlab = createFakePatternLab({ - patterns: [ - createFakeListPattern({ - template: '{{ title }}', - extendedTemplate: '{{ title }}', - patternPartial: 'test-simple', - jsonFileData: {}, - }), - ], - }); - - //act - list_item_hunter - .process_list_item_partials(currentPattern, patternlab) - .then(() => { - //assert - test.equals(currentPattern.extendedTemplate, 'Foo'); - test.end(); - }); - } -); - tap.test( - 'process_list_item_partials uses local listItem property if that property is not set globally', - function(test) { + 'process_list_item_partials converts partial to simpler format', + test => { //arrange - //setup current pattern from what we would have during execution - var currentPattern = createFakeListPattern({ - template: '{{#listItems.one}}{{ title }}{{/listItems.one}}', - extendedTemplate: - '{{#listItems.one}}{{> test-simple }}{{/listItems.one}}', - key: 'test-patternName', - jsonFileData: {}, - listitems: { - '1': [{ title: 'One' }], - '2': [{ title: 'One' }, { title: 'Two' }], - }, - }); + const pl = util.fakePatternLab(testPatternsPath); + const listPath = path.join('00-test', '685-list.mustache'); + const testPattern = loadPattern(listPath, pl); - var patternlab = createFakePatternLab({ - patterns: [ - createFakeListPattern({ - template: '{{ title }}', - extendedTemplate: '{{ title }}', - patternPartial: 'test-simple', - jsonFileData: {}, - }), - ], - }); - delete patternlab.listitems['1']; // remove the "1" list + //usually decompose does this + testPattern.extendedTemplate = testPattern.template; //act - list_item_hunter - .process_list_item_partials(currentPattern, patternlab) - .then(() => { - //assert - test.equals(typeof patternlab.listitems['1'], 'undefined'); - test.equals(currentPattern.extendedTemplate, 'One'); - test.end(); - }); - } -); - -tap.test( - 'process_list_item_partials - correctly ignores bookended partials without a style modifier when the same partial has a style modifier between', - function(test) { - //arrange - var fs = require('fs-extra'); - var patterns_dir = './test/files/_patterns'; - - var pl = {}; - pl.config = {}; - pl.data = {}; - pl.data.link = {}; - pl.config.logLevel = 'quiet'; - pl.patterns = []; - pl.partials = {}; - pl.config.patterns = { source: patterns_dir }; - pl.listitems = { - '1': [ - { - message: 'Foo', - }, - ], - '2': [ - { - message: 'Foo', - }, - { - message: 'Bar', - }, - ], - }; - - var atomPattern = new Pattern('00-test/03-styled-atom.mustache'); - atomPattern.template = fs.readFileSync( - patterns_dir + '/00-test/03-styled-atom.mustache', - 'utf8' - ); - atomPattern.extendedTemplate = atomPattern.template; - atomPattern.stylePartials = atomPattern.findPartialsWithStyleModifiers(); - - var bookendPattern = new Pattern('00-test/11-bookend-listitem.mustache'); - bookendPattern.template = fs.readFileSync( - patterns_dir + '/00-test/11-bookend-listitem.mustache', - 'utf8' - ); - bookendPattern.extendedTemplate = bookendPattern.template; - bookendPattern.stylePartials = bookendPattern.findPartialsWithStyleModifiers(); - - pl.patterns.push(atomPattern); - pl.patterns.push(bookendPattern); - - //act - list_item_hunter.process_list_item_partials(bookendPattern, pl).then(() => { - //assert. here we expect {{styleModifier}} to be replaced with an empty string or the styleModifier value from the found partial with the :styleModifier - var expectedValue = - '
Foo Foo Foo Bar Bar Bar
'; + list_item_hunter.process_list_item_partials(testPattern, pl).then(() => { + //assert test.equals( - util.sanitized(bookendPattern.extendedTemplate), - util.sanitized(expectedValue) + util.sanitized(testPattern.extendedTemplate), + util.sanitized(` + {{#listItems-three}} + {{title}} + {{/listItems-three}} + `) ); test.end(); }); @@ -391,60 +42,26 @@ tap.test( ); tap.test( - 'process_list_item_partials - correctly ignores already processed partial that had a style modifier when the same partial no longer has one', - function(test) { + 'process_list_item_partials converts partial with includes to simpler format', + test => { //arrange - var fs = require('fs-extra'); - - var pl = createFakePatternLab(); + const pl = util.fakePatternLab(testPatternsPath); + const listPath = path.join('00-test', 'listWithPartial.mustache'); + const testPattern = loadPattern(listPath, pl); - var atomPattern = new Pattern('00-test/03-styled-atom.mustache'); - atomPattern.template = fs.readFileSync( - pl.config.paths.source.patterns + '/00-test/03-styled-atom.mustache', - 'utf8' - ); - atomPattern.extendedTemplate = atomPattern.template; - atomPattern.stylePartials = atomPattern.findPartialsWithStyleModifiers(); - - var anotherStyledAtomPattern = new Pattern( - '00-test/12-another-styled-atom.mustache' - ); - anotherStyledAtomPattern.template = fs.readFileSync( - pl.config.paths.source.patterns + - '/00-test/12-another-styled-atom.mustache', - 'utf8' - ); - anotherStyledAtomPattern.extendedTemplate = - anotherStyledAtomPattern.template; - anotherStyledAtomPattern.stylePartials = anotherStyledAtomPattern.findPartialsWithStyleModifiers(); - - var listPattern = new Pattern('00-test/13-listitem.mustache'); - listPattern.template = fs.readFileSync( - pl.config.paths.source.patterns + '/00-test/13-listitem.mustache', - 'utf8' - ); - listPattern.extendedTemplate = listPattern.template; - listPattern.stylePartials = listPattern.findPartialsWithStyleModifiers(); - - pl.patterns.push(atomPattern); - pl.patterns.push(anotherStyledAtomPattern); - pl.patterns.push(listPattern); + //usually decompose does this + testPattern.extendedTemplate = testPattern.template; //act - Promise.all([ - processRecursive(atomPattern.relPath, pl), - processRecursive(anotherStyledAtomPattern.relPath, pl), - processRecursive(listPattern.relPath, pl), - ]).then(() => { - //assert. - var expectedValue = - '
FooM
'; + list_item_hunter.process_list_item_partials(testPattern, pl).then(() => { + //assert test.equals( - listPattern.extendedTemplate - .replace(/\s\s+/g, ' ') - .replace(/\n/g, ' ') - .trim(), - expectedValue.trim() + util.sanitized(testPattern.extendedTemplate), + util.sanitized(` + {{#listItems-two}} + {{> test-comment }} + {{/listItems-two}} + `) ); test.end(); }); diff --git a/test/processRecursive_tests.js b/test/processRecursive_tests.js index b356ea279..d36338c1c 100644 --- a/test/processRecursive_tests.js +++ b/test/processRecursive_tests.js @@ -378,48 +378,6 @@ tap }) .catch(tap.threw); -tap.test('processRecursive - 685 ensure listitems data is used', function( - test -) { - //arrange - const patternlab = util.fakePatternLab(patterns_dir, { - data: { - title: '0', - }, - listitems: { - '1': { - title: '1', - }, - '2': { - title: '2', - }, - '3': { - title: '3', - }, - }, - }); - - buildListItems(patternlab); - - var listPatternPath = path.join('00-test', '685-list.mustache'); - var listPattern = loadPattern(listPatternPath, patternlab); - - Promise.all([processIterative(listPattern, patternlab)]) - .then(results => { - //act - processRecursive(listPatternPath, patternlab) - .then(() => { - //assert - test.true(results[0].extendedTemplate.indexOf(1) > -1); - test.true(results[0].extendedTemplate.indexOf(2) > -1); - test.true(results[0].extendedTemplate.indexOf(3) > -1); - test.end(); - }) - .catch(test.threw); - }) - .catch(test.threw); -}); - tap.test('hidden patterns can be called by their nice names', function(test) { //arrange const patternlab = util.fakePatternLab(patterns_dir);