-
Notifications
You must be signed in to change notification settings - Fork 671
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
124 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
Immutability is all the rage nowadays. Let's explain what it is and then implement out version of Facebook's [Immutability Helpers](https://facebook.github.io/react/docs/update.html) | ||
|
||
The basic idea is to have all object immutable, which means that once an object is created it can never be change. At this point you're wondering how is it possible to build an anything with this restriction. Well instead of mutating an object we switch bindings to a very similar but slightly different object. Switching bindings is just a fancy way of saying making a variable refer to a different object | ||
|
||
Let's say we have an App that contains something like this: | ||
|
||
```js | ||
var state = { | ||
myName: 'Alice', | ||
todos: [ 'shopping', 'cleaning' ], | ||
}; | ||
``` | ||
|
||
Now if we wanted to change the name instead of just changing `state.myName` we would return a new object with just the `myName` property changed: | ||
|
||
```js | ||
var newState = { | ||
myName: 'Bob', | ||
todos: state.todos, | ||
}; | ||
``` | ||
|
||
The problem is, this can start to get annoying, let's instead follow Facebook's method and create an update function that takes [certain commands](https://facebook.github.io/react/docs/update.html#available-commands) | ||
|
||
Here's the basic usage of the file that you'll be creating: | ||
|
||
```js | ||
var update = require('./') // <- this is the file you make; | ||
|
||
var state = { name: 'Alice', todos: [] }; | ||
var nextState = update(state, { | ||
name: {$set: 'Bob'} | ||
}); | ||
console.log(state.todos === nextState.todos); // true | ||
``` | ||
|
||
More info: https://facebook.github.io/react/docs/update.html#available-commands |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"private": true, | ||
"scripts": { | ||
"test": "node ../node_modules/mocha/bin/mocha" | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
var assert = require('assert'); | ||
var update = require('./'); | ||
|
||
describe('update', function() { | ||
|
||
describe('has a #$set method that', function() { | ||
var state; | ||
var commands; | ||
var nextState; | ||
beforeEach(function() { | ||
state = { | ||
a: { | ||
b: 22, | ||
c: 33 | ||
}, | ||
unChanged: {}, | ||
}; | ||
commands = { a: { c: {$set: 44} } }; | ||
nextState = update(state, commands); | ||
}); | ||
|
||
it('changes the tree on the directive', function() { | ||
assert(state.a.c !== nextState.a.c); | ||
}) | ||
|
||
it('reuses state on different branches', function() { | ||
assert(state.unChanged === nextState.unChanged); | ||
}); | ||
|
||
it('reuses state on same level', function() { | ||
assert(state.a.b === state.a.b); | ||
}); | ||
|
||
|
||
}); | ||
|
||
|
||
|
||
describe("can pass react's test suite", function() { | ||
|
||
|
||
it('should support push', function() { | ||
assert.deepEqual(update([1], {$push: [7]}), [1, 7]); | ||
}); | ||
|
||
it('should support unshift', function() { | ||
assert.deepEqual(update([1], {$unshift: [7]}), [7, 1]); | ||
}); | ||
|
||
it('should support splice', function() { | ||
assert.deepEqual(update([1, 4, 3], {$splice: [[1, 1, 2]]}), [1, 2, 3]); | ||
}); | ||
|
||
it('should support merge', function() { | ||
assert.deepEqual(update({a: 'b'}, {$merge: {c: 'd'}}), {a: 'b', c: 'd'}); | ||
}); | ||
|
||
it('should support set', function() { | ||
assert.deepEqual(update({a: 'b'}, {$set: {c: 'd'}}), {c: 'd'}); | ||
}); | ||
|
||
it('should support apply', function() { | ||
assert.equal(update(2, {$apply: function(x) { return x * 2; }}), 4); | ||
}); | ||
|
||
it('should support deep updates', function() { | ||
assert.deepEqual(update({a: 'b', c: {d: 'e'}}, {c: {d: {$set: 'f'}}}), { | ||
a: 'b', | ||
c: {d: 'f'}, | ||
}); | ||
}); | ||
|
||
it('should perform safe hasOwnProperty check', function() { | ||
assert.deepEqual(update({}, {'hasOwnProperty': {$set: 'a'}}), { | ||
'hasOwnProperty': 'a', | ||
}); | ||
}); | ||
}); | ||
|
||
|
||
}); |