<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC] ## 概況 ### 背景 當我們在寫一些UI測試的時候,我們總需要到瀏覽器去看一下一些DOM的變化。比如,我們點擊了某個下拉菜單,會有另外一個聯動的下拉菜單發生了變化。而如果這個事件更復雜的時候,有時我們可能就很難觀察出來他們之間的變化。 ### ShowCase ![](https://box.kancloud.cn/2016-05-18_573c1daaef5f0.jpg) Luffa Screenshot 源碼見:[https://github.com/phodal/luffa](https://github.com/phodal/luffa) ### 基本原理 盡管這里的例子是以Jasmine作為例子,但是我想對于React也會有同樣的方法。 **一個Jasmine jQuery測試** 如下是一個簡單的Jamine jQuery的測試示例: ~~~ describe("toHaveCss", function (){ beforeEach(function (){ setFixtures(sandbox()) }) it("should pass if the element has matching css", function (){ $("#sandbox").css("display", "none") $("#sandbox").css("margin-left", "10px") expect($("#sandbox")).toHaveCss({display: "none", "margin-left": "10px"}) }) }); ~~~ 在beforeEach的時候,我們設定了固定的DOM進去,按照用戶的行為做一些相應的操作。接著依據這個DOM中的元素變化 ,來作一些斷言。 那么,即使我們已經有一個固定的DOM,想要監聽這個DOM的變化就是一件容易的事。在我們斷言之前,我們就會有一個新的DOM。我們只需要Diff一下這兩個DOM的變化,就可以生成這部分測試代碼。 ## 步驟 ### Step 1: Virtual-dom與HyperScript 在尋覓中發現了[virtual-dom](https://github.com/Matt-Esch/virtual-dom)這個庫,一個可以支持創建元素、diff計算以及patch操作的庫,并且它效率好像還不錯。 virtual-dom可以說由下面幾部分組成的: 1. createElement,用于創建virtual Node。 2. diff,顧名思義,diff算法。 3. h,用于創建虛擬樹的DSL——HyperScript。HyperScript是一個JavaScript的HyperText。 4. patch,用于patch修改的內容。 舉例來說,我們有下面一個生成Virtual DOM的函數: ~~~ function render(count) { return h('div', { style: { textAlign: 'center', lineHeight: (100 + count) + 'px', border: '1px solid red', width: (100 + count) + 'px', height: (100 + count) + 'px' } }, [String(count)]); } ~~~ render函數用于生成一個Virtual Node。在這里,我們可以將我們的變量傳進去,如1。就會生成如下圖所示的節點: ~~~ { "children": [ { "text": "1" } ], "count": 1, "descendantHooks": false, "hasThunks": false, "hasWidgets": false, "namespace": null, "properties": { "style": { "border": "1px solid red", "height": "101px", "lineHeight": "101px", "textAlign": "center", "width": "101px" } }, "tagName": "DIV" } ~~~ 其中包含中相對應的屬性等等。而我們只要調用createElement就可以創建出這個DOM。 如果我們修改了這個節點的一些元素,或者我們render了一個count=2的值時,我們就可以diff兩個DOM。如: ~~~ virtualDom.diff(render(2), render(1)) ~~~ 根據兩個值的變化就會生成如下的一個對象: ~~~ { "0": { "patch": { "style": { "height": "101px", "lineHeight": "101px", "width": "101px" } }, "type": 4, "vNode": { ... } }, "1": { "patch": { "text": "1" }, "type": 1, "vNode": { "text": "2" } }, ... } ~~~ 第一個對象,即0中包含了一些屬性的變化。而第二個則是文本的變化——從2變成了1。我們所要做的測試生成便是標記這些變化,并記錄之。 ### Step 2: 標記DOM變化 由于virtual-dom依賴于虛擬節點vNode,我們需要將fixtures轉換為hyperscript。這里我們就需要一個名為html2hyperscript的插件,來解析html。接著,我們就可以diff轉換完后的DOM: ~~~ var leftNode = "", rightNode = ""; var fixtures = '<div id="example"><h1 class="hello">Hello World</h1></div>'; var change = '<div id="example"><h1 class="hello">Hello World</h1><h2>fs</h2></div>'; parser(fixtures, function (err, hscript) { leftNode = eval(hscript); }); parser(change, function (err, hscript) { rightNode = eval(hscript); }); var patches = diff(leftNode, rightNode); ~~~ 接著,我們需要調用patch函數來做一些相應的改變。 ~~~ luffa.patch(virtualDom.create(leftNode), patches) ~~~ 并且,我們可以嘗試在patch階段做一些處理——輸出修改: ~~~ function printChange(originRootNodeHTML, applyNode) { var patchType; for (var patchIndex = 0; patchIndex < applyNode.newNodes.length; patchIndex++) { patchType = applyNode.newNodes[patchIndex].method; switch (patchType) { case 'insert': printInsert(applyNode); break; case 'node': printNode(applyNode, originRootNodeHTML, patchIndex); break; case 'remove': printRemove(applyNode, originRootNodeHTML, patchIndex); break; case 'string': printString(applyNode, originRootNodeHTML, patchIndex); break; case 'prop': printProp(applyNode, originRootNodeHTML, patchIndex); break; default: printDefault(applyNode, originRootNodeHTML, patchIndex); } } } ~~~ 根據不同的類型,作一些對應的輸出處理,如pringNode: ~~~ function printNode(applyNode, originRootNodeHTML, patchIndex) { var originNode = $(applyNode.newNodes[patchIndex].vNode).prop('outerHTML') || $(applyNode.newNodes[patchIndex].vNode).text(); var newNode = $(applyNode.newNodes[patchIndex].newNode).prop('outerHTML'); console.log('%c' + originRootNodeHTML.replace(originNode, '%c' + originNode + '%c') + ', %c' + newNode, luffa.ORIGIN_STYLE, luffa.CHANGE_STYLE, luffa.ORIGIN_STYLE, luffa.NEW_STYLE); } ~~~ 用Chrome的console來標記修改的部分,及添加的部分。 最后,我們似乎就可以生成相應的測試代碼了。。。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看