diff --git a/Makefile b/Makefile
index 5b1c160..c6454b4 100644
--- a/Makefile
+++ b/Makefile
@@ -1,34 +1,25 @@
-SRC := libs controllers plugins models
TESTS = $(shell find test -type f -name "*.js")
TESTTIMEOUT = 5000
REPORTER = spec
JSCOVERAGE = ./node_modules/visionmedia-jscoverage/jscoverage
+PROJECT_DIR = $(shell pwd)
test:
@npm install
@if ! test -f config.js; then \
cp config.default.js config.js; \
fi
- @NODE_ENV=test ./node_modules/.bin/mocha \
+ @NODE_ENV=test ./node_modules/mocha/bin/mocha \
--reporter $(REPORTER) --timeout $(TESTTIMEOUT) $(TESTS)
-test-dot:
- @$(MAKE) test REPORTER=dot
-
cov:
- @for dir in $(SRC); do \
- mv $$dir $$dir.bak; \
- $(JSCOVERAGE) --encoding=utf-8 $$dir.bak $$dir; \
- done
-
-cov-clean:
- @for dir in $(SRC); do \
- rm -rf $$dir; \
- mv $$dir.bak $$dir; \
- done
+ @rm -rf ../nodeclub-cov
+ @$(JSCOVERAGE) --encoding=utf-8 --exclude=node_modules --exclude=public --exclude=test ./ ../nodeclub-cov
+ @cp -rf ./node_modules ./test ./public ../nodeclub-cov
test-cov: cov
- @-$(MAKE) test REPORTER=html-cov > coverage.html
- @$(MAKE) cov-clean
+ @$(MAKE) -C $(PROJECT_DIR)/../nodeclub-cov test REPORTER=progress
+ @$(MAKE) -C $(PROJECT_DIR)/../nodeclub-cov test REPORTER=html-cov > coverage.html
+ @$(MAKE) test REPORTER=markdown > test_results.md
-.PHONY: test test-cov test-dot cov cov-clean
+.PHONY: test test-cov cov
diff --git a/package.json b/package.json
index 043bc3b..5d58832 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "nodeclub",
- "version": "0.2.2",
+ "version": "0.2.9",
"main": "./app.js",
"private": true,
"dependencies": {
@@ -15,10 +15,10 @@
"data2xml": "0.4.0"
},
"devDependencies": {
- "should": ">=0.6.0",
- "mocha": ">=0.14.1",
- "rewire": ">=0.2.0",
- "visionmedia-jscoverage": ">=1.0.0"
+ "should": "*",
+ "mocha": "*",
+ "rewire": "*",
+ "visionmedia-jscoverage": "*"
},
"scripts": {
"test": "make test"
diff --git a/test_results.md b/test_results.md
new file mode 100644
index 0000000..fc761be
--- /dev/null
+++ b/test_results.md
@@ -0,0 +1,467 @@
+# TOC
+ - [app.js](#appjs)
+ - [controllers/at.js](#controllersatjs)
+ - [searchUsers()](#controllersatjs-searchusers)
+ - [linkUsers()](#controllersatjs-linkusers)
+ - [mock searchUsers() error](#controllersatjs-linkusers-mock-searchusers-error)
+ - [sendMessageToMentionUsers()](#controllersatjs-sendmessagetomentionusers)
+ - [mock Message.send_at_message() error](#controllersatjs-sendmessagetomentionusers-mock-messagesend_at_message-error)
+ - [controllers/rss.js](#controllersrssjs)
+ - [/rss](#controllersrssjs-rss)
+ - [mock `config.rss` not set](#controllersrssjs-rss-mock-configrss-not-set)
+ - [mock `topic.get_topics_by_query()` error](#controllersrssjs-rss-mock-topicget_topics_by_query-error)
+ - [controllers/site.js](#controllerssitejs)
+ - [controllers/status.js](#controllersstatusjs)
+ - [controllers/upload.js](#controllersuploadjs)
+ - [uploadImage()](#controllersuploadjs-uploadimage)
+ - [controllers/user.js](#controllersuserjs)
+ - [plugins/onehost.js](#pluginsonehostjs)
+ - [exclude options](#pluginsonehostjs-exclude-options)
+
+
+
+# app.js
+should / status 200.
+
+```js
+app.request().get('/').end(function (res) {
+ res.should.status(200);
+ done();
+});
+```
+
+
+# controllers/at.js
+
+## searchUsers()
+should found 3 test users.
+
+```js
+searchUsers(text, function (err, users) {
+ should.not.exist(err);
+ should.exist(users);
+ users.should.length(3);
+ for (var i = 0; i < users.length; i++) {
+ var user = users[i];
+ user.name.should.match(/^testuser\d$/);
+ }
+ done();
+});
+```
+
+should found 0 user in text.
+
+```js
+searchUsers('no users match in text @ @@@@ @ @@@ @哈哈 @ testuser1', function (err, users) {
+ should.not.exist(err);
+ should.exist(users);
+ users.should.length(0);
+ done();
+});
+```
+
+should found 0 user in db.
+
+```js
+searchUsers('@testuser123 @suqian2012 @ testuser1 no users match in db @ @@@@ @ @@@',
+function (err, users) {
+ should.not.exist(err);
+ should.exist(users);
+ users.should.length(0);
+ done();
+});
+```
+
+
+## linkUsers()
+should link all mention users.
+
+```js
+mentionUser.linkUsers(text, function (err, text2) {
+ should.not.exist(err);
+ text2.should.equal(linkedText);
+ done();
+});
+```
+
+
+### mock searchUsers() error
+should return error.
+
+```js
+mentionUser.linkUsers(text, function (err, text2) {
+ should.exist(err);
+ err.message.should.equal('mock searchUsers() error');
+ should.not.exist(text2);
+ done();
+});
+```
+
+
+## sendMessageToMentionUsers()
+should send message to all mention users.
+
+```js
+mentionUser.sendMessageToMentionUsers(text, '4fb9db9c1dc2160000000005', '4fcae41e1eb86c0000000003',
+function (err) {
+ should.not.exist(err);
+ done();
+});
+```
+
+should not send message to no mention users.
+
+```js
+mentionUser.sendMessageToMentionUsers('abc no mentions', '4fb9db9c1dc2160000000005', '4fcae41e1eb86c0000000003',
+function (err) {
+ should.not.exist(err);
+ done();
+});
+```
+
+
+### mock Message.send_at_message() error
+should return error.
+
+```js
+mentionUser.sendMessageToMentionUsers(text, '4fb9db9c1dc2160000000005', '4fcae41e1eb86c0000000003',
+function (err) {
+ should.exist(err);
+ err.message.should.equal('mock send_at_message() error');
+ done();
+});
+```
+
+
+# controllers/rss.js
+
+## /rss
+should return `application/xml` Content-Type.
+
+```js
+app.request().get('/rss').end(function (res) {
+ res.should.status(200);
+ res.should.header('content-type', 'application/xml');
+ var body = res.body.toString();
+ body.indexOf('').should.equal(0);
+ body.should.include('');
+ body.should.include('' + config.rss.title + '');
+ done();
+});
+```
+
+
+### mock `config.rss` not set
+should return waring message.
+
+```js
+app.request().get('/rss').end(function (res) {
+ res.should.status(404);
+ res.body.toString().should.equal('Please set `rss` in config.js');
+ done();
+});
+```
+
+
+### mock `topic.get_topics_by_query()` error
+should return error.
+
+```js
+app.request().get('/rss').end(function (res) {
+ res.should.status(500);
+ res.body.toString().should.include('mock get_topics_by_query() error');
+ done();
+});
+```
+
+
+# controllers/site.js
+should /index 200.
+
+```js
+app.request().get('/').end(function (res) {
+ res.should.status(200);
+ done();
+});
+```
+
+should /?q=neverexistskeyword 200.
+
+```js
+app.request().get('/?q=neverexistskeyword').end(function (res) {
+ res.should.status(200);
+ res.body.toString().should.include('无话题');
+ done();
+});
+```
+
+should /?q=neverexistskeyword&q=foo2 200.
+
+```js
+app.request().get('/?q=neverexistskeyword&q=foo2').end(function (res) {
+ res.should.status(200);
+ res.body.toString().should.include('无话题');
+ done();
+});
+```
+
+
+# controllers/status.js
+should /status 200.
+
+```js
+app.request().get('/status').end(function (res) {
+ res.should.status(200);
+ res.should.header('content-type', 'application/json; charset=utf-8');
+ var json;
+ try {
+ json = JSON.parse(res.body.toString());
+ } catch (e) {
+ done(e);
+ }
+ json.should.have.property("status", "success");
+ json.should.have.property("now");
+ done();
+});
+```
+
+
+# controllers/upload.js
+
+## uploadImage()
+should forbidden when user not login.
+
+```js
+upload.uploadImage({}, {
+ send: function (data) {
+ data.should.have.property('status', 'forbidden');
+ done();
+ }
+}, function () {
+ throw new Error('should not call this method');
+});
+```
+
+should failed when no file upload.
+
+```js
+upload.uploadImage(mockRequest, {
+ send: function (data) {
+ data.should.have.property('status', 'failed');
+ data.should.have.property('message', 'no file');
+ done();
+ }
+}, function () {
+ throw new Error('should not call this method');
+});
+```
+
+should upload file success.
+
+```js
+upload.uploadImage(mockLoginedRequest, {
+ send: function (data) {
+ data.should.have.property('status', 'success');
+ data.should.have.property('url');
+ data.url.should.match(/^\/upload\/mock_user_id\/\d+\_tmp_test_file\.png$/);
+ var uploadfile = path.join(tmpdirpath, data.url.replace('/upload/', ''));
+ should.ok(path.existsSync(uploadfile));
+ done();
+ }
+}, function () {
+ throw new Error('should not call this method');
+});
+```
+
+should return mock ndir.mkdir() error.
+
+```js
+var upload2 = rewire('../../controllers/upload');
+upload2.__set__({
+ ndir: {
+ mkdir: function (dir, callback) {
+ process.nextTick(function () {
+ callback(new Error('mock ndir.mkdir() error'));
+ });
+ }
+ }
+});
+
+upload2.uploadImage(mockLoginedRequest, {
+ send: function (data) {
+ throw new Error('should not call this method');
+ }
+}, function (err) {
+ should.exist(err);
+ err.message.should.equal('mock ndir.mkdir() error');
+ done();
+});
+```
+
+should return mock fs.rename() error.
+
+```js
+var upload3 = rewire('../../controllers/upload');
+upload3.__set__({
+ fs: {
+ rename: function (from, to, callback) {
+ process.nextTick(function () {
+ callback(new Error('mock fs.rename() error'));
+ });
+ }
+ }
+});
+
+upload3.uploadImage(mockLoginedRequest, {
+ send: function (data) {
+ throw new Error('should not call this method');
+ }
+}, function (err) {
+ should.exist(err);
+ err.message.should.equal('mock fs.rename() error');
+ done();
+});
+```
+
+
+# controllers/user.js
+/user/testuser1 should 200.
+
+```js
+app.request().get('/user/testuser1').end(function (res) {
+ res.should.status(200);
+ done();
+});
+```
+
+/stars should 200.
+
+```js
+app.request().get('/stars').end(function (res) {
+ res.should.status(200);
+ done();
+});
+```
+
+/users/top100 should 200.
+
+```js
+app.request().get('/users/top100').end(function (res) {
+ res.should.status(200);
+ done();
+});
+```
+
+/setting should 302 when not login.
+
+```js
+app.request().get('/setting').end(function (res) {
+ res.should.status(302);
+ done();
+});
+```
+
+
+# plugins/onehost.js
+should 301 redirect all `GET` to test.localhost.onehost.com.
+
+```js
+app.request().get('/foo/bar').end(function (res) {
+ res.should.status(301);
+ res.headers.location.should.equal('http://' + bindHost + '/foo/bar');
+ done();
+});
+```
+
+should 301 when GET request 127.0.0.1:port.
+
+```js
+app.request({ address: '127.0.0.1', port: app.address().port }).get('/foo/bar').end(function (res) {
+ res.should.status(301);
+ res.headers.location.should.equal('http://' + bindHost + '/foo/bar');
+ done();
+});
+```
+
+should no redirect for `post`.
+
+```js
+app.request()[method]('/foo/bar').end(function (res) {
+ res.should.status(200);
+ res.headers.should.not.have.property('location');
+ if (method === 'head') {
+ res.body.should.length(0);
+ } else {
+ res.body.toString().should.equal(method.toUpperCase() + ' /foo/bar');
+ }
+ done();
+});
+```
+
+should no redirect for `put`.
+
+```js
+app.request()[method]('/foo/bar').end(function (res) {
+ res.should.status(200);
+ res.headers.should.not.have.property('location');
+ if (method === 'head') {
+ res.body.should.length(0);
+ } else {
+ res.body.toString().should.equal(method.toUpperCase() + ' /foo/bar');
+ }
+ done();
+});
+```
+
+should no redirect for `delete`.
+
+```js
+app.request()[method]('/foo/bar').end(function (res) {
+ res.should.status(200);
+ res.headers.should.not.have.property('location');
+ if (method === 'head') {
+ res.body.should.length(0);
+ } else {
+ res.body.toString().should.equal(method.toUpperCase() + ' /foo/bar');
+ }
+ done();
+});
+```
+
+should no redirect for `head`.
+
+```js
+app.request()[method]('/foo/bar').end(function (res) {
+ res.should.status(200);
+ res.headers.should.not.have.property('location');
+ if (method === 'head') {
+ res.body.should.length(0);
+ } else {
+ res.body.toString().should.equal(method.toUpperCase() + ' /foo/bar');
+ }
+ done();
+});
+```
+
+
+## exclude options
+should 301 redirect all `GET` to test.localhost.onehost.com.
+
+```js
+app.request().get('/foo/bar').end(function (res) {
+ res.should.status(301);
+ res.headers.location.should.equal('http://' + bindHost + '/foo/bar');
+ done();
+});
+```
+
+should 200 when request GET exclude host.
+
+```js
+app2.request({ address: '127.0.0.1', port: 58964 }).get('/foo/bar').end(function (res) {
+ res.should.status(200);
+ res.body.toString().should.equal('GET /foo/bar');
+ done();
+});
+```
+