• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Node.js sample application with jQuery Mobile and Express.


Commit MetaInfo

修訂22c55d62993483364156e5986880ad84823755aa (tree)
時間2012-10-20 19:14:27
作者hylom <hylom@hylo...>
Commiterhylom

Log Message

add some fixes...

Change Summary

差異

--- /dev/null
+++ b/Makefile
@@ -0,0 +1,9 @@
1+MOCHA = node_modules/.bin/mocha -R spec
2+
3+test:
4+ $(MOCHA) testing/models
5+
6+reset-db:
7+ mongo mobbs tools/sampledata.js
8+
9+
--- a/models/database.js
+++ b/models/database.js
@@ -54,7 +54,8 @@ Database.prototype.close = function() {
5454 Database.prototype._getCollection = function (collectionName, callback) {
5555 this._open('mobbs', function(err, db) {
5656 if (err) {
57- return callback(err);
57+ callback(err);
58+ return;
5859 }
5960 db.createCollection(collectionName, callback);
6061 });
@@ -83,11 +84,8 @@ Topics.prototype.getLatest = function (start, end, callback) {
8384 callback(err);
8485 return;
8586 }
86- // topicsデータの全データにアクセスするカーソルを作成する
8787 var cursor = collection.find({});
88- // start、endの値に応じてカーソル位置を移動させる
8988 cursor.sort([['date', -1]]).limit(end - start).skip(start);
90- // カーソルの対象となる値を配列として返す
9189 cursor.toArray(callback);
9290 });
9391 };
@@ -101,7 +99,6 @@ Topics.prototype.findById = function (topicId, callback) {
10199 callback(err);
102100 return;
103101 }
104- // topicIdフィールドが指定したトピックIDであるドキュメントを取得
105102 collection.findOne({topicId: topicId}, callback);
106103 });
107104 };
@@ -113,11 +110,12 @@ Topics.prototype.insert = function (topic, callback) {
113110 var self = this;
114111
115112 // countersコレクションからカウンタの値を取得する
116- this._getCollection('counters', function (err, collection) {
113+ self._getCollection('counters', function (err, collection) {
117114 if (err) {
118115 callback(err);
119116 return;
120117 }
118+ // counterの値を取得すると同時にインクリメントする
121119 collection.findAndModify({name:'topics'}, {}, {$inc: {count:1}}, createTopic);
122120 });
123121
@@ -150,30 +148,9 @@ Topics.prototype.insert = function (topic, callback) {
150148 };
151149
152150 /**
153- * 指定したトピックのreplies要素に指定したコメントIDを追加する
154- */
155-Topics.prototype.appendReply = function (topicId, commentId, callback) {
156- this._getCollection('topics', function (err, collection) {
157- if (err) {
158- callback(err);
159- return;
160- }
161- var cursor = collection.findAndModify(
162- {topicId:topicId},
163- {},
164- {$push: {replies:commentId}},
165- callback
166- );
167- });
168-};
169-
170-/**
171151 * コメントデータにアクセスするためのオブジェクト
172152 */
173-var Comments = function () {
174- this._db = null;
175- this._client = null;
176-};
153+var Comments = function () {};
177154 Comments.prototype = new Database();
178155
179156 /**
@@ -192,41 +169,30 @@ Comments.prototype.findById = function (commentId, callback) {
192169 callback(err);
193170 return;
194171 }
195- // commentIdフィールドが指定したコメントIDであるドキュメントを取得
196- var cursor = collection.findOne({commentId: commentId}, callback);
197- });
198-};
199-
200-/**
201- * 指定したコメントのreplies要素に指定したコメントIDを追加する
202- */
203-Comments.prototype.appendReply = function (parentId, childId, callback) {
204- this._getCollection('comments', function (err, collection) {
205- if (err) {
206- callback(err);
207- return;
172+ // commentId引数が数値の場合、コメントオブジェクトを返す
173+ if (typeof commentId === 'number') {
174+ collection.findOne({commentId: commentId}, callback);
175+ } else {
176+ // commentId引数が配列の場合、取得したコメントを配列で返す
177+ var cursor = collection.find({commentId: {$in: commentId}});
178+ cursor.sort([['date', -1]]);
179+ cursor.toArray(callback);
208180 }
209- var cursor = collection.findAndModify(
210- {commentId:parentId},
211- {},
212- {$push: {replies:childId}},
213- callback
214- );
215181 });
216182 };
217183
218184 /**
219185 * コメントを新規作成してデータベースに挿入する
220186 */
221-Comments.prototype.insert = function (comment, callback) {
187+Comments.prototype.insert = function (topicId, comment, callback) {
222188 var self = this;
223189 // countersコレクションからカウンタの値を取得する
224- this._getCollection('counters', function (err, collection) {
190+ self._getCollection('counters', function (err, collection) {
225191 if (err) {
226192 callback(err);
227193 return;
228194 }
229- collection.findAndModify({name:'comment'}, {}, {$inc: {count:1}}, createComment);
195+ collection.findAndModify({name:'comments'}, {}, {$inc: {count:1}}, createComment);
230196 });
231197
232198 // 取得したカウンタの値をコメントIDとするコメントを作成
@@ -234,7 +200,7 @@ Comments.prototype.insert = function (comment, callback) {
234200 var nextId = counter.count;
235201 var newComment = {
236202 commentId: nextId,
237- topicId: comment.topicId,
203+ topicId: topicId,
238204 title: comment.title,
239205 text: comment.text,
240206 date: new Date(),
@@ -244,31 +210,64 @@ Comments.prototype.insert = function (comment, callback) {
244210 parentCommentId: comment.parentCommentId || null
245211 };
246212
247- // 親コメントが指定されていない場合、トピックのrepliesにIDを追加
248- if (comment.parentCommentId === null) {
249- var topics = database.getTopics();
250- topics.appendReply(comment.topicId, nextId, function (err, topic) {
251- topics.close();
213+ // 親コメントが指定されていない場合、トピックのrepliesフィールドに
214+ // コメントIDを追加する
215+ if (newComment.parentCommentId === null) {
216+ appendReplyToTopic(newComment, function (err) {
252217 if (err) {
253218 callback(err);
254219 return;
255220 }
256- insertComment(newComment, callback);
257- });
221+ insertComment(newComment);
222+ });
258223 } else {
259- self.appendReply(comment.parentCommentId, nextId, function (err, parent) {
224+ // 親コメントが指定されている場合は親コメントのrepliesフィールドに
225+ // コメントIDを追加する
226+ appendReplyToComment(newComment, function (err) {
260227 if (err) {
261228 callback(err);
262229 return;
263230 }
264- insertComment(newComment, callback);
231+ insertComment(newComment);
265232 });
266233 }
267234 }
268235
236+ // 指定したコメントのrepliesフィールドに指定したコメントIDを追加する
237+ function appendReplyToComment(comment, callback) {
238+ var parentId = comment.parentCommentId;
239+ var childId = comment.commentId;
240+ self._getCollection('comments', function (err, collection) {
241+ if (err) {
242+ callback(err);
243+ return;
244+ }
245+ collection.findAndModify( {commentId:parentId},
246+ {},
247+ {$push: {replies:childId}},
248+ callback);
249+ });
250+ };
251+
252+ // 指定したトピックのreplesフィールドに指定したコメントIDを追加する
253+ function appendReplyToTopic(comment, callback) {
254+ var parentId = comment.topicId;
255+ var childId = comment.commentId;
256+ self._getCollection('topics', function (err, collection) {
257+ if (err) {
258+ callback(err);
259+ return;
260+ }
261+ collection.findAndModify( {topicId:parentId},
262+ {},
263+ {$push: {replies:childId}},
264+ callback);
265+ });
266+ };
267+
269268 // コメントをデータベースに挿入する
270- function inserteComment(newComment) {
271- this._getCollection('comments', function (err, collection) {
269+ function insertComment(newComment) {
270+ self._getCollection('comments', function (err, collection) {
272271 if (err) {
273272 callback(err);
274273 return;
@@ -278,6 +277,7 @@ Comments.prototype.insert = function (comment, callback) {
278277 callback(err);
279278 return;
280279 }
280+ // 挿入したオブジェクトを引数に与えてコールバック関数を実行する
281281 callback(err, obj[0]);
282282 });
283283 });
@@ -285,12 +285,12 @@ Comments.prototype.insert = function (comment, callback) {
285285 };
286286
287287 /**
288- * コメントに付けられたコメントをツリー状のオブジェクトで取得する
288+ * トピックに付けられたコメントをツリー状のオブジェクトで取得する
289289 */
290290 Comments.prototype.getCommentTree = function (topicId, callback) {
291291 var self = this;
292- var topics = database.getTopics();
293292
293+ var topics = database.getTopics();
294294 topics.findById(topicId, function (err, topic) {
295295 topics.close();
296296 if (err) {
@@ -314,7 +314,6 @@ Comments.prototype.getCommentTree = function (topicId, callback) {
314314 items[comment.commentId] = comment;
315315 } else {
316316 // ループ終了時の処理
317- comments.close();
318317 var tree = buildCommentTree(topic.replies, items, []);
319318 callback(null, tree);
320319 }
--- /dev/null
+++ b/testing/models.js
@@ -0,0 +1,137 @@
1+
2+var assert = require('assert');
3+var database = require('../models/database');
4+
5+describe('database', function () {
6+
7+ describe('.Topics#getLatest(start, end)', function () {
8+ it('can retrive some topic', function(done) {
9+ var topics = database.getTopics();
10+ topics.getLatest(1, 2, function (err, doc) {
11+ topics.close();
12+ assert(!err);
13+ console.log('--------');
14+ assert(doc.length > 0, 'Number of found items is invalid.');
15+ for (var i = 0; i < doc.length; i++) {
16+ console.log(doc[i]);
17+ }
18+ done();
19+ return;
20+ });
21+ });
22+ });
23+
24+ describe('.Topics#findById(topicId)', function () {
25+ it('can retrive one topic', function(done) {
26+ var topics = database.getTopics();
27+ topics.findById(1, function (err, doc) {
28+ topics.close();
29+ assert(!err);
30+ assert(doc);
31+ console.log('--------');
32+ console.log(doc);
33+ done();
34+ return;
35+ });
36+ });
37+ });
38+
39+ describe('.Topics#insert(topic, callback)', function () {
40+ it('insert new topic', function(done) {
41+ var topics = database.getTopics();
42+ var topic = {
43+ title: 'テストトピック',
44+ text: 'テスト用本文'
45+ };
46+ topics.insert(topic, function (err, topicId) {
47+ topics.close();
48+ assert(!err);
49+ assert(topicId !== undefined);
50+ done();
51+ });
52+ });
53+ });
54+
55+ describe('.Comments#findById(commentId)', function () {
56+ it('can retrive one comments', function(done) {
57+ var comments = database.getComments();
58+ comments.findById(1, function (err, doc) {
59+ comments.close();
60+ assert(!err);
61+ console.log('--------');
62+ console.log(doc);
63+ done();
64+ return;
65+ });
66+ });
67+ });
68+
69+ describe('.Comments#findById(commentId)', function () {
70+ it('can retrive some comments', function(done) {
71+ var comments = database.getComments();
72+ comments.findById([1, 2], function (err, docs) {
73+ comments.close();
74+ assert(!err);
75+ assert(docs.length == 2, 'length is ' + docs.length);
76+ console.log('--------');
77+ console.log(docs[0]);
78+ console.log(docs[1]);
79+ done();
80+ return;
81+ });
82+ });
83+ });
84+
85+ describe('.Comments#insert(topicId, comment, callback)', function () {
86+ it('can insert comment', function(done) {
87+ var comments = database.getComments();
88+ var comment = {
89+ title: 'テストコメント',
90+ text: 'テスト用コメント本文',
91+ };
92+ comments.insert(1, comment, function (err, comment) {
93+ comments.close();
94+ assert(!err);
95+ assert(comment.commentId !== undefined);
96+ done();
97+ });
98+ });
99+ });
100+
101+ describe('.Comments#insert(topicId, comment, callback)', function () {
102+ it('can insert child comment', function(done) {
103+ var comments = database.getComments();
104+ var comment = {
105+ title: 'テストコメント',
106+ text: 'テスト用コメント本文',
107+ parentCommentId: 2,
108+ };
109+ comments.insert(1, comment, function (err, comment) {
110+ comments.close();
111+ assert(!err);
112+ assert(comment.commentId !== undefined);
113+ assert(comment.parentCommentId === 2);
114+ done();
115+ });
116+ });
117+ });
118+
119+ describe('.Comments#getCommentTree(topicId)', function () {
120+ it('can retrive some comment', function(done) {
121+ var count = 0;
122+ var comments = database.getComments();
123+ comments.getCommentTree(1, function (err, doc) {
124+ comments.close();
125+ assert(!err);
126+ assert(doc);
127+ console.log(doc);
128+ done();
129+ return;
130+ });
131+ });
132+ });
133+
134+});
135+
136+
137+
--- a/views/index.jade
+++ b/views/index.jade
@@ -21,48 +21,3 @@ block content
2121 h1
2222 a(href='#about') mobbs ver.0.0.1
2323
24- // aboutページ
25- #about(data-role='page')
26- div(data-role='header')
27- h1 mobbs test BBS
28- // a要素にdata-rel='back'属性を付けると、要素をクリックしたときに
29- // 「戻る」動作が行われる
30- a(href='#', data-rel='back') 戻る
31- div(data-role='content')
32- h2 mobbsについて
33- p mobbsはNode.jsとjQuery Mobileで実装されたスマートフォン/タブレット向け掲示板アプリケーションです。
34- div(data-role='footer')
35- h1
36- | mobbs ver.0.0.1
37-
38- // トピック一覧ページ
39- #topics-list(data-role='page')
40- div(data-role='header')
41- h1 トピック一覧
42- a.ui-btn-right(href='#dialog-create-topic', data-role='button') 新規作成
43- div(data-role='content')
44- // data-role='listview'を指定すると、リストをリストビュー形式で
45- // 表示できる
46- ul#topics-listview(data-role='listview')
47- div(data-role='footer')
48- h1
49- a(href='#about') mobbs ver.0.0.1
50-
51- #dialog-create-topic(data-role='dialog')
52- div(data-role='header')
53- h2 トピックの新規作成
54- div(data-role='content')
55- form(action='/topic/create', method='post', data-ajax='false')
56- label(for='topic-post-name') お名前:
57- input(type='text', id='topic-post-name', name='name')
58- label(for='topic-post-title') タイトル(必須):
59- input(type='text', id='topic-post-title', name='title')
60- label(for='topic-post-related') URL:
61- input(type='url', id='topic-post-related', name='relatedUrl')
62- label(for='topic-post-text') 本文(必須):
63- textarea(id='topic-post-text', name='text')
64- // data-rel='back'を指定すると、クリック時に前ページに戻る
65- a(href='#', data-rel='back', type='button') トピック一覧に戻る
66- input(type='submit', id='topic-post-submit', value='トピック作成', disabled='disabled')
67-
68-