2018-06-09 19:19:14 +00:00
|
|
|
const fs = require('fs')
|
2017-11-24 11:08:59 +00:00
|
|
|
const glob = require('../../../src/components/index/glob')
|
2018-06-09 19:19:14 +00:00
|
|
|
const { sep } = require('path')
|
2018-06-11 21:51:33 +00:00
|
|
|
const os = require('os')
|
2017-11-24 11:08:59 +00:00
|
|
|
const should = require('should/as-function')
|
2018-06-09 19:19:14 +00:00
|
|
|
const tmp = require('tmp')
|
2017-11-24 11:08:59 +00:00
|
|
|
|
|
|
|
describe('Index: glob', function () {
|
2017-11-26 10:14:31 +00:00
|
|
|
this.slow(500)
|
|
|
|
this.timeout(500)
|
|
|
|
|
2017-11-26 11:32:03 +00:00
|
|
|
// we require "mock-fs" inside the tests, otherwise it also affects other tests
|
2023-03-21 21:39:52 +00:00
|
|
|
let mock = null
|
2017-11-26 11:32:03 +00:00
|
|
|
before(() => {
|
|
|
|
mock = require('mock-fs')
|
|
|
|
})
|
|
|
|
|
2017-11-26 10:14:31 +00:00
|
|
|
afterEach(() => {
|
|
|
|
mock.restore()
|
|
|
|
})
|
|
|
|
|
2017-11-26 11:47:51 +00:00
|
|
|
it('bootstraps micromatch', () => {
|
|
|
|
// This is a workaround for https://github.com/tschaub/mock-fs/issues/213
|
|
|
|
// Because micromatch() loads packages dynamically which doesn't work if the filesystem is being mocked
|
|
|
|
// So we need to pre-load them now
|
|
|
|
require('micromatch').match('file.txt', '**/**')
|
|
|
|
})
|
|
|
|
|
2019-01-08 20:53:20 +00:00
|
|
|
it('can include photo extensions', () => {
|
2019-01-23 21:48:54 +00:00
|
|
|
const ext = glob.supportedExtensions({ includePhotos: true, includeVideos: false, includeRawPhotos: false })
|
|
|
|
should(ext.indexOf('jpg')).above(-1)
|
|
|
|
should(ext.indexOf('mp4')).eql(-1)
|
|
|
|
should(ext.indexOf('cr2')).eql(-1)
|
2019-01-08 20:53:20 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
it('can include video extensions', () => {
|
2019-01-23 21:48:54 +00:00
|
|
|
const ext = glob.supportedExtensions({ includePhotos: false, includeVideos: true, includeRawPhotos: false })
|
|
|
|
should(ext.indexOf('jpg')).eql(-1)
|
|
|
|
should(ext.indexOf('mp4')).above(-1)
|
|
|
|
should(ext.indexOf('cr2')).eql(-1)
|
2019-01-08 20:53:20 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
it('can include raw photo extensions', () => {
|
2019-01-23 21:48:54 +00:00
|
|
|
const ext = glob.supportedExtensions({ includePhotos: false, includeVideos: false, includeRawPhotos: true })
|
|
|
|
should(ext.indexOf('jpg')).eql(-1)
|
|
|
|
should(ext.indexOf('mp4')).eql(-1)
|
|
|
|
should(ext.indexOf('cr2')).above(-1)
|
2019-01-08 20:53:20 +00:00
|
|
|
})
|
|
|
|
|
2019-01-23 21:48:54 +00:00
|
|
|
it('lists all images by default', (done) => {
|
2017-11-26 10:14:31 +00:00
|
|
|
mock({
|
|
|
|
'media/IMG_0001.jpg': '...',
|
|
|
|
'media/IMG_0002.jpg': '...'
|
|
|
|
})
|
2019-01-23 21:48:54 +00:00
|
|
|
const options = {}
|
|
|
|
assertGlobReturns('media', options, [
|
|
|
|
'IMG_0001.jpg',
|
|
|
|
'IMG_0002.jpg'
|
|
|
|
], done)
|
2017-11-26 10:14:31 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
it('can list nested images', (done) => {
|
|
|
|
mock({
|
|
|
|
'media/2016/June/IMG_0001.jpg': '...',
|
|
|
|
'media/2017/IMG_0002.jpg': '...'
|
|
|
|
})
|
2019-01-23 21:48:54 +00:00
|
|
|
const options = {}
|
|
|
|
assertGlobReturns('media', options, [
|
|
|
|
'2016/June/IMG_0001.jpg',
|
|
|
|
'2017/IMG_0002.jpg'
|
|
|
|
], done)
|
2017-11-26 10:14:31 +00:00
|
|
|
})
|
|
|
|
|
2019-01-08 20:45:02 +00:00
|
|
|
it('includes photos and videos by default', (done) => {
|
|
|
|
mock({
|
|
|
|
'media/IMG_0001.jpg': '...',
|
|
|
|
'media/IMG_0002.mp4': '...'
|
|
|
|
})
|
2019-01-23 21:48:54 +00:00
|
|
|
const options = {}
|
|
|
|
assertGlobReturns('media', options, [
|
|
|
|
'IMG_0001.jpg',
|
|
|
|
'IMG_0002.mp4'
|
|
|
|
], done)
|
2019-01-08 20:45:02 +00:00
|
|
|
})
|
|
|
|
|
2019-01-23 21:48:54 +00:00
|
|
|
it('can exclude photos', (done) => {
|
2019-01-08 20:45:02 +00:00
|
|
|
mock({
|
|
|
|
'media/IMG_0001.jpg': '...',
|
|
|
|
'media/IMG_0002.mp4': '...'
|
|
|
|
})
|
2019-01-23 21:48:54 +00:00
|
|
|
const options = { includePhotos: false }
|
|
|
|
assertGlobReturns('media', options, [
|
|
|
|
'IMG_0002.mp4'
|
|
|
|
], done)
|
2019-01-08 20:45:02 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
it('can excludes videos', (done) => {
|
|
|
|
mock({
|
|
|
|
'media/IMG_0001.jpg': '...',
|
|
|
|
'media/IMG_0002.mp4': '...'
|
|
|
|
})
|
2019-01-23 21:48:54 +00:00
|
|
|
const options = { includeVideos: false }
|
|
|
|
assertGlobReturns('media', options, [
|
|
|
|
'IMG_0001.jpg'
|
|
|
|
], done)
|
2019-01-08 20:45:02 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
it('can include raw photos', (done) => {
|
|
|
|
mock({
|
|
|
|
'media/IMG_0001.jpg': '...',
|
|
|
|
'media/IMG_0002.cr2': '...'
|
|
|
|
})
|
2019-01-23 21:48:54 +00:00
|
|
|
const options = { includeRawPhotos: true }
|
|
|
|
assertGlobReturns('media', options, [
|
|
|
|
'IMG_0001.jpg',
|
|
|
|
'IMG_0002.cr2'
|
|
|
|
], done)
|
2019-01-08 20:45:02 +00:00
|
|
|
})
|
|
|
|
|
2019-01-23 21:48:54 +00:00
|
|
|
it('is case insensitive for the extension', (done) => {
|
2017-11-26 10:14:31 +00:00
|
|
|
mock({
|
|
|
|
'media/IMG_0001.JPG': '...'
|
|
|
|
})
|
2019-01-23 21:48:54 +00:00
|
|
|
const options = {}
|
|
|
|
assertGlobReturns('media', options, [
|
|
|
|
'IMG_0001.JPG'
|
|
|
|
], done)
|
2017-11-26 10:14:31 +00:00
|
|
|
})
|
|
|
|
|
2017-11-26 11:32:03 +00:00
|
|
|
it('ignores any folder starting with a dot', (done) => {
|
2017-11-26 10:14:31 +00:00
|
|
|
mock({
|
2017-11-26 11:32:03 +00:00
|
|
|
'media/IMG_0001.jpg': '...',
|
|
|
|
'media/.git/IMG_0002.jpg': '...',
|
|
|
|
'media/nested/.private/IMG_0003.jpg': '...',
|
|
|
|
'media/just/a.dot/IMG_0004.jpg': '...'
|
2017-11-26 10:14:31 +00:00
|
|
|
})
|
2019-01-23 21:48:54 +00:00
|
|
|
const options = {}
|
|
|
|
assertGlobReturns('media', options, [
|
|
|
|
'IMG_0001.jpg',
|
|
|
|
'just/a.dot/IMG_0004.jpg'
|
|
|
|
], done)
|
2017-11-26 11:32:03 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
it('ignores folders called @eaDir (Synology thumbnail folders)', (done) => {
|
|
|
|
mock({
|
|
|
|
'media/holidays/IMG_0001.jpg': '...',
|
|
|
|
'media/holidays/@eaDir/IMG_0001.jpg': '...'
|
|
|
|
})
|
2019-01-23 21:48:54 +00:00
|
|
|
const options = {}
|
|
|
|
assertGlobReturns('media', options, [
|
|
|
|
'holidays/IMG_0001.jpg'
|
|
|
|
], done)
|
2017-11-24 11:08:59 +00:00
|
|
|
})
|
2017-12-10 12:34:32 +00:00
|
|
|
|
|
|
|
it('ignores root folders called #recycle (Synology recycle bin)', (done) => {
|
|
|
|
mock({
|
|
|
|
'media/holidays/IMG_0001.jpg': '...',
|
|
|
|
'media/#recycle/IMG_0002.jpg': '...'
|
|
|
|
})
|
2019-01-23 21:48:54 +00:00
|
|
|
const options = {}
|
|
|
|
assertGlobReturns('media', options, [
|
|
|
|
'holidays/IMG_0001.jpg'
|
|
|
|
], done)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('can specify an include pattern', (done) => {
|
|
|
|
mock({
|
|
|
|
'media/work/IMG_0001.jpg': '...',
|
|
|
|
'media/holidays/IMG_0002.jpg': '...'
|
2017-12-10 12:34:32 +00:00
|
|
|
})
|
2019-01-23 21:48:54 +00:00
|
|
|
const options = {
|
2023-03-21 21:39:52 +00:00
|
|
|
include: ['holidays/**']
|
2019-01-23 21:48:54 +00:00
|
|
|
}
|
|
|
|
assertGlobReturns('media', options, [
|
|
|
|
'holidays/IMG_0002.jpg'
|
|
|
|
], done)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('can specify an exclude pattern', (done) => {
|
|
|
|
mock({
|
|
|
|
'media/work/IMG_0001.jpg': '...',
|
|
|
|
'media/holidays/IMG_0002.jpg': '...'
|
|
|
|
})
|
|
|
|
const options = {
|
2023-03-21 21:39:52 +00:00
|
|
|
exclude: ['work/**']
|
2019-01-23 21:48:54 +00:00
|
|
|
}
|
|
|
|
assertGlobReturns('media', options, [
|
|
|
|
'holidays/IMG_0002.jpg'
|
|
|
|
], done)
|
2017-12-10 12:34:32 +00:00
|
|
|
})
|
2018-06-09 19:19:14 +00:00
|
|
|
|
2021-03-03 22:19:36 +00:00
|
|
|
it('ignores invalid file names on Linux', function (done) {
|
|
|
|
if (os.platform() !== 'linux') {
|
2018-06-11 21:51:33 +00:00
|
|
|
// the invalid filename generates a system error on macOS
|
2021-03-03 22:19:36 +00:00
|
|
|
// and is actually valid on Windows
|
2018-06-11 21:51:33 +00:00
|
|
|
return this.skip()
|
|
|
|
}
|
2018-06-09 19:19:14 +00:00
|
|
|
const tmpdir = tmp.dirSync({ unsafeCleanup: true })
|
|
|
|
const filenames = [
|
|
|
|
Buffer.from('file1a.jpg'),
|
|
|
|
Buffer.concat([
|
|
|
|
Buffer.from('file2'),
|
|
|
|
Buffer.from([0xfc]),
|
|
|
|
Buffer.from('.jpg')
|
|
|
|
]),
|
|
|
|
Buffer.from('file3c.jpg')
|
|
|
|
]
|
2023-03-21 21:39:52 +00:00
|
|
|
for (const filename of filenames) {
|
2018-06-09 19:19:14 +00:00
|
|
|
// we can't use path.join because it will check whether the components
|
|
|
|
// are valid, which they are not
|
|
|
|
fs.writeFileSync(Buffer.concat([
|
|
|
|
Buffer.from(tmpdir.name),
|
|
|
|
Buffer.from(sep),
|
|
|
|
filename
|
|
|
|
]), '...')
|
|
|
|
}
|
2019-01-08 20:45:02 +00:00
|
|
|
glob.find(tmpdir.name, {}, (err, map) => {
|
2018-06-09 19:19:14 +00:00
|
|
|
if (err) return done(err)
|
|
|
|
const keys = Object.keys(map).sort()
|
|
|
|
should(keys).eql([
|
|
|
|
'file1a.jpg',
|
|
|
|
'file3c.jpg'
|
|
|
|
])
|
|
|
|
done()
|
|
|
|
})
|
|
|
|
})
|
2018-06-12 20:58:45 +00:00
|
|
|
|
|
|
|
it('ignores non-traversable directories', (done) => {
|
|
|
|
mock({
|
|
|
|
'media/secret': mock.directory({
|
|
|
|
mode: 0,
|
|
|
|
items: {
|
|
|
|
'IMG_0001.jpg': '...'
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
'media/IMG_0002.jpg': '...'
|
|
|
|
})
|
2019-01-08 20:45:02 +00:00
|
|
|
glob.find('media', {}, (err, map) => {
|
2018-06-12 20:58:45 +00:00
|
|
|
if (err) return done(err)
|
|
|
|
const keys = Object.keys(map).sort()
|
|
|
|
should(keys).eql([
|
|
|
|
'IMG_0002.jpg'
|
|
|
|
])
|
|
|
|
done()
|
|
|
|
})
|
|
|
|
})
|
2017-11-24 11:08:59 +00:00
|
|
|
})
|
2019-01-23 21:48:54 +00:00
|
|
|
|
|
|
|
function assertGlobReturns (root, options, expected, done) {
|
|
|
|
glob.find(root, options, (err, map) => {
|
|
|
|
if (err) return done(err)
|
|
|
|
const keys = Object.keys(map).sort()
|
|
|
|
should(keys).eql(expected)
|
|
|
|
done()
|
|
|
|
})
|
|
|
|
}
|