国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

基于Virtual DOM與Diff DOM的測(cè)試代碼生成

CoXie / 3412人閱讀

摘要:但是,我還是覺得這是一個(gè)非常不錯(cuò)的話題測(cè)試代碼生成。,用于創(chuàng)建虛擬樹的。,用于修改的內(nèi)容。而第二個(gè)則是文本的變化從變成了。我們所要做的測(cè)試生成便是標(biāo)記這些變化,并記錄之。其他源碼見原文基于與的測(cè)試代碼生成

盡管是在年末,并且也還沒把書翻譯完,也還沒寫完書的第一稿。但是,我還是覺得這是一個(gè)非常不錯(cuò)的話題——測(cè)試代碼生成。

當(dāng)我們?cè)趯懸恍︰I測(cè)試的時(shí)候,我們總需要到瀏覽器去看一下一些DOM的變化。比如,我們點(diǎn)擊了某個(gè)下拉菜單,會(huì)有另外一個(gè)聯(lián)動(dòng)的下拉菜單發(fā)生了變化。而如果這個(gè)事件更復(fù)雜的時(shí)候,有時(shí)我們可能就很難觀察出來他們之間的變化。

Virtual DOM

盡管這里的例子是以Jasmine作為例子,但是我想對(duì)于React也會(huì)有同樣的方法。

一個(gè)Jasmine jQuery測(cè)試

如下是一個(gè)簡(jiǎn)單的Jamine jQuery的測(cè)試示例:

  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的時(shí)候,我們?cè)O(shè)定了固定的DOM進(jìn)去,按照用戶的行為做一些相應(yīng)的操作。接著依據(jù)這個(gè)DOM中的元素變化 ,來作一些斷言。

那么,即使我們已經(jīng)有一個(gè)固定的DOM,想要監(jiān)聽這個(gè)DOM的變化就是一件容易的事。在我們斷言之前,我們就會(huì)有一個(gè)新的DOM。我們只需要Diff一下這兩個(gè)DOM的變化,就可以生成這部分測(cè)試代碼。

virtual-dom與HyperScript

在尋覓中發(fā)現(xiàn)了virtual-dom這個(gè)庫,一個(gè)可以支持創(chuàng)建元素、diff計(jì)算以及patch操作的庫,并且它效率好像還不錯(cuò)。

virtual-dom可以說由下面幾部分組成的:

createElement,用于創(chuàng)建virtual Node。

diff,顧名思義,diff算法。

h,用于創(chuàng)建虛擬樹的DSL——HyperScript。HyperScript是一個(gè)JavaScript的HyperText。

patch,用于patch修改的內(nèi)容。

舉例來說,我們有下面一個(gè)生成Virtual DOM的函數(shù):

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函數(shù)用于生成一個(gè)Virtual Node。在這里,我們可以將我們的變量傳進(jìn)去,如1。就會(huì)生成如下圖所示的節(jié)點(diǎn):

{
    "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"
}

其中包含中相對(duì)應(yīng)的屬性等等。而我們只要調(diào)用createElement就可以創(chuàng)建出這個(gè)DOM。

如果我們修改了這個(gè)節(jié)點(diǎn)的一些元素,或者我們r(jià)ender了一個(gè)count=2的值時(shí),我們就可以diff兩個(gè)DOM。如:

virtualDom.diff(render(2), render(1))

根據(jù)兩個(gè)值的變化就會(huì)生成如下的一個(gè)對(duì)象:

{
    "0": {
        "patch": {
            "style": {
                "height": "101px",
                "lineHeight": "101px",
                "width": "101px"
            }
        },
        "type": 4,
        "vNode": {
            ...
        }
    },
    "1": {
        "patch": {
            "text": "1"
        },
        "type": 1,
        "vNode": {
            "text": "2"
        }
    },
    ...
}

第一個(gè)對(duì)象,即0中包含了一些屬性的變化。而第二個(gè)則是文本的變化——從2變成了1。我們所要做的測(cè)試生成便是標(biāo)記這些變化,并記錄之。

標(biāo)記DOM變化

由于virtual-dom依賴于虛擬節(jié)點(diǎn)vNode,我們需要將fixtures轉(zhuǎn)換為hyperscript。這里我們就需要一個(gè)名為html2hyperscript的插件,來解析html。接著,我們就可以diff轉(zhuǎn)換完后的DOM:

var leftNode = "", rightNode = "";
var fixtures = "

Hello World

"; var change = "

Hello World

fs

"; parser(fixtures, function (err, hscript) { leftNode = eval(hscript); }); parser(change, function (err, hscript) { rightNode = eval(hscript); }); var patches = diff(leftNode, rightNode);

