Skip to content

Commit

Permalink
added update challange
Browse files Browse the repository at this point in the history
  • Loading branch information
kolodny committed Dec 6, 2015
1 parent 2a729ab commit 47103a0
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 0 deletions.
37 changes: 37 additions & 0 deletions update/README.md
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
6 changes: 6 additions & 0 deletions update/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"private": true,
"scripts": {
"test": "node ../node_modules/mocha/bin/mocha"
}
}
81 changes: 81 additions & 0 deletions update/test.js
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',
});
});
});


});

0 comments on commit 47103a0

Please sign in to comment.