Adapt tests for TemplateBlock

This commit is contained in:
Samy Pesse
2016-10-07 11:46:57 +02:00
parent 1d291ff2f0
commit 9cedcc6b6e
7 changed files with 423 additions and 422 deletions
@@ -5,7 +5,7 @@ describe('Page', function() {
describe('toText', function() {
it('must not prepend frontmatter if no attributes', function() {
const page = Page().merge({
const page = (new Page()).merge({
content: 'Hello World'
});
@@ -13,7 +13,7 @@ describe('Page', function() {
});
it('must prepend frontmatter if attributes', function() {
const page = Page().merge({
const page = (new Page()).merge({
content: 'Hello World',
attributes: Immutable.fromJS({
hello: 'world'
@@ -24,4 +24,3 @@ describe('Page', function() {
});
});
});
@@ -5,49 +5,56 @@ const Promise = require('../../utils/promise');
describe('TemplateBlock', function() {
const TemplateBlock = require('../templateBlock');
describe('create', function() {
describe('.create', function() {
it('must initialize a simple TemplateBlock from a function', function() {
const templateBlock = TemplateBlock.create('sayhello', function(block) {
return {
body: '<p>Hello, World!</p>',
parse: true
};
return { message: 'Hello World' };
});
// Check basic templateBlock properties
expect(templateBlock.getName()).toBe('sayhello');
expect(templateBlock.getEndTag()).toBe('endsayhello');
expect(templateBlock.getBlocks().size).toBe(0);
expect(templateBlock.getExtensionName()).toBe('BlocksayhelloExtension');
});
});
// Check result of applying block
return Promise()
.then(function() {
return templateBlock.applyBlock();
})
.then(function(result) {
expect(result.name).toBe('sayhello');
expect(result.body).toBe('<p>Hello, World!</p>');
describe('.toProps', function() {
it('must handle sync method', function() {
const templateBlock = TemplateBlock.create('sayhello', function(block) {
return { message: 'Hello World' };
});
return templateBlock.toProps()
.then(function(props) {
expect(props).toEqual({ message: 'Hello World' });
});
});
it('must not fsil if return a string', function() {
const templateBlock = TemplateBlock.create('sayhello', function(block) {
return 'Hello World';
});
return templateBlock.toProps()
.then(function(props) {
expect(props).toEqual({ children: 'Hello World' });
});
});
});
describe('getShortcuts', function() {
describe('.getShortcuts', function() {
it('must return undefined if no shortcuts', function() {
const templateBlock = TemplateBlock.create('sayhello', function(block) {
return {
body: '<p>Hello, World!</p>',
parse: true
};
return { message: 'Hello World' };
});
expect(templateBlock.getShortcuts()).toNotExist();
});
it('must return complete shortcut', function() {
it('.must return complete shortcut', function() {
const templateBlock = TemplateBlock.create('sayhello', {
process(block) {
return '<p>Hello, World!</p>';
return { message: 'Hello World' };
},
shortcuts: {
parsers: ['markdown'],
@@ -66,45 +73,12 @@ describe('TemplateBlock', function() {
});
});
describe('toNunjucksExt()', function() {
it('should replace by block anchor', function() {
describe('.toNunjucksExt()', function() {
it('should render children correctly', function() {
const templateBlock = TemplateBlock.create('sayhello', function(block) {
return 'Hello';
});
let blocks = {};
// Create a fresh Nunjucks environment
const env = new nunjucks.Environment(null, { autoescape: false });
// Add template block to environement
const Ext = templateBlock.toNunjucksExt({}, blocks);
env.addExtension(templateBlock.getExtensionName(), new Ext());
// Render a template using the block
const src = '{% sayhello %}{% endsayhello %}';
return Promise.nfcall(env.renderString.bind(env), src)
.then(function(res) {
blocks = Immutable.fromJS(blocks);
expect(blocks.size).toBe(1);
const blockId = blocks.keySeq().get(0);
const block = blocks.get(blockId);
expect(res).toBe('{{-%' + blockId + '%-}}');
expect(block.get('body')).toBe('Hello');
expect(block.get('name')).toBe('sayhello');
});
});
it('must create a valid nunjucks extension', function() {
const templateBlock = TemplateBlock.create('sayhello', function(block) {
return {
body: '<p>Hello, World!</p>',
parse: true
};
});
// Create a fresh Nunjucks environment
const env = new nunjucks.Environment(null, { autoescape: false });
@@ -116,15 +90,34 @@ describe('TemplateBlock', function() {
const src = '{% sayhello %}{% endsayhello %}';
return Promise.nfcall(env.renderString.bind(env), src)
.then(function(res) {
expect(res).toBe('<p>Hello, World!</p>');
expect(res).toBe('<xblock name="sayhello" props="{}">Hello</xblock>');
});
});
it('must apply block arguments correctly', function() {
it('must handle HTML children', function() {
const templateBlock = TemplateBlock.create('sayhello', function(block) {
return '<p>Hello, World!</p>';
});
// Create a fresh Nunjucks environment
const env = new nunjucks.Environment(null, { autoescape: false });
// Add template block to environement
const Ext = templateBlock.toNunjucksExt();
env.addExtension(templateBlock.getExtensionName(), new Ext());
// Render a template using the block
const src = '{% sayhello %}{% endsayhello %}';
return Promise.nfcall(env.renderString.bind(env), src)
.then(function(res) {
expect(res).toBe('<xblock name="sayhello" props="{}"><p>Hello, World!</p></xblock>');
});
});
it('must inline props without children', function() {
const templateBlock = TemplateBlock.create('sayhello', function(block) {
return {
body: '<' + block.kwargs.tag + '>Hello, ' + block.kwargs.name + '!</' + block.kwargs.tag + '>',
parse: true
message: block.kwargs.tag + ' ' + block.kwargs.name
};
});
@@ -139,17 +132,17 @@ describe('TemplateBlock', function() {
const src = '{% sayhello name="Samy", tag="p" %}{% endsayhello %}';
return Promise.nfcall(env.renderString.bind(env), src)
.then(function(res) {
expect(res).toBe('<p>Hello, Samy!</p>');
expect(res).toBe('<xblock name="sayhello" props="{&quot;message&quot;:&quot;p Samy&quot;}"></xblock>');
});
});
it('must accept an async function', function() {
const templateBlock = TemplateBlock.create('sayhello', function(block) {
return Promise()
.delay(1)
.then(function() {
return {
body: 'Hello ' + block.body,
parse: true
children: 'Hello ' + block.children
};
});
});
@@ -165,7 +158,7 @@ describe('TemplateBlock', function() {
const src = '{% sayhello %}Samy{% endsayhello %}';
return Promise.nfcall(env.renderString.bind(env), src)
.then(function(res) {
expect(res).toBe('Hello Samy');
expect(res).toBe('<xblock name="sayhello" props="{}">Hello Samy</xblock>');
});
});
@@ -177,13 +170,10 @@ describe('TemplateBlock', function() {
const nested = {};
block.blocks.forEach(function(blk) {
nested[blk.name] = blk.body.trim();
nested[blk.name] = blk.children.trim();
});
return {
body: '<p class="yoda">' + nested.end + ' ' + nested.start + '</p>',
parse: true
};
return '<p class="yoda">' + nested.end + ' ' + nested.start + '</p>';
}
});
@@ -198,7 +188,7 @@ describe('TemplateBlock', function() {
const src = '{% yoda %}{% start %}this sentence should be{% end %}inverted{% endyoda %}';
return Promise.nfcall(env.renderString.bind(env), src)
.then(function(res) {
expect(res).toBe('<p class="yoda">inverted this sentence should be</p>');
expect(res).toBe('<xblock name="yoda" props="{}"><p class="yoda">inverted this sentence should be</p></xblock>');
});
});
});
@@ -1,6 +1,6 @@
const URIIndex = require('../uriIndex');
describe.only('URIIndex', () => {
describe('URIIndex', () => {
let index;
before(() => {
@@ -40,6 +40,18 @@ describe.only('URIIndex', () => {
});
describe('.resolveToURL', () => {
it('should resolve a basic file path with directory index', () => {
expect(index.resolveToURL('README.md')).toBe('./');
});
it('should resolve a basic file path with directory index', () => {
expect(index.resolveToURL('hello/README.md')).toBe('hello/');
});
});
describe('.resolveFrom', () => {
it('should resolve correctly in same directory', () => {
+211 -207
View File
@@ -1,6 +1,6 @@
const is = require('is');
const extend = require('extend');
const Immutable = require('immutable');
const { Record, List, Map } = require('immutable');
const escape = require('escape-html');
const Promise = require('../utils/promise');
@@ -9,232 +9,236 @@ const TemplateShortcut = require('./templateShortcut');
const NODE_ENDARGS = '%%endargs%%';
const HTML_TAGNAME = 'xblock';
const TemplateBlock = Immutable.Record({
const DEFAULTS = {
// Name of block, also the start tag
name: String(),
name: String(),
// End tag, default to "end<name>"
end: String(),
end: String(),
// Function to process the block content
process: Function(),
process: Function(),
// List of String, for inner block tags
blocks: Immutable.List(),
blocks: List(),
// List of shortcuts to replace with this block
shortcuts: Immutable.Map()
}, 'TemplateBlock');
TemplateBlock.prototype.getName = function() {
return this.get('name');
shortcuts: Map()
};
TemplateBlock.prototype.getEndTag = function() {
return this.get('end') || ('end' + this.getName());
};
TemplateBlock.prototype.getProcess = function() {
return this.get('process');
};
TemplateBlock.prototype.getBlocks = function() {
return this.get('blocks');
};
/**
* Return shortcuts associated with this block or undefined
* @return {TemplateShortcut|undefined}
*/
TemplateBlock.prototype.getShortcuts = function() {
const shortcuts = this.get('shortcuts');
if (shortcuts.size === 0) {
return undefined;
class TemplateBlock extends Record(DEFAULTS) {
getName() {
return this.get('name');
}
return TemplateShortcut.createForBlock(this, shortcuts);
};
/**
* Return name for the nunjucks extension
* @return {String}
*/
TemplateBlock.prototype.getExtensionName = function() {
return 'Block' + this.getName() + 'Extension';
};
/**
* Return a nunjucks extension to represents this block
* @return {Nunjucks.Extension}
*/
TemplateBlock.prototype.toNunjucksExt = function(mainContext, blocksOutput) {
blocksOutput = blocksOutput || {};
const that = this;
const name = this.getName();
const endTag = this.getEndTag();
const blocks = this.getBlocks().toJS();
function Ext() {
this.tags = [name];
this.parse = function(parser, nodes) {
let lastBlockName = null;
let lastBlockArgs = null;
const allBlocks = blocks.concat([endTag]);
// Parse first block
const tok = parser.nextToken();
lastBlockArgs = parser.parseSignature(null, true);
parser.advanceAfterBlockEnd(tok.value);
const args = new nodes.NodeList();
const bodies = [];
const blockNamesNode = new nodes.Array(tok.lineno, tok.colno);
const blockArgCounts = new nodes.Array(tok.lineno, tok.colno);
// Parse while we found "end<block>"
do {
// Read body
const currentBody = parser.parseUntilBlocks(...allBlocks);
// Handle body with previous block name and args
blockNamesNode.addChild(new nodes.Literal(args.lineno, args.colno, lastBlockName));
blockArgCounts.addChild(new nodes.Literal(args.lineno, args.colno, lastBlockArgs.children.length));
bodies.push(currentBody);
// Append arguments of this block as arguments of the run function
lastBlockArgs.children.forEach(function(child) {
args.addChild(child);
});
// Read new block
lastBlockName = parser.nextToken().value;
// Parse signature and move to the end of the block
if (lastBlockName != endTag) {
lastBlockArgs = parser.parseSignature(null, true);
}
parser.advanceAfterBlockEnd(lastBlockName);
} while (lastBlockName != endTag);
args.addChild(blockNamesNode);
args.addChild(blockArgCounts);
args.addChild(new nodes.Literal(args.lineno, args.colno, NODE_ENDARGS));
return new nodes.CallExtensionAsync(this, 'run', args, bodies);
};
this.run = function(context, ...fnArgs) {
let args;
const blocks = [];
let bodies = [];
// Extract callback
const callback = fnArgs.pop();
// Detect end of arguments
const endArgIndex = fnArgs.indexOf(NODE_ENDARGS);
// Extract arguments and bodies
args = fnArgs.slice(0, endArgIndex);
bodies = fnArgs.slice(endArgIndex + 1);
// Extract block counts
const blockArgCounts = args.pop();
const blockNames = args.pop();
// Recreate list of blocks
blockNames.forEach((blkName, i) => {
const countArgs = blockArgCounts[i];
const blockBody = bodies.shift();
const blockArgs = countArgs > 0 ? args.slice(0, countArgs) : [];
args = args.slice(countArgs);
const blockKwargs = extractKwargs(blockArgs);
blocks.push({
name: blkName,
children: blockBody(),
args: blockArgs,
kwargs: blockKwargs
});
});
const mainBlock = blocks.shift();
mainBlock.blocks = blocks;
Promise()
.then(function() {
const ctx = extend({
ctx: context
}, mainContext || {});
return that.applyBlock(mainBlock, ctx);
})
.then(function(props) {
return that.blockResultToHtml(props);
})
.nodeify(callback);
};
getEndTag() {
return this.get('end') || ('end' + this.getName());
}
return Ext;
};
getProcess() {
return this.get('process');
}
/**
* Apply a block to a content.
*
* @param {Object} inner
* @param {Object} context
* @return {Promise<Props>|Props}
*/
TemplateBlock.prototype.applyBlock = function(inner, context) {
const processFn = this.getProcess();
getBlocks() {
return this.get('blocks');
}
inner = inner || {};
inner.args = inner.args || [];
inner.kwargs = inner.kwargs || {};
inner.blocks = inner.blocks || [];
return processFn.call(context, inner);
};
/**
* Return shortcuts associated with this block or undefined
* @return {TemplateShortcut|undefined}
*/
getShortcuts() {
const shortcuts = this.get('shortcuts');
if (shortcuts.size === 0) {
return undefined;
}
/**
* Convert a block props to HTML. This HTML is then being
* parsed by gitbook-core during rendering, and binded to the right react components.
*
* @param {Object} props
* @return {String}
*/
TemplateBlock.prototype.blockResultToHtml = function(props) {
const { children, ...innerProps } = props;
const payload = escape(JSON.stringify(innerProps));
return TemplateShortcut.createForBlock(this, shortcuts);
}
return (
`<${HTML_TAGNAME} name="${this.name}" props="${payload}">${children}</${HTML_TAGNAME}>`
);
};
/**
* Return name for the nunjucks extension
* @return {String}
*/
getExtensionName() {
return 'Block' + this.getName() + 'Extension';
}
/**
* Create a template block from a function or an object
* @param {String} blockName
* @param {Object} block
* @return {TemplateBlock}
*/
TemplateBlock.create = function(blockName, block) {
if (is.fn(block)) {
block = new Immutable.Map({
process: block
/**
* Return a nunjucks extension to represents this block
* @return {Nunjucks.Extension}
*/
toNunjucksExt(mainContext = {}) {
const that = this;
const name = this.getName();
const endTag = this.getEndTag();
const blocks = this.getBlocks().toJS();
function Ext() {
this.tags = [name];
this.parse = (parser, nodes) => {
let lastBlockName = null;
let lastBlockArgs = null;
const allBlocks = blocks.concat([endTag]);
// Parse first block
const tok = parser.nextToken();
lastBlockArgs = parser.parseSignature(null, true);
parser.advanceAfterBlockEnd(tok.value);
const args = new nodes.NodeList();
const bodies = [];
const blockNamesNode = new nodes.Array(tok.lineno, tok.colno);
const blockArgCounts = new nodes.Array(tok.lineno, tok.colno);
// Parse while we found "end<block>"
do {
// Read body
const currentBody = parser.parseUntilBlocks(...allBlocks);
// Handle body with previous block name and args
blockNamesNode.addChild(new nodes.Literal(args.lineno, args.colno, lastBlockName));
blockArgCounts.addChild(new nodes.Literal(args.lineno, args.colno, lastBlockArgs.children.length));
bodies.push(currentBody);
// Append arguments of this block as arguments of the run function
lastBlockArgs.children.forEach(function(child) {
args.addChild(child);
});
// Read new block
lastBlockName = parser.nextToken().value;
// Parse signature and move to the end of the block
if (lastBlockName != endTag) {
lastBlockArgs = parser.parseSignature(null, true);
}
parser.advanceAfterBlockEnd(lastBlockName);
} while (lastBlockName != endTag);
args.addChild(blockNamesNode);
args.addChild(blockArgCounts);
args.addChild(new nodes.Literal(args.lineno, args.colno, NODE_ENDARGS));
return new nodes.CallExtensionAsync(this, 'run', args, bodies);
};
this.run = (context, ...fnArgs) => {
let args;
const blocks = [];
let bodies = [];
// Extract callback
const callback = fnArgs.pop();
// Detect end of arguments
const endArgIndex = fnArgs.indexOf(NODE_ENDARGS);
// Extract arguments and bodies
args = fnArgs.slice(0, endArgIndex);
bodies = fnArgs.slice(endArgIndex + 1);
// Extract block counts
const blockArgCounts = args.pop();
const blockNames = args.pop();
// Recreate list of blocks
blockNames.forEach((blkName, i) => {
const countArgs = blockArgCounts[i];
const blockBody = bodies.shift();
const blockArgs = countArgs > 0 ? args.slice(0, countArgs) : [];
args = args.slice(countArgs);
const blockKwargs = extractKwargs(blockArgs);
blocks.push({
name: blkName,
children: blockBody(),
args: blockArgs,
kwargs: blockKwargs
});
});
const mainBlock = blocks.shift();
mainBlock.blocks = blocks;
Promise()
.then(function() {
const ctx = extend({
ctx: context
}, mainContext);
return that.toProps(mainBlock, ctx);
})
.then(function(props) {
return that.toHTML(props);
})
.nodeify(callback);
};
}
return Ext;
}
/**
* Apply a block an return the props
*
* @param {Object} inner
* @param {Object} context
* @return {Promise<Props>}
*/
toProps(inner, context) {
const processFn = this.getProcess();
inner = inner || {};
inner.args = inner.args || [];
inner.kwargs = inner.kwargs || {};
inner.blocks = inner.blocks || [];
return Promise()
.then(() => processFn.call(context, inner))
.then(props => {
if (is.string(props)) {
return { children: props };
}
return props;
});
}
block = new TemplateBlock(block);
block = block.set('name', blockName);
return block;
};
/**
* Convert a block props to HTML. This HTML is then being
* parsed by gitbook-core during rendering, and binded to the right react components.
*
* @param {Object} props
* @return {String}
*/
toHTML(props) {
const { children, ...innerProps } = props;
const payload = escape(JSON.stringify(innerProps));
return (
`<${HTML_TAGNAME} name="${this.name}" props="${payload}">${children || ''}</${HTML_TAGNAME}>`
);
}
/**
* Create a template block from a function or an object
* @param {String} blockName
* @param {Object} block
* @return {TemplateBlock}
*/
static create(blockName, block) {
if (is.fn(block)) {
block = new Map({
process: block
});
}
block = new TemplateBlock(block);
block = block.set('name', blockName);
return block;
}
}
/**
* Extract kwargs from an arguments array
+102 -108
View File
@@ -1,139 +1,133 @@
const nunjucks = require('nunjucks');
const Immutable = require('immutable');
const TemplateEngine = Immutable.Record({
// Map of {TemplateBlock}
blocks: Immutable.Map(),
const { Record, Map, List } = require('immutable');
const DEFAULTS = {
// List of {TemplateBlock}
blocks: List(),
// Map of Extension
extensions: Immutable.Map(),
extensions: Map(),
// Map of filters: {String} name -> {Function} fn
filters: Immutable.Map(),
filters: Map(),
// Map of globals: {String} name -> {Mixed}
globals: Immutable.Map(),
globals: Map(),
// Context for filters / blocks
context: Object(),
// Nunjucks loader
loader: nunjucks.FileSystemLoader('views')
}, 'TemplateEngine');
TemplateEngine.prototype.getBlocks = function() {
return this.get('blocks');
};
TemplateEngine.prototype.getGlobals = function() {
return this.get('globals');
};
class TemplateEngine extends Record(DEFAULTS) {
getBlocks() {
return this.get('blocks');
}
TemplateEngine.prototype.getFilters = function() {
return this.get('filters');
};
getGlobals() {
return this.get('globals');
}
TemplateEngine.prototype.getShortcuts = function() {
return this.get('shortcuts');
};
getFilters() {
return this.get('filters');
}
TemplateEngine.prototype.getLoader = function() {
return this.get('loader');
};
getShortcuts() {
return this.get('shortcuts');
}
TemplateEngine.prototype.getContext = function() {
return this.get('context');
};
getLoader() {
return this.get('loader');
}
TemplateEngine.prototype.getExtensions = function() {
return this.get('extensions');
};
getContext() {
return this.get('context');
}
/**
Return a block by its name (or undefined)
getExtensions() {
return this.get('extensions');
}
@param {String} name
@return {TemplateBlock}
*/
TemplateEngine.prototype.getBlock = function(name) {
const blocks = this.getBlocks();
return blocks.find(function(block) {
return block.getName() === name;
});
};
/**
* Return a block by its name (or undefined).
* @param {String} name
* @return {TemplateBlock} block?
*/
getBlock(name) {
const blocks = this.getBlocks();
return blocks.find(function(block) {
return block.getName() === name;
});
}
/**
Return a nunjucks environment from this configuration
/**
* Return a nunjucks environment from this configuration
* @return {Nunjucks.Environment} env
*/
toNunjucks() {
const loader = this.getLoader();
const blocks = this.getBlocks();
const filters = this.getFilters();
const globals = this.getGlobals();
const extensions = this.getExtensions();
const context = this.getContext();
@return {Nunjucks.Environment}
*/
TemplateEngine.prototype.toNunjucks = function(blocksOutput) {
const loader = this.getLoader();
const blocks = this.getBlocks();
const filters = this.getFilters();
const globals = this.getGlobals();
const extensions = this.getExtensions();
const context = this.getContext();
const env = new nunjucks.Environment(
loader,
{
// Escaping is done after by the asciidoc/markdown parser
autoescape: false,
const env = new nunjucks.Environment(
loader,
{
// Escaping is done after by the asciidoc/markdown parser
autoescape: false,
// Syntax
tags: {
blockStart: '{%',
blockEnd: '%}',
variableStart: '{{',
variableEnd: '}}',
commentStart: '{###',
commentEnd: '###}'
// Syntax
tags: {
blockStart: '{%',
blockEnd: '%}',
variableStart: '{{',
variableEnd: '}}',
commentStart: '{###',
commentEnd: '###}'
}
}
}
);
);
// Add filters
filters.forEach(function(filterFn, filterName) {
env.addFilter(filterName, filterFn.bind(context));
});
// Add filters
filters.forEach(function(filterFn, filterName) {
env.addFilter(filterName, filterFn.bind(context));
});
// Add blocks
blocks.forEach(function(block) {
const extName = block.getExtensionName();
const Ext = block.toNunjucksExt(context, blocksOutput);
// Add blocks
blocks.forEach(function(block) {
const extName = block.getExtensionName();
const Ext = block.toNunjucksExt(context);
env.addExtension(extName, new Ext());
});
env.addExtension(extName, new Ext());
});
// Add globals
globals.forEach(function(globalValue, globalName) {
env.addGlobal(globalName, globalValue);
});
// Add globals
globals.forEach(function(globalValue, globalName) {
env.addGlobal(globalName, globalValue);
});
// Add other extensions
extensions.forEach(function(ext, extName) {
env.addExtension(extName, ext);
});
// Add other extensions
extensions.forEach(function(ext, extName) {
env.addExtension(extName, ext);
});
return env;
};
return env;
}
/**
Create a template engine
@param {Object} def
@return {TemplateEngine}
*/
TemplateEngine.create = function(def) {
return new TemplateEngine({
blocks: Immutable.List(def.blocks || []),
extensions: Immutable.Map(def.extensions || {}),
filters: Immutable.Map(def.filters || {}),
globals: Immutable.Map(def.globals || {}),
context: def.context,
loader: def.loader
});
};
/**
* Create a template engine.
* @param {Object} def
* @return {TemplateEngine} engine
*/
static create(def) {
return new TemplateEngine({
blocks: List(def.blocks || []),
extensions: Map(def.extensions || {}),
filters: Map(def.filters || {}),
globals: Map(def.globals || {}),
context: def.context,
loader: def.loader
});
}
}
module.exports = TemplateEngine;
@@ -3,7 +3,7 @@ const { OrderedMap } = require('immutable');
const parseURIIndexFromPages = require('../parseURIIndexFromPages');
const Page = require('../../models/page');
describe.only('parseURIIndexFromPages', () => {
describe('parseURIIndexFromPages', () => {
it('should map file to html', () => {
const pages = OrderedMap({
@@ -14,24 +14,13 @@ describe.only('parseURIIndexFromPages', () => {
expect(urls.resolve('page.md')).toBe('page.html');
});
it('should map README to index.html (directoryIndex: false)', () => {
const pages = OrderedMap({
'hello/README.md': new Page()
});
const urls = parseURIIndexFromPages(pages, {
directoryIndex: false
});
expect(urls.resolve('hello/README.md')).toBe('hello/index.html');
});
it('should map README to folder', () => {
const pages = OrderedMap({
'hello/README.md': new Page()
});
const urls = parseURIIndexFromPages(pages);
expect(urls.resolve('hello/README.md')).toBe('hello/');
expect(urls.resolveToURL('hello/README.md')).toBe('hello/');
});
});
@@ -4,30 +4,34 @@ const TemplateEngine = require('../../models/templateEngine');
const renderTemplate = require('../render');
const ConrefsLoader = require('../conrefsLoader');
describe('ConrefsLoader', function() {
describe('ConrefsLoader', () => {
const dirName = __dirname + '/';
const fileName = path.join(dirName, 'test.md');
describe('Git', function() {
const engine = TemplateEngine({
loader: new ConrefsLoader(dirName)
describe('Git', () => {
let engine;
before(() => {
engine = new TemplateEngine({
loader: new ConrefsLoader(dirName)
});
});
it('should include content from git', function() {
it('should include content from git', () => {
return renderTemplate(engine, fileName, '{% include "git+https://gist.github.com/69ea4542e4c8967d2fa7.git/test.md" %}')
.then(function(out) {
expect(out.getContent()).toBe('Hello from git');
});
});
it('should handle deep inclusion (1)', function() {
it('should handle deep inclusion (1)', () => {
return renderTemplate(engine, fileName, '{% include "git+https://gist.github.com/69ea4542e4c8967d2fa7.git/test2.md" %}')
.then(function(out) {
expect(out.getContent()).toBe('First Hello. Hello from git');
});
});
it('should handle deep inclusion (2)', function() {
it('should handle deep inclusion (2)', () => {
return renderTemplate(engine, fileName, '{% include "git+https://gist.github.com/69ea4542e4c8967d2fa7.git/test3.md" %}')
.then(function(out) {
expect(out.getContent()).toBe('First Hello. Hello from git');
@@ -35,20 +39,24 @@ describe('ConrefsLoader', function() {
});
});
describe('Local', function() {
const engine = TemplateEngine({
loader: new ConrefsLoader(dirName)
describe('Local', () => {
let engine;
before(() => {
engine = new TemplateEngine({
loader: new ConrefsLoader(dirName)
});
});
describe('Relative', function() {
it('should resolve basic relative filepath', function() {
describe('Relative', () => {
it('should resolve basic relative filepath', () => {
return renderTemplate(engine, fileName, '{% include "include.md" %}')
.then(function(out) {
expect(out.getContent()).toBe('Hello World');
});
});
it('should resolve basic parent filepath', function() {
it('should resolve basic parent filepath', () => {
return renderTemplate(engine, path.join(dirName, 'hello/test.md'), '{% include "../include.md" %}')
.then(function(out) {
expect(out.getContent()).toBe('Hello World');
@@ -57,23 +65,24 @@ describe('ConrefsLoader', function() {
});
describe('Absolute', function() {
it('should resolve absolute filepath', function() {
it('should resolve absolute filepath', () => {
return renderTemplate(engine, fileName, '{% include "/include.md" %}')
.then(function(out) {
expect(out.getContent()).toBe('Hello World');
});
});
it('should resolve absolute filepath when in a directory', function() {
it('should resolve absolute filepath when in a directory', () => {
return renderTemplate(engine, path.join(dirName, 'hello/test.md'), '{% include "/include.md" %}')
.then(function(out) {
expect(out.getContent()).toBe('Hello World');
});
});
});
});
describe('transform', function() {
describe('transform', () => {
function transform(filePath, source) {
expect(filePath).toBeA('string');
expect(source).toBeA('string');
@@ -83,11 +92,16 @@ describe('ConrefsLoader', function() {
return 'test-' + source + '-endtest';
}
const engine = TemplateEngine({
loader: new ConrefsLoader(dirName, transform)
let engine;
before(() => {
engine = new TemplateEngine({
loader: new ConrefsLoader(dirName, transform)
});
});
it('should transform included content', function() {
it('should transform included content', () => {
return renderTemplate(engine, fileName, '{% include "include.md" %}')
.then(function(out) {
expect(out.getContent()).toBe('test-Hello World-endtest');
@@ -95,4 +109,3 @@ describe('ConrefsLoader', function() {
});
});
});