import { describe, it } from 'mocha'; import { autoBind } from '../lib'; import { expect } from 'chai'; describe('autoBind utility #utility', () => { it('does bind methods to class', () => { class Class { val = 'val'; fn() { return this?.val; } } const c = new Class(); function fn(cb) { return cb(); } expect(fn(c.fn)).to.eql(undefined, 'Unbound Function did not return undefined.'); autoBind(c); expect(fn(c.fn)).to.eql(c.val, 'Bound Function did not return value.'); }); it('does bind methods of nested plain Object to rootClass', () => { class Class { val = 'val'; nested = { val: 'wrongVal', fn() { return this?.val; }, }; } const c = new Class(); function fn(cb) { return cb(); } expect(fn(c.nested.fn)).to.eql(undefined, 'Unbound Function did not return undefined.'); autoBind(c); expect(fn(c.nested.fn)).to.eql(c.val, 'Bound Function did not return value.'); }); it('does NOT bind methods of nested classes to rootClass', () => { class NestedClass { val = 'wrongVal'; fn() { return this?.val; } } class Class { val = 'val'; nested = new NestedClass(); } const c = new Class(); function fn(cb) { return cb(); } expect(fn(c.nested.fn)).to.eql(undefined, 'Unbound Function did not return undefined.'); autoBind(c); expect(fn(c.nested.fn)).to.eql(undefined, 'Function was bound, even though it should not be.'); }); it('does bind methods to plain Object', () => { const obj = { val: 'val', fn() { return this?.val; }, }; function fn(cb) { return cb(); } expect(fn(obj.fn)).to.eql(undefined, 'Unbound Function did not return undefined.'); autoBind(obj); expect(fn(obj.fn)).to.eql(obj.val, 'Bound Function did not return value.'); }); it('does bind methods of nested plain Object to rootObj', () => { const obj = { val: 'val', nested: { val: 'wrongVal', fn() { return this?.val; }, }, }; function fn(cb) { return cb(); } expect(fn(obj.nested.fn)).to.eql(undefined, 'Unbound Function did not return undefined.'); autoBind(obj); expect(fn(obj.nested.fn)).to.eql(obj.val, 'Bound Function did not return value.'); }); it('does NOT bind methods of nested class to rootObj', () => { class NestedClass { val = 'wrongVal'; fn() { return this?.val; } } const obj = { val: 'val', nested: new NestedClass(), }; function fn(cb) { return cb(); } expect(fn(obj.nested.fn)).to.eql(undefined, 'Unbound Function did not return undefined.'); autoBind(obj); expect(fn(obj.nested.fn)).to.eql(undefined, 'function was bound, even though it should not be.'); }); it('respects exclude option', () => { const obj = { val: 'val', nested: { val: 'wrongVal', fn() { return this?.val; }, }, }; function fn(cb) { return cb(); } expect(fn(obj.nested.fn)).to.eql(undefined, 'Unbound Function did not return undefined.'); autoBind(obj, { exclude: ['fn'] }); expect(fn(obj.nested.fn)).to.eql(undefined, 'function was bound, even though it should not be.'); }); it('respects include option', () => { const obj = { val: 'val', fn() { return this?.val; }, other() { return this?.val; }, }; function fn(cb) { return cb(); } expect(fn(obj.fn)).to.eql(undefined, 'Unbound Function did not return undefined.'); autoBind(obj, { include: ['fn'] }); expect(fn(obj.fn)).to.eql(obj.val, 'function was not bound, even though it should be.'); expect(fn(obj.other)).to.eql(undefined, 'function was bound, even though it should not be.'); }); });