@amritk/基因-实例
用于从 JSON Schemas 生成快速检查仲裁和实例值的程序API .
概览
@amritk/generate-examples 将 JSON Schema 变成 测试数据在
其他mjst发电机给你代码 消耗量 运行时的数据(参数,
校验器、 类型 , 此选项通过将数据发送给 练习
那个密码.
每个生成的文件导出 :
- 类型脚本
type计划的定义 - A 类
fast-check任意( a)FooArbitrary(中文(简体) ) 用于基于属性的测试的理想 - 具体、自成一体的例子价值(
fooExample——理想的固定装置, 种子和文档
一个 index.ts 枪管再出口一切.
[注] 生成的仲裁导入
fast-check,所以消费者需要安装 (单位:千美元)npm i -D fast-check) (中文(简体) ). 任意的,其策略使用关键字 否fc.*组合器自行抓取( e)if编号 :then编号 :else, (中文(简体) ),not专用oneOf, (中文(简体) ),contains,以及显示对象的关键字——patternProperties, (中文(简体) ),propertyNames, (中文(简体) ),dependent*, (中文(简体) ),min编号 :maxProperties进口@amritk/runtime-validators用于生成后验证过滤器;不需要此过滤器的文件不需要. 静态fooExample值没有运行时间依赖性.
@amritk/runtime-validators是一个dependency这里不是同伴,因为 这台发电机是自己进口的 这解决了发电机,但 没有 必然用于生成的文件——文件所在区域 源树,所以 在 pnpm 的严格布局下或 Yarn PnP 它从您的项目解决,而不是从 这个包裹。 如果您的计划使用了其中的任何关键词, 请直接安装 (单位:千美元)npm i @amritk/runtime-validators) (中文(简体) ). 无法声明为对等点: Bun 拒绝同时列出的工作空间包,以及--frozen-lockfile失败 整个回放.
安装
npm install @amritk/generate-examples
# or
pnpm add @amritk/generate-examples
# or
yarn add @amritk/generate-examples
# or
bun add @amritk/generate-examples
使用量
import { buildExampleSchema } from '@amritk/generate-examples'
const schema = {
type: 'object',
properties: {
id: { type: 'string', format: 'uuid' },
age: { type: 'integer', minimum: 0 },
},
required: ['id'],
} as const
const files = await buildExampleSchema(schema, 'User')
// → [{ filename: 'user.ts', content: '...' }, { filename: 'index.ts', content: '...' }]
生成的 user.ts 看起来像:
import * as fc from 'fast-check'
export type User = { id: string; age?: number }
export const UserArbitrary: fc.Arbitrary<User> = fc.record(
{ "id": fc.uuid(), "age": fc.integer({ min: 0 }) },
{ requiredKeys: ["id"] },
)
export const userExample: User = { "id": "00000000-0000-0000-0000-000000000000", "age": 0 }
在属性测试中使用任意性 :
import { test, fc } from '@fast-check/vitest'
import { UserArbitrary } from './generated'
import { parseUser } from './parsers'
test.prop([UserArbitrary])('parseUser round-trips any valid User', (user) => {
expect(parseUser(user)).toEqual(user)
})
...或者抓住静态的例子作为固定:
import { userExample } from './generated'
const res = await fetch('/users', { method: 'POST', body: JSON.stringify(userExample) })
低级 API
| 导出 | 说明 |
|---|---|
buildExampleSchema(schema, rootName, suffix?) | 走着走着 $ref 图表并返回 a GeneratedFile[] (每个计划一个文件+一个 index.ts) (中文(简体) ). |
generateArbitrary(schema, typeName, suffix?, lazyRefFilenames?, rootSchema?) | 返回 export const …Arbitrary 单一计划节点的来源. |
generateExampleConst(schema, typeName, rootSchema?) | 返回 export const …Example 单一计划节点的来源. |
deriveExample(schema, rootSchema?) | 返回一个混凝土, 计数系统验证的 JavaScript 值( 无代码生成) . |
serializeValue(value) | 将衍生值序列化为 TypeScript 源表达式( 手) Date编号 :bigint) (中文(简体) ). |
支持的关键字
type 包括多种类型的工会,例如: ['string', 'null'] —— 说
(字符串/数字/整数/布尔/核/阵列/对象), properties, (中文(简体) ),
required, (中文(简体) ), additionalProperties, (中文(简体) ), items, (中文(简体) ), prefixItems, (中文(简体) ),
minItems编号 :maxItems, (中文(简体) ), uniqueItems, (中文(简体) ),
minLength编号 :maxLength, (中文(简体) ), pattern, (中文(简体) ), format, (中文(简体) ), minimum编号 :maximum, (中文(简体) ),
exclusiveMinimum编号 :exclusiveMaximum, (中文(简体) ), multipleOf, (中文(简体) ), enum (被兄弟们过滤)
限制), const, (中文(简体) ), minProperties编号 :maxProperties, (中文(简体) ), patternProperties, (中文(简体) ),
propertyNames, (中文(简体) ), dependentRequired, (中文(简体) ), dependentSchemas, (中文(简体) ), contains, (中文(简体) ),
minContains, (中文(简体) ), allOf (合并为一个计划), oneOf编号 :anyOf, (中文(简体) ),
if编号 :then编号 :else, (中文(简体) ), not, (中文(简体) ), $ref,则 x-mjst 扩展
(单位:千美元)Date, (中文(简体) ), bigint) (中文(简体) ). if编号 :then编号 :else, (中文(简体) ), not,以及 oneOf 排他性是
通过验证生成的候选人以对抗计划及
重试/拒绝。 不支持的构造可降解为 fc.anything() 内
仲裁和仲裁 null 在静态示例中.
静态实例包括: format @amritk/runtime-validators 知道该如何
检查 : email, (中文(简体) ), idn-email, (中文(简体) ), date, (中文(简体) ), date-time, (中文(简体) ), time, (中文(简体) ), duration, (中文(简体) ), uuid, (中文(简体) ),
uri, (中文(简体) ), iri, (中文(简体) ), uri-reference, (中文(简体) ), iri-reference, (中文(简体) ), uri-template, (中文(简体) ), json-pointer, (中文(简体) ),
relative-json-pointer, (中文(简体) ), hostname, (中文(简体) ), idn-hostname, (中文(简体) ), ipv4, (中文(简体) ), ipv6, (中文(简体) ), regex, (中文(简体) ),
加上 OpenAPI 代码 url。未识别 format 倒计时 "string"。 。 。 .
已知限制
每个 fooExample 在书写之前,将依据自己的计划加以验证。 何时
值不能满足它仍然发射的图谋——所以模块总是
编译——但生成器打印 a console.warn 命名类型。 到达
FooArbitrary 在这种情况下:任意性带有运行时间验证过滤器
,并在静态值不能时保持正确.
其价值不足有三个原因:
- 计划没有实例.
{ pattern: '^ab$', minLength: 5 }, (中文(简体) ),uniqueItems以布尔表示minItems: 3页:1required键additionalProperties: false禁止,或oneOf他们的分行 每一个价值 两次匹配。 没有任何正确的信息发出;警告指向 计划 不是发电机. - 所行所行所行所行所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出所出.
pattern由一个样本 最好的递归 - 贵族行走 regex, 所以看看周围和 回溯引用回溯到"string"; 未识别format做同样的. - 约束比任何固定的要大. 衍生的字符串、 数组或
对象停止以 10,000 个字符 / 元素 / 密钥生长, 因此文档
请求
minLength: 50000000生成一个上限值和一个警告,而不是 a 50 MB 字节.FooArbitrary仍然尊重真正的约束.
几个值得了解的形状,每个形状都保留生成的文件 编译而非更正:
- 一个计划需要一把钥匙 它的 生成类型从未声明 —— 说
required命名缺少的东西properties页:1dependentRequired编号 :dependentSchemas扶养,或aminProperties填充对象为无 索引签名。 此示例保留了密钥( 缺少其方案 ) 要求是断开的数据),并作为… as Foo,因为一个赤裸的物体 含有多余属性的字元无法编译 . - 作者
examples[0](或,当没有examples,则default)为 使用过的 只有它满足了自己的计划。提示不会 (单位:千美元){ type: 'string', default: 42 }常见于其字段类型 页:1 衍生值, 因为生成的类型遵循了图谋并拒绝 直接的暗示.const永远是荣誉:类型是康斯特自己的 字面类型,所以两者不能有分歧. - 一个 不满足范围 (单位:千美元)
minLength: 10, maxLength: 2) 倒塌在其上 上面的束缚在任意。 每个界限fc.*组合者称min <= max抛出 导入,从而将所有其它出口 与它并列的文件。 整数范围也仅限于快速检查本身 32-位范围,和长度/计算范围到非负整数. - A 类 递归定义的 样板必须停下来,然后停下来
null,不可更改的类型不承认,因此排放为… as unknown as Node。 。 。 .NodeArbitrary将重现通过fc.letrec并且不需要这样的逃脱. - A 类
pattern这是 无效的 JavaScript regex,或者使用前视线 或往后看,倒入平地fc.string()。 。 。 .fc.stringMatching编译 模块范围的图案,不能从一个断言中产生,因此荣誉 它会把文件扔到无法使用的地方 而不是那个 随意松开. - 巢穴深于400级 以错误命名限制. 建造一个任意的,每个图级需要几个堆栈框架,所以更深 文档耗尽了堆栈——盖子将它变成一个信息,说些什么 错了.
两种形状无法生成, 任意性会重试 永远,如果你的样本。 两者都是没有实例的诡计 和例子 警告说:
- A 类
pattern所需长度的字符串无法匹配 (单位:千美元){ pattern: '^[a-z]{2}$', minLength: 5 }) (中文(简体) ). 可爱但狭小的配对 (单位:千美元){ pattern: '^[a-f0-9]+$', minLength: 32, maxLength: 32 })对于 同样的原因 --fc.stringMatching很少按准确的长度降落. - A 类
minLength编号 :minItems如此之大,所以无法建立如此大小的值.
还有一个缺口不是这个包的关闭:a $ref 无处解决
文档按其名称键入(Nope)但从未进口,因为它是
从未作为文件生成 。 任意贬低为: fc.anything()不过
键入时仍为它命名,因此文件不编译。 同样的 { "type": [] }, (中文(简体) ),
类型为 export type Foo = ;两者来自
@amritk/helpers/generate-type-definition。 。 。 .
[TIP] 实例
$ref以数值表示内含,所以定义图宽度 扇出出出出相相相应大字. 成本在产出中 大小,而不是生成时间——每个定义每文档产生一次.