|
|
|
import * as cp from 'child_process'
|
|
|
|
import fs from 'fs/promises'
|
|
|
|
import { join, resolve, isAbsolute } from 'path'
|
|
|
|
import { tmpdir } from 'os'
|
|
|
|
import { promisify } from 'util'
|
|
|
|
const { mkdir, rmdir, readFile } = fs
|
|
|
|
const exec = promisify(cp.exec)
|
|
|
|
|
|
|
|
export const setup = async ({ path }) => {
|
|
|
|
const tmpPath = `${tmpdir()}/personal-shopper`
|
|
|
|
const filePath = `${tmpPath}/personal-shopper.json`
|
|
|
|
|
|
|
|
await mkdir(tmpPath)
|
|
|
|
const run = async cmd => {
|
|
|
|
const output = await exec(`node ${path} ${filePath} ${cmd}`)
|
|
|
|
const fileContent = await readFile(`${filePath}`, 'utf8')
|
|
|
|
|
|
|
|
return {
|
|
|
|
data: JSON.parse(fileContent),
|
|
|
|
stdout: output.stdout.trim(),
|
|
|
|
stderr: output.stderr.trim(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return { run }
|
|
|
|
}
|
|
|
|
|
|
|
|
export const tests = []
|
|
|
|
|
|
|
|
tests.push(async ({ eq, ctx }) => {
|
|
|
|
// create make an empty json file
|
|
|
|
|
|
|
|
const { data, stderr } = await ctx.run('create')
|
|
|
|
return eq({ data, stderr }, { data: {}, stderr: '' })
|
|
|
|
})
|
|
|
|
|
|
|
|
tests.push(async ({ path, eq, ctx }) => {
|
|
|
|
// no elem specifiel, should log an error
|
|
|
|
|
|
|
|
return eq(await ctx.run('add'), {
|
|
|
|
stdout: '',
|
|
|
|
stderr: 'No elem specified.',
|
|
|
|
data: {},
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
tests.push(async ({ path, eq, ctx }) => {
|
|
|
|
// add without number, should add 1
|
|
|
|
|
|
|
|
const { data } = await ctx.run('add beetroot')
|
|
|
|
return eq(data, { beetroot: 1 })
|
|
|
|
})
|
|
|
|
|
|
|
|
tests.push(async ({ path, eq, ctx }) => {
|
|
|
|
// with a valid number it shoud add the correct amount
|
|
|
|
|
|
|
|
const { data } = await ctx.run(`add beetroot 5`)
|
|
|
|
return eq(data, { beetroot: 6 })
|
|
|
|
})
|
|
|
|
|
|
|
|
tests.push(async ({ path, eq, ctx }) => {
|
|
|
|
// negative numbers should reduce the amount
|
|
|
|
|
|
|
|
const { data } = await ctx.run(`add beetroot -1`)
|
|
|
|
return eq(data, { beetroot: 5 })
|
|
|
|
})
|
|
|
|
|
|
|
|
tests.push(async ({ path, eq, ctx }) => {
|
|
|
|
// add NaN value, should add 1
|
|
|
|
|
|
|
|
const { data } = await ctx.run('add beetroot someNaN')
|
|
|
|
return eq(data, { beetroot: 6 })
|
|
|
|
})
|
|
|
|
|
|
|
|
tests.push(async ({ path, eq, ctx }) => {
|
|
|
|
// add negative exact number of elem (= 0)
|
|
|
|
// -> should delete the entry
|
|
|
|
|
|
|
|
const { data } = await ctx.run(`add beetroot -6`)
|
|
|
|
return eq(data, {})
|
|
|
|
})
|
|
|
|
|
|
|
|
tests.push(async ({ path, eq, ctx }) => {
|
|
|
|
// add negative value, bigger than current value
|
|
|
|
// -> should delete the entry
|
|
|
|
|
|
|
|
await ctx.run(`add beetroot 4`)
|
|
|
|
const { data } = await ctx.run(`add beetroot -10`)
|
|
|
|
return eq(data, {})
|
|
|
|
})
|
|
|
|
|
|
|
|
tests.push(async ({ path, eq, ctx }) => {
|
|
|
|
// no elem specified, should log an error
|
|
|
|
|
|
|
|
return eq(await ctx.run('rm'), {
|
|
|
|
stdout: '',
|
|
|
|
stderr: 'No elem specified.',
|
|
|
|
data: {},
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
tests.push(async ({ path, eq, ctx }) => {
|
|
|
|
// rm elem which is not in the list, should do nothing
|
|
|
|
|
|
|
|
const { data, stderr } = await ctx.run(`rm mustard`)
|
|
|
|
return eq({ stderr, data}, { stderr: '', data: {} })
|
|
|
|
})
|
|
|
|
|
|
|
|
tests.push(async ({ path, eq, ctx }) => {
|
|
|
|
// rm negative value, should add it
|
|
|
|
|
|
|
|
const { data } = await ctx.run(`rm mustard -4`)
|
|
|
|
return eq(data, { mustard: 4 })
|
|
|
|
})
|
|
|
|
|
|
|
|
tests.push(async ({ path, eq, ctx }) => {
|
|
|
|
// rm positive value, smaller than current value
|
|
|
|
// -> should substract it from current value
|
|
|
|
|
|
|
|
const { data } = await ctx.run(`rm mustard 2`)
|
|
|
|
return eq(data, { mustard: 2 })
|
|
|
|
})
|
|
|
|
|
|
|
|
tests.push(async ({ path, eq, ctx }) => {
|
|
|
|
// rm without number, should delete the entry
|
|
|
|
|
|
|
|
const { data } = await ctx.run(`rm mustard`)
|
|
|
|
return eq(data, {})
|
|
|
|
})
|
|
|
|
|
|
|
|
tests.push(async ({ path, eq, ctx }) => {
|
|
|
|
// should print an empty list
|
|
|
|
|
|
|
|
const { stdout } = await ctx.run('ls')
|
|
|
|
return eq(`Empty list.`, stdout.trim())
|
|
|
|
})
|
|
|
|
|
|
|
|
tests.push(async ({ path, eq, ctx }) => {
|
|
|
|
// should print the list with the elem as expected inside
|
|
|
|
|
|
|
|
await ctx.run(`add mustard 2`)
|
|
|
|
const { stdout } = await ctx.run('ls')
|
|
|
|
return eq(`- mustard (2)`, stdout.trim())
|
|
|
|
})
|
|
|
|
|
|
|
|
tests.push(async ({ path, eq, ctx, randStr, between}) => {
|
|
|
|
// should print the list with the elem as expected inside
|
|
|
|
|
|
|
|
const randomElem = randStr(7)
|
|
|
|
const randomAmount = between(1000, 5000)
|
|
|
|
|
|
|
|
await ctx.run(`add mustard 2`)
|
|
|
|
await ctx.run(`add beetroot 1`)
|
|
|
|
await ctx.run(`add chips ${randomAmount}`)
|
|
|
|
await ctx.run(`add ${randomElem} 4`)
|
|
|
|
const { stdout } = await ctx.run('ls')
|
|
|
|
|
|
|
|
return eq(
|
|
|
|
[
|
|
|
|
`- mustard (4)`,
|
|
|
|
`- beetroot (1)`,
|
|
|
|
`- chips (${randomAmount})`,
|
|
|
|
`- ${randomElem} (4)`,
|
|
|
|
],
|
|
|
|
stdout.split('\n'),
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
tests.push(async ({ path, eq, ctx }) => {
|
|
|
|
// should print the helper that include every commands
|
|
|
|
|
|
|
|
const { stdout } = await ctx.run(`help`)
|
|
|
|
return ['add', 'rm', 'delete', 'create', 'ls', 'help'].every(c =>
|
|
|
|
stdout.includes(c),
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
tests.push(async ({ path, eq, ctx }) => {
|
|
|
|
// should print the helper
|
|
|
|
|
|
|
|
const { stdout } = await ctx.run(``)
|
|
|
|
return ['add', 'rm', 'delete', 'create', 'ls', 'help'].every(c =>
|
|
|
|
stdout.includes(c),
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
tests.push(async ({ path, eq, ctx }) => {
|
|
|
|
// delete should remove the file
|
|
|
|
|
|
|
|
return ctx.run(`delete`)
|
|
|
|
.then(() => Promise.reject(Error('json file still present after delete')))
|
|
|
|
.catch(err => err.code === 'ENOENT' || err)
|
|
|
|
})
|
|
|
|
|
|
|
|
Object.freeze(tests)
|