Sean's Note: 2017

2017年4月30日 星期日

Node.js 學習筆記(三) - 使用 Mocha, Expect 和 SuperTest 來做測試 Testing with Mocha, Expect and SuperTest

Mocha

Mocha 是一套 JavaScript 的測試 framework。透過 npm 安裝:
npm install mocha --save
範例:
const math_utils = require ('./math_utils')

it('add two numbers', () => {
  var res = math_utils.add(1, 2);

  if (res !== 3) {
    throw new Error(`Expected 3, but got ${res}.`);
  }
});

it('add two numbers', () => {
  var res = math_utils.add(1, 2);

  if (res !== 4) {
    throw new Error(`Expected 4, but got ${res}.`);
  }
});
然後透過修改 package.json 來增加測試的腳本:
{
  ...
  "scripts": {
    "test": "mocha **/**.test.js"
  },
  ...
}
之後在 console 上執行:
npm test
就可以看到 test 的結果如圖1,有一個成功一個失敗。

圖1. npm test

Expect

Expect 是一套 Assertion Library。
npm install expect --save
有了 Expect,我們就可以把上面的範例改寫成:
const expect = require ('expect')
const math_utils = require ('./math_utils')

it('add two numbers', () => {
  var res = math_utils.add(1, 2);

  expect(res).toBe(3);
});

it('add two numbers', () => {
  var res = math_utils.add(1, 2);

  expect(res).toNotBe(4);
});
GitHub 的文件有更多的範例可以參考。

非同步的測試 Testing Asynchronous Code

const expect = require ('expect')
const math_utils = require ('./math_utils')

it('add two numbers', () => {
  var res = math_utils.addAsync(1, 2, (sum) => {
  expect(sum).toBe(4);
});
上面的測試是會成功 pass 的,因為 Mocha 跑完 addAsync 就結束了,根本沒有等 callback 回來,所以為了告訴 Mocha 等待,必須使用 done:
const expect = require ('expect')
const math_utils = require ('./math_utils')

it('add two numbers', (done) => {
  var res = math_utils.addAsync(1, 2, (sum) => {
  expect(sum).toBe(4);
  done();
});
這樣就可以讓此測試預期是失敗的。

SuperTest

SuperTest 是一套用來測試 HTTP Request 的 Assertion Library。
npm install supertest --save
可以直接參考 GitHub 的文件範例。

2017年4月14日 星期五

[GitHub] 如何調整 PR 上圖片的大小與增加邊框

  • 調整圖片的大小:
    <img src="..." width="300">

  • 為圖片增加增加邊框:
    <kbd>
        <img ...>
    </kbd>

2017年3月5日 星期日

Node.js 學習筆記 (二)

Express

Express 是最小又靈活的 Node.js Web 應用程式架構。
以下是一個簡單的 Hello World Web Application 範例:
var express = require('express');
var app = express();

app.get('/', function (req, res) {
  res.send('Hello Express!');
});

app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});
第四行指的是設定了一個 handler,用來處理 "/" 的網頁請求,結果如圖 1。
圖1. Hello Express!

使用中介軟體 (Middleware)

在 express app 回傳任何請求前,可以透過 middleware function 來截斷請求,這裡可以用來印一些資訊到 console 上,或處理驗證請求的合法性。之後呼叫 next 函式,讓請求繼續被處理,否則程式會停擺在那。
範例,在任何請求之前印出當前的時間資訊:
var app = express()

app.use(function (req, res, next) {
  console.log('Time:', Date.now())
  next()
})

Handlebars

Handlebars 是一套模板引擎,且相容於 Mustache 的格式,可以用來動態渲染 HTML 的內容。
透過 npm 安裝:
npm install hbs --save
範例:
var express = require('express');
var hbs = require('hbs');

var app = express();
app.set('view engine', 'hbs');
app.get('/about', function (req, res) {
  res.render('about.hbs', {
    pageTitle: 'This is About Page!'
  });
});

app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});
// about.hbs
<pre class="brush: html">
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>{{pageTitle}}</title>
</head>
<body>
    <h1>About Page</h1>
</body>
</html>
在網址列上輸入 localhost:3000/about 後,就可以看到顯示 "This is About Page!",表示 pageTitle 有正確被傳遞給 about.hbs 了。

