Xem xét một Liên minh phân biệt đối xử:Làm thế nào để dễ dàng lọc ra một trường hợp công đoàn phân biệt trong FsCheck?
type DU = | Foo of string | Bar of int | Baz of decimal * float | Qux of bool
Tôi muốn tạo ra một danh sách các DU
giá trị với FsCheck, nhưng tôi muốn không ai trong số các giá trị được của vụ án Qux
.
vị này đã tồn tại:
let isQux = function Qux _ -> true | _ -> false
nỗ lực đầu tiên
nỗ lực đầu tiên của tôi để tạo ra một danh sách các DU
giá trị mà không có trường hợp Qux
là một cái gì đó như thế này:
type DoesNotWork =
static member DU() = Arb.from<DU> |> Arb.filter (not << isQux)
[<Property(MaxTest = 10 , Arbitrary = [| typeof<DoesNotWork> |])>]
let repro (dus : DU list) =
printfn "%-5b : %O" (dus |> List.exists isQux |> not) dus
Chạy điều này dường như tạo ra một tràn ngăn xếp, vì vậy tôi giả định rằng ha ppens đằng sau hiện trường là Arb.from<DU>
gọi DoesNotWork.DU
.
nỗ lực thứ hai
Sau đó, tôi cố gắng này:
type DoesNotWorkEither =
static member DU() =
Arb.generate<DU>
|> Gen.suchThat (not << isQux)
|> Arb.fromGen
[<Property(MaxTest = 10 , Arbitrary = [| typeof<DoesNotWorkEither> |])>]
let repro (dus : DU list) =
printfn "%-5b : %O" (dus |> List.exists isQux |> not) dus
Cùng một vấn đề như trên.
giải pháp Verbose
Đây là giải pháp tốt nhất mà tôi đã có thể đưa ra cho đến nay:
type WithoutQux =
static member DU() =
[
Arb.generate<string> |> Gen.map Foo
Arb.generate<int> |> Gen.map Bar
Arb.generate<decimal * float> |> Gen.map Baz
]
|> Gen.oneof
|> Arb.fromGen
[<Property(MaxTest = 10 , Arbitrary = [| typeof<WithoutQux> |])>]
let repro (dus : DU list) =
printfn "%-5b : %O" (dus |> List.exists isQux |> not) dus
này hoạt động, nhưng có những nhược điểm sau:
- Có vẻ như rất nhiều công việc
- Nó không sử dụng sẵn cóChức năng, do đó có vẻ như vi phạm một cách tinh tế DRY
- Nó không thực sự là bộ lọc, mà chỉ sản xuất các trường hợp mong muốn (do đó chỉ lọc theo thiếu sót).
- Nó không phải là đặc biệt duy trì, bởi vì nếu tôi bao giờ thêm một trường hợp thứ năm để
DU
, tôi sẽ phải nhớ cũng thêmGen
cho trường hợp đó.
Có cách nào thanh lịch hơn để yêu cầu FsCheck lọc ra các giá trị Qux
không?
Vâng, điều đó phá vỡ vấn đề bằng cách tạo một 'Arbitrary' thay vì một 'Arbitrary ', có thể sol đã vấn đề trước mắt của tôi, nhưng dường như không giải quyết được vấn đề cơ bản. –
Không phải điều này đặt ra vấn đề mà chúng tôi không nhận được hỗ trợ thu hẹp cho DU? – Henrik