聲明:
如下爲老馬的全棧視頻教程的筆記,若是須要了解詳情,請直接配合視頻學習。視頻所有免費,視頻地址:https://ke.qq.com/course/294595?tuin=1eb4a0a4javascript
$ npm i -g nodemon # 使用: nodemon app.js
官網: https://aui.github.io/art-template/zh-cn/index.htmlphp
第一步: 引入 art-template 的包css
npm install --save art-template npm install --save express-art-template
第二步:項目中設置 express 的應用 art-template 模板引擎html
const art_express = require('express-art-template'); const app = express(); // 建立app對象。 // 設置art的模板引擎 app.engine('art', art_express); app.get('/user/list', (req, res) => { res.render('users/userlist2.art', { title: '你好啊!', users: userService.getUsers() }); });
{{value}}
{{data.key}}
{{data['key']}} {{a ? b : c}} {{a || b}} {{a + b}}
<%= value %> <%= data.key %> <%= data['key'] %> <%= a ? b : c %> <%= a || b %> <%= a + b %>
模板一級特殊變量能夠使用 $data
加下標的方式訪問:java
{{$data['user list']}}
node
{{@ value }}
原始語法git
<%- value %>
github
原文輸出語句不會對 HTML 內容進行轉義處理,可能存在安全風險,請謹慎使用。shell
{{if value}} ... {{/if}} {{if v1}} ... {{else if v2}} ... {{/if}}
原始語法express
<% if (value) { %> ... <% } %> <% if (v1) { %> ... <% } else if (v2) { %> ... <% } %>
{{each target}}
{{$index}} {{$value}} {{/each}}
原始語法
<% for(var i = 0; i < target.length; i++){ %> <%= i %> <%= target[i] %> <% } %>
target
支持 array
與 object
的迭代,其默認值爲 $data。$value
與 $index
能夠自定義:{{each target val key}}
。變量標準語法
{{set temp = data.sub.content}}
原始語法
<% var temp = data.sub.content; %>
{{extend './layout.art'}} {{block 'head'}} ... {{/block}}
原始語法
<% extend('./layout.art') %> <% block('head', function(){ %> ... <% }) %>
模板繼承容許你構建一個包含你站點共同元素的基本模板「骨架」。範例:
<!--layout.art--> <!doctype html> <html> <head> <meta charset="utf-8"> <title>{{block 'title'}}My Site{{/block}}</title> {{block 'head'}} <link rel="stylesheet" href="main.css"> {{/block}} </head> <body> {{block 'content'}}{{/block}} </body> </html> <!--index.art--> {{extend './layout.art'}} {{block 'title'}}{{title}}{{/block}} {{block 'head'}} <link rel="stylesheet" href="custom.css"> {{/block}} {{block 'content'}} <p>This is just an awesome page.</p> {{/block}}
渲染 index.art 後,將自動應用佈局骨架。
{{include './header.art'}} {{include './header.art' data}}
原始語法
<% include('./header.art') %> <% include('./header.art', data) %>
data
數默認值爲 $data
;標準語法不支持聲明 object
與 array
,只支持引用變量,而原始語法不受限制。art-template
內建 HTML 壓縮器,請避免書寫 HTML 非正常閉合的子模板,不然開啓壓縮後標籤可能會被意外「優化。過濾器註冊過濾器
template.defaults.imports.dateFormat = function(date, format){/_[code..]_/};
template.defaults.imports.timestamp = function(value){return value \* 1000};
標準語法
{{date | timestamp | dateFormat 'yyyy-MM-dd hh:mm:ss'}} {{value | filter}} 過濾器語法相似管道操做符,它的上一個輸出做爲下一個輸入。
原始語法
<%= $imports.dateFormat($imports.timestamp(date), 'yyyy-MM-dd hh:mm:ss') %>
官網地址: http://mockjs.com/
安裝:npm install mockjs
// 使用 Mock var Mock = require('mockjs'); let data = Mock.mock({ "users|33": [{ "id|+1": 20000, "name": "@cname", "email": "@email", "phone": "@natural(132000000,133000000)", "address": "@county(true)", "zip": "@zip", "birthday": "@date('yyyy-MM-dd')" }] }); // 輸出結果 console.log(JSON.stringify(data, null, 4));
安裝
$ npm install --global mocha
建立測試文件夾 test 目錄,而後添加測試腳本文件
// 引用node的默認的斷言庫 var assert = require('assert'); // 建立描述場景 describe('Array', function() { // 場景能夠進行嵌套 describe('#indexOf()', function() { // 實際的測試用例 it('should return -1 when the value is not present', function() { assert.equal(-1, [1, 2, 3].indexOf(4)); }); }); });
執行測試:
$ mocha
行爲驅動開發(英語:Behavior-driven development,縮寫 BDD)是一種敏捷軟件開發的技術,它鼓勵軟件項目中的開發者、QA 和非技術人員或商業參與者之間的協做。BDD(行爲驅動開發 )是第二代的、由外及內的、基於拉(pull)的、多方利益相關者的(stakeholder)、多種可擴展的、高自動化的敏捷方法。它描述了一個交互循環,能夠具備帶有良好定義的輸出(即工做中交付的結果):已測試過的軟件。
mocha 默認的測試接口是 bdd 的方式。
describe('Array', function() { before(function() { // ... }); describe('#indexOf()', function() { it('should return -1 when not present', function() { [1, 2, 3].indexOf(4).should.equal(-1); }); }); after(function() { // ... }); });
TDD,全稱 Test-driven Development,中文測試驅動開發,主要方法:先寫測試用例(test case),測試用例寫好後,再來實現須要實現的方法或功能。
如下是 TDD 的接口列表
suite:定義一組測試用例。
suiteSetup:此方法會在這個 suite 全部測試用例執行前執行一次,只一次,這是跟 setup 的區別。
setup:此方法會在每一個測試用例執行前都執行一遍。
test:具體執行的測試用例實現代碼。
teardown:此方法會在每一個測試用例執行後都執行一遍,與 setup 相反。
suiteTeardown:此方法會在這個 suite 全部測試用例執行後執行一次,與 suiteSetup 相反。
這些接口都是與 TDD 概念中的接口對應與相關實現,方便組織測試用例。BDD 的接口在這裏不予贅述,可參考官方文檔。
var assert = require('assert'); var mocha = require('mocha'); var suite = mocha.suite; var setup = mocha.setup; var suiteSetup = mocha.suiteSetup; var test = mocha.test; var teardown = mocha.teardown; var suiteTeardown = mocha.suiteTeardown; //test case suite('Array', function() { suiteSetup(function() { //suiteSetup will run only 1 time in suite Array, before all suite //... console.log('suitSetup...'); }); setup(function() { //setup will run 1 time before every suite runs in suite Array //... console.log('setup...'); }); suite('indexOf()', function() { test('should return -1 when not present', function() { assert.equal(-1, [1, 2, 3].indexOf(4)); }); }); suite('indexOf2()', function() { test('should return not -1 when present', function() { assert.equal(0, [1, 2, 3].indexOf(1)); }); }); teardown(function() { //teardown will run 1 time after every suite runs in suite Array //... console.log('teardown...'); }); suiteTeardown(function() { //suiteTeardown will run 1 time in suite Array, after all suits run over. //... console.log('suiteTeardown...'); }); });
$ npm install should -P
should 提供了一個全局方法,構造一個斷言對象。
const should = require('should'); var obj = { a: 123 }; should(obj).eqls({ a: 123 }); should(obj).be.a.Object();
另外 should 劫持了 Object 的原型對象,因此全部的對象都擁有了 should 方法。should.js 源碼以下:
/** * Expose api via `Object#should`. * * @api public */ Object.defineProperty(Object.prototype, 'should', { set: function() {}, get: function() { return should(this); }, configurable: true });
因此代碼中能夠直接用 should 方法構建斷言對象。
const a = { b: 123 }; a.should.be.a.Object(); a.b.should.above(3);
should(3).eql(3)
should(3).notEqual(45)
should(3).equal(3)
should(3>1).true()
[1, 2, 3].should.containEql(1);
(10).should.be.above(0);
(0).should.be.belowOrEqual(10);
(10).should.not.be.NaN();
[1, 2].should.have.length(2);
其餘
'abca'.should.endWith('a'); 'abc'.should.startWith('a'); ({ a: 10 }.should.have.value('a', 10)); ({ a: 10 }.should.have.property('a')); 'ab'.should.be.equalOneOf('a', 10, 'ab');
should 實現了能夠直接鏈式編程的效果,這些方法內部都是返回斷言對象自身,可是語義化卻厲害了,其中能夠直接應用鏈式編程的有:['an', 'of', 'a', 'and', 'be', 'has', 'have', 'with', 'is', 'which', 'the', 'it']
應用:
const should = require('should'); describe('#getUsers 測試獲取用戶全部數據', function() { it('service.getUsers() should be Array', function() { should(service.getUsers()).be.a.Array(); }); it('service.getPageUsers(2, 5) should return Array[]', function() { let data = service.getPageUsers(2, 5); // should(users).be.a.Object(); (data.users.length <= 5).should.be.true(); let returnUser = service.addUser(addUser); returnUser.should.containEql(addUser); returnMsg.should.be.eql({ status: 1, msg: '刪除成功' }); service.getUserById(10008).should.be.containEql({ status: 1, msg: 'ok' }); }); });
代碼覆蓋率(code coverage
)。它有四個測量維度。
Istanbul 是 JavaScript 程序的代碼覆蓋率工具
$ npm install -g istanbul
$ istanbul cover simple.js ===== Coverage summary ===== Statements : 75% ( 3/4 ) Branches : 50% ( 1/2 ) Functions : 100% ( 0/0 ) Lines : 75% ( 3/4 ) =============================
這條命令同時還生成了一個 coverage
子目錄,其中的 coverage.json
文件包含覆蓋率的原始數據,coverage/lcov-report
是能夠在瀏覽器打開的覆蓋率報告,其中有詳細信息,到底哪些代碼沒有覆蓋到。
$ istanbul cover _mocha
上面命令中,istanbul cover 命令後面跟的是 _mocha 命令,前面的下劃線是不能省略的。由於,mocha 和 _mocha 是兩個不一樣的命令,前者會新建一個進程執行測試,然後者是在當前進程(即 istanbul 所在的進程)執行測試,只有這樣, istanbul 纔會捕捉到覆蓋率數據。其餘測試框架也是如此,必須在同一個進程執行測試。
若是要向 mocha 傳入參數,能夠寫成下面的樣子。
$ istanbul cover _mocha -- tests/test.sqrt.js -R spec
上面命令中,兩根連詞線後面的部分,都會被看成參數傳入 Mocha 。若是不加那兩根連詞線,它們就會被看成 istanbul 的參數