diff --git a/scripts/commands/generate-guides.js b/scripts/commands/generate-guides.js index 560bb9c6..2154c40d 100644 --- a/scripts/commands/generate-guides.js +++ b/scripts/commands/generate-guides.js @@ -1,8 +1,5 @@ -const { db, logger, file, parser } = require('../core') +const { db, logger, file, xml } = require('../core') const _ = require('lodash') -const dayjs = require('dayjs') -const utc = require('dayjs/plugin/utc') -dayjs.extend(utc) let channels = [] let programs = [] @@ -15,6 +12,7 @@ async function main() { await generateChannelsJson() await generateProgramsJson() + await generateEpgXML() } main() @@ -28,25 +26,23 @@ async function loadChannels() { let items = await db.channels.find({}).sort({ xmltv_id: 1 }) let output = {} - items.forEach(channel => { - if (!output[channel.xmltv_id]) { - const countryCode = channel.xmltv_id.split('.')[1] + items.forEach(item => { + if (!output[item.xmltv_id]) { + const countryCode = item.xmltv_id.split('.')[1] - output[channel.xmltv_id] = { - id: channel.xmltv_id, - name: [channel.name], - logo: channel.logo || null, - country: countryCode ? countryCode.toUpperCase() : null + output[item.xmltv_id] = { + id: item.xmltv_id, + name: [item.name], + logo: item.logo || null, + country: countryCode ? countryCode.toUpperCase() : null, + site: item.site } } else { - if (!output[channel.xmltv_id].logo && channel.logo) { - output[channel.xmltv_id].logo = channel.logo - } - - if (!output[channel.xmltv_id].name.includes(channel.name)) { - output[channel.xmltv_id].name.push(channel.name) - } + output[item.xmltv_id].logo = output[item.xmltv_id].logo || item.logo + output[item.xmltv_id].name.push(item.name) } + + output[item.xmltv_id].name = _.uniq(output[item.xmltv_id].name) }) return Object.values(output) @@ -103,132 +99,22 @@ async function loadPrograms() { async function generateChannelsJson() { logger.info('Generating channels.json...') - await file.create(`${PUBLIC_DIR}/api/channels.json`, JSON.stringify(channels, null, 2)) + await file.create(`${PUBLIC_DIR}/api/channels.json`, JSON.stringify(channels)) } async function generateProgramsJson() { logger.info('Generating programs.json...') - await file.create(`${PUBLIC_DIR}/api/programs.json`, JSON.stringify(programs, null, 2)) + await file.create(`${PUBLIC_DIR}/api/programs.json`, JSON.stringify(programs)) } -// async function generateGuideXML() { -// logger.info(`Generating guide.xml...`) +async function generateEpgXML() { + logger.info(`Generating epg.xml...`) -// const channels = Object.keys(programs) -// let items = await db.find({ xmltv_id: { $in: channels } }) -// items = _.sortBy(items, item => item.name) + const output = {} + const filteredChannels = Object.keys(programs) + output.channels = channels.filter(c => filteredChannels.includes(c.id)) + output.programs = _.flatten(Object.values(programs)) -// let buffer = {} -// items.forEach(item => { -// if (!buffer[item.xmltv_id]) { -// const countryCode = item.xmltv_id.split('.')[1] - -// buffer[item.xmltv_id] = { -// id: item.xmltv_id, -// display_name: [item.name], -// logo: item.logo || null, -// country: countryCode ? countryCode.toUpperCase() : null, -// site: `https://${programs[item.xmltv_id][0].site}` -// } -// } else { -// if (!buffer[item.xmltv_id].logo && item.logo) { -// buffer[item.xmltv_id].logo = item.logo -// } - -// if (!buffer[item.xmltv_id].display_name.includes(item.name)) { -// buffer[item.xmltv_id].display_name.push(item.name) -// } -// } -// }) - -// items = Object.values(buffer) - -// let outputProgs = [] -// for (let ip of Object.values(programs)) { -// outputProgs = outputProgs.concat(ip) -// } - -// const xml = convertToXMLTV({ channels: items, programs: outputProgs }) -// await file.write('./guide.xml', xml) -// } - -// function convertToXMLTV({ channels, programs }) { -// let output = `\r\n` -// for (let channel of channels) { -// output += `` -// channel.display_name.forEach(displayName => { -// output += `${escapeString(displayName)}` -// }) -// if (channel.logo) { -// const logo = escapeString(channel.logo) -// output += `` -// } -// output += `${channel.site}` -// output += `\r\n` -// } - -// for (let program of programs) { -// if (!program) continue - -// const start = program.start ? dayjs.unix(program.start).utc().format('YYYYMMDDHHmmss ZZ') : '' -// const stop = program.stop ? dayjs.unix(program.stop).utc().format('YYYYMMDDHHmmss ZZ') : '' -// const icon = escapeString(program.icon) - -// if (start && stop) { -// output += `` - -// program.title.forEach(title => { -// output += `${escapeString(title.value)}` -// }) - -// program.description.forEach(description => { -// output += `${escapeString(description.value)}` -// }) - -// program.categories.forEach(category => { -// output += `${escapeString(category.value)}` -// }) - -// program.icons.forEach(icon => { -// output += `` -// }) - -// output += '\r\n' -// } -// } - -// output += '' - -// return output -// } - -// function escapeString(string, defaultValue = '') { -// if (!string) return defaultValue - -// const regex = new RegExp( -// '((?:[\0-\x08\x0B\f\x0E-\x1F\uFFFD\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]))|([\\x7F-\\x84]|[\\x86-\\x9F]|[\\uFDD0-\\uFDEF]|(?:\\uD83F[\\uDFFE\\uDFFF])|(?:\\uD87F[\\uDF' + -// 'FE\\uDFFF])|(?:\\uD8BF[\\uDFFE\\uDFFF])|(?:\\uD8FF[\\uDFFE\\uDFFF])|(?:\\uD93F[\\uDFFE\\uD' + -// 'FFF])|(?:\\uD97F[\\uDFFE\\uDFFF])|(?:\\uD9BF[\\uDFFE\\uDFFF])|(?:\\uD9FF[\\uDFFE\\uDFFF])' + -// '|(?:\\uDA3F[\\uDFFE\\uDFFF])|(?:\\uDA7F[\\uDFFE\\uDFFF])|(?:\\uDABF[\\uDFFE\\uDFFF])|(?:\\' + -// 'uDAFF[\\uDFFE\\uDFFF])|(?:\\uDB3F[\\uDFFE\\uDFFF])|(?:\\uDB7F[\\uDFFE\\uDFFF])|(?:\\uDBBF' + -// '[\\uDFFE\\uDFFF])|(?:\\uDBFF[\\uDFFE\\uDFFF])(?:[\\0-\\t\\x0B\\f\\x0E-\\u2027\\u202A-\\uD7FF\\' + -// 'uE000-\\uFFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|' + -// '(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]))', -// 'g' -// ) - -// string = String(string || '').replace(regex, '') - -// return string -// .replace(/&/g, '&') -// .replace(//g, '>') -// .replace(/"/g, '"') -// .replace(/'/g, ''') -// .replace(/\n|\r/g, ' ') -// .replace(/ +/g, ' ') -// .trim() -// } + await file.create(`${PUBLIC_DIR}/guides/epg.xml`, xml.create(output)) +} diff --git a/scripts/commands/save-results.js b/scripts/commands/save-results.js index f86f880e..76349bef 100644 --- a/scripts/commands/save-results.js +++ b/scripts/commands/save-results.js @@ -4,7 +4,6 @@ const _ = require('lodash') const LOGS_DIR = process.env.LOGS_DIR || 'scripts/logs' async function main() { - db.programs.reset() const files = await file.list(`${LOGS_DIR}/load-cluster/cluster_*.log`) for (const filepath of files) { const results = await parser.parseLogs(filepath) diff --git a/scripts/core/file.js b/scripts/core/file.js index 56da4db9..bf1336a6 100644 --- a/scripts/core/file.js +++ b/scripts/core/file.js @@ -45,7 +45,7 @@ file.create = function (filepath, data = '') { } file.write = function (filepath, data = '') { - return fs.writeFile(path.resolve(filepath), data).catch(console.error) + return fs.writeFile(path.resolve(filepath), data, { encoding: 'utf8' }).catch(console.error) } file.clear = function (filepath) { diff --git a/scripts/core/index.js b/scripts/core/index.js index c1436174..aa4d5ead 100644 --- a/scripts/core/index.js +++ b/scripts/core/index.js @@ -3,3 +3,4 @@ exports.logger = require('./logger') exports.file = require('./file') exports.parser = require('./parser') exports.timer = require('./timer') +exports.xml = require('./xml') diff --git a/scripts/core/xml.js b/scripts/core/xml.js new file mode 100644 index 00000000..60542e4c --- /dev/null +++ b/scripts/core/xml.js @@ -0,0 +1,81 @@ +const dayjs = require('dayjs') +const utc = require('dayjs/plugin/utc') +dayjs.extend(utc) + +const xml = {} + +xml.create = function ({ channels, programs }) { + let output = `\n` + for (let channel of channels) { + output += `` + channel.name.forEach(name => { + output += `${escapeString(name)}` + }) + if (channel.logo) { + output += `` + } + if (channel.site) output += `https://${channel.site}` + output += `\n` + } + + for (let program of programs) { + const start = program.start ? dayjs.unix(program.start).utc().format('YYYYMMDDHHmmss ZZ') : '' + const stop = program.stop ? dayjs.unix(program.stop).utc().format('YYYYMMDDHHmmss ZZ') : '' + + if (start && stop) { + output += `` + + program.title.forEach(title => { + output += `${escapeString(title.value)}` + }) + + program.description.forEach(description => { + output += `${escapeString(description.value)}` + }) + + program.categories.forEach(category => { + output += `${escapeString(category.value)}` + }) + + if (program.image) output += `` + + output += '\n' + } + } + + output += '' + + return output +} + +module.exports = xml + +function escapeString(string, defaultValue = '') { + if (!string) return defaultValue + + const regex = new RegExp( + '((?:[\0-\x08\x0B\f\x0E-\x1F\uFFFD\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]))|([\\x7F-\\x84]|[\\x86-\\x9F]|[\\uFDD0-\\uFDEF]|(?:\\uD83F[\\uDFFE\\uDFFF])|(?:\\uD87F[\\uDF' + + 'FE\\uDFFF])|(?:\\uD8BF[\\uDFFE\\uDFFF])|(?:\\uD8FF[\\uDFFE\\uDFFF])|(?:\\uD93F[\\uDFFE\\uD' + + 'FFF])|(?:\\uD97F[\\uDFFE\\uDFFF])|(?:\\uD9BF[\\uDFFE\\uDFFF])|(?:\\uD9FF[\\uDFFE\\uDFFF])' + + '|(?:\\uDA3F[\\uDFFE\\uDFFF])|(?:\\uDA7F[\\uDFFE\\uDFFF])|(?:\\uDABF[\\uDFFE\\uDFFF])|(?:\\' + + 'uDAFF[\\uDFFE\\uDFFF])|(?:\\uDB3F[\\uDFFE\\uDFFF])|(?:\\uDB7F[\\uDFFE\\uDFFF])|(?:\\uDBBF' + + '[\\uDFFE\\uDFFF])|(?:\\uDBFF[\\uDFFE\\uDFFF])(?:[\\0-\\t\\x0B\\f\\x0E-\\u2027\\u202A-\\uD7FF\\' + + 'uE000-\\uFFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|' + + '(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]))', + 'g' + ) + + string = String(string || '').replace(regex, '') + + return string + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, ''') + .replace(/\n|\r/g, ' ') + .replace(/ +/g, ' ') + .trim() +} diff --git a/tests/__data__/expected/api/channels.json b/tests/__data__/expected/api/channels.json new file mode 100644 index 00000000..734877e5 --- /dev/null +++ b/tests/__data__/expected/api/channels.json @@ -0,0 +1 @@ +[{"id":"AndorraTV.ad","name":["Andorra TV"],"logo":null,"country":"AD","site":"andorradifusio.ad"}] \ No newline at end of file diff --git a/tests/__data__/expected/api/programs.json b/tests/__data__/expected/api/programs.json new file mode 100644 index 00000000..8feeed53 --- /dev/null +++ b/tests/__data__/expected/api/programs.json @@ -0,0 +1 @@ +{"AndorraTV.ad":[{"channel":"AndorraTV.ad","title":[{"lang":"ca","value":"InfoNeu "}],"description":[],"categories":[],"image":null,"start":1641711600,"stop":1641715200},{"channel":"AndorraTV.ad","title":[{"lang":"ca","value":"Club Piolet"}],"description":[],"categories":[],"image":null,"start":1641715200,"stop":1641718800},{"channel":"AndorraTV.ad","title":[{"lang":"ca","value":"InfoNeu "}],"description":[],"categories":[],"image":null,"start":1641718800,"stop":1641729600},{"channel":"AndorraTV.ad","title":[{"lang":"ca","value":"Andorra Actualitat (RNA)"}],"description":[],"categories":[],"image":null,"start":1641729600,"stop":1641730800},{"channel":"AndorraTV.ad","title":[{"lang":"ca","value":"El Trànsit"}],"description":[],"categories":[],"image":null,"start":1641730800,"stop":1641732000},{"channel":"AndorraTV.ad","title":[{"lang":"ca","value":"El Trànsit"}],"description":[],"categories":[],"image":null,"start":1641732000,"stop":1641732300},{"channel":"AndorraTV.ad","title":[{"lang":"ca","value":"Informatiu migdia"}],"description":[],"categories":[],"image":null,"start":1641732300,"stop":1641733800},{"channel":"AndorraTV.ad","title":[{"lang":"ca","value":"El Trànsit"}],"description":[],"categories":[],"image":null,"start":1641733800,"stop":1641736200},{"channel":"AndorraTV.ad","title":[{"lang":"ca","value":"La Terre vue du Sport"}],"description":[],"categories":[],"image":null,"start":1641736200,"stop":1641736800},{"channel":"AndorraTV.ad","title":[{"lang":"ca","value":"Informatiu migdia"}],"description":[],"categories":[],"image":null,"start":1641736800,"stop":1641738300},{"channel":"AndorraTV.ad","title":[{"lang":"ca","value":"Club Piolet"}],"description":[],"categories":[],"image":null,"start":1641738300,"stop":1641741900},{"channel":"AndorraTV.ad","title":[{"lang":"ca","value":"Informatiu migdia"}],"description":[],"categories":[],"image":null,"start":1641741900,"stop":1641743400},{"channel":"AndorraTV.ad","title":[{"lang":"ca","value":"El Trànsit"}],"description":[],"categories":[],"image":null,"start":1641743400,"stop":1641750900},{"channel":"AndorraTV.ad","title":[{"lang":"ca","value":"La rotonda"}],"description":[],"categories":[],"image":null,"start":1641750900,"stop":1641753600},{"channel":"AndorraTV.ad","title":[{"lang":"ca","value":"Club Piolet"}],"description":[],"categories":[],"image":null,"start":1641753600,"stop":1641757200},{"channel":"AndorraTV.ad","title":[{"lang":"ca","value":"El Trànsit"}],"description":[],"categories":[],"image":null,"start":1641757200,"stop":1641757500},{"channel":"AndorraTV.ad","title":[{"lang":"ca","value":"Informatiu vespre"}],"description":[],"categories":[],"image":null,"start":1641757500,"stop":1641759000},{"channel":"AndorraTV.ad","title":[{"lang":"ca","value":"Recull setmanal"}],"description":[],"categories":[],"image":null,"start":1641759000,"stop":1641761100},{"channel":"AndorraTV.ad","title":[{"lang":"ca","value":"Memòries d'arxiu: 10 anys d'ATV"}],"description":[],"categories":[],"image":null,"start":1641761100,"stop":1641763800},{"channel":"AndorraTV.ad","title":[{"lang":"ca","value":"El cafè dels matins"}],"description":[],"categories":[],"image":null,"start":1641763800,"stop":1641766800},{"channel":"AndorraTV.ad","title":[{"lang":"ca","value":"La Terre vue du Sport"}],"description":[],"categories":[],"image":null,"start":1641766800,"stop":1641767400},{"channel":"AndorraTV.ad","title":[{"lang":"ca","value":"Informatiu vespre"}],"description":[],"categories":[],"image":null,"start":1641767400,"stop":1641772800},{"channel":"AndorraTV.ad","title":[{"lang":"ca","value":"Àrea Andorra Difusió"}],"description":[],"categories":[],"image":null,"start":1641772800,"stop":1641776400}]} \ No newline at end of file diff --git a/tests/__data__/expected/guides/epg.xml b/tests/__data__/expected/guides/epg.xml new file mode 100644 index 00000000..74b292d3 --- /dev/null +++ b/tests/__data__/expected/guides/epg.xml @@ -0,0 +1,26 @@ + +Andorra TVhttps://andorradifusio.ad +InfoNeu +Club Piolet +InfoNeu +Andorra Actualitat (RNA) +El Trànsit +El Trànsit +Informatiu migdia +El Trànsit +La Terre vue du Sport +Informatiu migdia +Club Piolet +Informatiu migdia +El Trànsit +La rotonda +Club Piolet +El Trànsit +Informatiu vespre +Recull setmanal +Memòries d'arxiu: 10 anys d'ATV +El cafè dels matins +La Terre vue du Sport +Informatiu vespre +Àrea Andorra Difusió + \ No newline at end of file diff --git a/tests/commands/create-database.test.js b/tests/commands/create-database.test.js index ba0804e5..72097a8a 100644 --- a/tests/commands/create-database.test.js +++ b/tests/commands/create-database.test.js @@ -5,26 +5,32 @@ const { execSync } = require('child_process') beforeEach(() => { fs.rmdirSync('tests/__data__/output', { recursive: true }) fs.mkdirSync('tests/__data__/output') -}) -it('can create channels database', () => { - const results = execSync( + execSync( 'DB_DIR=tests/__data__/output/database node scripts/commands/create-database.js --channels=tests/__data__/input/site.channels.xml --max-clusters=1', { encoding: 'utf8' } ) +}) - const database = fs.readFileSync(path.resolve('tests/__data__/output/database/channels.db'), { - encoding: 'utf8' - }) - const item = database.split('\n').find(i => i.includes('AndorraTV.ad')) - expect(JSON.parse(item)).toMatchObject({ - name: 'Andorra TV', +it('can create channels database', () => { + const output = content('tests/__data__/output/database/channels.db') + + expect(output).toMatchObject({ lang: 'ca', xmltv_id: 'AndorraTV.ad', site_id: 'atv', + name: 'Andorra TV', site: 'andorradifusio.ad', channelsPath: 'tests/__data__/input/site.channels.xml', configPath: 'tests/__data__/input/andorradifusio.ad.config.js', cluster_id: 1 }) }) + +function content(filepath) { + const data = fs.readFileSync(path.resolve(filepath), { + encoding: 'utf8' + }) + + return JSON.parse(data) +} diff --git a/tests/commands/create-matrix.test.js b/tests/commands/create-matrix.test.js index 2f79ddb7..34a6405e 100644 --- a/tests/commands/create-matrix.test.js +++ b/tests/commands/create-matrix.test.js @@ -5,17 +5,15 @@ const { execSync } = require('child_process') beforeEach(() => { fs.rmdirSync('tests/__data__/output', { recursive: true }) fs.mkdirSync('tests/__data__/output') - fs.copyFileSync('tests/__data__/input/channels.db', 'tests/__data__/temp/channels.db') -}) - -afterEach(() => { - fs.rmdirSync('tests/__data__/temp', { recursive: true }) - fs.mkdirSync('tests/__data__/temp') }) it('can create valid matrix', () => { - const result = execSync('DB_DIR=tests/__data__/temp node scripts/commands/create-matrix.js', { - encoding: 'utf8' - }) + const result = execSync( + 'DB_DIR=tests/__data__/input/database node scripts/commands/create-matrix.js', + { + encoding: 'utf8' + } + ) + expect(result).toBe('::set-output name=matrix::{"cluster_id":[1]}\n') }) diff --git a/tests/commands/generate-guides.test.js b/tests/commands/generate-guides.test.js index 0dc6c2ed..d89c1899 100644 --- a/tests/commands/generate-guides.test.js +++ b/tests/commands/generate-guides.test.js @@ -5,47 +5,38 @@ const { execSync } = require('child_process') beforeEach(() => { fs.rmdirSync('tests/__data__/output', { recursive: true }) fs.mkdirSync('tests/__data__/output') - fs.mkdirSync('tests/__data__/output/api') + + execSync( + 'PUBLIC_DIR=tests/__data__/output DB_DIR=tests/__data__/input/database node scripts/commands/generate-guides.js', + { encoding: 'utf8' } + ) }) it('can generate channels.json', () => { - const result = execSync( - 'PUBLIC_DIR=tests/__data__/output DB_DIR=tests/__data__/input/database node scripts/commands/generate-guides.js', - { encoding: 'utf8' } - ) - const json = fs.readFileSync(path.resolve('tests/__data__/output/api/channels.json'), { - encoding: 'utf8' - }) - const parsed = JSON.parse(json) - expect(parsed[0]).toMatchObject({ - id: 'AndorraTV.ad', - name: ['Andorra TV'], - logo: null, - country: 'AD' - }) + const output = content('tests/__data__/output/api/channels.json') + const expected = content('tests/__data__/expected/api/channels.json') + + expect(output).toBe(expected) }) it('can generate programs.json', () => { - const result = execSync( - 'PUBLIC_DIR=tests/__data__/output DB_DIR=tests/__data__/input/database node scripts/commands/generate-guides.js', - { encoding: 'utf8' } - ) - const json = fs.readFileSync(path.resolve('tests/__data__/output/api/programs.json'), { + const output = content('tests/__data__/output/api/programs.json') + const expected = content('tests/__data__/expected/api/programs.json') + + expect(output).toBe(expected) +}) + +it('can generate epg.xml', () => { + const output = content('tests/__data__/output/guides/epg.xml') + const expected = content('tests/__data__/expected/guides/epg.xml') + + expect(output).toBe(expected) +}) + +function content(filepath) { + const data = fs.readFileSync(path.resolve(filepath), { encoding: 'utf8' }) - const parsed = JSON.parse(json) - const program = parsed['AndorraTV.ad'][0] - expect(Object.keys(program).sort()).toEqual([ - 'categories', - 'channel', - 'description', - 'image', - 'start', - 'stop', - 'title' - ]) - expect(Array.isArray(program.title)).toBe(true) - expect(Array.isArray(program.description)).toBe(true) - expect(Array.isArray(program.categories)).toBe(true) - expect(program.image === null || typeof program.image === 'string').toBe(true) -}) + + return JSON.stringify(data) +} diff --git a/tests/commands/load-cluster.test.js b/tests/commands/load-cluster.test.js index f9c42279..4449f3c0 100644 --- a/tests/commands/load-cluster.test.js +++ b/tests/commands/load-cluster.test.js @@ -5,20 +5,22 @@ const { execSync } = require('child_process') beforeEach(() => { fs.rmdirSync('tests/__data__/output', { recursive: true }) fs.mkdirSync('tests/__data__/output') -}) -it('can load cluster', () => { - const result = execSync( + execSync( 'DB_DIR=tests/__data__/input/database LOGS_DIR=tests/__data__/output/logs node scripts/commands/load-cluster.js --cluster-id=1', { encoding: 'utf8' } ) - const logs = fs.readFileSync( +}) + +it('can load cluster', () => { + const output = fs.readFileSync( path.resolve('tests/__data__/output/logs/load-cluster/cluster_1.log'), { encoding: 'utf8' } ) - const lines = logs.split('\n') + const lines = output.split('\n') const parsed = JSON.parse(lines[0]) + expect(parsed._id).toBe('K1kaxwsWVjsRIZL6') }) diff --git a/tests/commands/save-results.test.js b/tests/commands/save-results.test.js index 4e716ce8..5f85ce5e 100644 --- a/tests/commands/save-results.test.js +++ b/tests/commands/save-results.test.js @@ -5,20 +5,20 @@ const { execSync } = require('child_process') beforeEach(() => { fs.rmdirSync('tests/__data__/output', { recursive: true }) fs.mkdirSync('tests/__data__/output') - fs.mkdirSync('tests/__data__/output/database') - fs.copyFileSync('tests/__data__/input/programs.db', 'tests/__data__/output/database/programs.db') -}) -it('can save results', () => { - const result = execSync( + execSync( 'DB_DIR=tests/__data__/output/database LOGS_PATH=tests/__data__/input/logs node scripts/commands/save-results.js', { encoding: 'utf8' } ) - const logs = fs.readFileSync(path.resolve('tests/__data__/output/database/programs.db'), { +}) + +it('can save results', () => { + const output = fs.readFileSync(path.resolve('tests/__data__/output/database/programs.db'), { encoding: 'utf8' }) - const lines = logs.split('\n') + const lines = output.split('\n') const parsed = JSON.parse(lines[0]) + expect(Object.keys(parsed).sort()).toEqual([ '_id', 'category',