ts-schedule-decorators
Version:
Schedule decorator for TypeScript
177 lines (149 loc) • 4.52 kB
text/typescript
import { Schedulable } from './schedulable'
import { Interval, intervalMetadataKey } from './interval'
import { expect } from 'chai'
import * as sinon from 'sinon'
describe('Interval decorator', () => {
it('should add metadata to the class prototype when decorating an instance method with "@Interval()"', () => {
()
class Cat {
(50)
public meow() { }
}
expect(Reflect.getOwnMetadata(intervalMetadataKey, Cat)).to.be.empty
expect(Reflect.getOwnMetadata(intervalMetadataKey, Cat.prototype)).to.have.lengthOf(1)
const interval = Reflect.getOwnMetadata(intervalMetadataKey, Cat.prototype)[0]
expect(interval).to.deep.equal({
propertyKey: 'meow',
delay: 50,
options: {
leading: false,
protectOriginal: true
}
})
})
it('should execute an instance method at regular intervals', (done) => {
const callback = sinon.spy()
()
class Cat {
(100)
public meow() {
callback()
}
}
expect(callback.called).to.be.false
const garfield = new Cat()
setTimeout(() => {
expect(callback.callCount).to.equal(3)
done()
}, 390)
})
it('should add metadata to the class prototype when decorating an instance method with "@Interval()"', () => {
()
class Cat {
(50)
public static miaow() { }
}
expect(Reflect.getOwnMetadata(intervalMetadataKey, Cat)).to.have.lengthOf(1)
expect(Reflect.getOwnMetadata(intervalMetadataKey, Cat.prototype)).to.be.empty
const interval = Reflect.getOwnMetadata(intervalMetadataKey, Cat)[0]
expect(interval).to.deep.equal({
propertyKey: 'miaow',
delay: 50,
options: {
leading: false,
protectOriginal: true
}
})
})
it('should execute a static method at regular intervals', (done) => {
const callback = sinon.spy()
()
class Cat {
(100)
public static miaow() {
callback()
}
}
expect(callback.called).to.be.false
setTimeout(() => {
expect(callback.callCount).to.equal(3)
done()
}, 390)
})
it('should execute a method once more if the "leading" option is true', (done) => {
const callback = sinon.spy()
()
class Cat {
(100, { leading: true })
public meow() {
callback()
}
}
expect(callback.called).to.be.false
const garfield = new Cat()
setTimeout(() => {
expect(callback.callCount).to.equal(4)
done()
}, 390)
})
it('should stop the intervals if the "stop" function given as option returns true', (done) => {
const callback = sinon.spy()
()
class Cat {
public shouldStop: boolean = false
public constructor() {
setTimeout(() => {
this.shouldStop = true
}, 70)
}
(50, {
stop: (self) => {
return self.shouldStop
}
})
public meow() {
callback()
}
}
expect(callback.called).to.be.false
const garfield = new Cat()
setTimeout(() => {
expect(callback.callCount).to.equal(1)
done()
}, 190)
})
it('should throw an error if the decorated member is not a function', () => {
const declaration = () => {
()
class Cat {
(50)
public name: string = 'Garfield'
}
}
expect(declaration).to.throw('Interval decorator can only be applied to methods')
})
it('should throw an error if the method is called manually while the "protectOriginal" property is true', () => {
()
class Cat {
(50)
public meow() { }
(50)
public static miaow() { }
}
const garfield = new Cat()
expect(garfield.meow).to.throw('interval method cannot be invoked')
expect(Cat.miaow).to.throw('interval method cannot be invoked')
})
it('should not throw an error if the method is called manually while the "protectOriginal" property is false', () => {
()
class Cat {
(50, { protectOriginal: false })
public meow() { }
(50, { protectOriginal: false })
public static miaow() { }
}
const garfield = new Cat()
expect(garfield.meow).not.to.throw('interval method cannot be invoked')
expect(Cat.miaow).not.to.throw('interval method cannot be invoked')
})
})