接著,我們需要調(diào)用patch函數(shù)來做一些相應(yīng)的改變。

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);
    }
  }
}

根據(jù)不同的類型,作一些對(duì)應(yīng)的輸出處理,如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來標(biāo)記修改的部分,及添加的部分。

最后,我們似乎就可以生成相應(yīng)的測(cè)試代碼了。。。

其他

源碼見:https://github.com/phodal/luffa
原文:基于Virtual DOM與Diff DOM的測(cè)試代碼生成

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/78347.html

相關(guān)文章

  • 你不知道Virtual DOM(五):自定義組件

    摘要:現(xiàn)在流行的前端框架都支持自定義組件,組件化開發(fā)已經(jīng)成為提高前端開發(fā)效率的銀彈。二對(duì)自定義組件的支持要想正確的渲染組件,第一步就是要告訴某個(gè)標(biāo)簽是自定義組件。下面的例子里,就是一個(gè)自定義組件。解決了識(shí)別自定義標(biāo)簽的問題,下一步就是定義標(biāo)簽了。 歡迎關(guān)注我的公眾號(hào)睿Talk,獲取我最新的文章:showImg(https://segmentfault.com/img/bVbmYjo); 一、...

    lk20150415 評(píng)論0 收藏0
  • 解讀React源碼(一):初探React源碼

    摘要:前言的基本概念組件的構(gòu)建方法以及高級(jí)用法這背后的一切如何運(yùn)轉(zhuǎn)深入內(nèi)部的實(shí)現(xiàn)機(jī)制和原理初探源碼代碼組織結(jié)構(gòu)包含一系列的工具方法插件包含一系列同構(gòu)方法包含一些公用或常用方法如等包含一些測(cè)試方法等包含一些邊界錯(cuò)誤的測(cè)試用例是代碼的核心部分它包含了 前言 React的基本概念,API,組件的構(gòu)建方法以及高級(jí)用法,這背后的一切如何運(yùn)轉(zhuǎn),深入Virtual DOM內(nèi)部的實(shí)現(xiàn)機(jī)制和原理. 初探Rea...

    Eminjannn 評(píng)論0 收藏0
  • 你不知道Virtual DOM(三):Virtual Dom更新優(yōu)化

    摘要:經(jīng)過這次優(yōu)化,計(jì)算的時(shí)間快了那么幾毫秒。基于當(dāng)前這個(gè)版本的代碼還能做怎樣的優(yōu)化呢,請(qǐng)看下一篇的內(nèi)容你不知道的四的作用。 歡迎關(guān)注我的公眾號(hào)睿Talk,獲取我最新的文章:showImg(https://segmentfault.com/img/bVbmYjo); 一、前言 目前最流行的兩大前端框架,React和Vue,都不約而同的借助Virtual DOM技術(shù)提高頁面的渲染效率。那么,什...

    xiongzenghui 評(píng)論0 收藏0
  • 去哪兒網(wǎng)迷你React研發(fā)心得

    摘要:市面上竟然擁有多個(gè)虛擬庫。虛擬庫,就是出來后的一種新式庫,以虛擬與算法為核心,屏蔽操作,操作數(shù)據(jù)即操作視圖。及其他虛擬庫已經(jīng)將虛擬的生成交由與處理了,因此不同點(diǎn)是,虛擬的結(jié)構(gòu)與算法。因此虛擬庫是分為兩大派系算法派與擬態(tài)派。 去哪兒網(wǎng)迷你React是年初立項(xiàng)的新作品,在這前,去哪兒網(wǎng)已經(jīng)深耕多年,擁有QRN(react-native的公司制定版),HY(基于React的hybird方案)...

    pekonchan 評(píng)論0 收藏0
  • React源碼分析實(shí)現(xiàn)(三):實(shí)操DOM Diff

    摘要:速度略有損失,但可讀性大大提高。與傳統(tǒng)對(duì)比傳統(tǒng)的算法通過循環(huán)遞歸每一個(gè)節(jié)點(diǎn),進(jìn)行對(duì)比,這樣的操作效率非常的低,復(fù)雜程度其中標(biāo)識(shí)樹的節(jié)點(diǎn)總數(shù)。 原文鏈接:Nealyang PersonalBlog 由于源碼中diff算法摻雜了太多別的功能模塊,并且dom diff相對(duì)于之前的代碼實(shí)現(xiàn)來說還是有些麻煩的,尤其是列表對(duì)比的算法,所以這里我們單獨(dú)拿出來說他實(shí)現(xiàn) 前言 眾所周知,React中最...

    Drummor 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

CoXie

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<