chore: upgrade to latest version of StandardJS

pull/334/head
Romain 1 year ago
parent 0ebf105396
commit 8cb7a3596b

@ -26,7 +26,7 @@ if (firstRun) {
// Basic usage report (anonymous statistics)
const analytics = new Analytics({
enabled: opts['usageStats']
enabled: opts.usageStats
})
analytics.start()

5679
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -75,24 +75,19 @@
"require-lint": "^2.0.3",
"should": "^13.2.3",
"sinon": "^15.0.2",
"standard": "^12.0.1",
"standard": "^17.0.0",
"stream-mock": "^2.0.5",
"tmp": "^0.2.1",
"yaml": "^2.2.1"
},
"standard": {
"env": [
"mocha"
],
"ignore": [
"themes/**/public"
],
"globals": [
"after",
"afterEach",
"before",
"beforeEach",
"describe",
"xdescribe",
"it",
"xit",
"itLinux",
"itWindows"
]

@ -1,3 +1,4 @@
/* eslint-disable quote-props */
const messages = require('./messages')
const path = require('path')
const yargs = require('yargs')
@ -506,7 +507,7 @@ exports.get = (args) => {
}
function replaceInArray (list, match, replacement) {
for (var i = 0; i < list.length; ++i) {
for (let i = 0; i < list.length; ++i) {
if (list[i] === match) {
list[i] = replacement
}
@ -523,3 +524,4 @@ function changeExtension (file, ext) {
const filename = path.basename(file, originalExt)
return path.join(path.dirname(file), filename + ext)
}
/* eslint-enable quote-props */

@ -28,10 +28,10 @@ exports.parse = (rootFolder, filePaths) => {
// create a new <exiftool> child process
const child = childProcess.spawn('exiftool', args, {
cwd: rootFolder,
stdio: [ 'pipe', 'pipe', 'pipe' ]
stdio: ['pipe', 'pipe', 'pipe']
})
child.on('error', (err) => {
error(`Error: please verify that <exiftool> is installed on your system`)
error('Error: please verify that <exiftool> is installed on your system')
error(err.toString())
})
child.on('close', (code, signal) => {

@ -1,3 +1,4 @@
/* eslint-disable no-prototype-builtins */
const _ = require('lodash')
/*
@ -31,3 +32,4 @@ exports.calculate = (databaseMap, diskMap) => {
})
return delta
}
/* eslint-enable no-prototype-builtins */

@ -34,13 +34,13 @@ class Index {
// create hashmap of all files in the database
const databaseMap = {}
for (var row of selectStatement.iterate()) {
for (const row of selectStatement.iterate()) {
databaseMap[row.path] = row.timestamp
}
function finished () {
// emit every file in the index
for (var row of selectMetadata.iterate()) {
for (const row of selectMetadata.iterate()) {
emitter.emit('file', {
path: row.path,
timestamp: new Date(row.timestamp),
@ -72,7 +72,7 @@ class Index {
})
// check if any files need parsing
var processed = 0
let processed = 0
const toProcess = _.union(deltaFiles.added, deltaFiles.modified)
if (toProcess.length === 0) {
return finished()
@ -85,7 +85,7 @@ class Index {
const timestamp = moment(entry.File.FileModifyDate, EXIF_DATE_FORMAT).valueOf()
insertStatement.run(entry.SourceFile, timestamp, JSON.stringify(entry))
++processed
emitter.emit('progress', { path: entry.SourceFile, processed: processed, total: toProcess.length })
emitter.emit('progress', { path: entry.SourceFile, processed, total: toProcess.length })
}).on('end', finished)
})

@ -58,7 +58,7 @@ exports.build = function (opts, done) {
})
}
], {
renderer: renderer,
renderer,
dateFormat: false
})

@ -14,6 +14,7 @@ class AlbumMapper {
const defaulted = (patterns && patterns.length > 0) ? patterns : ['%path']
this.patterns = defaulted.map(p => load(p, opts))
}
getAlbums (file) {
return _.flatMap(this.patterns, pattern => pattern(file))
}

@ -29,7 +29,7 @@ exports.create = (pattern, opts) => {
function mapperFunction (pattern, cache, opts) {
if (opts === undefined) { opts = {} }
return file => {
var album = pattern
let album = pattern
// replace known tokens
if (cache.usesTokens) {
album = album.replace(TOKEN_REGEX, token => replaceToken(file, token))

@ -14,7 +14,7 @@ exports.createAlbums = function (collection, mapper, opts, picasaReader) {
function group (collection, mapper, opts, picasaReader) {
// this hashtable will contain all albums, with the full path as key
// e.g. groups['holidays/tokyo']
var groups = {
const groups = {
// the home album is indexed as '.'
// the value of '.' is local to this function, and doesn't appear anywhere else
'.': new Album(opts.homeAlbumName)
@ -38,7 +38,7 @@ function group (collection, mapper, opts, picasaReader) {
}
function createAlbumHierarchy (allGroupNames, segment, opts, picasaReader) {
if (!allGroupNames.hasOwnProperty(segment)) {
if (!allGroupNames.hasOwnProperty(segment)) { // eslint-disable-line
// create parent albums first
const parent = path.dirname(segment)
if (parent !== '.') {

@ -13,11 +13,13 @@ class Picasa {
// memory cache of all Picasa files read so far
this.folders = {}
}
album (dir) {
const entry = this.folderMetadata(dir)
// album metadata is stored in a section called [Picasa]
return entry.Picasa || null
}
file (filepath) {
const dir = path.dirname(filepath)
const entry = this.folderMetadata(dir)
@ -26,6 +28,7 @@ class Picasa {
const fileParts = filename.split('.')
return getIniValue(entry, fileParts)
}
folderMetadata (dirname) {
// try reading from cache first
if (this.folders[dirname]) {

@ -11,21 +11,21 @@ const path = require('path')
const slugify = require('slugify')
const url = require('./url')
var index = 0
let index = 0
// number of images to show in the album preview grid
const PREVIEW_COUNT = 10
const SLUGIFY_OPTIONS = { replacement: '-', remove: /[*+~.()'"!:@]/g }
const SORT_ALBUMS_BY = {
'title': function (album) { return album.title },
title: function (album) { return album.title },
'start-date': function (album) { return album.stats.fromDate },
'end-date': function (album) { return album.stats.toDate }
}
const SORT_MEDIA_BY = {
'filename': function (file) { return file.filename },
'date': function (file) { return file.meta.date }
filename: function (file) { return file.filename },
date: function (file) { return file.meta.date }
}
const PREVIEW_MISSING = {
@ -50,7 +50,7 @@ function Album (opts) {
Album.prototype.finalize = function (options, parent) {
options = options || {}
var albumsOutputFolder = options.albumsOutputFolder || '.'
const albumsOutputFolder = options.albumsOutputFolder || '.'
// calculate final file paths and URLs
if (parent == null) {
this.path = options.index || 'index.html'
@ -69,7 +69,7 @@ Album.prototype.finalize = function (options, parent) {
this.zip = this.path.replace(/\.[^\\/.]+$/, '.zip')
}
// then finalize all nested albums (which uses the parent basename)
for (var i = 0; i < this.albums.length; ++i) {
for (let i = 0; i < this.albums.length; ++i) {
this.albums[i].finalize(options, this)
}
// perform stats & other calculations
@ -83,15 +83,15 @@ Album.prototype.finalize = function (options, parent) {
Album.prototype.calculateStats = function () {
// nested albums
var nestedPhotos = _.map(this.albums, 'stats.photos')
var nestedVideos = _.map(this.albums, 'stats.videos')
var nestedFromDates = _.map(this.albums, 'stats.fromDate')
var nestedToDates = _.map(this.albums, 'stats.toDate')
const nestedPhotos = _.map(this.albums, 'stats.photos')
const nestedVideos = _.map(this.albums, 'stats.videos')
const nestedFromDates = _.map(this.albums, 'stats.fromDate')
const nestedToDates = _.map(this.albums, 'stats.toDate')
// current level
var currentPhotos = _.filter(this.files, { type: 'image' }).length
var currentVideos = _.filter(this.files, { type: 'video' }).length
var currentFromDate = _.map(this.files, 'meta.date')
var currentToDate = _.map(this.files, 'meta.date')
const currentPhotos = _.filter(this.files, { type: 'image' }).length
const currentVideos = _.filter(this.files, { type: 'video' }).length
const currentFromDate = _.map(this.files, 'meta.date')
const currentToDate = _.map(this.files, 'meta.date')
// aggregate all stats
this.stats = {
albums: this.albums.length,
@ -104,7 +104,7 @@ Album.prototype.calculateStats = function () {
}
Album.prototype.calculateSummary = function () {
var items = [
const items = [
itemCount(this.stats.albums, 'album'),
itemCount(this.stats.photos, 'photo'),
itemCount(this.stats.videos, 'video')
@ -123,7 +123,7 @@ Album.prototype.sort = function (options) {
Album.prototype.pickPreviews = function (options) {
// consider nested albums if there aren't enough photos
var potential = this.files
let potential = this.files
if (potential.length < PREVIEW_COUNT) {
const nested = _.flatMap(this.albums, 'previews').filter(file => file !== PREVIEW_MISSING)
potential = potential.concat(nested)
@ -146,15 +146,15 @@ Album.prototype.pickPreviews = function (options) {
}
// and fill any gap with a placeholder
var missing = PREVIEW_COUNT - this.previews.length
for (var i = 0; i < missing; ++i) {
const missing = PREVIEW_COUNT - this.previews.length
for (let i = 0; i < missing; ++i) {
this.previews.push(PREVIEW_MISSING)
}
}
function itemCount (count, type) {
if (count === 0) return ''
var plural = (count > 1) ? 's' : ''
const plural = (count > 1) ? 's' : ''
return '' + count + ' ' + type + plural
}

@ -14,7 +14,7 @@ const url = require('./url')
const MIME_REGEX = /([^/]+)\/(.*)/
const EXIF_DATE_FORMAT = 'YYYY:MM:DD HH:mm:ssZ'
var index = 0
let index = 0
class File {
constructor (dbEntry, meta, opts) {

@ -103,18 +103,18 @@ function people (exif) {
}
function video (exif) {
return MIME_VIDEO_REGEX.test(exif.File['MIMEType'])
return MIME_VIDEO_REGEX.test(exif.File.MIMEType)
}
function animated (exif) {
if (exif.File['MIMEType'] !== 'image/gif') return false
if (exif.File.MIMEType !== 'image/gif') return false
if (exif.GIF && exif.GIF.FrameCount > 0) return true
return false
}
function rating (exif) {
if (!exif.XMP) return 0
return exif.XMP['Rating'] || 0
return exif.XMP.Rating || 0
}
function favourite (picasa) {

@ -49,6 +49,6 @@ function relationship (filepath, rel, opts) {
}
return {
path: fn(filepath, rel, opts),
rel: rel
rel
}
}

@ -9,25 +9,26 @@ exports.createMap = function (opts) {
quality: opts.photoQuality,
args: opts.gmArgs
}
const watermark = (!opts.watermark) ? null : {
const watermarkDefault = {
file: opts.watermark,
position: opts.watermarkPosition
}
const watermark = (!opts.watermark) ? null : watermarkDefault
const seek = opts.videoStills === 'middle' ? -1 : opts.videoStillsSeek
const thumbnail = Object.assign({}, defaultOptions, {
height: thumbSize,
width: thumbSize,
seek: seek
seek
})
const small = Object.assign({}, defaultOptions, {
height: smallSize,
seek: seek
seek
})
const large = Object.assign({}, defaultOptions, {
height: largeSize,
watermark: watermark,
watermark,
animated: true,
seek: seek
seek
})
const videoOpts = {
format: opts.videoFormat,

@ -42,10 +42,10 @@ function createZip (targetZipPath, currentFolder, filesToInclude, done) {
trace(`Calling: zip ${args.join(' ')}`)
const child = childProcess.spawn('zip', args, {
cwd: currentFolder,
stdio: [ 'ignore', 'ignore', 'ignore' ]
stdio: ['ignore', 'ignore', 'ignore']
})
child.on('error', (err) => {
error(`Error: please verify that <zip> is installed on your system`)
error('Error: please verify that <zip> is installed on your system')
error(err.toString())
})
child.on('close', (code, signal) => {

@ -11,7 +11,7 @@ exports.run = function (fileCollection, outputRoot) {
const requiredFiles = []
fileCollection.forEach(f => {
Object.keys(f.output).forEach(out => {
var dest = path.join(outputRoot, f.output[out].path)
const dest = path.join(outputRoot, f.output[out].path)
requiredFiles.push(dest)
})
})

@ -27,7 +27,7 @@ exports.run = function (opts, callback) {
})
// after a file is indexed
var lastPercent = -1
let lastPercent = -1
emitter.on('progress', stats => {
const percent = Math.floor(stats.processed * 100 / stats.total)
if (percent > lastPercent) {

@ -43,12 +43,12 @@ exports.create = function (files, opts, problems) {
sourceFiles.add(f.path)
tasks[dest] = {
file: f,
dest: dest,
dest,
rel: f.output[out].rel,
action: (done) => {
fs.mkdirsSync(path.dirname(dest))
debug(`${f.output[out].rel} from ${src} to ${dest}`)
return action({ src: src, dest: dest }, err => {
return action({ src, dest }, err => {
if (err) {
error(`Error processing ${f.path} -> ${f.output[out].path}\n${err}`)
problems.addFile(f.path)
@ -75,7 +75,7 @@ function listrTaskFromJob (job, outputRoot) {
title: relative,
task: (ctx, task) => {
return new Promise((resolve, reject) => {
var progressEmitter = job.action(err => {
const progressEmitter = job.action(err => {
err ? reject(err) : resolve()
})
// render progress percentage for videos

@ -16,8 +16,8 @@ function createPages (baseModel, album, pageSize, breadcrumbs) {
const pagination = createPagination(slicedAlbums, index)
const model = Object.assign({}, baseModel, {
path: pagination[index].path,
breadcrumbs: breadcrumbs,
album: album,
breadcrumbs,
album,
pagination: (pageSize ? pagination : [])
})
return model

@ -7,11 +7,11 @@
{{/slice}}
*/
module.exports = (context, block) => {
var ret = ''
var count = parseInt(block.hash.count)
let ret = ''
let count = parseInt(block.hash.count)
if (isNaN(count)) count = 1
var i = 0
var j = (count < context.length) ? count : context.length
let i = 0
const j = (count < context.length) ? count : context.length
for (i, j; i < j; i++) {
ret += block.fn(context[i])
}

@ -6,11 +6,11 @@
{{/times}}
*/
module.exports = function (n, block) {
var accum = ''
let accum = ''
const data = require('handlebars').createFrame({})
for (var i = 0; i < n; ++i) {
for (let i = 0; i < n; ++i) {
data.index = i
accum += block.fn(this, { data: data })
accum += block.fn(this, { data })
}
return accum
}

@ -40,7 +40,7 @@ class Theme {
const pkg = JSON.parse(contents)
return pkg.thumbsup || {}
} catch (ex) {
debug(`Theme does not have a package.json, using default options`)
debug('Theme does not have a package.json, using default options')
return {}
}
}
@ -142,7 +142,7 @@ class Theme {
}
function compileTemplate (hbsFile) {
var src = fs.readFileSync(hbsFile)
const src = fs.readFileSync(hbsFile)
return handlebars.compile(src.toString())
}

@ -4,12 +4,12 @@ const should = require('should/as-function')
describe('Index: delta', () => {
it('no changes', () => {
const database = {
'IMG_0001': 1410000000000,
'IMG_0002': 1420000000000
IMG_0001: 1410000000000,
IMG_0002: 1420000000000
}
const disk = {
'IMG_0001': 1410000000000,
'IMG_0002': 1420000000000
IMG_0001: 1410000000000,
IMG_0002: 1420000000000
}
const res = delta.calculate(database, disk)
should(res).eql({
@ -22,12 +22,12 @@ describe('Index: delta', () => {
it('no changes within a second', () => {
const database = {
'IMG_0001': 1410000001000,
'IMG_0002': 1420000001000
IMG_0001: 1410000001000,
IMG_0002: 1420000001000
}
const disk = {
'IMG_0001': 1410000001500, // 500ms later
'IMG_0002': 1420000000500 // 500ms earlier
IMG_0001: 1410000001500, // 500ms later
IMG_0002: 1420000000500 // 500ms earlier
}
const res = delta.calculate(database, disk)
should(res).eql({
@ -40,13 +40,13 @@ describe('Index: delta', () => {
it('new files', () => {
const database = {
'IMG_0001': 1410000000000,
'IMG_0002': 1420000000000
IMG_0001: 1410000000000,
IMG_0002: 1420000000000
}
const disk = {
'IMG_0001': 1410000000000,
'IMG_0002': 1420000000000,
'IMG_0003': 1430000000000
IMG_0001: 1410000000000,
IMG_0002: 1420000000000,
IMG_0003: 1430000000000
}
const res = delta.calculate(database, disk)
should(res).eql({
@ -59,11 +59,11 @@ describe('Index: delta', () => {
it('deleted files', () => {
const database = {
'IMG_0001': 1410000000000,
'IMG_0002': 1420000000000
IMG_0001: 1410000000000,
IMG_0002: 1420000000000
}
const disk = {
'IMG_0001': 1410000000000
IMG_0001: 1410000000000
}
const res = delta.calculate(database, disk)
should(res).eql({
@ -76,12 +76,12 @@ describe('Index: delta', () => {
it('modified files', () => {
const database = {
'IMG_0001': 1410000000000,
'IMG_0002': 1420000000000
IMG_0001: 1410000000000,
IMG_0002: 1420000000000
}
const disk = {
'IMG_0001': 1410000000000,
'IMG_0002': 1420000002000
IMG_0001: 1410000000000,
IMG_0002: 1420000002000
}
const res = delta.calculate(database, disk)
should(res).eql({
@ -94,14 +94,14 @@ describe('Index: delta', () => {
it('all cases', () => {
const database = {
'IMG_0001': 1410000000000,
'IMG_0002': 1420000000000,
'IMG_0003': 1430000000000
IMG_0001: 1410000000000,
IMG_0002: 1420000000000,
IMG_0003: 1430000000000
}
const disk = {
'IMG_0001': 1410000000000,
'IMG_0002': 1420000002000,
'IMG_0004': 1445000000000
IMG_0001: 1410000000000,
IMG_0002: 1420000002000,
IMG_0004: 1445000000000
}
const res = delta.calculate(database, disk)
should(res).eql({

@ -10,7 +10,7 @@ describe('Index: glob', function () {
this.timeout(500)
// we require "mock-fs" inside the tests, otherwise it also affects other tests
var mock = null
let mock = null
before(() => {
mock = require('mock-fs')
})
@ -169,7 +169,7 @@ describe('Index: glob', function () {
'media/holidays/IMG_0002.jpg': '...'
})
const options = {
include: [ 'holidays/**' ]
include: ['holidays/**']
}
assertGlobReturns('media', options, [
'holidays/IMG_0002.jpg'
@ -182,7 +182,7 @@ describe('Index: glob', function () {
'media/holidays/IMG_0002.jpg': '...'
})
const options = {
exclude: [ 'work/**' ]
exclude: ['work/**']
}
assertGlobReturns('media', options, [
'holidays/IMG_0002.jpg'
@ -205,7 +205,7 @@ describe('Index: glob', function () {
]),
Buffer.from('file3c.jpg')
]
for (let filename of filenames) {
for (const filename of filenames) {
// we can't use path.join because it will check whether the components
// are valid, which they are not
fs.writeFileSync(Buffer.concat([

@ -8,7 +8,7 @@ describe('Index', function () {
this.slow(1000)
this.timeout(1000)
var tmpdir = null
let tmpdir = null
before(() => {
const image = fixtures.fromDisk('photo.jpg')
@ -22,8 +22,8 @@ describe('Index', function () {
const index = new Index(path.join(tmpdir, 'thumbsup.db'))
const emitter = index.update(path.join(tmpdir, 'input'))
const emitted = []
var processed = 0
var stats = null
let processed = 0
let stats = null
emitter.on('progress', () => ++processed)
emitter.on('file', meta => emitted.push(meta))
emitter.on('stats', s => { stats = s })
@ -49,9 +49,9 @@ describe('Index', function () {
it('can re-index with no changes', (done) => {
const index = new Index(path.join(tmpdir, 'thumbsup.db'))
const emitter = index.update(path.join(tmpdir, 'input'))
var emitted = 0
var processed = 0
var stats = null
let emitted = 0
let processed = 0
let stats = null
emitter.on('progress', () => ++processed)
emitter.on('file', () => ++emitted)
emitter.on('stats', s => { stats = s })
@ -70,9 +70,9 @@ describe('Index', function () {
fs.unlinkSync(path.join(tmpdir, 'input/newyork/IMG_0002.jpg'))
const index = new Index(path.join(tmpdir, 'thumbsup.db'))
const emitter = index.update(path.join(tmpdir, 'input'))
var emitted = 0
var processed = 0
var stats = null
let emitted = 0
let processed = 0
let stats = null
emitter.on('progress', () => ++processed)
emitter.on('file', () => ++emitted)
emitter.on('stats', s => { stats = s })

@ -9,15 +9,18 @@ module.exports = class ListrTestRenderer {
static get nonTTY () {
return true
}
constructor (tasks) {
this._tasks = tasks
this.output = []
}
render () {
for (let task of this._tasks) {
for (const task of this._tasks) {
this.subscribe(task)
}
}
subscribe (task) {
task.subscribe(
event => {
@ -32,12 +35,14 @@ module.exports = class ListrTestRenderer {
}
)
}
allTitles (tasks, indent) {
return tasks.map(task => {
const subTitles = this.allTitles(task.subtasks, indent + 1)
return ' '.repeat(indent) + task.title + '\n' + subTitles
}).join('')
}
end () {
}
}

@ -26,12 +26,12 @@ describe('Listr work queue', function () {
listr.run().then(() => {
const output = listr._renderer.output
// At some point a thread should have been waiting
hasItemMatching(output, `Waiting`)
hasItemMatching(output, 'Waiting')
// And a thread should have finished
hasItemMatching(output, `Finished`)
hasItemMatching(output, 'Finished')
// And every single render should conform to a particular format
const regex = /^Running jobs\n((\s\s(Waiting|Finished|Job \d+)\n){3})?$/
for (let line of output) {
for (const line of output) {
if (!regex.test(line)) {
should.fail(`Listr output does not match expected format: ${line}`)
}

@ -74,5 +74,5 @@ exports.createTempStructure = function (files) {
// convert to OS-dependent style paths for testing
exports.ospath = function (filepath) {
return filepath.replace(RegExp('/', 'g'), path.sep)
return filepath.replace(/\//g, path.sep)
}

@ -15,7 +15,7 @@ keywords=beach,sunset
describe('Picasa', function () {
// we require "mock-fs" inside the tests, otherwise it also affects other tests
var mock = null
let mock = null
beforeEach(function () {
mock = require('mock-fs')

@ -30,7 +30,7 @@ describe('Album', function () {
album.finalize()
const thumbs = album.previews.map(outputName)
should(thumbs.slice(0, 5)).eql(['0', '1', '2', '3', '4'])
for (var i = 5; i < 10; ++i) {
for (let i = 5; i < 10; ++i) {
should(album.previews[i].urls.thumbnail).eql('public/missing.png')
}
})
@ -54,7 +54,7 @@ describe('Album', function () {
should(album.previews).have.length(10)
const thumbs = album.previews.map(outputName)
should(thumbs.slice(0, 6)).eql(['a1', 'a2', 'b1', 'b2', 'c1', 'c2'])
for (var i = 6; i < 10; ++i) {
for (let i = 6; i < 10; ++i) {
should(album.previews[i].urls.thumbnail).eql('public/missing.png')
}
})
@ -97,7 +97,7 @@ describe('Album', function () {
should(album.previews).have.length(10)
const thumbs = album.previews.map(outputName)
should(thumbs.slice(0, 5)).eql(['0', '1', '2', '3', '4'])
for (var i = 5; i < 10; ++i) {
for (let i = 5; i < 10; ++i) {
should(album.previews[i].urls.thumbnail).eql('public/missing.png')
}
})

@ -1,6 +1,6 @@
var should = require('should/as-function')
var Album = require('../../src/model/album')
var fixtures = require('../fixtures')
const should = require('should/as-function')
const Album = require('../../src/model/album')
const fixtures = require('../fixtures')
describe('Album', function () {
describe('stats', function () {

@ -32,7 +32,7 @@ describe('Album', function () {
})
it('sanitises more special characters than the slugify() default', function () {
const a = new Album(`hello*+~.()'"!:@world`)
const a = new Album('hello*+~.()\'"!:@world')
should(a.basename).eql('helloworld')
})
@ -161,7 +161,8 @@ describe('Album', function () {
})
it('sorts nested albums too', function () {
const nested = new Album({ title: 'nested',
const nested = new Album({
title: 'nested',
files: [fileB, fileA]
})
const root = new Album({ title: 'home', albums: [nested] })
@ -315,5 +316,5 @@ function albumWithFileDates (dates) {
const files = dates.map(function (d) {
return fixtures.photo({ date: d })
})
return new Album({ files: files })
return new Album({ files })
}

@ -1,6 +1,6 @@
const should = require('should/as-function')
const Metadata = require('../../src/model/metadata')
var fixtures = require('../fixtures')
const fixtures = require('../fixtures')
describe('Metadata', function () {
describe('date taken', function () {
@ -167,7 +167,7 @@ describe('Metadata', function () {
it('can read a single IPTC keyword', function () {
// a single keyword is returned as a string by <exiftool>
const exiftool = fixtures.exiftool()
exiftool.IPTC['Keywords'] = 'beach'
exiftool.IPTC.Keywords = 'beach'
const meta = new Metadata(exiftool, {})
should(meta.keywords).eql(['beach'])
})
@ -175,7 +175,7 @@ describe('Metadata', function () {
it('can read multiple IPTC keywords', function () {
// multiple keywords are returned as an array by <exiftool>
const exiftool = fixtures.exiftool()
exiftool.IPTC['Keywords'] = ['beach', 'sunset']
exiftool.IPTC.Keywords = ['beach', 'sunset']
const meta = new Metadata(exiftool)
should(meta.keywords).eql(['beach', 'sunset'])
})
@ -197,8 +197,8 @@ describe('Metadata', function () {
it('combines all keyword sources', function () {
const exiftool = fixtures.exiftool()
exiftool.IPTC['Keywords'] = ['beach', 'sunset']
exiftool.XMP['Subject'] = 'holiday'
exiftool.IPTC.Keywords = ['beach', 'sunset']
exiftool.XMP.Subject = 'holiday'
const picasa = { keywords: 'sandiego' }
const meta = new Metadata(exiftool, picasa, {})
should(meta.keywords).eql(['beach', 'sunset', 'holiday', 'sandiego'])
@ -206,8 +206,8 @@ describe('Metadata', function () {
it('only keeps unique keywords', function () {
const exiftool = fixtures.exiftool()
exiftool.IPTC['Keywords'] = ['beach', 'sunset']
exiftool.XMP['Subject'] = ['beach', 'holiday']
exiftool.IPTC.Keywords = ['beach', 'sunset']
exiftool.XMP.Subject = ['beach', 'holiday']
const meta = new Metadata(exiftool)
should(meta.keywords).eql(['beach', 'sunset', 'holiday'])
})
@ -222,7 +222,7 @@ describe('Metadata', function () {
it('reads the rating from the XMP tags', function () {
const exiftool = fixtures.exiftool()
exiftool.XMP['Rating'] = 3
exiftool.XMP.Rating = 3
const meta = new Metadata(exiftool)
should(meta.rating).eql(3)
})

@ -84,7 +84,7 @@ describe('Output paths', function () {
// some of these formats are supported on certain browser, but we aim for maximum compatibility
['bmp', 'tiff', 'webp'].forEach(ext => {
const o = output.paths(`holidays/beach.${ext}`, 'image', {})
should(o.thumbnail.path).eql(ospath(`media/thumbs/holidays/beach.jpg`))
should(o.thumbnail.path).eql(ospath('media/thumbs/holidays/beach.jpg'))
})
})
})

@ -8,7 +8,7 @@ const ospath = fixtures.ospath
describe('Steps: cleanup', () => {
// we require "mock-fs" inside the tests, otherwise it also affects other tests
var mock = null
let mock = null
beforeEach(() => {
mock = require('mock-fs')

@ -6,31 +6,31 @@ describe('Handlebars helpers: compare', () => {
handlebars.registerHelper('compare', compare)
it('executes the block if the condition is true', () => {
const template = handlebars.compile(`{{#compare value '==' 3}}TRUE{{/compare}}`)
const template = handlebars.compile("{{#compare value '==' 3}}TRUE{{/compare}}")
const res = template({ value: 3 })
should(res).eql('TRUE')
})
it('does not execute the block if the condition is false', () => {
const template = handlebars.compile(`{{#compare value '==' 3}}{{/compare}}`)
const template = handlebars.compile("{{#compare value '==' 3}}{{/compare}}")
const res = template({ value: 4 })
should(res).eql('')
})
it('executes the {{else}} block if the condition is false', () => {
const template = handlebars.compile(`{{#compare value '==' 3}}TRUE{{else}}FALSE{{/compare}}`)
const template = handlebars.compile("{{#compare value '==' 3}}TRUE{{else}}FALSE{{/compare}}")
const res = template({ value: 4 })
should(res).eql('FALSE')
})
it('defaults to a strict equality', () => {
const template = handlebars.compile(`{{#compare value 3}}TRUE{{/compare}}`)
const template = handlebars.compile('{{#compare value 3}}TRUE{{/compare}}')
const res = template({ value: 3 })
should(res).eql('TRUE')
})
it('throws an error if the operator is not known', () => {
const template = handlebars.compile(`{{#compare value '~~' 3}}TRUE{{/compare}}`)
const template = handlebars.compile("{{#compare value '~~' 3}}TRUE{{/compare}}")
should(() => {
template({ value: 3 })
}).throw(/operator/)
@ -38,69 +38,69 @@ describe('Handlebars helpers: compare', () => {
it('throws an error if there arent enough parameters', () => {
should(() => {
const template = handlebars.compile(`{{#compare value}}TRUE{{/compare}}`)
const template = handlebars.compile('{{#compare value}}TRUE{{/compare}}')
template({ value: 3 })
}).throw(/needs 2 parameters/)
})
it('keeps the context when executing the block', () => {
const template = handlebars.compile(`{{#compare value '==' 3}}{{hello}}{{/compare}}`)
const template = handlebars.compile("{{#compare value '==' 3}}{{hello}}{{/compare}}")
const res = template({ value: 3, hello: 'world' })
should(res).eql('world')
})
describe('operators', () => {
it('equal', () => {
const template = handlebars.compile(`{{#compare value '==' 3}}TRUE{{/compare}}`)
const template = handlebars.compile("{{#compare value '==' 3}}TRUE{{/compare}}")
should(template({ value: 3 })).eql('TRUE')
should(template({ value: '3' })).eql('TRUE')
should(template({ value: 4 })).eql('')
})
it('strict equal', () => {
const template = handlebars.compile(`{{#compare value '===' 3}}TRUE{{/compare}}`)
const template = handlebars.compile("{{#compare value '===' 3}}TRUE{{/compare}}")
should(template({ value: 3 })).eql('TRUE')
should(template({ value: '3' })).eql('')
should(template({ value: 4 })).eql('')
})
it('different', () => {
const template = handlebars.compile(`{{#compare value '!=' 3}}TRUE{{/compare}}`)
const template = handlebars.compile("{{#compare value '!=' 3}}TRUE{{/compare}}")
should(template({ value: 3 })).eql('')
should(template({ value: '3' })).eql('')
should(template({ value: 4 })).eql('TRUE')
})
it('strict different', () => {
const template = handlebars.compile(`{{#compare value '!==' 3}}TRUE{{/compare}}`)
const template = handlebars.compile("{{#compare value '!==' 3}}TRUE{{/compare}}")
should(template({ value: 3 })).eql('')
should(template({ value: '3' })).eql('TRUE')
should(template({ value: 4 })).eql('TRUE')
})
it('less than', () => {
const template = handlebars.compile(`{{#compare value '<' 3}}TRUE{{/compare}}`)
const template = handlebars.compile("{{#compare value '<' 3}}TRUE{{/compare}}")
should(template({ value: 2 })).eql('TRUE')
should(template({ value: 3 })).eql('')
should(template({ value: 4 })).eql('')
})
it('greater than', () => {
const template = handlebars.compile(`{{#compare value '>' 3}}TRUE{{/compare}}`)
const template = handlebars.compile("{{#compare value '>' 3}}TRUE{{/compare}}")
should(template({ value: 2 })).eql('')
should(template({ value: 3 })).eql('')
should(template({ value: 4 })).eql('TRUE')
})
it('less or equal', () => {
const template = handlebars.compile(`{{#compare value '<=' 3}}TRUE{{/compare}}`)
const template = handlebars.compile("{{#compare value '<=' 3}}TRUE{{/compare}}")
should(template({ value: 2 })).eql('TRUE')
should(template({ value: 3 })).eql('TRUE')
should(template({ value: 4 })).eql('')
})
it('greater or equal', () => {
const template = handlebars.compile(`{{#compare value '>=' 3}}TRUE{{/compare}}`)
const template = handlebars.compile("{{#compare value '>=' 3}}TRUE{{/compare}}")
should(template({ value: 2 })).eql('')
should(template({ value: 3 })).eql('TRUE')
should(template({ value: 4 })).eql('TRUE')

@ -7,19 +7,19 @@ describe('Handlebars helpers: date', () => {
handlebars.registerHelper('date', date)
it('renders a date as DD MMM YYYY by default', () => {
const template = handlebars.compile(`<p>{{date taken}}</p>`)
const template = handlebars.compile('<p>{{date taken}}</p>')
const res = template({ taken: new Date(2017, 10, 27) }) // month is 0-based
should(res).eql('<p>27 Nov 2017</p>')
})
it('renders a date with a custom format', () => {
const template = handlebars.compile(`<p>{{date taken "MMMM YYYY"}}</p>`)
const template = handlebars.compile('<p>{{date taken "MMMM YYYY"}}</p>')
const res = template({ taken: new Date(2017, 10, 27) }) // month is 0-based
should(res).eql('<p>November 2017</p>')
})
it('renders a date as <time ago>', () => {
const template = handlebars.compile(`<p>{{date taken "ago"}}</p>`)
const template = handlebars.compile('<p>{{date taken "ago"}}</p>')
const data = { taken: new Date(2017, 10, 27) } // month is 0-based
const res = template(data)
const expected = moment(data.taken).fromNow()

@ -6,7 +6,7 @@ describe('Handlebars helpers: relative', () => {
handlebars.registerHelper('relative', date)
it('returns a path in the same folder', () => {
const template = handlebars.compile(`<link rel="stylesheet" href="{{relative 'public/theme.css'}}" />`)
const template = handlebars.compile('<link rel="stylesheet" href="{{relative \'public/theme.css\'}}" />')
const res = template({
album: {
path: 'index.html'
@ -16,7 +16,7 @@ describe('Handlebars helpers: relative', () => {
})
it('returns a relative path for albums in nested folders', () => {
const template = handlebars.compile(`<link rel="stylesheet" href="{{relative 'public/theme.css'}}" />`)
const template = handlebars.compile('<link rel="stylesheet" href="{{relative \'public/theme.css\'}}" />')
const res = template({
album: {
path: 'albums/holidays.html'
@ -35,7 +35,7 @@ describe('Handlebars helpers: relative', () => {
// TODO: this should not be needed anymore because all URLs are already escaped
it('escapes single quotes so they can be used in CSS background-image', () => {
const template = handlebars.compile(`background-image('{{relative url}}')`)
const template = handlebars.compile("background-image('{{relative url}}')")
const res = template({
url: "l'histoire.jpg",
album: {
@ -47,7 +47,7 @@ describe('Handlebars helpers: relative', () => {
// TODO: this should not be needed anymore because all URLs are already escaped
it('escapes double quotes so they can be used in <img> tags', () => {
const template = handlebars.compile(`<img src="{{relative url}}" />`)
const template = handlebars.compile('<img src="{{relative url}}" />')
const res = template({
url: 'l"histoire.jpg',
album: {

@ -7,26 +7,26 @@ describe('Handlebars helpers: slice', () => {
const list = [1, 2, 3, 4, 5, 6, 7, 8, 9]
it('renders the first N items of an array', () => {
const template = handlebars.compile(`{{#slice list count=3}}{{.}}{{/slice}}`)
const res = template({ list: list })
const template = handlebars.compile('{{#slice list count=3}}{{.}}{{/slice}}')
const res = template({ list })
should(res).eql('123')
})
it('renders nothing if count=0', () => {
const template = handlebars.compile(`{{#slice list count=0}}{{.}}{{/slice}}`)
const res = template({ list: list })
const template = handlebars.compile('{{#slice list count=0}}{{.}}{{/slice}}')
const res = template({ list })
should(res).eql('')
})
it('renders the whole array if count > length', () => {
const template = handlebars.compile(`{{#slice list count=20}}{{.}}{{/slice}}`)
const res = template({ list: list })
const template = handlebars.compile('{{#slice list count=20}}{{.}}{{/slice}}')
const res = template({ list })
should(res).eql('123456789')
})
it('renders 1 item if count is not specified', () => {
const template = handlebars.compile(`{{#slice list}}{{.}}{{/slice}}`)
const res = template({ list: list })
const template = handlebars.compile('{{#slice list}}{{.}}{{/slice}}')
const res = template({ list })
should(res).eql('1')
})
})

@ -6,25 +6,25 @@ describe('Handlebars helpers: times', () => {
handlebars.registerHelper('times', times)
it('executes a block several times', () => {
const template = handlebars.compile(`{{#times 3}}Hello{{/times}}`)
const template = handlebars.compile('{{#times 3}}Hello{{/times}}')
const res = template({})
should(res).eql('HelloHelloHello')
})
it('skips the block when count is 0', () => {
const template = handlebars.compile(`{{#times 0}}Hello{{/times}}`)
const template = handlebars.compile('{{#times 0}}Hello{{/times}}')
const res = template({})
should(res).eql('')
})
it('passes the context to the block', () => {
const template = handlebars.compile(`{{#times 3}}{{hello}}{{/times}}`)
const template = handlebars.compile('{{#times 3}}{{hello}}{{/times}}')
const res = template({ hello: 'world' })
should(res).eql('worldworldworld')
})
it('passes the @index to the block', () => {
const template = handlebars.compile(`{{#times 3}}{{@index}}{{/times}}`)
const template = handlebars.compile('{{#times 3}}{{@index}}{{/times}}')
const res = template({})
should(res).eql('012')
})

@ -6,7 +6,7 @@ const Theme = require('../../src/website/theme')
describe('Theme', () => {
// we require "mock-fs" inside the tests, otherwise it also affects other tests
var mock = null
let mock = null
before(() => {
mock = require('mock-fs')
})
@ -233,7 +233,7 @@ function renderTheme (theme, album, next) {
theme.validateStructure()
theme.prepare(err => {
should(err).be.null()
theme.render(album.path, { album: album }, err => {
theme.render(album.path, { album }, err => {
should(err).be.null()
next()
})

@ -20,7 +20,7 @@ function pageSize (pageSize) {
function albumWithFiles (count) {
const file = fixtures.photo({ path: 'photo.jpg' })
const files = new Array(count).fill(file)
const album = new Album({ files: files })
const album = new Album({ files })
album.finalize({})
return album
}

Loading…
Cancel
Save