Skip to content
This repository was archived by the owner on May 7, 2024. It is now read-only.

Commit 854aa91

Browse files
authored
Merge pull request NightlyCommit#16 from ericmorand/issue_14
Fix issue NightlyCommit#14
2 parents b668d5f + ba1e7f1 commit 854aa91

File tree

3 files changed

+136
-118
lines changed

3 files changed

+136
-118
lines changed

package.json

+11-10
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@
4747
"dependencies": {
4848
"crypto-js": "^3.1.9-1",
4949
"loader-utils": "^1.2.3",
50-
"schema-utils": "^2.0.1"
50+
"schema-utils": "^2.2.0",
51+
"slash": "^3.0.0"
5152
},
5253
"devDependencies": {
5354
"@types/loader-utils": "^1.1.3",
@@ -56,21 +57,21 @@
5657
"@types/schema-utils": "^1.0.0",
5758
"@types/sinon": "^7.0.13",
5859
"@types/tape": "^4.2.33",
59-
"@types/webpack": "^4.32.1",
60-
"coveralls": "^3.0.5",
60+
"@types/webpack": "^4.39.1",
61+
"coveralls": "^3.0.6",
6162
"html-webpack-plugin": "^3.2.0",
6263
"memory-fs": "^0.4.1",
6364
"module-alias": "^2.2.1",
6465
"nyc": "^14.1.1",
65-
"rimraf": "^2.6.3",
66-
"sinon": "^7.3.2",
66+
"rimraf": "^2.7.1",
67+
"sinon": "^7.5.0",
6768
"tap-bail": "^1.0.0",
6869
"tap-spec": "^5.0.0",
6970
"tape": "^4.11.0",
70-
"ts-node": "^8.3.0",
71-
"twing": "^2.3.3",
72-
"typescript": "^3.5.3",
73-
"webpack": "^4.37.0",
74-
"webpack-cli": "^3.3.6"
71+
"ts-node": "^8.4.1",
72+
"twing": "^2.3.6",
73+
"typescript": "^3.6.3",
74+
"webpack": "^4.41.0",
75+
"webpack-cli": "^3.3.9"
7576
}
7677
}

src/index.ts

+8-6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {NodeVisitor} from "./node-visitor";
55

66
const sha256 = require('crypto-js/sha256');
77
const hex = require('crypto-js/enc-hex');
8+
const slash = require('slash');
89

910
const validateOptions = require('schema-utils');
1011

@@ -37,7 +38,8 @@ export default function (this: loader.LoaderContext, source: string) {
3738

3839
validateOptions(optionsSchema, options, 'Twing loader');
3940

40-
let environmentModulePath: string = options.environmentModulePath;
41+
let resourcePath: string = slash(this.resourcePath);
42+
let environmentModulePath: string = slash(options.environmentModulePath);
4143
let renderContext: any = options.renderContext;
4244

4345
this.addDependency(environmentModulePath);
@@ -49,14 +51,14 @@ export default function (this: loader.LoaderContext, source: string) {
4951

5052
if (renderContext === undefined) {
5153
let parts: string[] = [
52-
`const {cache, loader, getEnvironment} = require('${require.resolve('./runtime')}');`,
54+
`const {cache, loader, getEnvironment} = require('${slash(require.resolve('./runtime'))}');`,
5355
`const env = getEnvironment(require('${environmentModulePath}'));`
5456
];
5557

5658
let nodeVisitor: NodeVisitor;
5759

5860
nodeVisitor = new NodeVisitor();
59-
nodeVisitor.fromPath = this.resourcePath;
61+
nodeVisitor.fromPath = resourcePath;
6062

6163
environment.addNodeVisitor(nodeVisitor);
6264

@@ -74,7 +76,7 @@ export default function (this: loader.LoaderContext, source: string) {
7476
return hash + (index === null ? '' : '_' + index);
7577
});
7678

77-
let className: string = environment.getTemplateClass(this.resourcePath);
79+
let className: string = environment.getTemplateClass(resourcePath);
7880
let sourceContext: TwingSource = new TwingSource(source, className);
7981
let precompiledTemplate = environment.compile(environment.parse(environment.tokenize(sourceContext)));
8082

@@ -103,7 +105,7 @@ module.exports = function(context = {}) {
103105
} else {
104106
environment.setLoader(new TwingLoaderChain([
105107
new PathSupportingArrayLoader(new Map([
106-
[this.resourcePath, source]
108+
[resourcePath, source]
107109
])),
108110
environment.getLoader()
109111
]));
@@ -112,6 +114,6 @@ module.exports = function(context = {}) {
112114
this.addDependency(environment.getLoader().resolve(name, from));
113115
});
114116

115-
return `module.exports = ${JSON.stringify(environment.render(this.resourcePath, renderContext))};`;
117+
return `module.exports = ${JSON.stringify(environment.render(resourcePath, renderContext))};`;
116118
}
117119
};

