FsCheck如何生成元组

How to generate tuples by FsCheck

这是json一代:

let strGen = Arb.Default.String()
                |> Arb.toGen
strGen
    |> Gen.arrayOf
    |> Gen.map (String.concat "\", \"")
    |> Gen.map (fun strs -> "[\"" + strs + "\"]")

如何在我的测试主体中创建 jsonstring 来断言最终结果。

我最初的答案是使用 Gen.map2 组合两个生成器,一个用于字符串数组,一个用于 json 字符串。但是Gen.map2专门设计让两个独立的生成器组合,即一个生成器的结果不会影响结果另一个。 (例如,掷两个骰子:第一个骰子的结果与第二个骰子的结果无关)。您需要的是一个简单的 Gen.map,它采用字符串数组生成器并生成一个元组(字符串数组,json)。像这样:

let strGen = Arb.Default.String() |> Arb.toGen
let arrayGen = strGen |> Gen.arrayOf
arrayGen |> Gen.map (fun array ->
    let json =
        array
        |> String.concat "\", \""
        |> fun strs -> "[\"" + strs + "\"]")
    array,json)

与我在下面结合两个独立生成器的答案不同,这里只有一个生成器,其值用于生成数组和json值。所以这些值将是相关的而不是独立的,并且 json 将始终匹配字符串数组。

原创,不正确,答案如下,保留以防两个答案之间的对比有用:

Easy. Just save the array generator, and re-use it later, using Gen.map2 to combine the array and the json. E.g.:

let strGen = Arb.Default.String()
                |> Arb.toGen
let arrayGen = strGen |> Gen.arrayOf
let jsonGen =
    arrayGen
    |> Gen.map (String.concat "\", \"")
    |> Gen.map (fun strs -> "[\"" + strs + "\"]")
Gen.map2 (fun array json -> array,json) arrayGen jsonGen

And now you have a generator that produces a 2-tuple. The first element of the tuple is the string array, and the second element is the json that was generated.

BTW, your JSON-creating code isn't quite correct yet, because if the generated string contains quotation marks, you'll need to quote them in some way or your generated JSON will be invalid. But I'll let you handle that, or ask a new question about that if you don't know how to handle that. The "single responsibility principle" applies to Stack Overflow questions, too: each question should ideally be about just one subject.

似乎无法将代码放在注释中,所以这是一个清理过的版本:

let isDigitOrWord i =
        i |> String.isNullOrEmpty 
        |> not && Regex.IsMatch(i,"^[a-zA-Z0-9 ]*$")

let strGen = Arb.Default.String() |> Arb.toGen

Gen.arrayOf strGen 
|> Gen.map (fun array ->
    let array = array |>  Array.filter isDigitOrWord
    let json =
        array
        |> String.concat "\", \"" 
        |> fun strs -> if strs|> String.isEmpty then strs else "\"" + strs + "\""
        |> fun strs -> "[" + strs + "]"
    array,json)