test(themes): add integration tests using a mock file system

This replaces the basic unit tests that used private methods
and didn’t have a very clear intent
pull/108/head
Romain 6 years ago
parent deee049650
commit bd86ab6535

@ -40,14 +40,12 @@ class Theme {
// return a function that renders the given album HTML page
// this is used so that all pages can be created in parallel
render (album, data) {
render (album, data, next) {
const fullPath = path.join(this.dest, album.path)
return (next) => {
debug(`Theme rendering ${album.path}`)
const contents = this.template(Object.assign({album: album}, data))
fs.mkdirpSync(path.dirname(fullPath))
fs.writeFile(fullPath, contents, next)
}
debug(`Theme rendering ${album.path}`)
const contents = this.template(Object.assign({album: album}, data))
fs.mkdirpSync(path.dirname(fullPath))
fs.writeFile(fullPath, contents, next)
}
// ------------------------
@ -106,6 +104,8 @@ class Theme {
customStylesInclude () {
const customPath = this.opts.customStylesPath
if (customPath) {
// see http://lesscss.org/features/#import-atrules-feature
// we use (inline) to avoid processing raw CSS files
const includeType = path.extname(customPath) === '.css' ? '(inline) ' : ''
return `\n@import ${includeType}'${customPath}';`
}

@ -44,11 +44,13 @@ function galleryModel (rootAlbum, opts) {
}
function createRenderingTasks (theme, album, gallery, breadcrumbs) {
// render this album
const thisAlbumTask = theme.render(album, {
gallery: gallery,
breadcrumbs: breadcrumbs
})
// a function to render this album
const thisAlbumTask = next => {
theme.render(album, {
gallery: gallery,
breadcrumbs: breadcrumbs
}, next)
}
const tasks = [thisAlbumTask]
// and all nested albums
album.albums.forEach(function (nested) {

@ -1,32 +1,96 @@
const fs = require('fs')
const should = require('should/as-function')
const Theme = require('../../src/website/theme')
describe('Theme', () => {
it('supports not having custom styles', () => {
const theme = new Theme('./mytheme', './dest', {
customStylesPath: null
// we require "mock-fs" inside the tests, otherwise it also affects other tests
var mock = null
before(() => {
mock = require('mock-fs')
})
afterEach(() => {
mock.restore()
})
it('renders the main HTML file', testEnd => {
mock({
'dest': mock.directory(),
'theme/theme.less': '',
'theme/album.hbs': 'Welcome to {{album.title}}'
})
const album = { path: 'albums/holidays.html', title: 'my album' }
const theme = new Theme('theme', 'dest', {})
renderTheme(theme, album, () => {
const html = fs.readFileSync('dest/albums/holidays.html', 'utf-8')
should(html).equal('Welcome to my album')
testEnd()
})
const include = theme.customStylesInclude()
should(include).eql('')
})
it('adds an inline @import for CSS files', () => {
// to ensure we support any type of CSS
// since not all CSS is valid LESS
const theme = new Theme('./mytheme', './dest', {
customStylesPath: 'path/to/style.css'
it('renders the main CSS file', testEnd => {
mock({
'dest': mock.directory(),
'theme/theme.less': '@color: #abc; body { color: @color; }',
'theme/album.hbs': ''
})
const album = { path: 'index.html' }
const theme = new Theme('theme', 'dest', {})
renderTheme(theme, album, () => {
const css = fs.readFileSync('dest/public/theme.css', 'utf-8')
should(css).equal('body {\n color: #abc;\n}\n')
testEnd()
})
const include = theme.customStylesInclude()
should(include).eql("\n@import (inline) 'path/to/style.css';")
})
it('adds a standard @import for LESS files', () => {
// to ensure the LESS file is processed normally
// including overriding any variables
const theme = new Theme('./mytheme', './dest', {
customStylesPath: 'path/to/style.less'
it('can include an extra CSS files (unprocessed)', testEnd => {
mock({
'dest': mock.directory(),
'theme/theme.less': 'body { color: red; }',
'theme/other.css': 'h1 { color: blue; }',
'theme/album.hbs': ''
})
const album = { path: 'index.html' }
const theme = new Theme('theme', 'dest', {
customStylesPath: 'other.css'
})
renderTheme(theme, album, () => {
// Note the CSS file was not re-indented
// It's important it's not processed since not all CSS is valid LESS
const css = fs.readFileSync('dest/public/theme.css', 'utf-8')
should(css).equal('body {\n color: red;\n}\nh1 { color: blue; }\n')
testEnd()
})
})
it('can include an extra LESS file', testEnd => {
mock({
'dest': mock.directory(),
'theme/theme.less': 'body { color: red; }',
'theme/other.less': 'h1 { color: blue; }',
'theme/album.hbs': ''
})
const album = { path: 'index.html' }
const theme = new Theme('theme', 'dest', {
customStylesPath: 'other.less'
})
renderTheme(theme, album, () => {
const css = fs.readFileSync('dest/public/theme.css', 'utf-8')
should(css).equal('body {\n color: red;\n}\nh1 {\n color: blue;\n}\n')
testEnd()
})
const include = theme.customStylesInclude()
should(include).eql("\n@import 'path/to/style.less';")
})
})
process.on('unhandledRejection', err => console.log('err', err))
function renderTheme (theme, album, next) {
theme.validateStructure()
theme.prepare(err => {
should(err).be.null()
theme.render(album, {}, err => {
should(err).be.null()
next()
})
})
}

Loading…
Cancel
Save