部署網頁應用程式

網路上有很多平台,可以幫助開發者或企業部署網頁應用程式,如 HEROKU, Amazon S3 等等。

2017年2月21日 星期二

Node.js 學習筆記 (一)

Node.js 的幾個特點:
1.  Runtime 是建立於 Chrome 的 V8 JavaScript 引擎之上的。
2. Event-driven 和 non-blocking I/O 的模型架構

npm

學 Node.js 不能不知道 npm 這個套件管理程式,npm 如同於 iOS 的 CocoaPods 抑或是 Python 的 pip 和 setuptools,透過一行指令就可以讓你方便下載別人已經寫好的套件,來加速開發應用程式。Node.js 會吸引了廣大的開發者,一部分也是因為 npm 上廣大的社群和擁有許多強大好用的套件。

用什麼編輯器來開發 Node.js?

Atom, Visual Studio Code, Sublime Text 都是不錯的選擇。

如何執行?

安裝好 node 後,只要執行以下的指令,就可以執行已經寫好的 app.js。
node app.js

常用的內建套件

常用的內建套件如:
  • File System - require('fs'),用來讀寫檔案
  • Process - no require needed,process.argv 用來讀取命令列的參數
  • ...etc.
參考更多:https://nodejs.org/dist/latest-v7.x/docs/api/

如何使用第三方套件

有些好用的套件 Node.js 本身不提供,但透過 npm 就可以很方便的下載,使用前必須先將專案初始化:
npm init
此時,專案裡就會產生一個 package.json:
{
  "name": "notes",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Sean",
  "license": "ISC"
}
這時還看不出來這個檔案有什麼用途,一旦我們安裝了一個套件之後
npm install lodash --save
檔案裡就會多了一個 dependencies 的欄位紀錄了這個專案所用到的套件。而下載過的這些套件也是不需要上傳到 repository 的,一起開發的夥伴們只需要下載原始碼,並且在本機端執行 npm install 就可以把所有專案用到的套件給下載下來。
{
  "name": "notes",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Sean",
  "license": "ISC",
  "dependencies": {
    "lodash": "^4.17.4"
  }
}

Lodash

Lodash makes JavaScript easier by taking the hassle out of working with arrays, numbers, objects, strings, etc.

yargs

Yargs helps you build interactive command line tools by parsing arguments and generating an elegant user interface.

request

Request is designed to be the simplest way possible to make http calls. It supports HTTPS and follows redirects by default.

nodemon

nodemon will watch the files in the directory in which nodemon was started, and if any files change, nodemon will automatically restart your node application.

如何除錯 debug?

Node.js 除了可以用 console.log() 的方法來觀察物件的值(對於寫 C/C++ 的人來說就是 printf 大法),也可以透過下斷點 (Break Point) 的方式來逐行除錯,只是不像 iOS 有 XCode,Android 有 Android Studio 一般,有友善的 IDE 介面來幫助除錯,而是透過指令的方式。例如輸入 next(n) 就是在往下一行執行。
node debug app.js

< Debugger listening on 127.0.0.1:5858
connecting to 127.0.0.1:5858 ... ok
break in app.js:1
> 1 console.log("Starting...");
  2
  3 const fs = require('fs');
debug> n
< Starting...
break in app.js:3
  1 console.log("Starting...");
  2
> 3 const fs = require('fs');
  4 const notes = require('./notes');
  5 const _ = require('lodash');
debug>


2017年2月13日 星期一

How to scroll TextView smoothly to bottom

 
   private void scrollToTop() {
        textViewLog.scrollTo(0, 0);
    }

   private void scrollToBottom() {
        final int scrollAmount = textViewLog.getLineCount() * textViewLog.getLineHeight() - (textViewLog.getBottom() - textViewLog.getTop());
        textViewLog.scrollTo(0, Math.max(0, scrollAmount));
    }
不過 TextView 的 scroll 並不是很 smooth,可以用 ScrollView 包覆 TextView 的方式來解決,並改用 ScrollView 的 Scroll 方法。
 
    private void scrollToTop() {
        scrollView.scrollTo(0, 0);
    }

    private void scrollToBottom() {
        scrollView.fullScroll(ScrollView.FOCUS_DOWN);
    }