Skip to content

Commit

Permalink
feat(adapter): Utility to parse internal into platform requiremed schema
Browse files Browse the repository at this point in the history
  • Loading branch information
timkinnane committed Sep 9, 2018
1 parent 303cd42 commit ec85334
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 5 deletions.
59 changes: 54 additions & 5 deletions src/lib/adapter-classes/base.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@ describe('[adapter-base]', () => {
expect(mockAdapter).to.be.instanceof(Adapter)
})
it('inherits bot properties', () => {
class MockAdapter extends Adapter {
name = 'mock-adapter'
async start () { return }
async shutdown () { return }
}
const mockAdapter = new MockAdapter(bot)
expect(mockAdapter.bot).to.include.all.keys([
'events',
Expand All @@ -32,4 +27,58 @@ describe('[adapter-base]', () => {
])
})
})
describe('.parseSchema', () => {
it('maps internal key values to given schema', () => {
const mockAdapter = new MockAdapter(bot)
const internal = {
room: { name: 'testing', id: '111' },
updated: Date.now(),
public: false
}
const schema = {
rId: 'room.id',
room_name: 'room.name',
updatedAt: 'updated',
public: 'public'
}
expect(mockAdapter.parseSchema(internal, schema)).to.eql({
rId: internal.room.id,
room_name: internal.room.name,
updatedAt: internal.updated,
public: internal.public
})
})
it('does not include undefined values', () => {
const mockAdapter = new MockAdapter(bot)
const internal = { room: { id: '111' } }
const schema = { rId: 'room.id', public: 'public' }
expect(mockAdapter.parseSchema(internal, schema)).to.eql({
rId: internal.room.id
})
})
it('does not include undefined nested attributes', () => {
const mockAdapter = new MockAdapter(bot)
const internal = { public: true }
const schema = { rId: 'room.id', public: 'public' }
expect(mockAdapter.parseSchema(internal, schema)).to.eql({
public: internal.public
})
})
it('result the target type if given', () => {
const mockAdapter = new MockAdapter(bot)
const internal = { room: { id: '111' } }
const schema = { rId: 'room.id', public: 'public' }
class Model { name = 'mock-model' }
const converted = mockAdapter.parseSchema(internal, schema, new Model())
expect(converted).to.eql({ name: 'mock-model', rId: internal.room.id })
expect(converted).to.be.instanceof(Model)
})
it('inherits unmapped attributes from target', () => {
const mockAdapter = new MockAdapter(bot)
const internal = { foo: 'foo', bar: 'bar' }
const schema = { fooToo: 'foo' }
const converted = mockAdapter.parseSchema(internal, schema, internal)
expect(converted).to.eql({ fooToo: 'foo', bar: 'bar' })
})
})
})
27 changes: 27 additions & 0 deletions src/lib/adapter-classes/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,31 @@ export abstract class Adapter {

/** Extend to add any bot shutdown requirements in adapter environment */
abstract shutdown (): Promise<void>

/**
* Utility to convert internal object to schema required in adapter platform.
* Passing the original internal object as the external, allows inheriting
* all attributes without needing to map the ones that are the same in both.
* Otherwise, result would only include values from defined schema fields.
*/
parseSchema (
internal: any,
schema: { [path: string]: string },
external: any = {}
) {
const converted: any = {}
const target = (external.constructor.name !== 'Object')
? Object.create(external)
: this.bot.deepClone(external)
for (let key in schema) {
const valueAtPath = schema[key].split('.').reduce((pre, cur) => {
return (typeof pre !== 'undefined') ? pre[cur] : undefined
}, internal)
if (typeof valueAtPath !== 'undefined') {
converted[key] = valueAtPath
delete target[schema[key]] // remove anything re-mapped
}
}
return Object.assign(target, converted)
}
}

0 comments on commit ec85334

Please sign in to comment.