Created
April 28, 2014 09:52
-
-
Save parris/11367257 to your computer and use it in GitHub Desktop.
(We now have a repo/npm package: https://github.com/parris/mixablejs) Mixin class for coffeescript. Based on Angus Croll style mixins and backbone.advice.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
_ = require('lodash') | |
class Mixable | |
constructor: -> | |
@initialize() | |
initialize: -> | |
@addToObj: (objectName, dictionary) -> | |
if _.isUndefined(@prototype[objectName]) | |
@prototype[objectName] = {} | |
if _.isObject(@prototype[objectName]) | |
@prototype[objectName] = _.extend dictionary, @prototype[objectName] | |
@after: (target, after) -> | |
previous = @prototype[target] or -> | |
@prototype[target] = -> | |
previous.apply @, arguments | |
after.apply @, arguments | |
@around: (target, wrapper) -> | |
@prototype[target] = _.wrap @prototype[target], wrapper | |
@before: (target, before) -> | |
previous = @prototype[target] or -> | |
@prototype[target] = -> | |
before.apply @, arguments | |
previous.apply @, arguments | |
@clobber: (name, thing) -> | |
@before 'initialize', -> | |
@[name] = thing | |
@hasMixin: (mixin) -> | |
_.indexOf @constructor.mixins, mixin | |
hasMixin: (mixin) -> | |
_.indexOf @mixins, mixin | |
@mixin: (mixin, options) -> | |
@mixins = @mixins or [] | |
mixin.call @, options | |
module.exports = Mixable |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
_ = require('lodash') | |
Mixable = require('./mixable.coffee') | |
newName = 'Parris' | |
order = [] | |
objectCounterMixin = -> | |
@numberAfterCreated = 0 | |
@numberBeforeCreated = 0 | |
@after 'initialize', -> | |
order.push 2 | |
@constructor.numberAfterCreated += 1 | |
@before 'initialize', -> | |
order.push 0 | |
@constructor.numberBeforeCreated += 1 | |
@around 'add', (fn, x, y) -> | |
fn(x, y) + 1 | |
moreMixin = -> | |
@clobber 'name', newName | |
@addToObj 'events', { | |
'click .js-hi': 'moreMixin' | |
'click .js-hi2': 'moreMixin' | |
} | |
@addToObj 'ninjas', {} | |
describe 'Mixable', -> | |
beforeEach -> | |
order = [] | |
class @Mixed extends Mixable | |
name: 'Default' | |
events: | |
'click .js-hi': 'default' | |
'click .js-hi3': 'default' | |
initialize: -> | |
super | |
order.push 1 | |
add: (x, y)-> | |
1 + x + y | |
@Mixed.mixin objectCounterMixin | |
@Mixed.mixin moreMixin, {} | |
describe 'before creation', -> | |
it 'can add mixins', -> | |
expect(@Mixed.numberAfterCreated).toBe 0 | |
it 'detects if a mixin is mixed', -> | |
expect(@Mixed.hasMixin objectCounterMixin).toBeTruthy | |
describe 'after creation', -> | |
beforeEach -> | |
@mixInstance1 = new @Mixed | |
@mixInstance2 = new @Mixed | |
describe 'hasMixin', -> | |
it 'detects if a mixin is mixed', -> | |
expect(@mixInstance1.hasMixin moreMixin).toBeTruthy | |
describe 'clobber', -> | |
it 'allows clobbering of instance variables', -> | |
expect(@mixInstance1.name).toEqual newName | |
describe 'before and after', -> | |
it 'allows for running method after another method', -> | |
expect(@Mixed.numberAfterCreated).toEqual 2 | |
it 'allows for running method before another method', -> | |
expect(@Mixed.numberAfterCreated).toEqual 2 | |
it 'calls before and after for initialize in the correct order', -> | |
expect(order[0]).toEqual 0 | |
expect(order[1]).toEqual 1 | |
expect(order[2]).toEqual 2 | |
describe 'addToObj', -> | |
it 'does not clobber', -> | |
expect(@mixInstance1.events['click .js-hi']).toEqual('default') | |
expect(@mixInstance1.events['click .js-hi3']).toEqual('default') | |
it 'adds keys to an object', -> | |
expect(@mixInstance1.events['click .js-hi2']).toEqual('moreMixin') | |
it 'creates an object if it does not exist', -> | |
expect(@mixInstance1.ninjas).toBeTruthy() | |
describe 'around', -> | |
it 'returns the result of the first function to the second', -> | |
expect(@mixInstance1.add(1, 1)).toEqual 4 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment