Skip to content

Commit

Permalink
feat(class-mock): add seed,setLocale function, add Fake decorator
Browse files Browse the repository at this point in the history
  • Loading branch information
2214962083 committed May 4, 2022
1 parent 982c087 commit cd47f54
Show file tree
Hide file tree
Showing 11 changed files with 65 additions and 37 deletions.
4 changes: 0 additions & 4 deletions packages/class-mock/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,13 @@
"url": "https://github.com/2214962083/vue-superman/issues"
},
"homepage": "https://github.com/2214962083/vue-superman#readme",
"peerDependencies": {
"reflect-metadata": "*"
},
"devDependencies": {
"@types/node": "^17.0.24",
"@types/rimraf": "^3.0.2",
"conventional-changelog-cli": "^2.2.2",
"cross-env": "^7.0.3",
"esno": "^0.14.1",
"jsdom": "^19.0.0",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"superman-shared": "workspace:*",
"typescript": "4.6.3",
Expand Down
3 changes: 2 additions & 1 deletion packages/class-mock/src/decorators/config.decorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import {mergeConfig, getTarget} from '@/utils/common'
import {MetadataStorage} from '@/utils/meta-storage'
import {
Nil,
MockPropertyDecoratorConfig,
MockPropertyMetadata,
MockPropertyDecorator,
Expand Down Expand Up @@ -82,7 +83,7 @@ export function ConfigDecorator<
...(typeof arrayConfig === 'number' ? {length: arrayConfig} : arrayConfig)
}),
isNotArray: () => createMergeConfigDecorator(<T>{array: false}),
groups: (groups: string[]) => createMergeConfigDecorator(<T>{groups})
groups: (groups: string[] | Nil) => createMergeConfigDecorator(<T>{groups})
}

