using System;
using System.Collections.Generic;
using System.Linq;
using FsCheck;
using FsCheck.Fluent;
using XplorePlane.Models;
namespace XplorePlane.Tests.Generators
{
///
/// FsCheck 3.x 自定义生成器:为配方相关模型定义 Arbitrary 生成器。
///
public class RecipeGenerators
{
public static Arbitrary PipelineModelArb()
{
var gen = from id in ArbMap.Default.GeneratorFor()
from name in ArbMap.Default.GeneratorFor()
from deviceId in ArbMap.Default.GeneratorFor()
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()
};
return gen.ToArbitrary();
}
public static Arbitrary 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 gen.ToArbitrary();
}
public static Arbitrary InspectionRecipeArb()
{
var gen = from id in ArbMap.Default.GeneratorFor()
from name in ArbMap.Default.GeneratorFor()
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 gen.ToArbitrary();
}
public static Arbitrary 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 ArbMap.Default.GeneratorFor()
select new RecipeExecutionState(currentStep, totalSteps, status, recipeName.Get);
return gen.ToArbitrary();
}
private static Gen> GenSequentialSteps(int count)
{
if (count == 0)
return Gen.Constant(new List());
// Build list step by step using SelectMany chain
Gen> result = Gen.Constant(new List());
for (int i = 0; i < count; i++)
{
var idx = i;
result = from list in result
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 List(list)
{
new RecipeStep(idx, motion, ray, detector, pipeline)
};
}
return result;
}
}
}