using System;
using FsCheck;
using XplorePlane.Models;
namespace XplorePlane.Tests.Generators
{
///
/// FsCheck 自定义生成器:为所有状态模型定义 Arbitrary 生成器。
/// 使用 Arb.Register<StateGenerators>() 注册。
///
public class StateGenerators
{
// ── 位置范围: -10000 ~ 10000, 速度范围: 0 ~ 1000 ──
private static Gen PositionGen =>
Gen.Choose(-10000000, 10000000).Select(i => i / 1000.0);
private static Gen SpeedGen =>
Gen.Choose(0, 1000000).Select(i => i / 1000.0);
private static Gen VoltageGen =>
Gen.Choose(0, 450000).Select(i => i / 1000.0);
private static Gen PowerGen =>
Gen.Choose(0, 3000000).Select(i => i / 1000.0);
private static Gen FrameRateGen =>
Gen.Choose(0, 120000).Select(i => i / 1000.0);
private static Gen MatrixGen =>
Gen.Choose(-10000000, 10000000).Select(i => i / 1000.0);
// ── MotionState: 6 positions + 6 speeds ──
public static Arbitrary MotionStateArb()
{
var gen = from xm in PositionGen
from ym in PositionGen
from zt in PositionGen
from zd in PositionGen
from tiltD in PositionGen
from dist in PositionGen
from xmSpd in SpeedGen
from ymSpd in SpeedGen
from ztSpd in SpeedGen
from zdSpd in SpeedGen
from tiltDSpd in SpeedGen
from distSpd in SpeedGen
select new MotionState(xm, ym, zt, zd, tiltD, dist,
xmSpd, ymSpd, ztSpd, zdSpd, tiltDSpd, distSpd);
return Arb.From(gen);
}
// ── RaySourceState: bool + 2 doubles ──
public static Arbitrary RaySourceStateArb()
{
var gen = from isOn in Arb.Default.Bool().Generator
from voltage in VoltageGen
from power in PowerGen
select new RaySourceState(isOn, voltage, power);
return Arb.From(gen);
}
// ── DetectorState: 2 bools + double + string ──
public static Arbitrary DetectorStateArb()
{
var gen = from isConnected in Arb.Default.Bool().Generator
from isAcquiring in Arb.Default.Bool().Generator
from frameRate in FrameRateGen
from res in Gen.Elements("1024x1024", "2048x2048", "2880x2880", "3072x3072", "4260x4260")
select new DetectorState(isConnected, isAcquiring, frameRate, res);
return Arb.From(gen);
}
// ── SystemState: OperationMode enum + bool + string ──
public static Arbitrary SystemStateArb()
{
var gen = from mode in Gen.Elements(
OperationMode.Idle,
OperationMode.Scanning,
OperationMode.CTAcquire,
OperationMode.RecipeRun)
from hasError in Arb.Default.Bool().Generator
from msg in Arb.Default.NonEmptyString().Generator
let errorMessage = hasError ? msg.Get : string.Empty
select new SystemState(mode, hasError, errorMessage);
return Arb.From(gen);
}
// ── CameraState: 2 bools + null CurrentFrame + 2 ints + double ──
public static Arbitrary CameraStateArb()
{
var gen = from isConnected in Arb.Default.Bool().Generator
from isStreaming in Arb.Default.Bool().Generator
from width in Gen.Choose(0, 8192)
from height in Gen.Choose(0, 8192)
from frameRate in FrameRateGen
select new CameraState(isConnected, isStreaming, null, width, height, frameRate);
return Arb.From(gen);
}
// ── CalibrationMatrix: 9 doubles ──
public static Arbitrary CalibrationMatrixArb()
{
var gen = from m11 in MatrixGen
from m12 in MatrixGen
from m13 in MatrixGen
from m21 in MatrixGen
from m22 in MatrixGen
from m23 in MatrixGen
from m31 in MatrixGen
from m32 in MatrixGen
from m33 in MatrixGen
select new CalibrationMatrix(m11, m12, m13, m21, m22, m23, m31, m32, m33);
return Arb.From(gen);
}
// ── PhysicalPosition: 3 doubles ──
public static Arbitrary PhysicalPositionArb()
{
var gen = from x in PositionGen
from y in PositionGen
from z in PositionGen
select new PhysicalPosition(x, y, z);
return Arb.From(gen);
}
// ── LinkedViewState: PhysicalPosition + bool + DateTime ──
public static Arbitrary LinkedViewStateArb()
{
var gen = from pos in PhysicalPositionArb().Generator
from isExecuting in Arb.Default.Bool().Generator
from ticks in Gen.Choose(0, int.MaxValue)
let dt = DateTime.MinValue.AddTicks((long)ticks * 10000)
select new LinkedViewState(pos, isExecuting, dt);
return Arb.From(gen);
}
}
}