const classDecoratorProto: MockClassDecoratorProps<T> = {
Expand Down
2 changes: 2 additions & 0 deletions packages/class-mock/src/decorators/faker.decorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,5 @@ export const System = createFakeProxy('system')
export const Time = createFakeProxy('time')
export const Vehicle = createFakeProxy('vehicle')
export const Word = createFakeProxy('word')

export const Fake = (...params: Parameters<typeof faker.fake>) => MockDecorator(faker.fake, ...params)
2 changes: 2 additions & 0 deletions packages/class-mock/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export {
// entity decorator
Entity,
// faker decorators
Fake,
Mersenne,
Random,
Helpers,
Expand Down Expand Up @@ -45,4 +46,5 @@ export {
} from './decorators'
export {createMock} from './utils/create-mock'
export type {CreateMockOptions} from './utils/create-mock'
export {setLocale, seed} from './utils/common'
export * from './utils/types-helper'
18 changes: 10 additions & 8 deletions packages/class-mock/src/playground.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import 'reflect-metadata'
import faker from '@faker-js/faker'
import {Random, Name, Phone, Address, Datatype} from './decorators/faker.decorator'
import {Random, Name, Phone, Address, Datatype, Fake} from './decorators/faker.decorator'
import {createMock} from './utils/create-mock'
import {IsArray, IsExclude, IsNotAlwaysRandom, IsPartial} from './decorators/config.decorator'
import {Groups, IsArray, IsExclude, IsNotAlwaysRandom} from './decorators/config.decorator'
import {DefaultAlwaysRandom} from './decorators/class.decorator'
import {Entity} from './decorators/entity.decorator'

faker.setLocale('zh_CN')
// setLocale('zh_CN')

@DefaultAlwaysRandom()
class User {
Expand All @@ -19,6 +17,7 @@ class User {
}

class Skill {
@Groups(['user', 'people'])
@Random.words(5)
name!: string
}
Expand All @@ -31,18 +30,21 @@ class Student extends User {
@Phone.phoneNumber('188########')
tel!: number

@IsPartial()
@Entity(() => Skill)
// @IsPartial()
@Entity(() => Skill).groups(['aaa'])
skills!: Skill[]

@Fake('Hi, my name is {{name.firstName}} {{name.lastName}}!')
introduction!: string

@IsExclude()
privateKey!: string
}

const mockStudent = createMock(Student)
console.log('mockStudent: ', mockStudent)

const mockStudentList = createMock(Student, {array: true, length: 3})
const mockStudentList = createMock(Student, {array: true, length: 3, groups: ['user', 'aaa'], seed: 12})
console.log('\n\nmockStudentList: ', mockStudentList)

// 比如提供一个 webpack 插件或者 vite 插件,配置一下,axios 或 fetch 访问该 url 就可以自动响应 mock 数据了
Expand Down
18 changes: 17 additions & 1 deletion packages/class-mock/src/utils/common.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import {Nil, ArrayConfig, BasePropertyConfig, MetadataTarget} from './types-helper'
import {DEFAULT_ARRAY_LENGTH, DEFAULT_ARRAY_MAX, DEFAULT_ARRAY_MIN} from '@/constants/meta.constants'
import {ArrayConfig, BasePropertyConfig, MetadataTarget} from './types-helper'
import faker, {UsableLocale} from '@faker-js/faker'

export function getTarget(target: any): MetadataTarget {
return target instanceof Function ? target : target.constructor
Expand Down Expand Up @@ -46,3 +47,18 @@ export function mergeConfig<Config extends BasePropertyConfig>(
...(newMeta || {})
} as Config
}

export function IsGroupsIntersect(source: any[] | Nil, target: any[] | Nil) {
if (!source && !target) return true
if (!source) return false
if (!target) return true
return source?.some(item => target?.includes(item))
}

export function setLocale(locale: UsableLocale) {
return faker.setLocale(locale)
}

export function seed(seed?: number | number[]) {
return faker.seed(seed)
}
36 changes: 26 additions & 10 deletions packages/class-mock/src/utils/create-mock.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,51 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import {CLASS_META_KEY} from '@/constants/meta.constants'
import {getGenerateArrayLength, randomBoolean} from './common'
import faker from '@faker-js/faker'
import {getGenerateArrayLength, IsGroupsIntersect, randomBoolean} from './common'
import {MetadataStorage} from './meta-storage'
import {BaseClass, BasePropertyConfig, MockPropertyMetadata} from './types-helper'

export interface CreateMockOptions<IsArray extends boolean = false> extends BasePropertyConfig {
export interface CreateMockOptions<IsArray extends boolean = false> extends Omit<BasePropertyConfig, 'partial'> {
/**
* if true, will generate an array
* @default false
*/
array?: IsArray

/**
* seed for generating same random value
*/
seed?: number | number[]
}

export function createMock<T extends BaseClass, IsArray extends boolean = false>(
Entity: T,
options: CreateMockOptions<IsArray> = {}
): IsArray extends false ? T : T[] {
if (options.seed) {
faker.seed(options.seed)
delete options.seed
}
if (!options.array) {
const metas = MetadataStorage.instance.getClassMetadatas(Entity)
const entity = new Entity()
metas.map(meta => {
const {
target,
propertyName,
alwaysRandom = true,
alwaysRandom: _alwaysRandom,
randomResult,
partialResult,
partial,
// groups = [],
groups,
array = false,
mockFn,
entityFn
} = meta
if (propertyName === CLASS_META_KEY) return
const exclude = partial === 'exclude'
const exclude = partial === 'exclude' || !IsGroupsIntersect(options.groups, groups)
const maybePartial = partial === 'partial' || partial === true
const alwaysRandom = options.alwaysRandom ?? _alwaysRandom ?? true

const updateMeta = (newMeta: Partial<MockPropertyMetadata>) => {
MetadataStorage.instance.updateMockMetadata(target, propertyName, newMeta)
Expand All @@ -48,8 +59,8 @@ export function createMock<T extends BaseClass, IsArray extends boolean = false>
} else if (typeof entityFn === 'function') {
const PropertyEntity = entityFn()
return createMock(PropertyEntity, {
array: false,
...otherOptions
...otherOptions,
array: false
})
}
return undefined
Expand All @@ -64,11 +75,11 @@ export function createMock<T extends BaseClass, IsArray extends boolean = false>
} else if (typeof entityFn === 'function') {
const PropertyEntity = entityFn()
return createMock(PropertyEntity, {
...otherOptions,
array: true,
length,
min,
max,
...otherOptions
max
})
}
return undefined
Expand All @@ -92,7 +103,12 @@ export function createMock<T extends BaseClass, IsArray extends boolean = false>
if (!shouldCreate) return delete entity[propertyName]
}

propertyValue = !array ? createSingleValue(meta) : createListValue(meta)
const newMeta: MockPropertyMetadata = {
...meta,
groups: options.groups,
alwaysRandom
}
propertyValue = !array ? createSingleValue(newMeta) : createListValue(newMeta)
updateMeta({randomResult: propertyValue})
entity[propertyName] = propertyValue
})
Expand Down
5 changes: 2 additions & 3 deletions packages/class-mock/src/utils/types-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,10 @@ export interface BasePropertyConfig extends ArrayConfig {
alwaysRandom?: boolean | undefined

/**
* @TODO
* property only generate in these groups, groups will provide by createMock
* @default undefined
*/
groups?: string[] | undefined
groups?: string[] | Nil

/**
* if true, value will be an array
Expand Down Expand Up @@ -175,7 +174,7 @@ export interface MockPropertyDecoratorProps<T extends BasePropertyConfig> {
* set metadata.groups to groups
* @param groups property only generate in these groups, groups will provide by createMock
*/
groups(groups: string[]): MockPropertyDecorator<T>
groups(groups: string[] | Nil): MockPropertyDecorator<T>
}
export interface MockPropertyDecorator<T extends BasePropertyConfig>
extends PropertyDecorator,
Expand Down
2 changes: 1 addition & 1 deletion packages/class-mock/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const createViteConfig = (options: CreateViteConfigOptions = {}): UserConfig =>
externalMap: {
'@faker-js/faker': ''
},
dedupe: ['reflect-metadata', '@faker-js/faker'] // use the same version
dedupe: ['@faker-js/faker'] // use the same version
})
}

Expand Down
4 changes: 2 additions & 2 deletions packages/vue-xrender/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export * from './hooks'
export * from './components'
export {useJsx} from './hooks'
export {XJsx, XTpl} from './components'
export * from './utils/types-helper'
8 changes: 1 addition & 7 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit cd47f54

Please sign in to comment.