ExiftoolContext is a context for zoroaster which allows to use node-exiftool
npm install exiftool-context
exiftool-contex is a context for zoroaster which allows to createExiftoolProcess, open it, create temp jpeg and data file, and make
sure they are removed, and exiftool is closed in the _destroy method.
Full API description see below.
npm i --save-dev exiftool-context
This package has to be published from a Linux, and not a Mac, because it
contains a filename with unicode encoding, which will be published in a
different form (see below)
Just specify ExiftoolContext as your test suite context.
``js
const ExiftoolContext = require('exiftool-context')
const myModuleTestSuite = {
context: ExiftoolContext,
'should have correct metadata': (ctx) => {
const ep = ctx.create()
return ep.open().then(() => {
// Context has a number of JPEG pictures with some metadata.
return ep.readMetadata(ctx.jpegFile)
})
.then((res) => {
const file = res.data[0]
return ctx.assertJpegMetadata(file)
})
},
}
module.exports = myModuleTestSuite
`
zoroaster example/myModuleTestSuite
`fs
example
myModuleTestSuite.js
✓ should have correct metadata
Executed 1 tests.
`
Fixtures are found in ./etc directory. These functions and properties are available:
CANON/IMG_9858.JPG
CANON/IMG_9859.JPG
You need to call ctx.createTempFile first, after which this will be set to a temp
jpeg file, into which you can write some metadata.
You need to call ctx.createDataFile first, after which this will be set to a data
file which can be used to open exiftool with and write commands to.
Returns exiftool.
exiftool will print "File not found: test/fixtures/no_such_file.jpg" in case of error,
even on windows. use this function to replace slashes on your platform.
no_such_file.jpg
no_such_file2.jpg
CANON
empty
Return a fixture file with utf-encoded filename.
> ./etc/fixtures/Fọto.jpg
Here's some some additional info about Mac, git and unicode which can help in
times of trouble.
Git and the Umlaut problem on Mac OS X
Filename that we test against is:
\u0046\u1ECD\u0074\u006F\u002E\u006A\u0070\u0067
Fọto.jpg: F\u1ECDto.jpg (Yoruba language) (NFC)
Fọto.jpg: Fo\u0323to.jpg - apparently another way to represent it (NFD)
Although the actual file may be in the wanted form, if there are other
files in the repo (probably preceding the test one) which are in another
form, git will use their format for other files (a guess but when it was
the case, the test was failing).
`js
// snippet to check filenames in unicode
const basename = path.basename(ctx.filenameWithEncoding)
const dir = path.dirname(ctx.filenameWithEncoding)
console.log('File to read: %s', ctx.filenameWithEncoding)
console.log('Filename in unicode to read: %s', ctx.toUnicode(basename))
const res = fs.readdirSync(dir)
console.log('Files in fixtures:')
res.map(n => ${n}: ${ctx.toUnicode(n)}).forEach(n => console.log(n))`
A function which has hard-coded metadata in it to assert against fixtures metadata.
An ExiftoolProcess instance. it is not set at first, call ctx.create() before accessing.
`js`
this._ep = new exiftool.ExiftoolProcess() // use dist-exiftool binary
this._ep = new exiftool.ExiftoolProcess(bin) // use specific binary
return this // allow chaining
Create a new instance with a given bin, and assign it to self.
`js`
if (this.ep) {
return this.ep.open(options)
}
throw new Error('ep has not been created')
Open exiftool.
`js`
this.create(bin).open(options)
Create an instance and open it.
`js`
this.ep.close()
Close instance
`js`
ep.readMetadata()
Read metadata of a file
`js`
ep.writeMetadata()
Write metadata to a file
`js`
ep.open.readMetadata()
Open ExiftoolProcess and read metadata
`js`
ep.open.writeMetadata()
Open ExiftoolProcess and write metadata
Create a new temp file for testing. Currently clones a jpeg fixture.
Create a data file which can be used to open exiftool
Write some data to the data file.
Perform the following:
* unlinkTempFile(this.dataFile)
* unlinkTempFile(this.tempFile)
That is, make sure that tests do not have open processes after them, or temp files.
Convert a string to unicode
(author).
`js`
// http://buildingonmud.blogspot.ru/2009/06/convert-string-to-unicode-in-javascript.html
function toUnicode(theString) {
let unicodeString = ''
for (var i=0; i < theString.length; i++) {
let theUnicode = theString.charCodeAt(i).toString(16).toUpperCase()
while (theUnicode.length < 4) {
theUnicode = '0' + theUnicode
}
theUnicode = '\\u' + theUnicode
unicodeString += theUnicode
}
return unicodeString
}
Because node-exiftool will be spawned with child_process.spawn, whenspawn
testing, we will mock the method. To do that, use ctx.mockSpawn(), andctx.proc
access the process's mock with . The _process_ is an EventEmitter, andclose
will emit event when its stdin is written with -stay_open\nfalse\n.
`js
ctx.mockSpawn()
const bin = 'echo'
const args = ['hello', 'world']
const options = {
cwd: HOME,
}
const proc = cp.spawn(bin, args, options)
assert.equal(ctx.proc, proc)
assert.equal(ctx.proc.args, { bin, args, options })
`
When args passed to cp.spawn include -stay_open True, it will automaticallystderr
push mocked date to the process's , simulating an opening echo.
Push some data to stderr readable stream.
Push some data to stdout readable stream.
An array with all data written to stdin.
Arguments passed when calling child_process.spawn command.
A test context is an object which is available to tests via ctx argument. This iszoroaster` test runner. It allows to abstract individual test contexts.
implemented in
That makes maintanence of test files easier when they don't have to rely on global scope
of each other. You can create unique and specific tests contexts to be used in testing
of your application. Save time by reusing the code, and using tests as a tool, and not
the other way around.
To learn more about the idea of test contexts, read zoroaster documentation.
---
(c) Zoroaster 2017