geospec
GeoSpec是一个CAD几何测试库,具有一个独立于主机的创作API:
loadModel 从 geospec/model 和 expectGeo 从 geospec。
这个包裹是 matcher-API衬底 (Apache-2.0): 创作DSL,
选择器语言,诊断和证据模式,匹配器
注册表和主机集成。它自己不执行任何几何: 每个索赔
由编译后的
geospec-engine 核心是
主机传递给跑者。Tau的桌面/浏览器组成和
geospec CLI 供应那个引擎。创作的测试
不要导入或选择引擎,也不会全局注册一个引擎。
以下是 *.geospec.ts 模块,用于CLI或Tau test_model:
import { describe, expectGeo, it } from 'geospec';
import { loadModel } from 'geospec/model';
const code = `
import { makeBaseBox } from 'replicad';
export default function main() {
return makeBaseBox(40, 20, 8);
}
`;
describe('bracket', () => {
it('has expected measurements', async () => {
const model = await loadModel({
code: { 'main.ts': code },
file: 'main.ts',
format: 'glb',
});
expectGeo(model).toHaveBoundingBox({ size: { x: 40, y: 20, z: 8 }, tolerance: 0.1 });
expectGeo(model).toHaveSurfaceArea({ value: 2560, tolerance: 10 });
expectGeo(model).toHaveVolume({ value: 6400, tolerance: 10 });
});
});
运行规范
主题和主持人寿命
等待 loadModel,然后进行同步 expectGeo 断言。它的
GeoSpecSubject 是不透明的:不读取网格字段,伪造主题哈希,还是
在其所属的加载器/运行被处置后重用一个主体。主机保留
源和参数的同一性和具有几何允许、重用和释放性。
独立主机和Vitest主机通过以下方式提供托管加载程序 createModelLoader
与现有主机集成; geospec/vitest 提供框架
适配器。轻快地的 describe/it 来自Vitest,而助手进口
从 geospec 以上都属于GeoSpec的VM运行器。普通的断言仍然存在
expectGeo;可选的Vitest expect 扩展有自己的异步
结算合同。看到 主机绑定文档。
Python使用 load_model/expect_geo 从 geospec,车轮的pytest
插件范围或独立 GeoSpecEngine 上下文。τ test_model 发现
TypeScript/JavaScript测试,而不是Python文件。
阅读 runStatus,完整的核算,发现和源谱系状态时
解释跑步。不支持、不确定、跳过和未运行的要求
不是通行证。紧凑的 test_model 输出可以省略细节; 其保留
fullResult 保留完整的结果。一个空的失败列表本身并不是
确认和过滤的需求仍然在演示的范围之外。
跑步者配置
这个 geospec bin在编译引擎上运行项目的规范,从
geospec-engine:
如果这个平台有一个本地插件,那么它就是WASM构建。的模型,
STEP或GLB不是来自 exporters 项目的 geospec.config.*
声明,在每个池工作线程中导入一次; 没有一个,这样的加载拒绝
与 GEOSPEC_EXPORTER_MISSING。
geospec run .
geospec run . --include "parts/**/*.geospec.ts"
geospec run . --file main.geospec.ts --test-name-pattern volume
geospec run . --workers # worker pool, auto-sized
geospec run . --workers 4 --shard-timeout 600000
geospec run . --config ci.geospec.config.ts
geospec run . --json
规范进口。 CLI将每个规范与本机esbuild捆绑在
project:一个规范可以导入项目文件和GeoSpec内置(geospec,
geospec/model, geospec/config)。npm包或URL导入拒绝使用
BUNDLER_FAILED 以及命名说明符的消息;没有什么是牵强的
安装。解析包的主机将自己的模块VM传递为
createModuleVm (CreateModuleVm 在 geospec/runner;对于节点池,
moduleVmModule)。Tau的主机以这种方式注入Tau的esbuild VM。浏览器主机
没有默认VM,必须注入一个。
| 国旗 | 意义 |
|---|---|
--file <path> | GeoSpec文件或目录根;可重复的。从项目根目录发现空输入。 |
--include <glob> / --exclude <glob> | vitest风格的文件globs;可重复的。包括默认值为 **/*.geospec.{ts,js}。 |
-t, --test-name-pattern <re> | JavaScript正则表达式与完整匹配 suite > test 名字。 |
--test-timeout <ms> | 每个异步测试一下回调的超时。 |
--workers [n] | 在工作池中运行。默认值是1;忽略标志后的计数以请求可用的CPU并行性。 |
--shard-timeout <ms> | 每个分片 non-verdict 看门狗。默认关闭。 |
--bail | 在第一个红色文件后停止。仅限互动使用-奖励运行需要完整的红色套装。 |
--config <path> | 这个 geospec.config.* 来代替项目根目录中的. |
--json | 在stdout上打印一个JSON结果文档,没有别的。 |
标志替换同名的config字段。 退出代码是
判决。 0 只有当跑步成功时;任何失败,任何运行级问题,
和一个空的选择都是 1。
检查没有规格的文件
geospec check 在STEP或GLB文件上运行一个捆绑的有效性规范,因此
首次使用无需 *.geospec.ts。它需要相同的转轮,引擎和报告
作为 geospec run;该文件的文件夹是项目根目录。
geospec check bracket.step
geospec check assembly.glb --components 3 --json
每个索赔都是自己的测试一下: 没有错误诊断,封闭边缘发生率
(toBeWatertight)和一个在每个轴上都是正大小的边界框,加上
GLB的网格完整性或STEP文件的有效BRep的封闭外壳。
--components <n> 添加精确的连接组件计数。发动机索赔
不能决定被报告为不确定的,从不作为通过,退出代码是
判决结果。
要嵌入池,请使用 createGeoSpecNodePoolRunner 从 geospec/runner/node;
每个工人拥有一台发动机和自己的出口,而不是活的对象
跨越工人界限。要在此进程中串行运行,请将引擎从
createNodeGeoSpecEngine 来 createNativeGeoSpecRunner 从
geospec/runner/native;它构建本机模型加载器并释放每个
每次跑步后入院。其他嵌入必须符合其实际
绑定、输入表示和支持域;共享创作语法
单独不能建立判决对等。
下面的过滤器是CLI的共享词汇表,即嵌入式运行程序
和Tau test_model 工具:
files: 要运行的GeoSpec文件或目录根目录。空输入递归地从项目根目录中发现。include: GeoSpec文件包括globs,默认为["**/*.geospec.{ts,js}"]exclude: GeoSpec文件排除globstestNamePattern:与full匹配的JavaScript正则表达式suite > test的名字testTimeout:异步测试超时时间,单位为毫秒
主机使用Tau运行时导出或已经导出的GLB/glTF/STEP字节。编写的测试使用 loadModel 对于代码和直接几何输入; 低级解析/主机api不是替代的创作测试一下方言。
负载故障带有结构化诊断。主张报告保留选定的主张、证据、出处和诊断;检查这些报告,而不是期望不透明主题上的可变证据字段。
保持每个测试都是可读的 loadModel() 呼叫。每个负载捕获电流源/参数标识;主机只能在匹配身份的情况下重用被承认的计算。不要认为文件名单独允许跨文件记忆:
import { describe, expectGeo, it } from 'geospec';
import { loadModel } from 'geospec/model';
describe('assembly', () => {
it('has no global part interference', async () => {
const model = await loadModel({ file: 'main.ts' });
expectGeo(model).toHaveNoComponentInterference({ tolerance: 0.1 });
});
it('keeps the ring and planet free of interference', async () => {
const model = await loadModel({ file: 'main.ts' });
expectGeo(model).toHaveNoComponentInterference({
tolerance: 0.05,
pairs: [{ left: /ring/i, right: /planet gear/i }],
});
});
});
生产装配套件可以结合网格-完整性、发生性、空间 关系,以及精确的BRep断言,而无需添加特定于域的断言 每个机械子系统的匹配器:
expectGeo(model).toHaveMeshIntegrity({
finitePositions: true,
degenerateTriangles: { count: 0 },
duplicateFaces: { count: 0 },
});
expectGeo(model).toHaveAssemblyOccurrences({
uniqueNames: true,
occurrences: [
{ name: 'Housing', count: 1 },
{ name: /^Fastener \d+$/, count: 8 },
],
});
expectGeo(model).toHaveSpatialRelationships({
relationships: [
{ id: 'shaft seats in bearing', kind: 'contact', subject: 'Shaft', target: 'Bearing', tolerance: 0.05 },
{ id: 'pin remains inside yoke', kind: 'containment', subject: 'Pin', target: 'Yoke', tolerance: 0.05 },
],
});
选择被接纳的源支持的选择器。一个合格的网格 body
选择器标识一种材料根及其型腔边界; 断开连接
根和洞里的岛是分开的。它的 of 范围
匹配完全保留的基元标签,包括任何序号后缀。
检查该标签并保留基数,而不是猜测发生的情况
路径。网格输入未发明装配祖先或分析面; 缺少
测量、调查或责令证据拒绝,甚至通过询问否定。
步骤体索引公开了每次出现的实体聚合,也是如此
不假设它的体计数一对一地映射到网格材质根。
全身接触不需要内部重叠和边界分离 宣称的包容性宽容。没有建立接触区域或密封; 有限面角度要求需要其实际的分析证据。
通过相同的编写API加载STEP:
import { loadModel } from 'geospec/model';
const subject = await loadModel({ file: 'part.step', format: 'step' });
对于CAD源, loadModel({ file: 'main.ts', format: 'step' }) 要求主机导出STEP。配置的编译引擎通过其OCCT绑定承认精确返回的字节。出口和来源本身并不构成几何要求。
测量匹配程序支持网格证据,并且在存在时更喜欢精确的BRep证据:
expectGeo(subject).toHaveSurfaceArea({ value: 12_345, tolerance: 1 });
expectGeo(subject).toHaveVolume({ value: 120_000, tolerance: 10 });
expectGeo(subject).toHaveMass({ value: 94.2, density: 0.000_785, tolerance: 0.5 });
expectGeo(subject).toHaveCenterOfMass({ point: { x: 0, y: 0, z: 10 }, tolerance: 0.05 });
当加载器提供BRep证据时,初始BRep特征匹配器可用:
import { loadModel } from 'geospec/model';
const subject = await loadModel({ file: 'main.ts', format: 'step' });
expectGeo(subject).toBeValidBrep({ maxTolerance: 0.01, closedShells: true });
expectGeo(subject).toHavePlanarFace({ normal: { x: 0, y: 0, z: 1 }, offset: 20, tolerance: 0.05 });
expectGeo(subject).toHaveCylindricalFace({ radius: 15, axis: 'z', tolerance: 0.05 });
expectGeo(subject).toHaveCircularHole({ diameter: 8, through: true, axis: 'z', center: { x: 25, y: 15 } });
expectGeo(subject).toHaveChamferFeature({ distance: 2, selection: 'outer top perimeter', tolerance: 0.05 });
expectGeo(subject).toHaveMinimumWallThickness({ value: { greaterThanOrEqual: 2 }, tolerance: 0.05 });
expectGeo(subject).toHaveVoidContinuity({
path: [{ occurrence: 'Throttle Body 1' }, { occurrence: 'Cylinder Head R' }],
material: ['Throttle Body 1', 'Intake Manifold 1', 'Cylinder Head R'],
minCrossSection: 900,
isolatedFrom: [[120, 0, 40]],
});
这些是需求示例,而不是每个被认可的模型都支持的声明
他们。 toHaveVoidContinuity 要求声明的路径、材料和隔离
在限定域中证明的命题。取样的横截面不能
建立连续最小值:一般抽样配置文件拒绝请求
minCrossSection。受限制的名义解析域有独立的前提;
一般网格流明,壁和运动资格仍然不完整。
同样,水密边缘入射不能证明流形有效性,布尔 保险丝或材料连接性。边界和回放无法建立联系, 间隙、密封或密封。保留预期的几何形状和公差; 报告不可用的证据,而不是用代理替换需求。
这个 规范API索引 描述了 普通的创作。单独的 完整的公共API索引 保留主机和框架契约。
当几何断言需要参数变量时,将该变量直接传递给 loadModel. 省略 parameters 练习由模型创作的默认值:
import { describe, expectGeo, it } from 'geospec';
import { loadModel } from 'geospec/model';
describe('parameter variants', () => {
it('uses the model defaults', async () => {
const model = await loadModel({ file: 'main.ts' });
expectGeo(model).toHaveBoundingBox({ size: { x: 40 }, tolerance: 1 });
});
it('accepts an explicit width', async () => {
const width = 80;
const model = await loadModel({
file: 'main.ts',
parameters: { width },
});
expectGeo(model).toHaveBoundingBox({ size: { x: width }, tolerance: 1 });
});
});
许可证
apache - 2.0。 这个包是允许的周边: 你的规格,你的 模型和你的判决不继承这个包的许可。看到 许可 对于路由映射 以及内部常见问题解答。