Browse Source

resource class and tests

modified-method-api
ojizero 4 years ago
parent
commit
bf448819fb
No known key found for this signature in database
GPG Key ID: FEBB7097845B0C7E
  1. 123
      src/resource.ts
  2. 45
      test/resource.spec.ts
  3. 2
      tsconfig.json

123
src/resource.ts

@ -1 +1,122 @@ @@ -1 +1,122 @@
export default class Resource {}
import { Client } from './client'
import method, { MethodSpec } from './method'
const defaultBaseSpecs: { [k: string]: MethodSpec } = {
list: {
path: '/',
method: 'GET',
},
get: {
path: '/:id',
method: 'GET',
},
edit: {
path: '/:id',
method: 'POST',
},
add: {
path: '/',
method: 'POST',
},
del: {
path: '/:id',
method: 'DELETE',
},
}
export class Resource {
client: Client
baseRoute: string
enabledRoutes: string[]
methodFactory: any
constructor (
client: Client,
baseRoute: string,
enabledRoutes?: string[],
extraMethods?: { [k: string]: any },
) {
this.client = client
this.baseRoute = baseRoute.trim()
if (this.baseRoute.endsWith('/')) this.baseRoute = this.baseRoute.slice(0, -1)
this.enabledRoutes = enabledRoutes || [
'list',
'get',
'edit',
'add',
'del',
]
this.methodFactory = this.generateMethodFactory()
this.initialize()
this.setExtraMethods(extraMethods)
}
initialize () {
this.enabledRoutes.forEach((route) => {
const routeMethod = this.methodFromRoute(route)
Object.defineProperty(this, route, {
value: routeMethod,
writable: false,
enumerable: true, // TODO: is it okay to have them enumerable ?
})
// Add is aliased as set
if (route === 'add') {
Object.defineProperty(this, 'set', {
value: routeMethod,
writable: false,
enumerable: true, // TODO: is it okay to have them enumerable ?
})
}
// Del is aliased as delete
if (route === 'del') {
Object.defineProperty(this, 'delete', {
value: routeMethod,
writable: false,
enumerable: true, // TODO: is it okay to have them enumerable ?
})
}
})
}
methodFromRoute (route: string) {
let spec = defaultBaseSpecs[route]
const prefix = this.baseRoute
const suffix = spec.path
spec = {
...spec,
path: `${prefix}${suffix}`
}
return this.methodFactory(spec)
}
generateMethodFactory () {
return method(this.client)
}
setExtraMethods (extraMethods?: { [k:string]: any }) {
if (!extraMethods) return
Object.entries(extraMethods)
.forEach(([method, fn]) => {
Object.defineProperty(this, method, {
value: fn,
writable: false,
enumerable: true, // TODO: is it okay to have them enumerable ?
})
})
}
}
export default function resrouceGenerator (client: Client) {
return function (baseRoute: string, enabledRoutes?: string[], extraMethods?: { [k:string]: any }): Resource {
return new Resource(client, baseRoute, enabledRoutes, extraMethods)
}
}

45
test/resource.spec.ts

@ -1,3 +1,46 @@ @@ -1,3 +1,46 @@
/// <reference path='typings/globals.d.ts' />
import resourceGenerator from '../src/resource'
describe('Resource', () => {
// TODO:
let client
let resourceFactory
let resource
before (() => {
resourceFactory = resourceGenerator(client)
})
describe('Rsource instantiation', () => {
it('exposes basic CRUD API', () => {
client = { request: sinon.spy() }
resource = resourceFactory('/mock-base')
expect(resource)
.to.include.all.keys('list', 'get', 'edit', 'del')
})
it('can be extended with additional methods', () => {
client = { request: sinon.spy() }
resourceFactory = resourceGenerator(client)
resource = resourceFactory('/mock-base', undefined, { extraMethod: () => {} })
expect(resource)
.to.include.all.keys('list', 'get', 'edit', 'del', 'extraMethod')
})
it('can limit exposed default methods', () => {
client = { request: sinon.spy() }
resourceFactory = resourceGenerator(client)
resource = resourceFactory('/mock-base', ['list', 'get'])
expect(resource)
.to.include.all.keys('list', 'get')
})
})
})

2
tsconfig.json

@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
// "lib": [], /* Specify library files to be included in the compilation. */
"lib": [ "es2015" ],
"lib": [ "es2017" ],
"allowJs": false,
"declaration": true,
"declarationMap": true,

Loading…
Cancel
Save