1 import pathFn from 'path';
3 import { writeFileSync, rmdirSync, unlinkSync, readFileSync } from 'hexo-fs';
4 import yml from 'js-yaml';
5 import Hexo from '../../../lib/hexo';
6 import multiConfigPath from '../../../lib/hexo/multi_config_path';
8 describe('config flag handling', () => {
9 const hexo = new Hexo(pathFn.join(__dirname, 'test_dir')) as any;
11 const mcp = multiConfigPath(hexo);
12 const base = hexo.base_dir;
14 function ConsoleReader() {
16 this.d = function(...args) {
19 for (let i = 0; i < args.length;) {
21 if (++i < args.length) {
32 this.i = function(...args) {
35 for (let i = 0; i < args.length;) {
37 if (++i < args.length) {
48 this.w = function(...args) {
49 const type = 'warning';
51 for (let i = 0; i < args.length;) {
53 if (++i < args.length) {
64 this.e = function(...args) {
67 for (let i = 0; i < args.length;) {
69 if (++i < args.length) {
81 hexo.log = new ConsoleReader();
95 ' ice_cream: chocolate'
100 '"author": "dinosaur",',
101 '"type": "elephant",',
102 '"favorites": {"food": "burgers"}',
108 '"author": "waldo",',
110 ' "food": "ice cream",',
111 ' "ice_cream": "strawberry"',
118 '"author": "james bond",',
120 ' "food": "martini",',
121 ' "ice_cream": "vanilla"',
127 writeFileSync(base + 'test1.yml', testYaml1);
128 writeFileSync(base + 'test2.yml', testYaml2);
129 writeFileSync(base + 'test1.json', testJson1);
130 writeFileSync(base + 'test2.json', testJson2);
131 // not supported type
132 writeFileSync(base + 'test1.xml', '');
133 writeFileSync('/tmp/test3.json', testJson3);
137 hexo.log.reader = [];
141 rmdirSync(hexo.base_dir);
142 unlinkSync('/tmp/test3.json');
145 it('no file', () => {
146 mcp(base).should.equal(base + '_config.yml');
147 hexo.log.reader[0].type.should.eql('warning');
148 hexo.log.reader[0].msg.should.eql('No config file entered.');
151 it('not supported type', () => {
152 mcp(base, 'test1.xml,test1.json').should.equal(base + '_multiconfig.yml');
153 hexo.log.reader[0].type.should.eql('warning');
154 hexo.log.reader[0].msg.should.eql('Config file test1.xml not supported type.');
158 mcp(base, 'test1.yml').should.eql(
159 pathFn.resolve(base + 'test1.yml'));
161 mcp(base, 'test1.json').should.eql(
162 pathFn.resolve(base + 'test1.json'));
164 mcp(base, '/tmp/test3.json').should.eql('/tmp/test3.json');
167 it('1 not found file warning', () => {
168 const notFile = 'not_a_file.json';
170 mcp(base, notFile).should.eql(pathFn.join(base, '_config.yml'));
171 hexo.log.reader[0].type.should.eql('warning');
172 hexo.log.reader[0].msg.should.eql('Config file ' + notFile
173 + ' not found, using default.');
176 it('1 not found file warning absolute', () => {
177 const notFile = '/tmp/not_a_file.json';
179 mcp(base, notFile).should.eql(pathFn.join(base, '_config.yml'));
180 hexo.log.reader[0].type.should.eql('warning');
181 hexo.log.reader[0].msg.should.eql('Config file ' + notFile
182 + ' not found, using default.');
185 it('combined config output', () => {
186 const combinedPath = pathFn.join(base, '_multiconfig.yml');
188 mcp(base, 'test1.yml').should.not.eql(combinedPath);
189 mcp(base, 'test1.yml,test2.yml').should.eql(combinedPath);
190 mcp(base, 'test1.yml,test1.json').should.eql(combinedPath);
191 mcp(base, 'test1.json,test2.json').should.eql(combinedPath);
192 mcp(base, 'notafile.yml,test1.json').should.eql(combinedPath);
194 hexo.log.reader[0].type.should.eql('info');
195 hexo.log.reader[0].msg.should.eql('Config based on 2 files');
196 hexo.log.reader[6].type.should.eql('warning');
197 hexo.log.reader[6].msg.should.eql('Config file notafile.yml not found.');
198 hexo.log.reader[7].type.should.eql('info');
199 hexo.log.reader[7].msg.should.eql('Config based on 1 files');
200 // because who cares about grammar anyway?
202 mcp(base, 'notafile.yml,alsonotafile.json').should.not.eql(combinedPath);
203 hexo.log.reader[11].type.should.eql('error');
204 hexo.log.reader[11].msg.should.eql('No config files found. Using _config.yml.');
207 it('combine config output with absolute paths', () => {
208 const combinedPath = pathFn.join(base, '_multiconfig.yml');
210 mcp(base, 'test1.json,/tmp/test3.json').should.eql(combinedPath);
211 hexo.log.reader[0].type.should.eql('info');
212 hexo.log.reader[0].msg.should.eql('Config based on 2 files');
215 it('2 YAML overwrite', () => {
216 const configFile = mcp(base, 'test1.yml,test2.yml');
217 let config: any = readFileSync(configFile);
218 config = yml.load(config);
220 config.author.should.eql('bar');
221 config.favorites.food.should.eql('candy');
222 config.type.should.eql('dinosaur');
224 config = readFileSync(mcp(base, 'test2.yml,test1.yml'));
225 config = yml.load(config);
227 config.author.should.eql('foo');
228 config.favorites.food.should.eql('sushi');
229 config.type.should.eql('dinosaur');
232 it('2 JSON overwrite', () => {
233 let config: any = readFileSync(mcp(base, 'test1.json,test2.json'));
234 config = yml.load(config);
236 config.author.should.eql('waldo');
237 config.favorites.food.should.eql('ice cream');
238 config.type.should.eql('elephant');
240 config = readFileSync(mcp(base, 'test2.json,test1.json'));
241 config = yml.load(config);
243 config.author.should.eql('dinosaur');
244 config.favorites.food.should.eql('burgers');
245 config.type.should.eql('elephant');
248 it('JSON & YAML overwrite', () => {
249 let config: any = readFileSync(mcp(base, 'test1.yml,test1.json'));
250 config = yml.load(config);
252 config.author.should.eql('dinosaur');
253 config.favorites.food.should.eql('burgers');
254 config.type.should.eql('elephant');
256 config = readFileSync(mcp(base, 'test1.json,test1.yml'));
257 config = yml.load(config);
259 config.author.should.eql('foo');
260 config.favorites.food.should.eql('sushi');
261 config.type.should.eql('dinosaur');
264 it('write multiconfig to specified path', () => {
265 const outputPath = osFn.tmpdir();
266 const combinedPath = pathFn.join(outputPath, '_multiconfig.yml');
268 mcp(base, 'test1.yml', outputPath).should.not.eql(combinedPath);
269 mcp(base, 'test1.yml,test2.yml', outputPath).should.eql(combinedPath);
270 mcp(base, 'test1.yml,test1.json', outputPath).should.eql(combinedPath);
271 mcp(base, 'test1.json,test2.json', outputPath).should.eql(combinedPath);
272 mcp(base, 'notafile.yml,test1.json', outputPath).should.eql(combinedPath);
273 mcp(base, 'notafile.yml,alsonotafile.json', outputPath).should.not.eql(combinedPath);
275 // delete /tmp/_multiconfig.yml
276 unlinkSync(combinedPath);
278 hexo.log.reader[1].type.should.eql('debug');
279 hexo.log.reader[1].msg.should.eql(`Writing _multiconfig.yml to ${combinedPath}`);
280 hexo.log.reader[2].type.should.eql('info');
281 hexo.log.reader[2].msg.should.eql('Config based on 2 files');
282 hexo.log.reader[6].type.should.eql('warning');
283 hexo.log.reader[6].msg.should.eql('Config file notafile.yml not found.');
284 hexo.log.reader[7].type.should.eql('info');
285 hexo.log.reader[7].msg.should.eql('Config based on 1 files');
286 hexo.log.reader[11].type.should.eql('error');
287 hexo.log.reader[11].msg.should.eql('No config files found. Using _config.yml.');