You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

398 lines
12 KiB

import * as cp from 'child_process'
import { readdir, rm, mkdir, writeFile, readFile } from 'fs/promises'
import { tmpdir } from 'os'
import { promisify } from 'util'
const exec = promisify(cp.exec)
export const tests = []
export const setup = async ({ path }) => {
const tmpPath = `${tmpdir()}/happiness-manager`
await mkdir(tmpPath)
await mkdir(`${tmpPath}/guests`)
const run = async (dir, file) => {
const output = await exec(
`node ${path} ${tmpPath}/${dir} ${tmpPath}/${file}`,
)
const fileContent = await readFile(
`${tmpPath}/${file}`,
'utf8',
).catch(err => (err.code === 'ENOENT' ? 'output file not found' : err))
return {
data:
fileContent === 'output file not found'
? fileContent
: JSON.parse(fileContent),
stdout: output.stdout.trim(),
}
}
const resetAnswersIn = async ({ dir }) => {
const files = await readdir(`${tmpPath}/${dir}`)
await Promise.all(files.map(file => rm(`${tmpPath}/${dir}/${file}`)))
}
const createAnswers = (nb, elem) => [...Array(nb).keys()].map(() => elem)
const setAnswersIn = async ({ answers, dir }) => {
await resetAnswersIn({ dir })
await Promise.all(
answers.map(
async (content, idx) =>
await writeFile(
`${tmpPath}/${dir}/${idx}.json`,
JSON.stringify(content, null, '\t'),
'utf8',
),
),
)
}
return { run, tmpPath, createAnswers, resetAnswersIn, setAnswersIn }
}
tests.push(async ({ eq, ctx }) => {
// test with no vips (no {answer: yes})
// no file should be created, a special message should appear in console
const answers = ctx.createAnswers(2, { answer: 'no' })
await ctx.setAnswersIn({ dir: 'guests', answers })
const { stdout, data } = await ctx.run('guests', 'happy-list.json')
return eq(
{ stdout, data },
{ stdout: 'No one is coming.', data: 'output file not found' },
)
})
tests.push(async ({ eq, ctx }) => {
// test when vips answer { food: 'carnivores' }
// should create a list with burgers and potatoes
const answers = ctx.createAnswers(2, { answer: 'yes', food: 'carnivore' })
await ctx.setAnswersIn({ dir: 'guests', answers })
const { data } = await ctx.run('guests', 'happy-carn-list.json')
return eq(data, { burgers: 2, potatoes: 2 })
})
tests.push(async ({ eq, ctx }) => {
// test when vips answer { food: 'fish' }
// should create a list with sardines and potatoes
const answers = [
{ answer: 'no', food: 'fish' },
...ctx.createAnswers(3, { answer: 'yes', food: 'fish' }),
]
await ctx.setAnswersIn({ dir: 'guests', answers })
const { data } = await ctx.run('guests', 'happy-fish-list.json')
return eq(data, { potatoes: 3, sardines: 3 })
})
tests.push(async ({ eq, ctx }) => {
// test when vips answer { food: 'everything' }
// should create a list with kebabs and potatoes
const answers = [
{ answer: 'no', food: 'everything' },
...ctx.createAnswers(3, { answer: 'yes', food: 'everything' }),
]
await ctx.setAnswersIn({ dir: 'guests', answers })
const { data } = await ctx.run('guests', 'happy-omni-list.json')
return eq(data, { potatoes: 3, kebabs: 3 })
})
tests.push(async ({ eq, ctx }) => {
// test when vips answer { drink: 'beer' }
// should create a list with 6-packs-beers and potatoes
const answers = [
{ answer: 'no', drink: 'beer' },
...ctx.createAnswers(1, { answer: 'yes', drink: 'beer' }),
]
await ctx.setAnswersIn({ dir: 'guests', answers })
const { data } = await ctx.run('guests', 'happy-beer-list.json')
return eq(data, { potatoes: 1, '6-packs-beers': 1 })
})
tests.push(async ({ eq, ctx }) => {
// test when vips answer { drink: 'beer' }
// should create a list with 6-packs-beers and potatoes
const answers = [
{ answer: 'no', drink: 'beer' },
...ctx.createAnswers(6, { answer: 'yes', drink: 'beer' }),
]
await ctx.setAnswersIn({ dir: 'guests', answers })
const { data } = await ctx.run('guests', 'happy-beer-pack-list.json')
return eq(data, { potatoes: 6, '6-packs-beers': 1 })
})
tests.push(async ({ eq, ctx }) => {
// test when vips answer { drink: 'wine' }
// should create a list with wine-bottles and potatoes
const answers = [
...ctx.createAnswers(3, { answer: 'no', drink: 'wine' }),
...ctx.createAnswers(5, { answer: 'yes', drink: 'wine' }),
]
await ctx.setAnswersIn({ dir: 'guests', answers })
const { data } = await ctx.run('guests', 'happy-wine-list.json')
return eq(data, { potatoes: 5, 'wine-bottles': 2 })
})
tests.push(async ({ eq, ctx }) => {
// test when vips answer { drink: 'wine' }
// should create a list with wine-bottles and potatoes
const answers = ctx.createAnswers(8, { answer: 'yes', drink: 'wine' })
await ctx.setAnswersIn({ dir: 'guests', answers })
const { data } = await ctx.run('guests', 'happy-wine-bottle-list.json')
return eq(data, { potatoes: 8, 'wine-bottles': 2 })
})
tests.push(async ({ eq, ctx }) => {
// test when vips answer { drink: 'water' }
// should create a list with water-bottles and potatoes
const answers = [
...ctx.createAnswers(2, { answer: 'no', drink: 'water' }),
...ctx.createAnswers(2, { answer: 'yes', drink: 'water' }),
]
await ctx.setAnswersIn({ dir: 'guests', answers })
const { data } = await ctx.run('guests', 'happy-water-list.json')
return eq(data, { potatoes: 2, 'water-bottles': 1 })
})
tests.push(async ({ eq, ctx }) => {
// test when vips answer { drink: 'water' }
// should create a list with water-bottles and potatoes
const answers = ctx.createAnswers(7, { answer: 'yes', drink: 'water' })
await ctx.setAnswersIn({ dir: 'guests', answers })
const { data } = await ctx.run('guests', 'happy-water-bottle-list.json')
return eq(data, { potatoes: 7, 'water-bottles': 2 })
})
tests.push(async ({ eq, ctx }) => {
// test when vips answer { drink: 'soft' }
// should create a list with soft-bottles and potatoes
const answers = [
...ctx.createAnswers(8, { answer: 'no', drink: 'soft' }),
...ctx.createAnswers(12, { answer: 'yes', drink: 'soft' }),
]
await ctx.setAnswersIn({ dir: 'guests', answers })
const { data } = await ctx.run('guests', 'happy-soft-list.json')
return eq(data, { potatoes: 12, 'soft-bottles': 3 })
})
tests.push(async ({ eq, ctx }) => {
// test when vips answer { drink: 'soft' }
// should create a list with soft-bottles and potatoes
const answers = ctx.createAnswers(13, { answer: 'yes', drink: 'soft' })
await ctx.setAnswersIn({ dir: 'guests', answers })
const { data } = await ctx.run('guests', 'happy-soft-bottle-list.json')
return eq(data, { potatoes: 13, 'soft-bottles': 4 })
})
// tests with veggstuff
// 1) vegan but no veggie
tests.push(async ({ eq, ctx }) => {
// test when vips answer { food: 'vegan' }
// should create a list with eggplants, mushrooms, courgettes and potatoes
const answers = [
...ctx.createAnswers(2, { answer: 'no', food: 'vegan' }),
...ctx.createAnswers(4, { answer: 'yes', food: 'vegan' }),
]
await ctx.setAnswersIn({ dir: 'guests', answers })
const { data } = await ctx.run('guests', 'happy-vegan-list.json')
return eq(data, {
potatoes: 4,
mushrooms: 4,
eggplants: 2,
courgettes: 2,
hummus: 2,
})
})
tests.push(async ({ eq, ctx }) => {
// test when vips answer { food: 'vegan' }
// should create a list with eggplants, mushrooms, hummus, courgettes and potatoes
const answers = ctx.createAnswers(6, { answer: 'yes', food: 'vegan' })
await ctx.setAnswersIn({ dir: 'guests', answers })
const { data } = await ctx.run('guests', 'happy-vegan-list.json')
return eq(data, {
potatoes: 6,
mushrooms: 6,
eggplants: 2,
courgettes: 2,
hummus: 2,
})
})
// 2) veggie but no vegan
tests.push(async ({ eq, ctx }) => {
// test when vips answer { food: 'veggie' }
// should create a list with eggplants, mushrooms, courgettes and potatoes
const answers = [
...ctx.createAnswers(2, { answer: 'no', food: 'veggie' }),
...ctx.createAnswers(4, { answer: 'yes', food: 'veggie' }),
]
await ctx.setAnswersIn({ dir: 'guests', answers })
const { data } = await ctx.run('guests', 'happy-veggie-list.json')
return eq(data, {
potatoes: 4,
mushrooms: 4,
eggplants: 2,
courgettes: 2,
hummus: 2,
})
})
tests.push(async ({ eq, ctx }) => {
// test when vips answer { food: 'veggie' }
// should create a list with eggplants, mushrooms, hummus, courgettes and potatoes
const answers = ctx.createAnswers(6, { answer: 'yes', food: 'veggie' })
await ctx.setAnswersIn({ dir: 'guests', answers })
const { data } = await ctx.run('guests', 'happy-veggie-list.json')
return eq(data, {
potatoes: 6,
mushrooms: 6,
eggplants: 2,
courgettes: 2,
hummus: 2,
})
})
// 3) both
tests.push(async ({ eq, ctx }) => {
// test when vips answer { food: 'vegan' } and { food: 'veggie' }
// should create a list with eggplants, mushrooms, courgettes and potatoes
const answers = [
...ctx.createAnswers(4, { answer: 'yes', food: 'vegan' }),
...ctx.createAnswers(2, { answer: 'yes', food: 'veggie' }),
]
await ctx.setAnswersIn({ dir: 'guests', answers })
const { data } = await ctx.run('guests', 'happy-vegg-list.json')
return eq(data, {
potatoes: 6,
mushrooms: 6,
eggplants: 2,
courgettes: 2,
hummus: 2,
})
})
tests.push(async ({ eq, ctx }) => {
// test when vips answer { food: 'vegan' } and { food: 'veggie' }
// should create a list with eggplants, mushrooms, hummus, courgettes and potatoes
const answers = [
...ctx.createAnswers(6, { answer: 'yes', food: 'vegan' }),
...ctx.createAnswers(1, { answer: 'yes', food: 'veggie' }),
]
await ctx.setAnswersIn({ dir: 'guests', answers })
const { data } = await ctx.run('guests', 'happy-vegg-list.json')
return eq(data, {
potatoes: 7,
mushrooms: 7,
eggplants: 3,
courgettes: 3,
hummus: 3,
})
})
// test with existing file
tests.push(async ({ eq, ctx }) => {
// test with an existing file
// should add elems to the existing list
await writeFile(
`${ctx.tmpPath}/old-happy-list.json`,
JSON.stringify({ candies: 2000 }),
)
const answers = ctx.createAnswers(1, { answer: 'yes', food: 'vegan' })
await ctx.setAnswersIn({ dir: 'guests', answers })
const { data } = await ctx.run('guests', 'old-happy-list.json')
return eq(data, {
candies: 2000,
potatoes: 1,
mushrooms: 1,
eggplants: 1,
courgettes: 1,
hummus: 1,
})
})
tests.push(async ({ eq, ctx }) => {
// test with an existing file
// should replace elems in the existing list (if already there)
await writeFile(
`${ctx.tmpPath}/old-happy-list.json`,
JSON.stringify({ candies: 2000, potatoes: 32 }),
)
const answers = ctx.createAnswers(1, { answer: 'yes', food: 'vegan' })
await ctx.setAnswersIn({ dir: 'guests', answers })
const { data } = await ctx.run('guests', 'old-happy-list.json')
return eq(data, {
candies: 2000,
potatoes: 1,
mushrooms: 1,
eggplants: 1,
courgettes: 1,
hummus: 1,
})
})
// test with a little bit of everything
tests.push(async ({ eq, ctx }) => {
// test with mix of everything
await writeFile(
`${ctx.tmpPath}/party.json`,
JSON.stringify({ 'super-gift': 1, balloons: 100, 'flower-bouquet': 7 }),
)
const answers = [
...ctx.createAnswers(7, { answer: 'no', food: 'vegan', drink: 'water' }),
...ctx.createAnswers(2, {
answer: 'yes',
food: 'carnivore',
drink: 'soft',
}),
...ctx.createAnswers(6, { answer: 'yes', food: 'vegan', drink: 'water' }),
...ctx.createAnswers(2, { answer: 'yes', food: 'veggie', drink: 'water' }),
...ctx.createAnswers(3, { answer: 'yes', food: 'veggie', drink: 'beer' }),
...ctx.createAnswers(11, { answer: 'yes', food: 'fish', drink: 'wine' }),
...ctx.createAnswers(4, {
answer: 'yes',
food: 'everything',
drink: 'beer',
}),
]
await ctx.setAnswersIn({ dir: 'guests', answers })
const { data } = await ctx.run('guests', 'party.json')
return eq(data, {
'super-gift': 1,
balloons: 100,
'flower-bouquet': 7,
potatoes: 28,
mushrooms: 11,
eggplants: 4,
courgettes: 4,
hummus: 4,
sardines: 11,
burgers: 2,
kebabs: 4,
'6-packs-beers': 2,
'wine-bottles': 3,
'water-bottles': 2,
'soft-bottles': 1,
})
})
Object.freeze(tests)