mirror of
https://github.com/tenrok/vue-meta.git
synced 2026-06-21 07:20:33 +03:00
chore: improve types
test: convert tests to ts
This commit is contained in:
+4
-7
@@ -6,10 +6,6 @@ module.exports = {
|
||||
|
||||
forceExit: false,
|
||||
|
||||
// https://github.com/facebook/jest/pull/6747 fix warning here
|
||||
// But its performance overhead is pretty bad (30+%).
|
||||
// detectOpenHandles: true
|
||||
|
||||
setupFilesAfterEnv: ['./test/utils/setup'],
|
||||
|
||||
coverageDirectory: './coverage',
|
||||
@@ -31,8 +27,9 @@ module.exports = {
|
||||
],
|
||||
|
||||
transform: {
|
||||
'^.+\\.[tj]s$': 'babel-jest',
|
||||
'.*\\.(vue)$': 'vue-jest'
|
||||
'^.+\\.jsx?$': 'babel-jest',
|
||||
'^.+\\.tsx?$': 'ts-jest',
|
||||
'^.+\\.vue$': 'vue-jest'
|
||||
},
|
||||
|
||||
moduleFileExtensions: [
|
||||
@@ -40,7 +37,7 @@ module.exports = {
|
||||
'js',
|
||||
'json'
|
||||
],
|
||||
|
||||
|
||||
globals: {
|
||||
__DEV__: true,
|
||||
__BROWSER__: true,
|
||||
|
||||
+2
-1
@@ -61,6 +61,7 @@
|
||||
"@rollup/plugin-commonjs": "^17.1.0",
|
||||
"@rollup/plugin-node-resolve": "^11.2.0",
|
||||
"@rollup/plugin-replace": "^2.4.1",
|
||||
"@types/jest": "^26.0.22",
|
||||
"@types/webpack": "^4.41.26",
|
||||
"@types/webpack-env": "^1.16.0",
|
||||
"@typescript-eslint/eslint-plugin": "^4.15.2",
|
||||
@@ -100,7 +101,7 @@
|
||||
"selenium-webdriver": "^4.0.0-beta.1",
|
||||
"standard-version": "^9.1.1",
|
||||
"tib": "^0.7.5",
|
||||
"ts-jest": "^26.5.2",
|
||||
"ts-jest": "^26.5.4",
|
||||
"ts-loader": "^8.0.17",
|
||||
"typescript": "^4.2.2",
|
||||
"vite": "^2.0.4",
|
||||
|
||||
+3
-3
@@ -60,12 +60,12 @@ export const createMetaManager = (config?: MetaConfig, resolver?: MetaResolver):
|
||||
|
||||
export class MetaManager {
|
||||
config: MetaConfig
|
||||
target: MergedObjectBuilder
|
||||
target: MergedObjectBuilder<MetaSource>
|
||||
resolver?: MetaResolverSetup
|
||||
|
||||
ssrCleanedUp: boolean = false
|
||||
|
||||
constructor (config: MetaConfig, target: MergedObjectBuilder, resolver: MetaResolver | ResolveMethod) {
|
||||
constructor (config: MetaConfig, target: MergedObjectBuilder<MetaSource>, resolver: MetaResolver | ResolveMethod) {
|
||||
this.config = config
|
||||
this.target = target
|
||||
|
||||
@@ -83,7 +83,7 @@ export class MetaManager {
|
||||
return resolver.resolve(options, contexts, active, key, pathSegments)
|
||||
}
|
||||
|
||||
const mergedObject = createMergedObject(resolve, active)
|
||||
const mergedObject = createMergedObject<MetaSource>(resolve, active)
|
||||
|
||||
// TODO: validate resolver
|
||||
const manager = new MetaManager(config, mergedObject, resolver)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// https://github.com/microsoft/TypeScript/issues/1863
|
||||
export const IS_PROXY = Symbol('kIsProxy') as unknown as string
|
||||
export const PROXY_SOURCES = Symbol('kProxySources') as unknown as string
|
||||
export const PROXY_TARGET = Symbol('kProxyTarget') as unknown as string
|
||||
export const RESOLVE_CONTEXT = Symbol('kResolveContext') as unknown as string
|
||||
export const IS_PROXY = Symbol('kIsProxy')
|
||||
export const PROXY_SOURCES = Symbol('kProxySources')
|
||||
export const PROXY_TARGET = Symbol('kProxyTarget')
|
||||
export const RESOLVE_CONTEXT = Symbol('kResolveContext')
|
||||
|
||||
+29
-28
@@ -1,9 +1,14 @@
|
||||
import { PROXY_TARGET } from './constants'
|
||||
import { IS_PROXY, PROXY_SOURCES, PROXY_TARGET, RESOLVE_CONTEXT } from './constants'
|
||||
import { createProxy } from './proxy'
|
||||
import { recompute } from './recompute'
|
||||
|
||||
export type MergeSource = {
|
||||
[key: string]: any
|
||||
export interface ResolveContext {}
|
||||
|
||||
export type MergeSource<T extends Object> = { [K in keyof T]: T[K] } & {
|
||||
[IS_PROXY]: boolean
|
||||
[PROXY_SOURCES]: MergeSource<T>[]
|
||||
[PROXY_TARGET]: MergeSource<T>
|
||||
[RESOLVE_CONTEXT]: ResolveContext
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-use-before-define
|
||||
@@ -15,49 +20,45 @@ export type MergedObject = {
|
||||
|
||||
export type PathSegments = Array<string>
|
||||
|
||||
export type ResolveContext = {}
|
||||
export interface ResolveMethod<T = any, U = ResolveContext> {
|
||||
(
|
||||
options: Array<T>,
|
||||
contexts: Array<U>,
|
||||
active: MergedObjectValue,
|
||||
key: string | number | symbol,
|
||||
pathSegments: PathSegments,
|
||||
): MergedObjectValue
|
||||
}
|
||||
|
||||
export type ResolveMethod<T = ResolveContext> = (
|
||||
options: Array<any>,
|
||||
contexts: Array<T>,
|
||||
active: MergedObjectValue,
|
||||
key: string | number | symbol,
|
||||
pathSegments: PathSegments,
|
||||
) => MergedObjectValue
|
||||
|
||||
export type MergeContext = {
|
||||
export type MergeContext<T> = {
|
||||
resolve: ResolveMethod
|
||||
active: MergedObject
|
||||
sources: Array<MergeSource>
|
||||
sources: MergeSource<T>[]
|
||||
}
|
||||
|
||||
export type MergedObjectBuilder = {
|
||||
context: MergeContext
|
||||
export type MergedObjectBuilder<T> = {
|
||||
context: MergeContext<T>
|
||||
compute: () => void
|
||||
addSource: (source: MergeSource, resolveContext: ResolveContext | undefined, recompute?: Boolean) => any
|
||||
delSource: (sourceOrProxy: MergeSource, recompute?: boolean) => boolean
|
||||
addSource: (source: T, resolveContext?: ResolveContext, recompute?: Boolean) => any
|
||||
delSource: (sourceOrProxy: T | MergeSource<T>, recompute?: boolean) => boolean
|
||||
}
|
||||
|
||||
export const createMergedObject = (resolve: ResolveMethod, active: MergedObject = {}): MergedObjectBuilder => {
|
||||
const sources: Array<MergeSource> = []
|
||||
export const createMergedObject = <T extends Object>(resolve: ResolveMethod<T>, active: T): MergedObjectBuilder<T> => {
|
||||
const sources: MergeSource<T>[] = []
|
||||
|
||||
if (!active) {
|
||||
active = {}
|
||||
}
|
||||
|
||||
const context: MergeContext = {
|
||||
const context: MergeContext<T> = {
|
||||
active,
|
||||
resolve,
|
||||
sources
|
||||
}
|
||||
|
||||
const compute: () => void = () => recompute(context)
|
||||
const compute: () => void = () => recompute<T>(context)
|
||||
|
||||
return {
|
||||
context,
|
||||
compute,
|
||||
addSource: (source, resolveContext, recompute = false) => {
|
||||
const proxy = createProxy(context, source, resolveContext || {})
|
||||
const proxy = createProxy<T>(context, source, resolveContext || {})
|
||||
|
||||
if (recompute) {
|
||||
compute()
|
||||
@@ -66,7 +67,7 @@ export const createMergedObject = (resolve: ResolveMethod, active: MergedObject
|
||||
return proxy
|
||||
},
|
||||
delSource: (sourceOrProxy, recompute = true) => {
|
||||
const index = sources.findIndex(src => src === sourceOrProxy || src[PROXY_TARGET] === sourceOrProxy)
|
||||
const index = sources.findIndex(source => source === sourceOrProxy || source[PROXY_TARGET] === sourceOrProxy)
|
||||
|
||||
if (index > -1) {
|
||||
sources.splice(index, 1)
|
||||
|
||||
+11
-10
@@ -5,9 +5,9 @@ import { IS_PROXY, PROXY_SOURCES, PROXY_TARGET, RESOLVE_CONTEXT } from './consta
|
||||
import { recompute } from './recompute'
|
||||
import type { MergeContext, MergeSource, MergedObjectValue, PathSegments, ResolveContext } from '.'
|
||||
|
||||
export const createProxy = (context: MergeContext, target: MergeSource, resolveContext: ResolveContext, pathSegments: PathSegments = []) => {
|
||||
const handler = createHandler(context, resolveContext, pathSegments)
|
||||
const proxy = markRaw(new Proxy(target, handler))
|
||||
export const createProxy = <T extends Record<string, any>>(context: MergeContext<T>, target: T, resolveContext: ResolveContext, pathSegments: PathSegments = []): MergeSource<T> => {
|
||||
const handler = createHandler<T>(context, resolveContext, pathSegments)
|
||||
const proxy = markRaw(new Proxy(target, handler)) as MergeSource<T>
|
||||
|
||||
if (!pathSegments.length && context.sources) {
|
||||
context.sources.push(proxy)
|
||||
@@ -16,7 +16,7 @@ export const createProxy = (context: MergeContext, target: MergeSource, resolveC
|
||||
return proxy
|
||||
}
|
||||
|
||||
export const createHandler: (context: MergeContext, resolveContext: ResolveContext, pathSegments: PathSegments) => ProxyHandler<any> = (context, resolveContext, pathSegments = []) => ({
|
||||
export const createHandler = <T>(context: MergeContext<T>, resolveContext: ResolveContext, pathSegments: PathSegments = []): ProxyHandler<MergeSource<T>> => ({
|
||||
get: (target, key, receiver) => {
|
||||
if (key === IS_PROXY) {
|
||||
return true
|
||||
@@ -40,11 +40,11 @@ export const createHandler: (context: MergeContext, resolveContext: ResolveConte
|
||||
return value
|
||||
}
|
||||
|
||||
if (!value[IS_PROXY]) {
|
||||
if (!(value as MergeSource<T>)[IS_PROXY]) {
|
||||
const keyPath: PathSegments = [...pathSegments, (key as string)]
|
||||
|
||||
value = createProxy(context, value, resolveContext, keyPath)
|
||||
target[key] = value
|
||||
value = createProxy<typeof value>(context, value, resolveContext, keyPath)
|
||||
Reflect.set(target, key, value)
|
||||
}
|
||||
|
||||
return value
|
||||
@@ -87,8 +87,8 @@ export const createHandler: (context: MergeContext, resolveContext: ResolveConte
|
||||
return success
|
||||
}
|
||||
|
||||
let keyContexts: Array<ResolveContext> = []
|
||||
let keySources
|
||||
let keyContexts: ResolveContext[] = []
|
||||
let keySources: MergeSource<T>[]
|
||||
|
||||
if (isArrayItem) {
|
||||
keySources = proxies
|
||||
@@ -138,6 +138,7 @@ export const createHandler: (context: MergeContext, resolveContext: ResolveConte
|
||||
|
||||
let index = 0
|
||||
for (const segment of pathSegments) {
|
||||
// @ts-ignore
|
||||
proxies = proxies.map(proxy => proxy[segment])
|
||||
|
||||
if (isArrayItem && index === pathSegments.length - 1) {
|
||||
@@ -152,7 +153,7 @@ export const createHandler: (context: MergeContext, resolveContext: ResolveConte
|
||||
// Check if the key still exists in one of the sourceProxies,
|
||||
// if so resolve the new value, if not remove the key
|
||||
if (proxies.some(proxy => (key in proxy))) {
|
||||
let keyContexts: Array<ResolveContext> = []
|
||||
let keyContexts: ResolveContext[] = []
|
||||
let keySources
|
||||
|
||||
if (isArrayItem) {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { clone, pluck } from '../utils'
|
||||
import { RESOLVE_CONTEXT } from './constants'
|
||||
import type { MergeContext, MergeSource, MergedObject, PathSegments, ResolveContext } from '.'
|
||||
|
||||
export const allKeys = (source?: MergeSource, ...sources: Array<MergeSource>): Array<string> => {
|
||||
export const allKeys = <T>(source?: MergeSource<T>, ...sources: MergeSource<T>[]): string[] => {
|
||||
const keys = source ? Object.keys(source) : []
|
||||
|
||||
if (sources) {
|
||||
@@ -25,7 +25,7 @@ export const allKeys = (source?: MergeSource, ...sources: Array<MergeSource>): A
|
||||
return keys
|
||||
}
|
||||
|
||||
export const recompute = (context: MergeContext, sources?: Array<MergeSource>, target?: MergedObject, path: PathSegments = []): void => {
|
||||
export const recompute = <T>(context: MergeContext<T>, sources?: MergeSource<T>[], target?: MergedObject, path: PathSegments = []): void => {
|
||||
if (!path.length) {
|
||||
if (!target) {
|
||||
target = context.active
|
||||
@@ -52,6 +52,7 @@ export const recompute = (context: MergeContext, sources?: Array<MergeSource>, t
|
||||
|
||||
for (const key of keys) {
|
||||
// This assumes consistent types usages for keys across sources
|
||||
// @ts-ignore
|
||||
if (isPlainObject(sources[0][key])) {
|
||||
if (!target[key]) {
|
||||
target[key] = {}
|
||||
@@ -60,6 +61,7 @@ export const recompute = (context: MergeContext, sources?: Array<MergeSource>, t
|
||||
const keySources = []
|
||||
for (const source of sources) {
|
||||
if (key in source) {
|
||||
// @ts-ignore
|
||||
keySources.push(source[key])
|
||||
}
|
||||
}
|
||||
@@ -69,6 +71,7 @@ export const recompute = (context: MergeContext, sources?: Array<MergeSource>, t
|
||||
}
|
||||
|
||||
// Ensure the target is an array if source is an array and target is empty
|
||||
// @ts-ignore
|
||||
if (!target[key] && isArray(sources[0][key])) {
|
||||
target[key] = []
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ export interface ResolveOptionPredicament<T, U> {
|
||||
(currentValue: T | undefined, context: U): T
|
||||
}
|
||||
|
||||
export const resolveOption = <T, U = ResolveContext>(predicament: ResolveOptionPredicament<T, U>, initialValue?: T): ResolveMethod<U> => (options, contexts) => {
|
||||
export const resolveOption = <T, U = ResolveContext>(predicament: ResolveOptionPredicament<T, U>, initialValue?: T): ResolveMethod<any, U> => (options, contexts) => {
|
||||
let resolvedIndex = -1
|
||||
|
||||
contexts.reduce((acc, context, index) => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
export const pluck = (collection: Array<any>, key: string, callback?: (row: any) => void) => {
|
||||
const plucked: Array<any> = []
|
||||
export const pluck = <T extends Record<string, any>>(collection: T[], key: string, callback?: (row: T) => void) => {
|
||||
const plucked: T[] = []
|
||||
|
||||
for (const row of collection) {
|
||||
if (key in row) {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { MergeContext } from 'src/object-merge'
|
||||
import { createProxy } from '../../src/object-merge/proxy'
|
||||
|
||||
describe('proxy', () => {
|
||||
let context
|
||||
let context: MergeContext<any>
|
||||
|
||||
beforeEach(() => {
|
||||
context = {
|
||||
sources: [],
|
||||
@@ -18,7 +20,7 @@ describe('proxy', () => {
|
||||
}
|
||||
}
|
||||
|
||||
const proxy = createProxy(context, target)
|
||||
const proxy = createProxy(context, target, {})
|
||||
|
||||
expect(proxy.str).toBe('test')
|
||||
expect(proxy.obj.str).toBe('test')
|
||||
@@ -27,7 +29,7 @@ describe('proxy', () => {
|
||||
test('string (set, update, delete)', () => {
|
||||
const target = {}
|
||||
|
||||
const proxy = createProxy(context, target)
|
||||
const proxy = createProxy(context, target, {})
|
||||
|
||||
proxy.str = 'test'
|
||||
|
||||
@@ -45,7 +47,7 @@ describe('proxy', () => {
|
||||
test('array (set, update, delete)', () => {
|
||||
const target = {}
|
||||
|
||||
const proxy = createProxy(context, target)
|
||||
const proxy = createProxy(context, target, {})
|
||||
|
||||
proxy.arr = [0, 1]
|
||||
|
||||
@@ -68,7 +70,7 @@ describe('proxy', () => {
|
||||
test('proxy (set object)', () => {
|
||||
const target = {}
|
||||
|
||||
const proxy = createProxy(context, target)
|
||||
const proxy = createProxy(context, target, {})
|
||||
|
||||
proxy.obj = { str: 'test' }
|
||||
|
||||
@@ -79,7 +81,7 @@ describe('proxy', () => {
|
||||
test('proxy (remove)', () => {
|
||||
const target = {}
|
||||
|
||||
const proxy = createProxy(context, target)
|
||||
const proxy = createProxy(context, target, {})
|
||||
|
||||
proxy.obj = { str: 'test' }
|
||||
|
||||
@@ -93,7 +95,7 @@ describe('proxy', () => {
|
||||
test('proxy (remove child)', () => {
|
||||
const target = {}
|
||||
|
||||
const proxy = createProxy(context, target)
|
||||
const proxy = createProxy(context, target, {})
|
||||
|
||||
proxy.obj = { str: 'test' }
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
// @ts-nocheck
|
||||
import { MetaRenderContext } from 'src'
|
||||
import * as render from '../../src/render'
|
||||
|
||||
// Note: testing isnt rly independent as they also rely on ./src/config/tags
|
||||
|
||||
describe('render', () => {
|
||||
test('render key-string element (without value attribute)', () => {
|
||||
const context = {}
|
||||
const context: MetaRenderContext = { metainfo: {} }
|
||||
const key = 'TitleTest'
|
||||
const data = 'my title'
|
||||
const config = {
|
||||
@@ -13,6 +15,10 @@ describe('render', () => {
|
||||
|
||||
const res = render.renderMeta(context, key, data, config)
|
||||
// console.log('RES', res)
|
||||
if (!res) {
|
||||
expect(res).toBeTruthy()
|
||||
return
|
||||
}
|
||||
|
||||
expect(res.to).toBeUndefined()
|
||||
expect(res.vnode).toMatchObject({ __v_isVNode: true })
|
||||
@@ -24,7 +30,7 @@ describe('render', () => {
|
||||
})
|
||||
|
||||
test('render key-string element (without name attribute)', () => {
|
||||
const context = {}
|
||||
const context: MetaRenderContext = { metainfo: {} }
|
||||
const key = 'CharsetTest'
|
||||
const data = 'utf8'
|
||||
const config = {
|
||||
@@ -44,7 +50,7 @@ describe('render', () => {
|
||||
})
|
||||
|
||||
test('render key-string element (with name attribute)', () => {
|
||||
const context = {}
|
||||
const context: MetaRenderContext = { metainfo: {} }
|
||||
const key = 'DescriptionTest'
|
||||
const data = 'my description'
|
||||
const config = {
|
||||
@@ -62,7 +68,7 @@ describe('render', () => {
|
||||
})
|
||||
|
||||
test('render key-object element', () => {
|
||||
const context = {}
|
||||
const context: MetaRenderContext = { metainfo: {} }
|
||||
const key = 'DescriptionTest2'
|
||||
const data = { content: 'my description 2' }
|
||||
const config = {
|
||||
@@ -80,7 +86,7 @@ describe('render', () => {
|
||||
})
|
||||
|
||||
test('render key-object element with json', () => {
|
||||
const context = {}
|
||||
const context: MetaRenderContext = { metainfo: {} }
|
||||
const key = 'JsonTest'
|
||||
const data = { json: ['content'] }
|
||||
const config = {
|
||||
@@ -99,7 +105,7 @@ describe('render', () => {
|
||||
})
|
||||
|
||||
test('render key-object element with raw content', () => {
|
||||
const context = {}
|
||||
const context: MetaRenderContext = { metainfo: {} }
|
||||
const key = 'RawTest'
|
||||
const data = { rawContent: '<p>One JS please!</p>' }
|
||||
const config = {
|
||||
@@ -117,7 +123,7 @@ describe('render', () => {
|
||||
})
|
||||
|
||||
test('render array<key-string> elements', () => {
|
||||
const context = {}
|
||||
const context: MetaRenderContext = { metainfo: {} }
|
||||
const key = 'kal-el'
|
||||
const data = [
|
||||
'man',
|
||||
@@ -146,7 +152,7 @@ describe('render', () => {
|
||||
})
|
||||
|
||||
test('render array<key-object> elements', () => {
|
||||
const context = {}
|
||||
const context: MetaRenderContext = { metainfo: {} }
|
||||
const key = 'kal-el'
|
||||
const data = [
|
||||
{ super: 'man' },
|
||||
@@ -173,7 +179,7 @@ describe('render', () => {
|
||||
})
|
||||
|
||||
test('render custom group', () => {
|
||||
const context = {}
|
||||
const context: MetaRenderContext = { metainfo: {} }
|
||||
const key = 'customGroup'
|
||||
const data = {
|
||||
title: 'my custom title',
|
||||
@@ -203,7 +209,7 @@ describe('render', () => {
|
||||
})
|
||||
|
||||
test('render custom group (namespaced tag)', () => {
|
||||
const context = {}
|
||||
const context: MetaRenderContext = { metainfo: {} }
|
||||
const key = 'og'
|
||||
const data = {
|
||||
title: 'my og title',
|
||||
@@ -249,7 +255,7 @@ describe('render', () => {
|
||||
})
|
||||
|
||||
test('render custom group (namespaced attribute and name attribute)', () => {
|
||||
const context = {}
|
||||
const context: MetaRenderContext = { metainfo: {} }
|
||||
const key = 'og'
|
||||
const data = {
|
||||
title: 'my og title',
|
||||
@@ -296,7 +302,7 @@ describe('render', () => {
|
||||
|
||||
test('render custom group (array)', () => {
|
||||
const spy = jest.spyOn(console, 'warn').mockImplementation(_ => _)
|
||||
const context = {}
|
||||
const context: MetaRenderContext = { metainfo: {} }
|
||||
const key = 'og'
|
||||
const data = ['data']
|
||||
|
||||
@@ -319,7 +325,7 @@ describe('render', () => {
|
||||
})
|
||||
|
||||
test('render custom group (tag namespaced)', () => {
|
||||
const context = {}
|
||||
const context: MetaRenderContext = { metainfo: {} }
|
||||
const key = 'esi'
|
||||
const data = {
|
||||
children: [{
|
||||
@@ -483,7 +489,7 @@ describe('render', () => {
|
||||
removeAttribute
|
||||
}])
|
||||
|
||||
const context = {}
|
||||
const context: MetaRenderContext = { metainfo: {} }
|
||||
|
||||
const res = render.renderMeta(context, key, data, config)
|
||||
// console.log('RES', res)
|
||||
@@ -1,19 +1,20 @@
|
||||
import { isArray, isPlainObject } from '@vue/shared'
|
||||
import { createMergedObject } from '../../src/object-merge'
|
||||
import { createMergedObject, ResolveMethod } from '../../src/object-merge'
|
||||
|
||||
const resolve = (options) => {
|
||||
// console.log('RESOLVE\n', options)
|
||||
const resolve: ResolveMethod = <T>(sources: T[]) => {
|
||||
// console.log('RESOLVE\n', sources)
|
||||
|
||||
const hasArrayOption = options.some(option => isArray(option))
|
||||
const hasArrayOption = sources.some(source => isArray(source))
|
||||
if (hasArrayOption) {
|
||||
const groupedOptions = {}
|
||||
for (const option of options) {
|
||||
if (!isArray(option)) {
|
||||
const groupedOptions: Record<string, object> = {}
|
||||
for (const source of sources) {
|
||||
if (!isArray(source)) {
|
||||
continue
|
||||
}
|
||||
|
||||
for (const value of option) {
|
||||
for (const value of source) {
|
||||
if (isPlainObject(value) && 'vmid' in value) {
|
||||
// @ts-ignore
|
||||
groupedOptions[value.vmid] = value
|
||||
}
|
||||
}
|
||||
@@ -21,16 +22,19 @@ const resolve = (options) => {
|
||||
|
||||
// console.log('GROUPED OPTIONS', groupedOptions)
|
||||
const values = []
|
||||
for (const option of options) {
|
||||
if (!isArray(option)) {
|
||||
for (const source of sources) {
|
||||
if (!isArray(source)) {
|
||||
continue
|
||||
}
|
||||
|
||||
for (const value of option) {
|
||||
for (const value of source) {
|
||||
if (!isPlainObject(value) || !('vmid' in value)) {
|
||||
values.push(value)
|
||||
// @ts-ignore
|
||||
} else if (groupedOptions[value.vmid]) {
|
||||
// @ts-ignore
|
||||
values.push(groupedOptions[value.vmid])
|
||||
// @ts-ignore
|
||||
delete groupedOptions[value.vmid]
|
||||
}
|
||||
}
|
||||
@@ -40,7 +44,7 @@ const resolve = (options) => {
|
||||
return values
|
||||
}
|
||||
|
||||
return options[options.length - 1]
|
||||
return sources[sources.length - 1]
|
||||
}
|
||||
|
||||
describe('resolve', () => {
|
||||
@@ -53,11 +57,14 @@ describe('resolve', () => {
|
||||
str: 'string value 2'
|
||||
}
|
||||
|
||||
const { active, addSource, delSource } = createMergedObject(resolve)
|
||||
type Source = { str?: string }
|
||||
|
||||
const { context, addSource, delSource } = createMergedObject<Source>(resolve, {})
|
||||
const { active } = context
|
||||
|
||||
// Set initial value & init proxy
|
||||
addSource(source1)
|
||||
const proxy2 = addSource(source2, null, true /* do an initial compute/walk of all sources */)
|
||||
const proxy2 = addSource(source2, undefined, true /* do an initial compute/walk of all sources */)
|
||||
|
||||
expect(active.str).toBe('string value 2')
|
||||
|
||||
@@ -87,11 +94,14 @@ describe('resolve', () => {
|
||||
}
|
||||
}
|
||||
|
||||
const { active, addSource, delSource } = createMergedObject(resolve)
|
||||
type Source = { obj?: { key?: string } }
|
||||
|
||||
const { context, addSource, delSource } = createMergedObject<Source>(resolve, {})
|
||||
const { active } = context
|
||||
|
||||
// Set initial value & init proxy
|
||||
const proxy1 = addSource(source1)
|
||||
const proxy2 = addSource(source2, null, true /* do an initial compute/walk of all sources */)
|
||||
const proxy2 = addSource(source2, undefined, true /* do an initial compute/walk of all sources */)
|
||||
|
||||
expect(active.obj.key).toBe('object value 2')
|
||||
|
||||
@@ -126,11 +136,12 @@ describe('resolve', () => {
|
||||
]
|
||||
}
|
||||
|
||||
const { active, sources, addSource, delSource } = createMergedObject(resolve)
|
||||
const { context, addSource, delSource } = createMergedObject(resolve, {})
|
||||
const { active, sources } = context
|
||||
|
||||
// Set initial value & init proxy
|
||||
const proxy1 = addSource(source1)
|
||||
const proxy2 = addSource(source2, null, true /* do an initial compute/walk of all sources */)
|
||||
const proxy2 = addSource(source2, undefined, true /* do an initial compute/walk of all sources */)
|
||||
|
||||
expect(active.arr).toEqual(['array value 1', 'array value 2'])
|
||||
|
||||
@@ -156,7 +167,7 @@ describe('resolve', () => {
|
||||
expect(active.arr).toEqual(['test again 2.1'])
|
||||
|
||||
proxy1.arr = ['test again 1']
|
||||
addSource(proxy1, null, true)
|
||||
addSource(proxy1, undefined, true)
|
||||
expect(active.arr).toEqual(['test again 2.1', 'test again 1'])
|
||||
|
||||
proxy2.arr = []
|
||||
@@ -179,11 +190,19 @@ describe('resolve', () => {
|
||||
]
|
||||
}
|
||||
|
||||
const { active, sources, addSource, delSource } = createMergedObject(resolve)
|
||||
type Source = {
|
||||
arr?: {
|
||||
vmid?: string,
|
||||
key: string
|
||||
}[]
|
||||
}
|
||||
|
||||
const { context, addSource, delSource } = createMergedObject<Source>(resolve, {})
|
||||
const { active, sources } = context
|
||||
|
||||
// Set initial value & init proxy
|
||||
const proxy1 = addSource(source1)
|
||||
const proxy2 = addSource(source2, null, true /* do an initial compute/walk of all sources */)
|
||||
const proxy2 = addSource(source2, undefined, true /* do an initial compute/walk of all sources */)
|
||||
|
||||
expect(active.arr).toEqual([
|
||||
{ key: 'collection value 1.1' },
|
||||
@@ -227,7 +246,7 @@ describe('resolve', () => {
|
||||
expect(active.arr).toBeUndefined()
|
||||
expect(active).toEqual({})
|
||||
|
||||
const proxy3 = addSource({ arr: [{ vmid: 'a', key: 'test again 1' }] }, null, true)
|
||||
const proxy3 = addSource({ arr: [{ vmid: 'a', key: 'test again 1' }] }, undefined, true)
|
||||
|
||||
expect(sources.length).toBe(2)
|
||||
expect(active.arr).toEqual([{ vmid: 'a', key: 'test again 1' }])
|
||||
@@ -985,10 +985,10 @@
|
||||
dependencies:
|
||||
"@types/istanbul-lib-report" "*"
|
||||
|
||||
"@types/jest@26.x":
|
||||
version "26.0.20"
|
||||
resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.20.tgz#cd2f2702ecf69e86b586e1f5223a60e454056307"
|
||||
integrity sha512-9zi2Y+5USJRxd0FsahERhBwlcvFh6D2GLQnY2FH2BzK8J9s9omvNHIbvABwIluXa0fD8XVKMLTO0aOEuUfACAA==
|
||||
"@types/jest@^26.0.22":
|
||||
version "26.0.22"
|
||||
resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.22.tgz#8308a1debdf1b807aa47be2838acdcd91e88fbe6"
|
||||
integrity sha512-eeWwWjlqxvBxc4oQdkueW5OF/gtfSceKk4OnOAGlUSwS/liBRtZppbJuz1YkgbrbfGOoeBHun9fOvXnjNwrSOw==
|
||||
dependencies:
|
||||
jest-diff "^26.0.0"
|
||||
pretty-format "^26.0.0"
|
||||
@@ -9082,12 +9082,11 @@ trim-off-newlines@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3"
|
||||
integrity sha1-n5up2e+odkw4dpi8v+sshI8RrbM=
|
||||
|
||||
ts-jest@^26.5.2:
|
||||
version "26.5.2"
|
||||
resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-26.5.2.tgz#5281d6b44c2f94f71205728a389edc3d7995b0c4"
|
||||
integrity sha512-bwyJ2zJieSugf7RB+o8fgkMeoMVMM2KPDE0UklRLuACxjwJsOrZNo6chrcScmK33YavPSwhARffy8dZx5LJdUQ==
|
||||
ts-jest@^26.5.4:
|
||||
version "26.5.4"
|
||||
resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-26.5.4.tgz#207f4c114812a9c6d5746dd4d1cdf899eafc9686"
|
||||
integrity sha512-I5Qsddo+VTm94SukBJ4cPimOoFZsYTeElR2xy6H2TOVs+NsvgYglW8KuQgKoApOKuaU/Ix/vrF9ebFZlb5D2Pg==
|
||||
dependencies:
|
||||
"@types/jest" "26.x"
|
||||
bs-logger "0.x"
|
||||
buffer-from "1.x"
|
||||
fast-json-stable-stringify "2.x"
|
||||
|
||||
Reference in New Issue
Block a user