From 6af7093bc8399f72b59c7cd41be60ed0ec7d523b Mon Sep 17 00:00:00 2001 From: rickcole Date: Wed, 5 Jun 2019 15:49:29 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=85tpl-builtin=20=E7=94=A8?= =?UTF-8?q?=E4=BE=8B(80%)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __tests__/utils/tpl-builtin.test.ts | 623 ++++++++++++++++++++++++++-- src/utils/tpl-builtin.ts | 26 +- 2 files changed, 609 insertions(+), 40 deletions(-) diff --git a/__tests__/utils/tpl-builtin.test.ts b/__tests__/utils/tpl-builtin.test.ts index 61061c63e..824cf7785 100644 --- a/__tests__/utils/tpl-builtin.test.ts +++ b/__tests__/utils/tpl-builtin.test.ts @@ -1,38 +1,611 @@ import { - prettyBytes, - escapeHtml, - formatDuration, - resolveVariableAndFilter + resolveVariableAndFilter, + dataMapping } from '../../src/utils/tpl-builtin'; -test('tpl-builtin:prettyBytes', () => { - expect(prettyBytes(1024)).toEqual('1.02 kB'); - expect(prettyBytes(1024000)).toEqual('1.02 MB'); +const filters = [ + { + type: 'raw1', + data: { + value: 1 + }, + path: '${value}', + filter: '| raw', + expectValue: 1 + }, + { + type: 'raw2', + data: { + value: '2' + }, + path: '${value}', + filter: '| raw', + expectValue: '2' + }, + { + type: 'raw3', + data: { + a: 1, + b: '2', + c: { + '1': 'first', + '2': 'second' + } + }, + path: '${c.${a}}', + filter: '| raw', + expectValue: 'first' + }, + { + type: 'raw4', + data: { + a: 1, + b: '2', + c: { + '1': 'first', + '2': 'second' + } + }, + path: '${c.${b}}', + filter: '| raw', + expectValue: 'second' + }, + { + type: 'raw5', + data: { + a: 1, + }, + path: '', + filter: '| raw', + expectValue: undefined + }, + { + type: 'raw6', + data: { + a: 1, + }, + path: '$$', + filter: '| raw', + expectValue: undefined + }, + { + type: 'raw7', + data: { + a: 1, + }, + path: '\$a', + filter: '| raw', + expectValue: 1 + }, + { + type: 'json', + data: { + value: { + a: 'a', + b: 'b' + } + }, + path: '${value}', + filter: '| json:0', + expectValue: "{\"a\":\"a\",\"b\":\"b\"}" + }, + { + type: 'toJson', + data: { + value: "{\"a\":\"a\",\"b\":\"b\"}", + }, + path: '${value}', + filter: '| toJson', + expectValue: { + a: 'a', + b: 'b' + } + }, + { + type: 'date', + data: { + value: 1559649981, + }, + path: '${value}', + filter: '| date', + expectValue: 'June 4, 2019 8:06 PM' + }, + { + type: 'number', + data: { + value: 9999 + }, + path: '${value}', + filter: '| number', + expectValue: '9,999' + }, + { + type: 'trim', + data: { + value: ' abc ' + }, + path: '${value}', + filter: '| trim', + expectValue: 'abc' + }, + { + type: 'percent', + data: { + value: 0.8232343 + }, + path: '${value}', + filter: '| percent', + expectValue: '82%' + }, + // duration + { + type: 'duration1', + data: { + value: 1 + }, + path: '${value}', + filter: '| duration', + expectValue: '1秒' + }, + { + type: 'duration2', + data: { + value: 61 + }, + path: '${value}', + filter: '| duration', + expectValue: '1分1秒' + }, + { + type: 'duration3', + data: { + value: 233233 + }, + path: '${value}', + filter: '| duration', + expectValue: '3天17时47分13秒' + }, + // bytes + { + type: 'bytes1', + data: { + value: 1024 + }, + path: '${value}', + filter: '| bytes', + expectValue: '1.02 KB' + }, + { + type: 'bytes2', + data: { + value: 1024000 + }, + path: '${value}', + filter: '| bytes', + expectValue: '1.02 MB' + }, + { + type: 'bytes3', + data: { + value: -1024 + }, + path: '${value}', + filter: '| bytes', + expectValue: '-1.02 KB' + }, + { + type: 'bytes4', + data: { + value: 0.5 + }, + path: '${value}', + filter: '| bytes', + expectValue: '0.5 B' + }, + // round + { + type: 'round1', + data: { + value: '啥啊' + }, + path: '${value}', + filter: '| round', + expectValue: 0 + }, + { + type: 'round2', + data: { + value: 1.22 + }, + path: '${value}', + filter: '| round:1', + expectValue: '1.2' + }, + { + type: 'round3', + data: { + value: 1.26 + }, + path: '${value}', + filter: '| round:1', + expectValue: '1.3' + }, + { + type: 'truncate1', + data: { + value: 'this is a very loooooong sentence.' + }, + path: '${value}', + filter: '| truncate:10', + expectValue: 'this is a ...' + }, + { + type: 'truncate2', + data: { + value: 'this is a very loooooong sentence.' + }, + path: '${value}', + filter: '| truncate:null', + expectValue: 'this is a very loooooong sentence.' + }, + { + type: 'url_encode', + data: { + value: 'http://www.baidu.com?query=123' + }, + path: '${value}', + filter: '| url_encode', + expectValue: 'http%3A%2F%2Fwww.baidu.com%3Fquery%3D123' + }, + { + type: 'url_decode', + data: { + value: 'http%3A%2F%2Fwww.baidu.com%3Fquery%3D123' + }, + path: '${value}', + filter: '| url_decode:10', + expectValue: 'http://www.baidu.com?query=123' + }, + { + type: 'default1', + data: { + value: '' + }, + path: '${value}', + filter: '| default', + expectValue: undefined + }, + { + type: 'default2', + data: { + value: '' + }, + path: '${value}', + filter: '| default:-', + expectValue: '-' + }, + { + type: 'join', + data: { + value: ['a', 'b', 'c'] + }, + path: '${value}', + filter: '| join:,', + expectValue: 'a,b,c' + }, + { + type: 'split', + data: { + value: 'a,b,c' + }, + path: '${value}', + filter: '| split', + expectValue: ['a', 'b', 'c'] + }, + { + type: 'first', + data: { + value: ['a', 'b', 'c'] + }, + path: '${value}', + filter: '| first', + expectValue: 'a' + }, + { + type: 'nth', + data: { + value: ['a', 'b', 'c'] + }, + path: '${value}', + filter: '| nth:1', + expectValue: 'b' + }, + { + type: 'last', + data: { + value: ['a', 'b', 'c'] + }, + path: '${value}', + filter: '| last', + expectValue: 'c' + }, + { + type: 'minus', + data: { + value: 5 + }, + path: '${value}', + filter: '| minus:1', + expectValue: 4 + }, + { + type: 'plus', + data: { + value: 5 + }, + path: '${value}', + filter: '| plus:1', + expectValue: 6 + }, + { + type: 'pick1', + data: { + value: { + a: '1', + b: '2' + } + }, + path: '${value}', + filter: '| pick:a', + expectValue: '1' + }, + { + type: 'pick2', + data: { + value: [ + { + label: 'A', + value: 'a' + }, + { + label: 'B', + value: 'b' + }, + { + label: 'C', + value: 'c' + }, + ] + }, + path: '${value}', + filter: '| pick:value', + expectValue: ['a', 'b', 'c'] + }, + { + type: 'pick_if_exist', + data: { + value: [ + { + label: 'A', + value: 'a' + }, + { + label: 'B', + value: 'b' + }, + { + label: 'C', + value: 'c' + }, + ] + }, + path: '${value}', + filter: '| pick_if_exist:$value', + expectValue: ['a', 'b', 'c'] + }, + { + type: 'str2date', + data: { + value: '1559649981' + }, + path: '${value}', + filter: '| str2date:X:YYYY-MM-DD HH-mm-ss', + expectValue: '2019-06-04 20-06-21' + }, + { + type: 'asArray', + data: { + value: 'a' + }, + path: '${value}', + filter: '| asArray', + expectValue: ['a'] + }, + { + type: 'base64Encode', + data: { + value: 'I love amis' + }, + path: '${value}', + filter: '| base64Encode', + expectValue: 'SSBsb3ZlIGFtaXM=' + }, + { + type: 'base64Decode', + data: { + value: 'SSBsb3ZlIGFtaXM=' + }, + path: '${value}', + filter: '| base64Decode', + expectValue: 'I love amis' + }, + { + type: 'lowerCase', + data: { + value: 'AbC' + }, + path: '${value}', + filter: '| lowerCase', + expectValue: 'abc' + }, + { + type: 'upperCase', + data: { + value: 'aBc' + }, + path: '${value}', + filter: '| upperCase', + expectValue: 'ABC' + }, + +] + +filters.forEach(f => { + test(`tpl-builtin:resolveVariableAndFilter:${f.type}`, () => { + expect(resolveVariableAndFilter(f.path, f.data, f.filter)).toEqual(f.expectValue); + }); }); - -test('tpl-builtin:escapeHtml', () => { - expect(escapeHtml('
Hello&world
')).toEqual('<div id="1">Hello&world</div>'); -}); - -test('tpl-builtin:formatDuration', () => { - expect(formatDuration(1)).toEqual('1秒'); - expect(formatDuration(61)).toEqual('1分1秒'); - expect(formatDuration(233233)).toEqual('3天17时47分13秒'); -}) - -test('tpl-bultin:resolveVariableAndFilter', () => { +test('tpl-builtin:dataMapping', () => { const data = { a: 1, b: '2', c: { '1': 'first', '2': 'second' - } + }, }; - expect(resolveVariableAndFilter('${a}', data, '| raw')).toEqual(1); - expect(resolveVariableAndFilter('${b}', data, '| raw')).toEqual('2'); - expect(resolveVariableAndFilter('${c.${a}}', data, '| raw')).toEqual('first'); - expect(resolveVariableAndFilter('${c.${b}}', data, '| raw')).toEqual('second'); -}); \ No newline at end of file + expect(dataMapping({ + '&': '$$' + }, data)).toEqual({ + a: 1, + b: '2', + c: { + '1': 'first', + '2': 'second' + } + }); + + expect(dataMapping({ + '&': '${b}' + }, data)).toEqual('2'); + + expect(dataMapping({ + '&': (data) => ({b: data.b}) + }, data)).toEqual({ + b: '2' + }); + + expect(dataMapping({ + 'all': '$$' + }, data)).toEqual({ + all: { + a: 1, + b: '2', + c: { + '1': 'first', + '2': 'second' + } + } + }); + + expect(dataMapping({ + a: '${a}', + b: '__undefined' + }, data)).toEqual({ + a: 1 + }); + + expect(dataMapping({ + value: { + a: '${a}', + d: 'd' + } + }, data)).toEqual({ + value: { + a: 1, + d: 'd' + } + }); + + expect(dataMapping({ + value: [ + { + a: '${a}', + d: 'd' + }, + { + b: '${b}', + d: 'd' + } + ], + }, data)).toEqual({ + value: [ + { + a: 1, + d: 'd' + }, + { + b: '2', + d: 'd' + } + ] + }); + + expect(dataMapping({ + value: '${a}', + }, data)).toEqual({ + value: 1 + }); + + expect(dataMapping({ + value: data => data.a, + }, data)).toEqual({ + value: 1 + }); + + const data2 = { + rows: [ + { + label: 'A', + value: 'a', + size: 'sm' + }, + { + label: 'B', + value: 'b', + size: 'md' + }, + { + label: 'C', + value: 'c', + size: 'sm' + }, + ] + } + + expect(dataMapping({ + items: { + $rows: { + label: '$label', + value: '$value' + } + } + }, data2)).toEqual({ + items: [ + { + label: 'A', + value: 'a' + }, + { + label: 'B', + value: 'b' + }, + { + label: 'C', + value: 'c' + } + ] + }); +}) \ No newline at end of file diff --git a/src/utils/tpl-builtin.ts b/src/utils/tpl-builtin.ts index 4487c1b76..5654ffa07 100644 --- a/src/utils/tpl-builtin.ts +++ b/src/utils/tpl-builtin.ts @@ -1,10 +1,10 @@ -import { reigsterTplEnginer, filter } from "./tpl"; +import {reigsterTplEnginer, filter} from "./tpl"; import * as moment from "moment"; -import { PlainObject } from "../types"; +import {PlainObject} from "../types"; import isPlainObject = require("lodash/isPlainObject"); -import { createObject, isObject, setVariable } from "./helper"; +import {createObject, isObject, setVariable} from "./helper"; -const UNITS = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; +const UNITS = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; export const prettyBytes = (num: number) => { if (!Number.isFinite(num)) { @@ -243,8 +243,8 @@ export function registerFilter( filters[name] = fn; } -export function pickValues(names:string, data:object) { - let arr:Array; +export function pickValues(names: string, data: object) { + let arr: Array; if (!names || (arr = names.split(',')) && arr.length < 2) { let idx = names.indexOf('~'); if (~idx) { @@ -257,7 +257,7 @@ export function pickValues(names:string, data:object) { return resolveVariable(names, data); } - let ret:any = {}; + let ret: any = {}; arr.forEach(name => { let idx = name.indexOf('~'); let target = name; @@ -281,22 +281,18 @@ export const resolveVariable = (path: string, data: any = {}): any => { return data; } else if (path[0] === "$") { path = path.substring(1); - } - - if (!path) { - return undefined; } else if (path === "&") { return data; } - + if (typeof data[path] !== "undefined") { return data[path]; } - + let parts = path.replace(/^{|}$/g, "").split("."); return parts.reduce((data, path) => { if ((isObject(data) || Array.isArray(data)) && path in data) { - return (data as { [propName: string]: any })[path]; + return (data as {[propName: string]: any})[path]; } return undefined; @@ -447,7 +443,7 @@ export function dataMapping(to: PlainObject, from: PlainObject): object { }; } else if (key === "&") { isPlainObject(item) - ? (item = { ...item, ...resolveMapping(value, itemData) }) + ? (item = {...item, ...resolveMapping(value, itemData)}) : (item = resolveMapping(value, itemData)); } else { item = isPlainObject(item) ? item : {};