Skip to content

Commit

Permalink
flatten todo data structure
Browse files Browse the repository at this point in the history
  • Loading branch information
stephenplusplus committed Oct 8, 2014
1 parent e96715f commit 77fd19c
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 113 deletions.
14 changes: 8 additions & 6 deletions apps/cli/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ function displayTodos() {
type: 'checkbox',
choices: entities.map(function(entity) {
return {
name: entity.data.text,
checked: entity.data.done,
name: entity.text,
checked: entity.done,
value: entity
};
})
Expand All @@ -110,16 +110,18 @@ function displayTodos() {
if (answers.completed.some(function(completed) {
return completed.id === entity.id;
})) {
entity.data.done = true;
entity.done = true;
} else {
entity.data.done = false;
entity.done = false;
}
return entity;
});

var updated = 0;
entities.forEach(function(entity) {
todos.update(entity.id, entity.data, function(err) {
var id = entity.id;
delete entity.id;
todos.update(id, entity, function(err) {
if (err) {
throw err;
}
Expand All @@ -143,7 +145,7 @@ function displayTodosAndDelete() {
type: 'checkbox',
choices: entities.map(function(entity) {
return {
name: entity.data.text,
name: entity.text,
checked: false,
value: entity
};
Expand Down
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@
"dependencies": {
"express": "^4.5.1",
"body-parser": "^1.4.3",
"gcloud": "^0.7.1",
"gcloud": "^0.8.0",
"markdown": "^0.5.0",
"github-markdown-css": "^1.1.1"
},
"devDependencies": {
"jshint": "^2.5.2",
"dredd": "^0.3.9",
"request": "^2.42.0"
"dredd": "^0.3.12"
},
"scripts": {
"lint": "jshint apps/**/*.js server/**/*.js",
Expand Down
4 changes: 1 addition & 3 deletions server/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,7 @@ app.get('/todos/:id', function(req, res) {
});

app.post('/todos', function(req, res) {
var todo = req.body;
todo.done = false;
todos.insert(todo, _handleResponse(res, 201));
todos.insert(req.body, _handleResponse(res, 201));
});

app.put('/todos/:id', function(req, res) {
Expand Down
57 changes: 33 additions & 24 deletions server/test/test_hooks.js
Original file line number Diff line number Diff line change
@@ -1,45 +1,54 @@
'use strict';

var request = require('request');
// imports the hooks module _injected_ by dredd.
var hooks = require('hooks');
var todos = require('../todos.js');

hooks.after('Todos > Todos Collection > Archive done Todos', function(transaction, done) {
todos.getAll(function(err, items) {
items.forEach(function(todo) {
console.assert(!todo.done);
});
done();
});
});

hooks.before('Todos > Todo > Get a Todo', function(transaction, done) {
request.post({
uri: 'http://localhost:8080/todos',
json: {'text': 'do that'}
}, function(err, res, todo) {
todos.insert({
text: 'do that'
}, function(err, todo) {
transaction.fullPath = '/todos/' + todo.id;
return done();
done();
});
});

hooks.before('Todos > Todo > Delete a Todo', function(transaction, done) {
request.post({
uri: 'http://localhost:8080/todos',
json: {'text': 'delete me'}
}, function(err, res, todo) {
todos.insert({
text: 'delete me'
}, function(err, todo) {
transaction.fullPath = '/todos/' + todo.id;
return done();
done();
});
});

hooks.after('Todos > Todo > Delete a Todo', function(transaction, done) {
request.get({
uri: 'http://localhost:8080' + transaction.fullPath,
}, function(err, res) {
console.assert(res.statusCode === 404);
return done();
var id = transaction.fullPath.split('/')[1];
todos.get(id, function(err) {
console.assert(err.code === 404);
done();
});
});

hooks.after('Todos > Todos Collection > Archive done Todos', function(transaction, done) {
request.get({
uri: 'http://localhost:8080/todos'
}, function(err, res, body) {
JSON.parse(body).forEach(function(todo) {
console.assert(!todo.done);
hooks.afterAll(function(done) {
todos.getAll(function(err, items) {
var deleted = 0;

items.forEach(function(todo) {
todos.delete(todo.id, function() {
if (++deleted === items.length) {
done();
}
});
});
return done();
});
});
});
31 changes: 10 additions & 21 deletions server/todos.apib
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@ Todos API is a todo storage backend for [TodoMVC](//todomvc.com).

{
"id": 42,
"data": {
"text": "do this",
"done": false
}
"text": "do this",
"done": false
}

## List all Todos [GET]
Expand All @@ -30,10 +28,8 @@ Todos API is a todo storage backend for [TodoMVC](//todomvc.com).

[{
"id": 42,
"data": {
"text": "do this",
"done": false
}
"text": "do this",
"done": false
}]

## Archive done Todos [DELETE]
Expand All @@ -51,10 +47,8 @@ Todos API is a todo storage backend for [TodoMVC](//todomvc.com).

{
"id": 42,
"data": {
"text": "do this",
"done": false
}
"text": "do this",
"done": false
}


Expand All @@ -63,21 +57,16 @@ Todos API is a todo storage backend for [TodoMVC](//todomvc.com).
+ Request (application/json)

{
"id": 42,
"data": {
"text": "do this",
"done": true
}
"text": "do this",
"done": true
}

+ Response 200 (application/json; charset=utf-8)

{
"id": 42,
"data": {
"text": "do this",
"done": true
}
"text": "do this",
"done": true
}

## Delete a Todo [DELETE]
Expand Down
107 changes: 51 additions & 56 deletions server/todos.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,43 @@ var gcloud = require('gcloud')({
var ds = gcloud.datastore.dataset();
var LIST_NAME = 'default-list';

function formatTodo(item) {
var todo = item.data;
todo.id = item.key.path.pop();
return todo;
}

module.exports = {
getAll: function(callback) {
var q = ds.createQuery('Todo')
.hasAncestor(ds.key(['TodoList', LIST_NAME]));
ds.runQuery(q, function(err, items) {
if (err) {
callback(err);
return;
}
callback(null, items.map(function(obj) {
return {
id: obj.key.path.pop(),
data: obj.data
};
}));
delete: function(id, callback) {
ds.delete(ds.key(['TodoList', LIST_NAME, 'Todo', id]), function(err) {
callback(err || null);
});
},

deleteCompleted: function(callback) {
ds.runInTransaction(function(transaction, done) {
var q = ds.createQuery('Todo')
.hasAncestor(ds.key(['TodoList', LIST_NAME]))
.filter('done =', true);
transaction.runQuery(q, function(err, items) {
if (err) {
transaction.rollback(done);
return;
}
var keys = items.map(function(todo) {
return todo.key;
});
transaction.delete(keys, function(err) {
if (err) {
transaction.rollback(done);
return;
}
done();
});
});
}, callback);
},

get: function(id, callback) {
ds.get(ds.key(['TodoList', LIST_NAME, 'Todo', id]), function(err, item) {
if (err) {
Expand All @@ -49,14 +68,24 @@ module.exports = {
});
return;
}
callback(null, {
id: item.key.path.pop(),
data: item.data
});
callback(null, formatTodo(item));
});
},

getAll: function(callback) {
var q = ds.createQuery('Todo')
.hasAncestor(ds.key(['TodoList', LIST_NAME]));
ds.runQuery(q, function(err, items) {
if (err) {
callback(err);
return;
}
callback(null, items.map(formatTodo));
});
},

insert: function(data, callback) {
data.done = false;
ds.save({
key: ds.key(['TodoList', LIST_NAME, 'Todo']),
data: data
Expand All @@ -65,10 +94,8 @@ module.exports = {
callback(err);
return;
}
callback(null, {
id: key.path.pop(),
data: data
});
data.id = key.path.pop();
callback(null, data);
});
},

Expand All @@ -81,40 +108,8 @@ module.exports = {
callback(err);
return;
}
callback(null, {
id: id,
data: data
});
});
},

deleteCompleted: function(callback) {
ds.runInTransaction(function(transaction, done) {
var q = ds.createQuery('Todo')
.hasAncestor(ds.key(['TodoList', LIST_NAME]))
.filter('done =', true);
transaction.runQuery(q, function(err, items) {
if (err) {
transaction.rollback(done);
return;
}
var keys = items.map(function(obj) {
return obj.key;
});
transaction.delete(keys, function(err) {
if (err) {
transaction.rollback(done);
return;
}
done();
});
});
}, callback);
},

delete: function(id, callback) {
ds.delete(ds.key(['TodoList', LIST_NAME, 'Todo', id]), function(err) {
callback(err || null);
data.id = id;
callback(null, data);
});
}
};

0 comments on commit 77fd19c

Please sign in to comment.