如何用suchjs來模擬數(shù)據(jù)

????????開發(fā)中乍炉,經(jīng)常遇到數(shù)據(jù)接口沒有準備好绢片,前端無法進行正常開發(fā)的情況,所以一直有個想法岛琼,想把數(shù)據(jù)模擬的工作變得更簡單底循、易擴展、易讀槐瑞、甚至能從一個已知結(jié)構(gòu)的一條數(shù)據(jù)模擬出多條數(shù)據(jù)此叠。當然這不是一個簡單的工作,但我覺得這是件有意義的事情随珠,至少設計的初衷讓它具備自己的獨特性,不會因為目前已有不少優(yōu)秀的mock數(shù)據(jù)的庫或框架猬错,而讓它變成一件重復造輪子的事情窗看。

????????從易讀性出發(fā),因此對數(shù)據(jù)進行描述性的解讀是個不錯的想法倦炒。我試圖提取一些數(shù)據(jù)通用的屬性显沈,用一些約定的符號來表達。于是便有了以下這些總結(jié):

1. 中括號[a,b]

? ? 可以用來表示范圍逢唤,對于數(shù)字就是數(shù)字的最小值拉讯,最大值;而對于字符串鳖藕,就可以表示為數(shù)字的unicode碼點范圍魔慷。

2. 大括號{a,b}

? ? 可以用來表示長度,對于字符是長度大小著恩,對于數(shù)組院尔,也可表示數(shù)組的長度大小蜻展。

3. 斜杠/a/

? ? 用來表示正則表達式。

4. 且&./a/b

? ? 用來表示對數(shù)據(jù)的引用邀摆,也可以表示為其它路徑的引用纵顾。

5. #[a=1,b=2]

? ? 定義一些變量值,可用來輔助數(shù)據(jù)生成栋盹。

6. @a|b

? ? 定義方法管道施逾,可以對數(shù)據(jù)進行最后的處理。

7. 百分號%

? ? 用來設置數(shù)據(jù)的格式化例获,比如數(shù)字類型汉额,時間類型。

8. 英文冒號:

? 用來標記類型躏敢,同時也作為各個參數(shù)之間的分隔符闷愤。


????????通過以上的這些想法,我需要一個簡單的分析器來將這些配置字符做出分隔件余,這也就是源碼中的parser所做的事情讥脐。每個配置類型都有自己的起始符,可能有自己的結(jié)束符啼器,也可能是一個能匹配到結(jié)束符的正則旬渠。但這里開始符和結(jié)束符的組合必須是唯一的,否則容易造成錯亂端壳。最終這些解析每段配置的parser會被放到一個dispatcher的分配器里告丢,分配器按照最長優(yōu)先匹配的原則來判斷最終使用哪個parser來解析。于是這些不同的配置被解析成了一個個規(guī)則對象损谦,里面包含了配置數(shù)據(jù)所需的所有信息岖免,為接下來的工作做準備。

接下來的工作就是要實現(xiàn)具體的數(shù)據(jù)類型了照捡,上面已經(jīng)獲得了各種屬性配置的值颅湘,具體類型使用的時候可能對具體的配置值有不同的要求,因此每個模擬類型里需要寫一些自己的對配置驗證的方法栗精,以及針對配置如何生成結(jié)果的generate方法闯参。上面說的有兩個配置是比較特殊的,一個是#[]里面的變量配置悲立,一個是@a|b這類的方法配置鹿寨,所有的類型都支持這兩種配置,對于變量配置薪夕,會有一個configOptions的數(shù)據(jù)驗證配置脚草,以保證設置的參數(shù)是符合規(guī)范的。其他的配置則通過添加rule的方式原献,在獲取到配置后會對數(shù)據(jù)進行驗證或更改玩讳。最終會在這些都完成后涩蜘,在generate方法里生成最終的結(jié)果數(shù)據(jù)。

這里內(nèi)置支持的類型有:

1. string

:string[97,120]:{10,20}

如上示例熏纯,表示一個字符串同诫,長度為10到20之間,每個字符的碼點范圍都在97到120之間樟澜。注意類型和第一個屬性配置之間的冒號是可以省略的误窖。

2. number

:number[100,200]:%.2f

