Application almost done
Some checks failed
continuous-integration/appveyor/branch AppVeyor build failed

This commit is contained in:
Jonatan Nilsson 2022-01-27 18:25:33 +00:00
parent a16a04a91f
commit f008af597d
11 changed files with 536 additions and 27 deletions

2
.gitignore vendored
View file

@ -108,6 +108,4 @@ db.json
package-lock.json package-lock.json
daemon daemon
app/*
manage/*
dev/public/main.js dev/public/main.js

View file

@ -13,6 +13,7 @@ export default class Application extends EventEmitter {
Object.assign(this, { Object.assign(this, {
setInterval: opts.setInterval || setInterval, setInterval: opts.setInterval || setInterval,
fs: opts.fs || fs,
}) })
this.db.addApplication(name) this.db.addApplication(name)
@ -35,6 +36,7 @@ export default class Application extends EventEmitter {
updateLog(message) { updateLog(message) {
this.db.data.core[this.name].updater += message this.db.data.core[this.name].updater += message
this.db.log.info(message) this.db.log.info(message)
return message
} }
async update() { async update() {
@ -42,28 +44,127 @@ export default class Application extends EventEmitter {
this.updating = true this.updating = true
this.db.data.core[this.name].updater = '' this.db.data.core[this.name].updater = ''
let cleanup = true
let folder = ''
let log = ''
let latest = null
try { try {
this.updateLog(`Checking for latest version at ${new Date().toISOString().replace('T', ' ').split('.')[0]}. `) log += this.updateLog(`Checking for latest version at ${new Date().toISOString().replace('T', ' ').split('.')[0]}. `) + '\n'
let latest = await this.provider.getLatestVersion() latest = await this.provider.getLatestVersion()
this.updateLog(`Found ${latest.version}. `) log += this.updateLog(`Found ${latest.version}. `) + '\n'
if (this.db.data.core[this.name].latestInstalled === latest.version) { if (this.db.data.core[this.name].latestInstalled === latest.version) {
this.updateLog('Already up to date, nothing to do. ') this.updateLog('Already up to date, nothing to do. ')
this.updating = false
return
}
latest.id = latest.version
var found = this.db.get(this.db.data.core[this.name].versions, latest.id)
if (found) {
Object.keys(latest).forEach(function(key) {
found[key] = latest[key]
})
latest = found
log = latest.log + log
} else {
this.db.upsert(this.db.data.core[this.name].versions, latest)
}
if (latest.failtodownload && latest.failtodownload > 3) {
this.updateLog('Version failed to download too many times, skipping this version. ')
this.updating = false
return
}
if (latest.failtoinstall && latest.failtoinstall > 3) {
this.updateLog('Version failed to install too many times, skipping this version. ')
this.updating = false
return return
} }
let target = this.util.getPathFromRoot(`./${this.name}/${latest.version}/file${this.util.getExtension(latest.filename)}`) let target = this.util.getPathFromRoot(`./${this.name}/${latest.version}/file${this.util.getExtension(latest.filename)}`)
folder = this.util.getPathFromRoot(`./${this.name}/${latest.version}`)
await fs.mkdir(this.util.getPathFromRoot(`./${this.name}/${latest.version}`), { recursive: true }) await this.fs.mkdir(folder, { recursive: true })
this.updateLog(`Downloading ${latest.link} to ${target}. `) log += this.updateLog(`Downloading ${latest.link} to ${target}. `) + '\n'
await this.provider.downloadVersion(latest, target) await this.provider.downloadVersion(latest, target)
.catch(function(err) {
latest.failtodownload = (latest.failtodownload || 0) + 1
return Promise.reject(err)
})
log += '\n' + this.updateLog(`Extracting ${target}. `) + '\n'
await this.util.extractFile(target, function(msg) {
log += msg
}).catch(function(err) {
latest.failtodownload = (latest.failtodownload || 0) + 1
return Promise.reject(err)
})
if (!log.endsWith('\n')) {
log += '\n'
}
if (!log.endsWith('\n\n')) {
log += '\n'
}
await this.fs.stat(this.util.getPathFromRoot(`./${this.name}/${latest.version}/index.mjs`))
.catch((err) => {
latest.failtodownload = (latest.failtodownload || 0) + 1
log += this.updateLog('Version did not include or was missing index.mjs. ') + '\n'
return Promise.reject(err)
})
cleanup = false
let packageStat = await this.fs.stat(this.util.getPathFromRoot(`./${this.name}/${latest.version}/package.json`))
.catch(function() { return null })
if (packageStat) {
log += this.updateLog(`running npm install --production. `) + '\n'
await this.util.runCommand(
'npm.cmd',
['install', '--production', '--no-optional', '--no-package-lock', '--no-audit', '--loglevel=notice'],
folder,
function(msg) {
log += msg
}
).catch(function(err) {
latest.failtoinstall = (latest.failtoinstall || 0) + 1
return Promise.reject(err)
})
if (!log.endsWith('\n')) {
log += '\n'
}
if (!log.endsWith('\n\n')) {
log += '\n'
}
} else {
log += this.updateLog('Release did not contain package.json, skipping npm install. ') + '\n'
}
} catch (err) { } catch (err) {
this.updating = false this.updating = false
log += this.updateLog(`Error: ${err.message}. `) + '\n'
if (folder && cleanup) {
await this.fs.rm(folder, { force: true, recursive: true }).catch((err) => {
this.updateLog(`Error while cleaning up: ${err.message}. `)
})
}
if (latest) {
latest.log = log
}
return Promise.reject(err) return Promise.reject(err)
} }
log += this.updateLog(`Finished updating ${this.name} to version ${latest.version}.`) + '\n'
this.db.data.core[this.name].latestInstalled = latest.version
latest.log = log
this.updating = false
} }
} }

View file

@ -48,8 +48,9 @@ export default function GetDB(config, log, orgFilename = 'db.json') {
col[i] = item col[i] = item
return return
} }
} } else {
item[db.id] = db.createId(col) item[db.id] = db.createId(col)
}
col.push(item) col.push(item)
} }

View file

@ -32,6 +32,7 @@ export default class GitProvider {
version: item.name, version: item.name,
link: asset.browser_download_url, link: asset.browser_download_url,
filename: asset.name, filename: asset.name,
description: item.body,
log: '', log: '',
} }
} }

View file

@ -70,19 +70,25 @@ export default class Util {
runCommand(command, options = [], folder = null, stream = function() {}) { runCommand(command, options = [], folder = null, stream = function() {}) {
return new Promise(function(res, rej) { return new Promise(function(res, rej) {
stream(`[Command] ${folder ? folder : ''}${command} ${options.join(' ')}\n`) let fullcommand = path.join(folder ? folder : '', command)
if (command.indexOf('/') >= 0 || command.indexOf('\\') >= 0) {
fullcommand = command
}
stream(`[Command] ${fullcommand} ${options.join(' ')}\n`)
let processor = spawn(command, options, { let processor = spawn(command, options, {
shell: true, shell: true,
cwd: folder, cwd: folder,
}) })
let timeOuter = setInterval(function() { let timeOuter = setInterval(function() {
try {
processor.stdin.write('n\n') processor.stdin.write('n\n')
} catch {}
}, 250) }, 250)
processor.stdout.on('data', function(data) { processor.stdout.on('data', function(data) {
stream(data.toString()) stream(data.toString().replace(/\r\n/g, '\n'))
}) })
processor.stderr.on('data', function(data) { processor.stderr.on('data', function(data) {
stream(data.toString()) stream(data.toString().replace(/\r\n/g, '\n'))
}) })
processor.on('error', function(err) { processor.on('error', function(err) {
clearInterval(timeOuter) clearInterval(timeOuter)

View file

@ -13,6 +13,7 @@
"patterns": [ "patterns": [
"{core,test}/*" "{core,test}/*"
], ],
"ignore": "test/testapp",
"extensions": "js,mjs", "extensions": "js,mjs",
"quiet": true, "quiet": true,
"inherit": true "inherit": true

View file

@ -0,0 +1,46 @@
import { Eltro as t, assert, stub } from 'eltro'
import fs from 'fs/promises'
import lowdb from '../core/db.mjs'
import Application from '../core/application.mjs'
import GitProvider from '../core/providers/git.mjs'
import Util from '../core/util.mjs'
const util = new Util(import.meta.url)
const logger = {
info: stub(),
warn: stub(),
error: stub(),
}
t.timeout(10000).describe('Application update integration test', function() {
let db
let app
let provider
t.before(function() {
return lowdb({ test: { } }, logger, util.getPathFromRoot('./db_test.json')).then(function(res) {
db = res
provider = new GitProvider({ url: 'https://git.nfp.is/api/v1/repos/thething/sc-helloworld/releases' })
app = new Application(util, db, provider, 'testapp')
return provider.getLatestVersion()
}).then(function(version) {
return fs.rm(`./test/testapp/${version.version}`, { force: true, recursive: true })
})
})
t.after(function() {
if (db.data.core.testapp.versions.length) {
return fs.rm(`./test/testapp/${db.data.core.testapp.versions[0].id}`, { force: true, recursive: true })
}
})
t.test('should run update and install correctly', async function(){
await app.update()
assert.ok(db.data.core.testapp.latestInstalled)
await fs.stat(util.getPathFromRoot(`./testapp/${db.data.core.testapp.latestInstalled}/index.mjs`))
await fs.stat(util.getPathFromRoot(`./testapp/${db.data.core.testapp.latestInstalled}/package.json`))
await fs.stat(util.getPathFromRoot(`./testapp/${db.data.core.testapp.latestInstalled}/node_modules`))
})
})

View file

@ -7,7 +7,7 @@ import Util from '../core/util.mjs'
const util = new Util(import.meta.url) const util = new Util(import.meta.url)
var logger = { const logger = {
info: stub(), info: stub(),
warn: stub(), warn: stub(),
error: stub(), error: stub(),
@ -163,12 +163,36 @@ t.timeout(250).describe('#update()', function() {
let db let db
let app let app
let provider let provider
let stubExtract
let stubRunCommand
let stubWrite
let stubFsMkdir
let stubFsRm
let stubFsStat
t.beforeEach(function() { t.beforeEach(function() {
util.extractFile = stubExtract = stub()
util.runCommand = stubRunCommand = stub()
stubExtract.resolves()
stubRunCommand.resolves()
return lowdb({ test: { } }, logger, null).then(function(res) { return lowdb({ test: { } }, logger, null).then(function(res) {
db = res db = res
db.write = stubWrite = stub()
provider = createProvider() provider = createProvider()
app = new Application(util, db, provider, 'testapp') app = new Application(util, db, provider, 'testapp', {
fs: {
mkdir: stubFsMkdir = stub(),
rm: stubFsRm = stub(),
stat: stubFsStat = stub(),
},
})
stubFsMkdir.resolves()
stubFsRm.resolves()
stubFsStat.resolves({})
provider.downloadVersion.resolves()
provider.getLatestVersion.resolves({ version: '123456789', link: 'httplinkhere', filename: 'test.7z' })
}) })
}) })
@ -203,12 +227,13 @@ t.timeout(250).describe('#update()', function() {
db.data.core.testapp.updater = '' db.data.core.testapp.updater = ''
let err = await assert.isRejected(app.update()) let err = await assert.isRejected(app.update())
assert.strictEqual(err, assertError)
assert.strictEqual(app.updating, false)
assert.strictEqual(app.updating, false)
assert.strictEqual(err, assertError)
assert.match(db.data.core.testapp.updater, /check/i) assert.match(db.data.core.testapp.updater, /check/i)
assert.match(db.data.core.testapp.updater, /version/i) assert.match(db.data.core.testapp.updater, /version/i)
assert.match(db.data.core.testapp.updater, new RegExp(new Date().toISOString().split('T')[0])) assert.match(db.data.core.testapp.updater, new RegExp(new Date().toISOString().split('T')[0]))
assert.match(db.data.core.testapp.updater, new RegExp(assertError.message))
}) })
t.test('should call provider download latest correctly if new 7zip version', async function() { t.test('should call provider download latest correctly if new 7zip version', async function() {
@ -216,17 +241,16 @@ t.timeout(250).describe('#update()', function() {
const assertLink = 'All of you' const assertLink = 'All of you'
const assertVersion = { version: '123456789', link: assertLink, filename: 'test.7z' } const assertVersion = { version: '123456789', link: assertLink, filename: 'test.7z' }
const assertTarget = util.getPathFromRoot('./testapp/123456789/file.7z') const assertTarget = util.getPathFromRoot('./testapp/123456789/file.7z')
assert.strictEqual(db.data.core.testapp.versions.length, 0)
await assert.isRejected(fs.stat('./test/testapp/123456789'))
provider.getLatestVersion.resolves(assertVersion) provider.getLatestVersion.resolves(assertVersion)
provider.downloadVersion.rejects(assertError) provider.downloadVersion.rejects(assertError)
db.data.core.testapp.updater = '' db.data.core.testapp.updater = ''
let err = await assert.isRejected(app.update()) let err = await assert.isRejected(app.update())
assert.strictEqual(err, assertError)
assert.strictEqual(app.updating, false)
assert.strictEqual(app.updating, false)
assert.strictEqual(err, assertError)
assert.match(db.data.core.testapp.updater, /found/i) assert.match(db.data.core.testapp.updater, /found/i)
assert.match(db.data.core.testapp.updater, new RegExp(assertVersion.version)) assert.match(db.data.core.testapp.updater, new RegExp(assertVersion.version))
assert.match(db.data.core.testapp.updater, /downloading/i) assert.match(db.data.core.testapp.updater, /downloading/i)
@ -234,8 +258,29 @@ t.timeout(250).describe('#update()', function() {
assert.match(db.data.core.testapp.updater, new RegExp(assertTarget.replace(/\\/g, '\\\\'))) assert.match(db.data.core.testapp.updater, new RegExp(assertTarget.replace(/\\/g, '\\\\')))
assert.strictEqual(provider.downloadVersion.firstCall[0], assertVersion) assert.strictEqual(provider.downloadVersion.firstCall[0], assertVersion)
assert.strictEqual(provider.downloadVersion.firstCall[1], assertTarget) assert.strictEqual(provider.downloadVersion.firstCall[1], assertTarget)
assert.match(db.data.core.testapp.updater, new RegExp(assertError.message))
await fs.stat('./test/testapp/123456789') assert.strictEqual(db.data.core.testapp.versions.length, 1)
assert.strictEqual(db.data.core.testapp.versions[0], assertVersion)
assert.ok(assertVersion.log)
assert.match(assertVersion.log, /\. \n/)
assert.match(assertVersion.log, new RegExp(assertError.message))
assert.ok(assertVersion.log.endsWith('\n'))
assert.strictEqual(assertVersion.failtodownload, 1)
assert.ok(stubFsMkdir.called)
assert.match(stubFsMkdir.firstCall[0], /123456789/)
assert.ok(stubFsMkdir.firstCall[1]?.recursive)
// Test if subsequent calls increment counter
err = await assert.isRejected(app.update())
assert.strictEqual(app.updating, false)
assert.strictEqual(err, assertError)
assert.strictEqual(db.data.core.testapp.versions.length, 1)
assert.strictEqual(db.data.core.testapp.versions[0], assertVersion)
assert.strictEqual(assertVersion.failtodownload, 2)
}) })
t.test('should call provider download latest correctly if new 7zip version', async function() { t.test('should call provider download latest correctly if new 7zip version', async function() {
@ -243,17 +288,16 @@ t.timeout(250).describe('#update()', function() {
const assertLink = 'All of you' const assertLink = 'All of you'
const assertVersion = { version: '123456789', link: assertLink, filename: 'test.7z' } const assertVersion = { version: '123456789', link: assertLink, filename: 'test.7z' }
const assertTarget = util.getPathFromRoot('./testapp/123456789/file.7z') const assertTarget = util.getPathFromRoot('./testapp/123456789/file.7z')
assert.strictEqual(db.data.core.testapp.versions.length, 0)
await assert.isRejected(fs.stat('./test/testapp/123456789'))
provider.getLatestVersion.resolves(assertVersion) provider.getLatestVersion.resolves(assertVersion)
provider.downloadVersion.rejects(assertError) provider.downloadVersion.rejects(assertError)
db.data.core.testapp.updater = '' db.data.core.testapp.updater = ''
let err = await assert.isRejected(app.update()) let err = await assert.isRejected(app.update())
assert.strictEqual(err, assertError)
assert.strictEqual(app.updating, false)
assert.strictEqual(app.updating, false)
assert.strictEqual(err, assertError)
assert.match(db.data.core.testapp.updater, /found/i) assert.match(db.data.core.testapp.updater, /found/i)
assert.match(db.data.core.testapp.updater, new RegExp(assertVersion.version)) assert.match(db.data.core.testapp.updater, new RegExp(assertVersion.version))
assert.match(db.data.core.testapp.updater, /downloading/i) assert.match(db.data.core.testapp.updater, /downloading/i)
@ -261,8 +305,265 @@ t.timeout(250).describe('#update()', function() {
assert.match(db.data.core.testapp.updater, new RegExp(assertTarget.replace(/\\/g, '\\\\'))) assert.match(db.data.core.testapp.updater, new RegExp(assertTarget.replace(/\\/g, '\\\\')))
assert.strictEqual(provider.downloadVersion.firstCall[0], assertVersion) assert.strictEqual(provider.downloadVersion.firstCall[0], assertVersion)
assert.strictEqual(provider.downloadVersion.firstCall[1], assertTarget) assert.strictEqual(provider.downloadVersion.firstCall[1], assertTarget)
assert.match(db.data.core.testapp.updater, new RegExp(assertError.message))
await fs.stat('./test/testapp/123456789') assert.strictEqual(db.data.core.testapp.versions.length, 1)
assert.strictEqual(db.data.core.testapp.versions[0], assertVersion)
assert.ok(assertVersion.log)
assert.match(assertVersion.log, /\. \n/)
assert.match(assertVersion.log, new RegExp(assertError.message))
assert.ok(assertVersion.log.endsWith('\n'))
assert.strictEqual(assertVersion.failtodownload, 1)
assert.ok(stubFsRm.called)
assert.match(stubFsRm.firstCall[0], /123456789/)
assert.ok(stubFsRm.firstCall[1]?.recursive)
assert.ok(stubFsRm.firstCall[1]?.force)
// Test if subsequent calls increment counter
err = await assert.isRejected(app.update())
assert.strictEqual(app.updating, false)
assert.strictEqual(err, assertError)
assert.strictEqual(db.data.core.testapp.versions.length, 1)
assert.strictEqual(db.data.core.testapp.versions[0], assertVersion)
assert.strictEqual(assertVersion.failtodownload, 2)
})
t.test('should call extract on util correctly', async function() {
const assertExtractText = 'Reverdations of Success'
const assertError = new Error('Dai Gekisen')
const assertTarget = util.getPathFromRoot('./testapp/123456789/file.7z')
stubExtract.returnWith(function(target, stream) {
stream(assertExtractText)
return Promise.reject(assertError)
})
assert.strictEqual(db.data.core.testapp.versions.length, 0)
let err = await assert.isRejected(app.update())
assert.strictEqual(app.updating, false)
assert.strictEqual(err, assertError)
assert.strictEqual(app.updating, false)
assert.strictEqual(stubExtract.firstCall[0], assertTarget)
assert.notOk(stubWrite.called)
assert.match(db.data.core.testapp.updater, new RegExp('extracting[^.]+file\.7z', 'i'))
assert.match(db.data.core.testapp.updater, new RegExp(assertError.message))
assert.ok(stubFsRm.called)
assert.match(stubFsRm.firstCall[0], /123456789/)
assert.ok(stubFsRm.firstCall[1]?.recursive)
assert.ok(stubFsRm.firstCall[1]?.force)
assert.strictEqual(db.data.core.testapp.versions.length, 1)
let version = db.data.core.testapp.versions[0]
assert.ok(version.log)
assert.match(version.log, /\. \n/)
assert.match(version.log, new RegExp('extracting[^.]+file\.7z', 'i'))
assert.match(version.log, new RegExp(assertError.message))
assert.match(version.log, new RegExp(assertExtractText))
assert.ok(version.log.endsWith('\n'))
assert.strictEqual(version.failtodownload, 1)
// Test if subsequent calls increment counter
err = await assert.isRejected(app.update())
assert.strictEqual(app.updating, false)
assert.strictEqual(err, assertError)
assert.strictEqual(db.data.core.testapp.versions.length, 1)
assert.strictEqual(db.data.core.testapp.versions[0], version)
assert.strictEqual(version.failtodownload, 2)
})
t.test('should not call npm install if stat fails to find index.mjs', async function() {
const assertError = new Error('File not found')
const assertTarget = util.getPathFromRoot('./testapp/123456789/index.mjs')
stubRunCommand.rejects(new Error('should not be seen'))
stubFsStat.rejects(assertError)
assert.strictEqual(db.data.core.testapp.versions.length, 0)
let err = await assert.isRejected(app.update())
assert.strictEqual(app.updating, false)
assert.ok(stubExtract.called)
assert.strictEqual(err, assertError)
assert.strictEqual(stubFsStat.firstCall[0], assertTarget)
assert.match(db.data.core.testapp.updater, /index\.mjs/i)
assert.match(db.data.core.testapp.updater, /missing/i)
assert.strictEqual(db.data.core.testapp.versions.length, 1)
let version = db.data.core.testapp.versions[0]
assert.ok(version.log)
assert.match(version.log, /index\.mjs/i)
assert.match(version.log, /missing/i)
assert.ok(version.log.endsWith('\n'))
assert.strictEqual(version.failtodownload, 1)
// Test if subsequent calls increment counter
err = await assert.isRejected(app.update())
assert.strictEqual(app.updating, false)
assert.strictEqual(err, assertError)
assert.strictEqual(db.data.core.testapp.versions.length, 1)
assert.strictEqual(db.data.core.testapp.versions[0], version)
assert.strictEqual(version.failtodownload, 2)
})
t.test('should not call npm install if package.json is missing but shuld pass', async function() {
const assertError = new Error('File not found')
const assertTarget = util.getPathFromRoot('./testapp/123456789/package.json')
stubRunCommand.rejects(new Error('should not be seen'))
stubFsStat.returnWith(function(path) {
if (path.endsWith('package.json')) {
return Promise.reject(assertError)
}
return Promise.resolve({})
})
assert.strictEqual(db.data.core.testapp.versions.length, 0)
await app.update()
assert.strictEqual(app.updating, false)
assert.strictEqual(stubFsStat.callCount, 2)
assert.strictEqual(stubFsStat.secondCall[0], assertTarget)
assert.ok(stubExtract.called)
assert.notOk(stubRunCommand.called)
assert.match(db.data.core.testapp.updater, /package\.json/i)
assert.match(db.data.core.testapp.updater, /contain/i)
assert.strictEqual(db.data.core.testapp.versions.length, 1)
let version = db.data.core.testapp.versions[0]
assert.ok(version.log)
assert.match(version.log, /package\.json/i)
assert.match(version.log, /contain/i)
assert.ok(version.log.endsWith('\n'))
assert.ok(db.data.core.testapp.latestInstalled)
assert.match(version.log, /finished/i)
assert.match(version.log, /updating/i)
// Test if subsequent calls do nothing
provider.downloadVersion.reset()
await app.update()
assert.strictEqual(db.data.core.testapp.versions.length, 1)
assert.notOk(provider.downloadVersion.called)
assert.match(db.data.core.testapp.updater, /already/i)
assert.match(db.data.core.testapp.updater, /nothing/i)
})
t.test('should otherwise call npm install correctly', async function() {
const assertExtractText = 'Egao no Hikair ni Tsutsumarete'
const assertNpmText = 'Dadadadash'
const assertVersion = { version: '123456789', link: 'somelinkhere', filename: 'test.7z' }
const assertError = new Error('Nagisa')
const assertTarget = util.getPathFromRoot('./testapp/123456789')
provider.getLatestVersion.resolves(assertVersion)
assert.strictEqual(db.data.core.testapp.versions.length, 0)
assert.notOk(stubWrite.called)
stubExtract.returnWith(function(target, stream) {
stream(assertExtractText)
return Promise.resolve()
})
stubRunCommand.returnWith(function(command, options, folder, stream) {
stream(assertNpmText)
return Promise.reject(assertError)
})
let err = await assert.isRejected(app.update())
assert.strictEqual(app.updating, false)
assert.strictEqual(err, assertError)
assert.strictEqual(stubRunCommand.firstCall[0], 'npm.cmd')
assert.ok(stubRunCommand.firstCall[1])
assert.strictEqual(stubRunCommand.firstCall[1][0], 'install')
assert.ok(stubRunCommand.firstCall[1].includes('--production'), 'should have --production')
assert.ok(stubRunCommand.firstCall[1].includes('--no-optional'), 'should have --no-optional')
assert.ok(stubRunCommand.firstCall[1].includes('--no-package-lock'), 'should have --no-package-lock')
assert.ok(stubRunCommand.firstCall[1].includes('--no-audit'), 'should have --no-audit')
assert.strictEqual(stubRunCommand.firstCall[2], assertTarget)
assert.notOk(stubFsRm.called)
assert.match(db.data.core.testapp.updater, /npm/i)
assert.match(db.data.core.testapp.updater, /install/i)
assert.strictEqual(db.data.core.testapp.versions.length, 1)
assert.strictEqual(db.data.core.testapp.versions[0], assertVersion)
assert.ok(assertVersion.log)
assert.match(assertVersion.log, /\. \n/)
assert.match(assertVersion.log, new RegExp(assertExtractText))
assert.match(assertVersion.log, new RegExp(assertNpmText))
assert.match(assertVersion.log, new RegExp(assertError.message))
assert.match(assertVersion.log, /npm/i)
assert.match(assertVersion.log, /install/i)
assert.ok(assertVersion.log.endsWith('\n'))
assert.strictEqual(assertVersion.failtoinstall, 1)
// Test if subsequent calls increment counter
err = await assert.isRejected(app.update())
assert.strictEqual(app.updating, false)
assert.strictEqual(err, assertError)
assert.strictEqual(db.data.core.testapp.versions.length, 1)
assert.strictEqual(db.data.core.testapp.versions[0], assertVersion)
assert.strictEqual(assertVersion.failtoinstall, 2)
})
t.test('should update latest installed correctly', async function() {
const assertVersion = { version: '123456789', link: 'httplinkhere', filename: 'test.7z' }
provider.getLatestVersion.resolves(assertVersion)
assert.notStrictEqual(db.data.core.testapp.latestInstalled, assertVersion.version)
assert.strictEqual(db.data.core.testapp.versions.length, 0)
await app.update()
assert.strictEqual(app.updating, false)
assert.strictEqual(db.data.core.testapp.latestInstalled, assertVersion.version)
assert.strictEqual(db.data.core.testapp.versions.length, 1)
assert.strictEqual(db.data.core.testapp.versions[0], assertVersion)
assert.ok(assertVersion.log)
assert.match(assertVersion.log, /found/i)
assert.match(assertVersion.log, new RegExp(assertVersion.version))
assert.match(assertVersion.log, /downloading/i)
assert.match(assertVersion.log, new RegExp('extracting[^.]+file\.7z', 'i'))
assert.match(assertVersion.log, /finished/i)
assert.match(assertVersion.log, /updating/i)
})
t.test('should update existing version if found', async function() {
const assertNewLink = 'THE last pain'
const assertNewFilename = 'The place of hope.7z'
const oldLog = 'The Smell of Sea\n'
const assertVersion = { version: '123456789', link: 'httplinkhere', filename: 'test.7z', log: oldLog }
assertVersion.id = assertVersion.version
db.upsert(db.data.core.testapp.versions, assertVersion)
provider.getLatestVersion.resolves({ version: assertVersion.version, link: assertNewLink, filename: assertNewFilename })
assert.strictEqual(db.data.core.testapp.versions.length, 1)
await app.update()
assert.strictEqual(app.updating, false)
assert.strictEqual(db.data.core.testapp.versions.length, 1)
assert.strictEqual(db.data.core.testapp.versions[0], assertVersion)
assert.ok(assertVersion.log)
assert.ok(assertVersion.log.startsWith(oldLog))
assert.match(assertVersion.log, /found/i)
assert.match(assertVersion.log, new RegExp(assertVersion.version))
assert.match(assertVersion.log, /downloading/i)
assert.match(assertVersion.log, new RegExp('extracting[^.]+file\.7z', 'i'))
assert.match(assertVersion.log, /finished/i)
assert.match(assertVersion.log, /updating/i)
}) })
t.test('should do nothing if latestInstalled matches version', async function() { t.test('should do nothing if latestInstalled matches version', async function() {
@ -274,8 +575,44 @@ t.timeout(250).describe('#update()', function() {
db.data.core.testapp.latestInstalled = assertVersion.version db.data.core.testapp.latestInstalled = assertVersion.version
await app.update() await app.update()
assert.strictEqual(app.updating, false)
assert.notOk(provider.downloadVersion.called) assert.notOk(provider.downloadVersion.called)
assert.match(db.data.core.testapp.updater, /already/i) assert.match(db.data.core.testapp.updater, /already/i)
assert.match(db.data.core.testapp.updater, /nothing/i) assert.match(db.data.core.testapp.updater, /nothing/i)
}) })
t.test('should do nothing it exists and failtodownload is higher than 3', async function() {
const assertError = new Error('should not be seen')
const assertVersion = { version: '999.888.777.666', filename: 'test.7z' }
provider.getLatestVersion.resolves(assertVersion)
provider.downloadVersion.rejects(assertError)
db.data.core.testapp.updater = ''
db.upsert(db.data.core.testapp.versions, { id: '999.888.777.666', version: '999.888.777.666', link: 'httplinkhere', filename: 'test.7z', failtodownload: 4 })
await app.update()
assert.strictEqual(app.updating, false)
assert.notOk(provider.downloadVersion.called)
assert.match(db.data.core.testapp.updater, /many/i)
assert.match(db.data.core.testapp.updater, /fail/i)
assert.match(db.data.core.testapp.updater, /skip/i)
})
t.test('should do nothing it exists and failtoinstall is higher than 3', async function() {
const assertError = new Error('should not be seen')
const assertVersion = { version: '999.888.777.666', filename: 'test.7z' }
provider.getLatestVersion.resolves(assertVersion)
provider.downloadVersion.rejects(assertError)
db.data.core.testapp.updater = ''
db.upsert(db.data.core.testapp.versions, { id: '999.888.777.666', version: '999.888.777.666', link: 'httplinkhere', filename: 'test.7z', failtoinstall: 4 })
await app.update()
assert.strictEqual(app.updating, false)
assert.notOk(provider.downloadVersion.called)
assert.match(db.data.core.testapp.updater, /many/i)
assert.match(db.data.core.testapp.updater, /fail/i)
assert.match(db.data.core.testapp.updater, /skip/i)
})
}) })

View file

@ -271,3 +271,17 @@ t.test('should have basic database-like functions with string-like name of colle
assert.strictEqual(dbSec.data.myarr.length, 1) assert.strictEqual(dbSec.data.myarr.length, 1)
assert.strictEqual(dbSec.get('myarr', assertItem1.id), null) assert.strictEqual(dbSec.get('myarr', assertItem1.id), null)
}) })
t.test('#upsert() should work properly', async function() {
let db = await lowdb({}, logger, null)
db.data.test = {
items: []
}
db.upsert(db.data.test.items, { id: '1234', text: '1' })
db.upsert(db.data.test.items, { id: '1234', text: '2' })
assert.strictEqual(db.data.test.items.length, 1)
assert.strictEqual(db.data.test.items[0].id, '1234')
assert.strictEqual(db.data.test.items[0].text, '2')
})

View file

@ -15,6 +15,7 @@ t.timeout(5000).describe('Git integration', function() {
let version = await provider.getLatestVersion() let version = await provider.getLatestVersion()
assert.ok(version) assert.ok(version)
assert.ok(version.version) assert.ok(version.version)
assert.ok(version.description)
assert.ok(version.link) assert.ok(version.link)
assert.match(version.link, /\/attachments\//) assert.match(version.link, /\/attachments\//)
}) })

View file

@ -233,6 +233,9 @@ t.describe('#extractFile()', function() {
t.test('should stream the process of extracting', async function() { t.test('should stream the process of extracting', async function() {
let output = '' let output = ''
await util.extractFile(util.getPathFromRoot('./testapp/example.tar.gz'), function(msg) { output += msg + '\n' }) await util.extractFile(util.getPathFromRoot('./testapp/example.tar.gz'), function(msg) { output += msg + '\n' })
console.log(output)
assert.match(output, /Extracting archive\:.+example.tar.gz/)
assert.match(output, /1 file, 123 bytes/)
assert.strictEqual(output.indexOf('\r\n'), -1)
}) })
}) })