Skip to content

Commit 17443fe

Browse files
committed
Fix issue #103
1 parent a1b9890 commit 17443fe

File tree

5 files changed

+202
-6
lines changed

5 files changed

+202
-6
lines changed

src/twing/loader/array.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export class TwingLoaderArray implements TwingLoaderInterface {
6060

6161
isFresh(name: string, time: number): boolean {
6262
if (!this.exists(name)) {
63-
throw new Error(`Template "${name}" is not defined.`);
63+
throw new TwingErrorLoader(`Template "${name}" is not defined.`);
6464
}
6565

6666
return true;

src/twing/loader/chain.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {TwingSource} from "../source";
77
/**
88
* Loads templates from other loaders.
99
*
10-
* @author Fabien Potencier <fabien@symfony.com>
10+
* @author Eric MORAND <eric.morand@gmail.com>
1111
*/
1212
export class TwingLoaderChain implements TwingLoaderInterface {
1313
private hasSourceCache: TwingMap<string, TwingTemplate> = new TwingMap();
@@ -45,7 +45,7 @@ export class TwingLoaderChain implements TwingLoaderInterface {
4545
}
4646
}
4747

48-
throw new TwingErrorLoader(`Template "${name}" is not defined${exceptions ? ' (' + exceptions.join(', ') + ')' : ''}.`);
48+
throw new TwingErrorLoader(`Template "${name}" is not defined${exceptions.length ? ' (' + exceptions.join(', ') + ')' : ''}.`);
4949
}
5050

5151
exists(name: string) {
@@ -84,7 +84,7 @@ export class TwingLoaderChain implements TwingLoaderInterface {
8484
}
8585
}
8686

87-
throw new TwingErrorLoader(`Template "${name}" is not defined${exceptions ? ' (' + exceptions.join(', ') + ')' : ''}.`);
87+
throw new TwingErrorLoader(`Template "${name}" is not defined${exceptions.length ? ' (' + exceptions.join(', ') + ')' : ''}.`);
8888
}
8989

9090
isFresh(name: string, time: number) {
@@ -105,6 +105,6 @@ export class TwingLoaderChain implements TwingLoaderInterface {
105105
}
106106
}
107107

108-
throw new TwingErrorLoader(`Template "${name}" is not defined${exceptions ? ' (' + exceptions.join(', ') + ')' : ''}.`);
108+
throw new TwingErrorLoader(`Template "${name}" is not defined${exceptions.length ? ' (' + exceptions.join(', ') + ')' : ''}.`);
109109
}
110110
}