如上示例,表示一個數(shù)字秩贰,大小在100到200之間霹俺,注意默認得到的值都是一個浮點數(shù),所以如果需要得到整數(shù)值毒费,可以使用類似c的printf方法進行格式化丙唧,如%d。示例中表示將數(shù)字轉(zhuǎn)化為一個帶兩位小數(shù)點的浮點數(shù)觅玻。

3. date

:date['2018-12-03 00:00:00','2018-12-05 00:00:00']:%yyyy-mm-dd HH\\:MM\\:ss

示例有點長想际,您應該已經(jīng)看出來了,這表示一個時間范圍在2018年12月3日和12月5日之間溪厘,最后格式化為年月日時分秒的一個日期胡本。實際上日期范圍內(nèi)的參數(shù)除了支持能被Date實例化的合理日期格式,也支持像php方法strtotime方法類似tomorrow畸悬,+1 week這種日期寫法侧甫,可以更靈活的使用。

4. regexp

:regexp/[\\u{4e00}-\\u{9afa}]{3,5}/u

表示一個匹配正則表達式的字符蹋宦,這里支持的正則表達式flags包括u,s,i披粟,由于是反解析正則,所以對一些功能有所限制冷冗,但也擴展支持了命名匹配的功能守屉。可以查看reregexp這個包的說明贾惦。

5. id

:id#[start=2,step=2]

通常用在數(shù)組里,表示一個自增的值敦捧,可以設置start和step屬性须板,來表示開始值和每次遞增的大小,默認都是1兢卵。

6. ref

:ref&./a,./b:@join('|')

表示一個對數(shù)據(jù)結(jié)構(gòu)和自身同級的字段a和字段b的引用习瑰,引用到數(shù)據(jù)后,可以通過方法配置來做進一步的處理秽荤。比如示例中的join方法甜奄,因為引用多個字段會轉(zhuǎn)化為數(shù)組柠横,所以可以調(diào)用數(shù)組的原生join方法。


? ? ? ? 以上就是目前所有內(nèi)置類型课兄,實際使用中牍氛,雖然基本可以使用正則來解決大部分的數(shù)據(jù)模擬,但在配置這些參數(shù)時會變得非常困難烟阐,做一些重復的工作搬俊,而且難以維護。所以需要提供一些入口蜒茄,來讓模擬基本數(shù)據(jù)之外的一些數(shù)據(jù)也變得更簡單唉擂。

? ? ? ? 于是在開發(fā)中,提供了以下接口方法:

Such.define()

定義新類型檀葛,第一個參數(shù)是和string玩祟、number這些類似的類型名,第二個參數(shù)可以是一個方法屿聋;也可以是一個基礎類型名空扎,表示這個新類型是從基礎類型擴展而來,不過它固定了某些參數(shù)配置胜臊;還可以是一個包含generate勺卢、init等方法的對象。

這里分別舉個簡單例子:

Such.define('boolean',(options) => { return options.such.utils.isOptional(); });

這里的options里包含了such象对,及全局的Such對象黑忱,Such對象上加入了靜態(tài)屬性utils,包含了系統(tǒng)內(nèi)置使用的一些常用utils方法勒魔。同時包括datas,dpath這兩個可通過數(shù)組作為key設置獲取數(shù)據(jù)的類map對象甫煞。datas里保存了已模擬出來的數(shù)據(jù),dpath保存了一個類似xpath的當前路徑數(shù)組冠绢。有了這些數(shù)據(jù)抚吠,就能更靈活地對數(shù)據(jù)進行模擬了。

Such.define('integer', 'number', '%d')

模擬了一個整數(shù)類型弟胀,這個類型繼承自number楷力,不過它的format參數(shù)配置被固定為%d。

第三種方式定義的類型更全面孵户,和定義原始類型方式是一致的萧朝。可以參考一下dict類型的實現(xiàn)夏哭。

node里支持的dict類型

以上就是define方法的簡單介紹检柬,也可以看看?such:recommend?里擴展的一些類型的寫法∈洌總之通過自定義類型何址,可以快速地擴展類型列表里逆,對于node版本,你也可以把一些通用的類型整理開放出來用爪,做成一個npm包原押,提供給他人使用。

Such.alias('short','long-short')

這個不用說项钮,大家就知道這是用來表示別名的班眯,比如上面擴展的integer類型,你覺得integer寫得太費勁了烁巫,就可以Such.alias('int','integer')署隘,記住前面寫短的,后面寫長的亚隙〈挪停可以想象類似bash里alias int=interger,千萬別寫反了阿弃。

