JSFiddle - React, Tailwind, and code Playground
by fresheyeball
HTML
<script src="http://cdnjs.cloudflare.com/ajax/libs/mocha/1.12.1/mocha.js"></script>
<script src="http://chaijs.com/chai.js"></script>
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/mocha/1.12.1/mocha.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script>
<script>
mocha.setup('bdd');
</script>
<body>
<div id="mocha"></div>
</body>
CoffeeScript
Object.defineProperty Function::, 'def',
enumerable : false
value : (name, config={}) ->
{get, set, init, derived} = config
_NAME = "_#{name}"
isDerived = derived or false
isPrivate = (_.first(name) is '_')
isConstant = (name.toUpperCase() is name)
if not isDerived and not isConstant
Object.defineProperty @::, _NAME,
enumerable : no
value : null
writable : true
attachClone = ->
@[_NAME] ?= _.cloneDeep init if init?
return
get ?= ->
attachClone.call @
@[_NAME]
set ?= (val) ->
attachClone.call @
@[_NAME] = val
Object.defineProperty @::, name, do ->
if isConstant
enumerable : not isPrivate
get : -> init
set : -> throw new Error "Can't set .#{name} is a constant"
else
enumerable : not isPrivate
get : get
set : set
{expect} = chai
describe 'def', ->
describe 'basic', ->
Person = null
beforeEach ->
class Person
@def 'name'
it 'should define the property', ->
person = new Person()
expect(person).to.have.property 'name'
expect(person.name).to.be.null
it 'should not share state between instances', ->
person1 = new Person()
person2 = new Person()
expect(person1.name).to.be.null
expect(person2.name).to.be.null
person1.name = "Jack"
expect(person1.name).to.equal "Jack"
...