#0039 全局数据结构设计
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FsCheck;
|
||||
using XplorePlane.Models;
|
||||
|
||||
namespace XplorePlane.Tests.Generators
|
||||
{
|
||||
/// <summary>
|
||||
/// FsCheck 自定义生成器:为配方相关模型定义 Arbitrary 生成器。
|
||||
/// 使用 Arb.Register<RecipeGenerators>() 注册。
|
||||
/// </summary>
|
||||
public class RecipeGenerators
|
||||
{
|
||||
// ── PipelineModel: class with settable properties ──
|
||||
|
||||
public static Arbitrary<PipelineModel> PipelineModelArb()
|
||||
{
|
||||
var gen = from id in Arb.Default.Guid().Generator
|
||||
from name in Arb.Default.NonEmptyString().Generator
|
||||
from deviceId in Arb.Default.NonEmptyString().Generator
|
||||
from ticks in Gen.Choose(0, int.MaxValue)
|
||||
let createdAt = DateTime.MinValue.AddTicks((long)ticks * 10000)
|
||||
let updatedAt = createdAt
|
||||
select new PipelineModel
|
||||
{
|
||||
Id = id,
|
||||
Name = name.Get,
|
||||
DeviceId = deviceId.Get,
|
||||
CreatedAt = createdAt,
|
||||
UpdatedAt = updatedAt,
|
||||
Nodes = new List<PipelineNodeModel>()
|
||||
};
|
||||
return Arb.From(gen);
|
||||
}
|
||||
|
||||
// ── RecipeStep: reuses StateGenerators for hardware states ──
|
||||
|
||||
public static Arbitrary<RecipeStep> RecipeStepArb()
|
||||
{
|
||||
var gen = from stepIndex in Gen.Choose(0, 100)
|
||||
from motion in StateGenerators.MotionStateArb().Generator
|
||||
from ray in StateGenerators.RaySourceStateArb().Generator
|
||||
from detector in StateGenerators.DetectorStateArb().Generator
|
||||
from pipeline in PipelineModelArb().Generator
|
||||
select new RecipeStep(stepIndex, motion, ray, detector, pipeline);
|
||||
return Arb.From(gen);
|
||||
}
|
||||
|
||||
// ── InspectionRecipe: 0-10 steps with sequential StepIndex ──
|
||||
|
||||
public static Arbitrary<InspectionRecipe> InspectionRecipeArb()
|
||||
{
|
||||
var gen = from id in Arb.Default.Guid().Generator
|
||||
from name in Arb.Default.NonEmptyString().Generator
|
||||
from ticks in Gen.Choose(0, int.MaxValue)
|
||||
let createdAt = DateTime.MinValue.AddTicks((long)ticks * 10000)
|
||||
let updatedAt = createdAt
|
||||
from stepCount in Gen.Choose(0, 10)
|
||||
from steps in GenSequentialSteps(stepCount)
|
||||
select new InspectionRecipe(
|
||||
id,
|
||||
name.Get,
|
||||
createdAt,
|
||||
updatedAt,
|
||||
steps.AsReadOnly());
|
||||
return Arb.From(gen);
|
||||
}
|
||||
|
||||
// ── RecipeExecutionState ──
|
||||
|
||||
public static Arbitrary<RecipeExecutionState> RecipeExecutionStateArb()
|
||||
{
|
||||
var gen = from totalSteps in Gen.Choose(0, 50)
|
||||
from currentStep in Gen.Choose(0, Math.Max(totalSteps, 1) - 1)
|
||||
from status in Gen.Elements(
|
||||
RecipeExecutionStatus.Idle,
|
||||
RecipeExecutionStatus.Running,
|
||||
RecipeExecutionStatus.Paused,
|
||||
RecipeExecutionStatus.Completed,
|
||||
RecipeExecutionStatus.Error)
|
||||
from recipeName in Arb.Default.NonEmptyString().Generator
|
||||
select new RecipeExecutionState(currentStep, totalSteps, status, recipeName.Get);
|
||||
return Arb.From(gen);
|
||||
}
|
||||
|
||||
// ── Helper: generate a list of steps with sequential StepIndex 0..n-1 ──
|
||||
|
||||
private static Gen<List<RecipeStep>> GenSequentialSteps(int count)
|
||||
{
|
||||
if (count == 0)
|
||||
return Gen.Constant(new List<RecipeStep>());
|
||||
|
||||
return Gen.Sequence(
|
||||
Enumerable.Range(0, count).Select(i =>
|
||||
from motion in StateGenerators.MotionStateArb().Generator
|
||||
from ray in StateGenerators.RaySourceStateArb().Generator
|
||||
from detector in StateGenerators.DetectorStateArb().Generator
|
||||
from pipeline in PipelineModelArb().Generator
|
||||
select new RecipeStep(i, motion, ray, detector, pipeline)
|
||||
)
|
||||
).Select(steps => steps.ToList());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user