src/twing/source.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ export class TwingSource {
33
private name: string;
44
private path: string;
55

6-
constructor(code: string, name: string, path: string = null) {
6+
constructor(code: string, name: string, path: string = '') {
77
this.code = code;
88
this.name = name;
99
this.path = path;

test/tests/unit/twing/loader/array.js

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const TwingLoaderArray = require('../../../../../lib/twing/loader/array').TwingLoaderArray;
2+
const TwingErrorLoader = require('../../../../../lib/twing/error/loader').TwingErrorLoader;
23

34
const tap = require('tap');
45
const nodePath = require('path');
@@ -29,5 +30,88 @@ tap.test('loader array', function (test) {
2930
test.end();
3031
});
3132

33+
test.test('getSourceContextWhenTemplateDoesNotExist', function (test) {
34+
let loader = new TwingLoaderArray({});
35+
36+
test.throws(function() {
37+
loader.getSourceContext('foo');
38+
}, new TwingErrorLoader('Template "foo" is not defined.'));
39+
40+
test.end();
41+
});
42+
43+
test.test('getCacheKey', function (test) {
44+
let loader = new TwingLoaderArray({
45+
foo: 'bar'
46+
});
47+
48+
test.same(loader.getCacheKey('foo'), 'foo:bar');
49+
50+
test.end();
51+
});
52+
53+
test.test('getCacheKeyWhenTemplateHasDuplicateContent', function (test) {
54+
let loader = new TwingLoaderArray({
55+
foo: 'bar',
56+
baz: 'bar'
57+
});
58+
59+
test.same(loader.getCacheKey('foo'), 'foo:bar');
60+
test.same(loader.getCacheKey('baz'), 'baz:bar');
61+
62+
test.end();
63+
});
64+
65+
test.test('getCacheKeyIsProtectedFromEdgeCollisions', function (test) {
66+
let loader = new TwingLoaderArray({
67+
foo__: 'bar',
68+
foo: '__bar'
69+
});
70+
71+
test.same(loader.getCacheKey('foo__'), 'foo__:bar');
72+
test.same(loader.getCacheKey('foo'), 'foo:__bar');
73+
74+
test.end();
75+
});
76+
77+
test.test('getCacheKeyWhenTemplateDoesNotExist', function (test) {
78+
let loader = new TwingLoaderArray({});
79+
80+
test.throws(function() {
81+
loader.getCacheKey('foo');
82+
}, new TwingErrorLoader('Template "foo" is not defined.'));
83+
84+
test.end();
85+
});
86+
87+
test.test('setTemplate', function (test) {
88+
let loader = new TwingLoaderArray({});
89+
loader.setTemplate('foo', 'bar');
90+
91+
test.same(loader.getSourceContext('foo').getCode(), 'bar');
92+
93+
test.end();
94+
});
95+
96+
test.test('isFresh', function (test) {
97+
let loader = new TwingLoaderArray({
98+
foo: 'bar'
99+
});
100+
101+
test.true(loader.isFresh('foo', new Date().getTime()));
102+
103+
test.end();
104+
});
105+
106+
test.test('isFreshWhenTemplateDoesNotExist', function (test) {
107+
let loader = new TwingLoaderArray({});
108+
109+
test.throws(function() {
110+
loader.isFresh('foo', new Date().getTime());
111+
}, new TwingErrorLoader('Template "foo" is not defined.'));
112+
113+
test.end();
114+
});
115+
32116
test.end();
33117
});
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
const TwingLoaderChain = require('../../../../../lib/twing/loader/chain').TwingLoaderChain;
2+
const TwingLoaderArray = require('../../../../../lib/twing/loader/array').TwingLoaderArray;
3+
const TwingLoaderFilesystem = require('../../../../../lib/twing/loader/filesystem').TwingLoaderFilesystem;
4+
const TwingErrorLoader = require('../../../../../lib/twing/error/loader').TwingErrorLoader;
5+
6+
const tap = require('tap');
7+
const nodePath = require('path');
8+
const sinon = require('sinon');
9+
10+
let fixturesPath = nodePath.resolve('test/tests/integration/fixtures');
11+
12+
tap.test('loader chain', function (test) {
13+
test.test('constructor', function(test) {
14+
test.test('should accept zero parameters', function(test) {
15+
let loader = new TwingLoaderChain();
16+
17+
test.ok(loader);
18+
19+
test.end();
20+
});
21+
22+
test.end();
23+
});
24+
25+
test.test('getSourceContext', function (test) {
26+
let loader = new TwingLoaderChain([
27+
new TwingLoaderArray({'foo': 'bar'}),
28+
new TwingLoaderArray({'errors/index.html': 'baz'}),
29+
new TwingLoaderFilesystem([fixturesPath]),
30+
]);
31+
32+
test.equals(loader.getSourceContext('foo').getName(), 'foo');
33+
test.same(loader.getSourceContext('foo').getPath(), '');
34+
35+
test.equals(loader.getSourceContext('errors/index.html').getName(), 'errors/index.html');
36+
test.same(loader.getSourceContext('errors/index.html').getPath(), '');
37+
test.equals(loader.getSourceContext('errors/index.html').getCode(), 'baz');
38+
39+
test.equals(loader.getSourceContext('errors/base.html').getName(), 'errors/base.html');
40+
test.equals(nodePath.resolve(loader.getSourceContext('errors/base.html').getPath()), nodePath.join(fixturesPath, 'errors/base.html'));
41+
test.notEquals(loader.getSourceContext('errors/base.html').getCode(), 'baz');
42+
43+
test.end();
44+
});
45+
46+
test.test('getSourceContextWhenTemplateDoesNotExist', function (test) {
47+
let loader = new TwingLoaderChain([]);
48+
49+
test.throws(function () {
50+
loader.getSourceContext('foo');
51+
}, new TwingErrorLoader('Template "foo" is not defined.'));
52+
53+
test.end();
54+
});
55+
56+
test.test('getCacheKey', function (test) {
57+
let loader = new TwingLoaderChain([
58+
new TwingLoaderArray({'foo': 'bar'}),
59+
new TwingLoaderArray({'foo': 'foobar', 'bar': 'foo'}),
60+
]);
61+
62+
test.equals(loader.getCacheKey('foo'), 'foo:bar');
63+
test.equals(loader.getCacheKey('bar'), 'bar:foo');
64+
65+
test.end();
66+
});
67+
68+
test.test('getCacheKeyWhenTemplateDoesNotExist', function (test) {
69+
let loader = new TwingLoaderChain([]);
70+
71+
test.throws(function () {
72+
loader.getCacheKey('foo');
73+
}, new TwingErrorLoader('Template "foo" is not defined.'));
74+
75+
test.end();
76+
});
77+
78+
test.test('addLoader', function (test) {
79+
let loader = new TwingLoaderChain([]);
80+
loader.addLoader(new TwingLoaderArray({'foo': 'bar'}));
81+
82+
test.equals(loader.getSourceContext('foo').getCode(), 'bar');
83+
84+
test.end();
85+
});
86+
87+
test.test('exists', function (test) {
88+
let loader1 = new TwingLoaderArray({});
89+
sinon.stub(loader1, 'exists').returns(false);
90+
sinon.stub(loader1, 'getSourceContext');
91+
92+
let loader2 = new TwingLoaderArray({});
93+
sinon.stub(loader2, 'exists').returns(true);
94+
sinon.stub(loader2, 'getSourceContext');
95+
96+
let loader = new TwingLoaderChain([]);
97+
loader.addLoader(loader1);
98+
loader.addLoader(loader2);
99+
100+
test.true(loader.exists('foo'));
101+
102+
sinon.assert.calledOnce(loader1['exists']);
103+
sinon.assert.notCalled(loader1['getSourceContext']);
104+
105+
sinon.assert.calledOnce(loader2['exists']);
106+
sinon.assert.notCalled(loader2['getSourceContext']);
107+
108+
test.end();
109+
});
110+
111+
test.end();
112+
});

0 commit comments

Comments
 (0)