有了以上兩個方法诊霹,基本的類型擴展用起來算是比較方便了,如果您有更好的意見渣淳,也歡迎您在Issue提出來脾还,為以后的功能擴展提供更多參考。


? ? ? ? 說到上面的node版本入愧,為了讓對類型擴展使用起來更方便鄙漏,支持了擴展包載入的方式,方便大家可以共享一些類型擴展等棺蛛。如果想要使用這些擴展類型該怎么做呢怔蚌?

Such.config(config)

通過這個config方法,可以將config里的參數(shù)使用對應的Such全局方法將其注冊進來旁赊。

{"extends":["such:recommend"],"types":{"integer":["number","%d"],alias:{"int":"integer"},"parsers":{}}

上面的config參數(shù)大概就長成這樣了桦踊,對于node版本,上面的extends才是生效的终畅,such:開頭的表示是內(nèi)置的擴展籍胯,其它的就可以根據(jù)包名填入了。當然离福,在node版本里杖狼,不需要我們自己來執(zhí)行Such.config方法,而是在項目根目錄配置一個such.config.js的配置文件就好了术徊。

如果你還想將你要模擬的數(shù)據(jù)使用一個json文件替代本刽,你可能需要創(chuàng)建一個文件目錄來作為suchjs模擬的根目錄鲸湃,用來保存這些文件赠涮。如果你還想支持一個多行的dict文件子寓,從里面隨機取一條數(shù)據(jù)做展示的話,你還需要在suchjs根目錄下創(chuàng)建一個數(shù)據(jù)文件目錄笋除。這樣你就可以很規(guī)范地使用它們來輸出模擬數(shù)據(jù)了斜友。

詳細的介紹可以查看項目的readme

當然,為了上述操作使用起來更方便垃它,目前提供了一個乞丐版的cli(太簡陋鲜屏,只支持一個命令),所以你的操作可能是這樣的国拇。

1洛史、進入你的node項目根目錄

2、npm install --save-dev such-cli

3酱吝、such init

好吧也殖,更多的細節(jié)說明放在這個不太詳細的中文文檔里了,感興趣的同學可以看一看务热。


最后忆嗜,貼一下項目的地址:https://github.com/suchjs/such?

感謝大家花費寶貴的時間看到這最后,希望能對實際有數(shù)據(jù)模擬需求的同學有用崎岂。如果您嘗試使用了它捆毫,遇到任何問題或者有任何想法,還請在issue里提出來冲甘,我一定會認真研究的绩卤。再次感謝!

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末损合,一起剝皮案震驚了整個濱河市省艳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌嫁审,老刑警劉巖跋炕,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異律适,居然都是意外死亡辐烂,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門捂贿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來纠修,“玉大人,你說我怎么就攤上這事厂僧】鄄荩” “怎么了摧莽?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵陨溅,是天一觀的道長。 經(jīng)常有香客問我,道長鬼悠,這世上最難降的妖魔是什么榔至? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任亭珍,我火速辦了婚禮镣丑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘尔破。我一直安慰自己街图,他們只是感情好,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布懒构。 她就那樣靜靜地躺著餐济,像睡著了一般。 火紅的嫁衣襯著肌膚如雪胆剧。 梳的紋絲不亂的頭發(fā)上颤介,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機與錄音赞赖,去河邊找鬼滚朵。 笑死,一個胖子當著我的面吹牛前域,可吹牛的內(nèi)容都是我干的辕近。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼匿垄,長吁一口氣:“原來是場噩夢啊……” “哼移宅!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起椿疗,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤漏峰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后届榄,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體浅乔,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年铝条,在試婚紗的時候發(fā)現(xiàn)自己被綠了靖苇。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡班缰,死狀恐怖贤壁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情埠忘,我是刑警寧澤脾拆,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布馒索,位于F島的核電站,受9級特大地震影響名船,放射性物質(zhì)發(fā)生泄漏双揪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一包帚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧运吓,春花似錦渴邦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至倦青,卻和暖如春瓮床,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背产镐。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工隘庄, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人癣亚。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓丑掺,卻偏偏與公主長得像,于是被迫代替她去往敵國和親述雾。 傳聞我的和親對象是個殘疾皇子街州,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容