Skip to content
This repository was archived by the owner on Dec 10, 2019. It is now read-only.

Commit 701477b

Browse files
committed
Tweaks, cleanups and unit tests for the Twig engine.
1 parent 1578b0b commit 701477b

File tree

5 files changed

+226
-8
lines changed

5 files changed

+226
-8
lines changed

core/lib/pattern_engines/engine_twig.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@
1111
/*
1212
* ENGINE SUPPORT LEVEL:
1313
*
14-
* Full. Partial calls and lineage hunting are supported. Handlebars does not
15-
* support the mustache-specific syntax extensions, style modifiers and pattern
16-
* parameters, because their use cases are addressed by the core Handlebars
17-
* feature set.
14+
* Full. Partial calls and lineage hunting are supported. Twig does not support
15+
* the mustache-specific syntax extensions, style modifiers and pattern
16+
* parameters, because their use cases are addressed by the core Twig feature
17+
* set.
1818
*
1919
*/
2020

2121
"use strict";
2222

23-
var Twig = require('twig/twig.js');
23+
var Twig = require('twig');
2424
var twig = Twig.twig;
2525

2626
var engine_twig = {
@@ -32,7 +32,7 @@ var engine_twig = {
3232
expandPartials: true,
3333

3434
// regexes, stored here so they're only compiled once
35-
findPartialsRE: /{%([ ]+)?(?:extends|include|embed)(\s\S)(.*)%}/g,
35+
findPartialsRE: /{%\s*(?:extends|include|embed)\s+('[^']+'|"[^"]+").*?%}/g,
3636
findPartialKeyRE: /"((?:\\.|[^"\\])*)"/,
3737
findListItemsRE: /({{#( )?)(list(I|i)tems.)(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)( )?}}/g, // TODO
3838

@@ -45,7 +45,7 @@ var engine_twig = {
4545
return result;
4646
},
4747

48-
// find and return any {{> template-name }} within pattern
48+
// find and return any {% include 'template-name' %} within pattern
4949
findPartials: function findPartials(pattern) {
5050
var matches = pattern.template.match(this.findPartialsRE);
5151
return matches;

test/engine_twig_tests.js

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
"use strict";
2+
/*eslint-disable dot-notation*/
3+
4+
// don't run these tests unless twig is installed
5+
try { var twig = require('twig'); }
6+
catch (err) { return; }
7+
8+
var path = require('path');
9+
var pa = require('../core/lib/pattern_assembler');
10+
var object_factory = require('../core/lib/object_factory');
11+
var testPatternsPath = path.resolve(__dirname, 'files', '_twig-test-patterns');
12+
13+
try {
14+
require('twig');
15+
} catch (err) {
16+
console.log('twig renderer not installed; skipping tests');
17+
return;
18+
}
19+
20+
// fake pattern lab constructor:
21+
// sets up a fake patternlab object, which is needed by the pattern processing
22+
// apparatus.
23+
function fakePatternLab() {
24+
var fpl = {
25+
partials: {},
26+
patterns: [],
27+
footer: '',
28+
header: '',
29+
listitems: {},
30+
listItemArray: [],
31+
data: {
32+
link: {}
33+
},
34+
config: require('../patternlab-config.json'),
35+
package: {}
36+
};
37+
38+
// patch the pattern source so the pattern assembler can correctly determine
39+
// the "subdir"
40+
fpl.config.paths.source.patterns = './test/files/_twig-test-patterns';
41+
42+
return fpl;
43+
}
44+
45+
46+
// function for testing sets of partials
47+
function testFindPartials(test, partialTests) {
48+
test.expect(partialTests.length + 1);
49+
50+
// setup current pattern from what we would have during execution
51+
// docs on partial syntax are here:
52+
// http://patternlab.io/docs/pattern-including.html
53+
var currentPattern = object_factory.oPattern.create(
54+
'/home/fakeuser/pl/source/_patterns/01-molecules/00-testing/00-test-mol.twig', // abspath
55+
'01-molecules\\00-testing', // subdir
56+
'00-test-mol.twig', // filename,
57+
null, // data
58+
{
59+
template: partialTests.join()
60+
}
61+
);
62+
63+
// act
64+
var results = currentPattern.findPartials();
65+
66+
// assert
67+
debugger;
68+
test.equals(results.length, partialTests.length);
69+
partialTests.forEach(function (testString, index) {
70+
test.equals(results[index], testString);
71+
});
72+
73+
test.done();
74+
}
75+
76+
exports['engine_twig'] = {
77+
'button twig pattern renders': function (test) {
78+
test.expect(1);
79+
80+
var patternPath = path.resolve(
81+
testPatternsPath,
82+
'00-atoms',
83+
'00-general',
84+
'08-button.twig'
85+
);
86+
87+
var expectedValue = '<style>\n .btn {\n padding: 10px;\n border-radius: 10px;\n display: inline-block;\n text-align: center;\n }\n</style>\n\n<a href="#" class="btn">Button</a>\n';
88+
89+
// do all the normal processing of the pattern
90+
var patternlab = new fakePatternLab();
91+
var assembler = new pa();
92+
var helloWorldPattern = assembler.process_pattern_iterative(patternPath, patternlab);
93+
assembler.process_pattern_recursive(patternPath, patternlab);
94+
95+
test.equals(helloWorldPattern.render(), expectedValue);
96+
test.done();
97+
},
98+
'media object twig pattern can see the atoms-button and atoms-image partials and renders them': function (test) {
99+
test.expect(1);
100+
101+
// pattern paths
102+
var buttonPatternPath = path.resolve(
103+
testPatternsPath,
104+
'00-atoms',
105+
'00-general',
106+
'08-button.twig'
107+
);
108+
var imagePatternPath = path.resolve(
109+
testPatternsPath,
110+
'00-atoms',
111+
'00-general',
112+
'09-image.twig'
113+
);
114+
var mediaObjectPatternPath = path.resolve(
115+
testPatternsPath,
116+
'00-molecules',
117+
'00-general',
118+
'00-media-object.twig'
119+
);
120+
121+
var expectedValue = '<style>\n .Media {\n display: flex;\n align-items: flex-start;\n }\n\n .Media > img {\n margin-right: 1em;\n max-width: 200px;\n }\n\n .Media-body {\n flex: 1;\n }\n</style>\n\n\n\n\n<div class="Media">\n <img src="http://placeholdit.imgix.net/~text?txtsize=33&txt=280%C3%97220&w=280&h=220&fm=pjpg"\n srcset="http://placeholdit.imgix.net/~text?txtsize=33&txt=280%C3%97220&w=280&h=220&fm=pjpg 280w,\n http://placeholdit.imgix.net/~text?txtsize=33&txt=560%C3%97440&w=560&h=440&fm=pjpg 560w,\n http://placeholdit.imgix.net/~text?txtsize=33&txt=840%C3%97660&w=840&h=660&fm=pjpg 840w"\n sizes="100vw">\n\n <style>\n .btn {\n padding: 10px;\n border-radius: 10px;\n display: inline-block;\n text-align: center;\n }\n</style>\n\n<a href="#" class="btn">Button</a>\n\n\n <div class="Media-body">\n\n \n \n\n <p>Oh, hello world!</p>\n </div>\n</div>\n';
122+
123+
// set up environment
124+
var patternlab = new fakePatternLab(); // environment
125+
var assembler = new pa();
126+
127+
// do all the normal processing of the pattern
128+
assembler.process_pattern_iterative(buttonPatternPath, patternlab);
129+
assembler.process_pattern_iterative(imagePatternPath, patternlab);
130+
var mediaObjectPattern = assembler.process_pattern_iterative(mediaObjectPatternPath, patternlab);
131+
assembler.process_pattern_recursive(buttonPatternPath, patternlab);
132+
assembler.process_pattern_recursive(imagePatternPath, patternlab);
133+
assembler.process_pattern_recursive(mediaObjectPatternPath, patternlab);
134+
135+
// test
136+
test.equals(mediaObjectPattern.render(), expectedValue);
137+
test.done();
138+
},
139+
// 'twig partials can render JSON values': function (test) {
140+
// test.expect(1);
141+
142+
// // pattern paths
143+
// var pattern1Path = path.resolve(
144+
// testPatternsPath,
145+
// '00-atoms',
146+
// '00-global',
147+
// '00-helloworld-withdata.hbs'
148+
// );
149+
150+
// // set up environment
151+
// var patternlab = new fakePatternLab(); // environment
152+
// var assembler = new pa();
153+
154+
// // do all the normal processing of the pattern
155+
// var helloWorldWithData = assembler.process_pattern_iterative(pattern1Path, patternlab);
156+
// assembler.process_pattern_recursive(pattern1Path, patternlab);
157+
158+
// // test
159+
// test.equals(helloWorldWithData.render(), 'Hello world!\nYeah, we got the subtitle from the JSON.\n');
160+
// test.done();
161+
// },
162+
// 'twig partials use the JSON environment from the calling pattern and can accept passed parameters': function (test) {
163+
// test.expect(1);
164+
165+
// // pattern paths
166+
// var atomPath = path.resolve(
167+
// testPatternsPath,
168+
// '00-atoms',
169+
// '00-global',
170+
// '00-helloworld-withdata.hbs'
171+
// );
172+
// var molPath = path.resolve(
173+
// testPatternsPath,
174+
// '00-molecules',
175+
// '00-global',
176+
// '00-call-atom-with-molecule-data.hbs'
177+
// );
178+
179+
// // set up environment
180+
// var patternlab = new fakePatternLab(); // environment
181+
// var assembler = new pa();
182+
183+
// // do all the normal processing of the pattern
184+
// var atom = assembler.process_pattern_iterative(atomPath, patternlab);
185+
// var mol = assembler.process_pattern_iterative(molPath, patternlab);
186+
// assembler.process_pattern_recursive(atomPath, patternlab);
187+
// assembler.process_pattern_recursive(molPath, patternlab);
188+
189+
// // test
190+
// test.equals(mol.render(), '<h2>Call with default JSON environment:</h2>\nThis is Hello world!\nfrom the default JSON.\n\n\n<h2>Call with passed parameter:</h2>\nHowever, this is Hello world!\nfrom a totally different blob.\n\n');
191+
// test.done();
192+
// },
193+
'find_pattern_partials finds partials': function (test) {
194+
testFindPartials(test, [
195+
'{% include "atoms-image" %}',
196+
"{% include 'atoms-image' %}",
197+
"{%include 'atoms-image'%}",
198+
"{% include 'molecules-template' only %}",
199+
"{% include 'organisms-sidebar' ignore missing %}",
200+
"{% include 'organisms-sidebar' ignore missing only %}"
201+
]);
202+
},
203+
'find_pattern_partials finds verbose partials': function (test) {
204+
testFindPartials(test, [
205+
"{% include '01-molecules/06-components/03-comment-header.twig' %}",
206+
"{% include '00-atoms/00-global/06-test' %}"
207+
]);
208+
},
209+
'find_pattern_partials finds partials with twig parameters': function (test) {
210+
testFindPartials(test, [
211+
"{% include 'molecules-template' with {'foo': 'bar'} %}",
212+
"{% include 'molecules-template' with vars %}",
213+
"{% include 'molecules-template.twig' with {'foo': 'bar'} only %}",
214+
"{% include 'organisms-sidebar' ignore missing with {'foo': 'bar'} %}"
215+
]);
216+
}
217+
};

source/_patterns/01-molecules/media-object.twig renamed to test/files/_twig-test-patterns/00-molecules/00-general/00-media-object.twig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,12 @@
2020

2121
<div class="Media">
2222
{% include "atoms-image" %}
23+
{% include "atoms-button" %}
2324

2425
<div class="Media-body">
2526

2627
{# Testing if we can also pull in non-twig templates without breaking anything (it works!). Good idea though? Eh... #}
27-
{% include "atoms-paragraph" %}
28+
{# GTP: let's not for now. It's messin' up the unit testing. #}
2829

2930
<p>Oh, hello {{ foo }}</p>
3031
</div>

0 commit comments

Comments
 (0)