test/unit/index/test.ts

+117-102
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {resolve as resolvePath} from "path";
55
import * as sinon from "sinon";
66
import {TwingEnvironment} from "twing/lib/environment";
77

8-
let dependencies: string[] = [];
8+
let dependencies: string[];
99

1010
const loaderContext = {
1111
query: {
@@ -18,112 +18,127 @@ const loaderContext = {
1818
};
1919

2020
tape('loader', (test: Test) => {
21-
let environment: TwingEnvironment = require(loaderContext.query.environmentModulePath);
21+
for (let separator of ['/', '\\']) {
22+
test.test(`with "${separator}" as path separator`, (test) => {
23+
dependencies = [];
2224

23-
let spy = sinon.spy(environment, 'addNodeVisitor');
24-
25-
loader.bind(loaderContext)('{% embed "./bar.twig" %}{% endembed %}');
26-
27-
test.same(dependencies, [resolvePath('test/unit/fixtures/environment.js')], 'declares the environment module as a dependency');
28-
29-
loader.bind(loaderContext)('');
30-
31-
test.true(spy.notCalled, 'doesn\'t pollute the environment outside of the loader');
32-
33-
test.test('handles "render at compile time" mode', (test) => {
34-
let renderLoaderContext: any = {
35-
query: {
36-
environmentModulePath: loaderContext.query.environmentModulePath,
37-
renderContext: {
38-
bar: 'BAR'
39-
}
40-
},
41-
resourcePath: loaderContext.resourcePath,
42-
addDependency: loaderContext.addDependency
43-
};
44-
45-
let actual: string = loader.bind(renderLoaderContext)('{% embed "./bar.twig" %}{% endembed %}{{bar}}');
46-
47-
test.same(actual, 'module.exports = " FOO\\nBAR";');
48-
49-
test.end();
50-
});
51-
52-
test.test('provides options validation', (test) => {
53-
type ValidationError = {
54-
dataPath: string,
55-
keyword: string,
56-
message: string
57-
};
58-
59-
type Fixture = {
60-
options: any,
61-
expectation: ValidationError
62-
};
63-
64-
let fixtures: Fixture[] = [
65-
{
66-
options: {},
67-
expectation: {
68-
dataPath: '',
69-
keyword: 'required',
70-
message: 'should have required property \'environmentModulePath\''
71-
}
72-
},
73-
{
74-
options: {
75-
environmentModulePath: {}
25+
let context = Object.assign({}, loaderContext, {
26+
query: {
27+
environmentModulePath: loaderContext.query.environmentModulePath.replace(/\//g, separator)
7628
},
77-
expectation: {
78-
dataPath: '.environmentModulePath',
79-
keyword: 'type',
80-
message: 'should be string'
29+
resourcePath: loaderContext.resourcePath.replace(/\//g, separator)
30+
});
31+
32+
let environment: TwingEnvironment = require(loaderContext.query.environmentModulePath);
33+
34+
let spy = sinon.spy(environment, 'addNodeVisitor');
35+
36+
loader.bind(context)('{% embed "./bar.twig" %}{% endembed %}');
37+
38+
test.same(dependencies, [resolvePath('test/unit/fixtures/environment.js')], 'declares the environment module as a dependency');
39+
40+
loader.bind(context)('');
41+
42+
test.true(spy.notCalled, 'doesn\'t pollute the environment outside of the loader');
43+
44+
test.test('handles "render at compile time" mode', (test) => {
45+
let renderLoaderContext: any = {
46+
query: {
47+
environmentModulePath: context.query.environmentModulePath,
48+
renderContext: {
49+
bar: 'BAR'
50+
}
51+
},
52+
resourcePath: context.resourcePath,
53+
addDependency: context.addDependency
54+
};
55+
56+
let actual: string = loader.bind(renderLoaderContext)('{% embed "./bar.twig" %}{% endembed %}{{bar}}');
57+
58+
test.same(actual, 'module.exports = " FOO\\nBAR";');
59+
60+
test.end();
61+
});
62+
63+
test.test('provides options validation', (test) => {
64+
type ValidationError = {
65+
dataPath: string,
66+
keyword: string,
67+
message: string
68+
};
69+
70+
type Fixture = {
71+
options: any,
72+
expectation: ValidationError
73+
};
74+
75+
let fixtures: Fixture[] = [
76+
{
77+
options: {},
78+
expectation: {
79+
dataPath: '',
80+
keyword: 'required',
81+
message: 'should have required property \'environmentModulePath\''
82+
}
83+
},
84+
{
85+
options: {
86+
environmentModulePath: {}
87+
},
88+
expectation: {
89+
dataPath: '.environmentModulePath',
90+
keyword: 'type',
91+
message: 'should be string'
92+
}
93+
},
94+
{
95+
options: {
96+
environmentModulePath: '',
97+
renderContext: ''
98+
},
99+
expectation: {
100+
dataPath: '.renderContext',
101+
keyword: 'type',
102+
message: 'should be object'
103+
}
104+
},
105+
{
106+
options: {
107+
environmentModulePath: '',
108+
foo: ''
109+
},
110+
expectation: {
111+
dataPath: '',
112+
keyword: 'additionalProperties',
113+
message: 'should NOT have additional properties'
114+
}
115+
}
116+
];
117+
118+
for (let fixture of fixtures) {
119+
let errors: ValidationError[];
120+
121+
try {
122+
loader.bind({
123+
query: fixture.options
124+
})();
125+
126+
errors = [];
127+
} catch (e) {
128+
errors = e.errors;
129+
}
130+
131+
test.same(errors[0].dataPath, fixture.expectation.dataPath);
132+
test.same(errors[0].keyword, fixture.expectation.keyword);
133+
test.same(errors[0].message, fixture.expectation.message);
81134
}
82-
},
83-
{
84-
options: {
85-
environmentModulePath: '',
86-
renderContext: ''
87-
},
88-
expectation: {
89-
dataPath: '.renderContext',
90-
keyword: 'type',
91-
message: 'should be object'
92-
}
93-
},
94-
{
95-
options: {
96-
environmentModulePath: '',
97-
foo: ''
98-
},
99-
expectation: {
100-
dataPath: '',
101-
keyword: 'additionalProperties',
102-
message: 'should NOT have additional properties'
103-
}
104-
}
105-
];
106-
107-
for (let fixture of fixtures) {
108-
let errors: ValidationError[];
109-
110-
try {
111-
loader.bind({
112-
query: fixture.options
113-
})();
114-
115-
errors = [];
116-
} catch (e) {
117-
errors = e.errors;
118-
}
119135

120-
test.same(errors[0].dataPath, fixture.expectation.dataPath);
121-
test.same(errors[0].keyword, fixture.expectation.keyword);
122-
test.same(errors[0].message, fixture.expectation.message);
123-
}
136+
test.end();
137+
});
124138

125-
test.end();
126-
});
139+
test.end();
140+
});
141+
}
127142

128143
test.end();
129144
});

0 commit comments

Comments
 (0)