More development
All checks were successful
continuous-integration/appveyor/branch AppVeyor build succeeded
All checks were successful
continuous-integration/appveyor/branch AppVeyor build succeeded
This commit is contained in:
parent
17830d7f8d
commit
0948885671
5 changed files with 174 additions and 19 deletions
33
core/db.mjs
33
core/db.mjs
|
@ -1,5 +1,6 @@
|
|||
import { Low, JSONFile } from 'lowdb'
|
||||
import { type } from 'os'
|
||||
import { defaults, isObject } from './defaults.mjs'
|
||||
|
||||
export default function GetDB(util, log, filename = 'db.json') {
|
||||
let fullpath = util.getPathFromRoot('./' + filename)
|
||||
|
@ -61,32 +62,30 @@ export default function GetDB(util, log, filename = 'db.json') {
|
|||
return false
|
||||
}
|
||||
|
||||
db.addApplication = function(name) {
|
||||
db.data.core[name] ||= {}
|
||||
defaults(db.data.core[name], {
|
||||
active: null,
|
||||
latestInstalled: null,
|
||||
latestVersion: null,
|
||||
versions: [],
|
||||
})
|
||||
}
|
||||
|
||||
return db.read()
|
||||
.then(function() {
|
||||
db.data ||= {
|
||||
core: {
|
||||
app: {
|
||||
active: null,
|
||||
latestInstalled: null,
|
||||
latestVersion: null,
|
||||
versions: [],
|
||||
},
|
||||
manager: {
|
||||
active: null,
|
||||
latestInstalled: null,
|
||||
latestVersion: null,
|
||||
versions: [],
|
||||
},
|
||||
version: 1,
|
||||
}
|
||||
if (!isObject(db.data)) {
|
||||
log.warn(`File ${fullpath} was empty or not a json object, clearing it.`)
|
||||
db.data = {}
|
||||
}
|
||||
defaults(db.data, { core: { version: 1 } })
|
||||
|
||||
return db.write()
|
||||
})
|
||||
.then(
|
||||
function() { return db },
|
||||
function(err) {
|
||||
let wrapped = new Error(`Error writing to ${fullpath}: ${err.code}`)
|
||||
let wrapped = new Error(`Error writing to ${fullpath}: ${err.message} (${err.code})`)
|
||||
wrapped.code = err.code
|
||||
throw wrapped
|
||||
}
|
||||
|
|
25
core/defaults.mjs
Normal file
25
core/defaults.mjs
Normal file
|
@ -0,0 +1,25 @@
|
|||
|
||||
// taken from isobject npm library
|
||||
export function isObject(val) {
|
||||
return val != null && typeof val === 'object' && Array.isArray(val) === false
|
||||
}
|
||||
|
||||
export function defaults(original, def) {
|
||||
if (!isObject(original)) throw new Error('defaults called with non-object type')
|
||||
|
||||
Object.keys(original).forEach(key => {
|
||||
if (isObject(original[key]) && def && isObject(def[key])) {
|
||||
defaults(original[key], def[key])
|
||||
}
|
||||
})
|
||||
|
||||
if (def) {
|
||||
Object.keys(def).forEach(function(key) {
|
||||
if (typeof original[key] === 'undefined') {
|
||||
original[key] = def[key]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return original
|
||||
}
|
|
@ -6,6 +6,7 @@ import Util from '../core/util.mjs'
|
|||
var util = new Util(import.meta.url)
|
||||
var logger = {
|
||||
info: stub(),
|
||||
warn: stub(),
|
||||
error: stub(),
|
||||
}
|
||||
|
||||
|
@ -28,10 +29,76 @@ t.test('Should auto create file with some defaults', async function() {
|
|||
assert.ok(stat.size > 0)
|
||||
|
||||
assert.ok(db.data.core)
|
||||
assert.ok(db.data.core.version)
|
||||
assert.notOk(db.data.core.app)
|
||||
assert.notOk(db.data.core.manager)
|
||||
})
|
||||
|
||||
t.test('Should apply defaults to existing file', async function() {
|
||||
await assert.isRejected(fs.stat('./test/db_test.json'))
|
||||
await fs.writeFile('./test/db_test.json', '{"test":true}')
|
||||
|
||||
let db = await lowdb(util, logger, 'db_test.json')
|
||||
|
||||
let stat = await fs.stat('./test/db_test.json')
|
||||
assert.ok(stat.size > 0)
|
||||
|
||||
assert.ok(db.data.core)
|
||||
assert.ok(db.data.core.version)
|
||||
assert.strictEqual(db.data.test, true)
|
||||
assert.notOk(db.data.core.app)
|
||||
assert.notOk(db.data.core.manager)
|
||||
})
|
||||
|
||||
t.test('Should not fail if db is invalid', async function() {
|
||||
logger.warn.reset()
|
||||
await assert.isRejected(fs.stat('./test/db_test.json'))
|
||||
await fs.writeFile('./test/db_test.json', '[]')
|
||||
|
||||
let db = await lowdb(util, logger, 'db_test.json')
|
||||
|
||||
let stat = await fs.stat('./test/db_test.json')
|
||||
assert.ok(stat.size > 0)
|
||||
|
||||
assert.ok(db.data.core)
|
||||
assert.ok(db.data.core.version)
|
||||
assert.notOk(db.data.core.app)
|
||||
assert.notOk(db.data.core.manager)
|
||||
assert.ok(logger.warn.called)
|
||||
assert.match(logger.warn.firstCall[0], /db_test.json/i)
|
||||
assert.match(logger.warn.firstCall[0], /clear/i)
|
||||
})
|
||||
|
||||
t.test('Should support adding an application with defaults', async function() {
|
||||
await assert.isRejected(fs.stat('./test/db_test.json'))
|
||||
|
||||
let db = await lowdb(util, logger, 'db_test.json')
|
||||
|
||||
let stat = await fs.stat('./test/db_test.json')
|
||||
assert.ok(stat.size > 0)
|
||||
|
||||
assert.ok(db.data.core)
|
||||
assert.ok(db.data.core.version)
|
||||
assert.notOk(db.data.core.app)
|
||||
assert.notOk(db.data.core.manager)
|
||||
|
||||
db.addApplication('app')
|
||||
|
||||
assert.ok(db.data.core.app)
|
||||
assert.ok(db.data.core.app.versions)
|
||||
assert.ok(db.data.core.manager)
|
||||
assert.ok(db.data.core.manager.versions)
|
||||
assert.strictEqual(db.data.core.app.active, null)
|
||||
assert.strictEqual(db.data.core.app.latestInstalled, null)
|
||||
assert.strictEqual(db.data.core.app.latestVersion, null)
|
||||
|
||||
assert.notOk(db.data.core.herpderp)
|
||||
|
||||
db.addApplication('herpderp')
|
||||
|
||||
assert.ok(db.data.core.herpderp)
|
||||
assert.ok(db.data.core.herpderp.versions)
|
||||
assert.strictEqual(db.data.core.herpderp.active, null)
|
||||
assert.strictEqual(db.data.core.herpderp.latestInstalled, null)
|
||||
assert.strictEqual(db.data.core.herpderp.latestVersion, null)
|
||||
})
|
||||
|
||||
t.test('Should support reading from db', async function() {
|
||||
|
|
64
test/defaults.test.mjs
Normal file
64
test/defaults.test.mjs
Normal file
|
@ -0,0 +1,64 @@
|
|||
import { Eltro as t, assert} from 'eltro'
|
||||
import { isObject, defaults } from '../core/defaults.mjs'
|
||||
|
||||
t.describe('#isObject()', () => {
|
||||
t.test('should return false for invalid objects', function() {
|
||||
let tests = [
|
||||
[],
|
||||
'',
|
||||
'asdf',
|
||||
12341,
|
||||
0,
|
||||
]
|
||||
|
||||
tests.forEach(function(check) {
|
||||
assert.strictEqual(isObject(check), false)
|
||||
})
|
||||
})
|
||||
t.test('should return true for valid objects', function() {
|
||||
let tests = [
|
||||
{},
|
||||
new Object(),
|
||||
]
|
||||
|
||||
tests.forEach(function(check) {
|
||||
assert.strictEqual(isObject(check), true)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
t.describe('#defaults()', () => {
|
||||
t.test('should throw if original is missing or invalid', () => {
|
||||
assert.throws(function() { defaults() })
|
||||
assert.throws(function() { defaults('asdf') })
|
||||
assert.throws(function() { defaults('') })
|
||||
assert.throws(function() { defaults(null) })
|
||||
assert.throws(function() { defaults(1234) })
|
||||
assert.throws(function() { defaults([]) })
|
||||
})
|
||||
t.test('should not override existing variables', () => {
|
||||
let assertOutput = { a: 2 }
|
||||
defaults(assertOutput, { a: 1 })
|
||||
|
||||
assert.deepStrictEqual(assertOutput, { a: 2 })
|
||||
})
|
||||
|
||||
t.test('should allow nesting through objects', () => {
|
||||
let def = { a: { b: 2 } }
|
||||
let inside = { a: { c: 3} }
|
||||
defaults(inside, def)
|
||||
|
||||
assert.deepStrictEqual(inside.a, {
|
||||
b: 2,
|
||||
c: 3,
|
||||
})
|
||||
})
|
||||
|
||||
t.test('should not return new reference', () => {
|
||||
let assertInput = { a: 1 }
|
||||
let existing = assertInput
|
||||
defaults(assertInput, { b: 2 })
|
||||
|
||||
assert.strictEqual(assertInput, existing)
|
||||
})
|
||||
})
|
0
test/updater.test.mjs
Normal file
0
test/updater.test.mjs
Normal file
Loading…
Reference in a new issue