使用FsCheck创建记录的问题 [英] Issues Creating Records with FsCheck

查看:74
本文介绍了使用FsCheck创建记录的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此问题是对使用FsCheck生成记录的早先问题的后续行动.最初的问题由一个结构良好的示例解决方案回答.但是,在共享答案之前,我尝试创建一个包含在下面的生成器.不幸的是,生成的type QueryRequest = {Symbol: string; StartDate: DateTime; EndDate: DateTime}记录存在以下问题:

This question is a follow-up to an earlier question on using FsCheck to generate records. The original question was answered with a well composed example solution. However, prior to the answer being shared, I attempted to create a generator which is included below. Unfortunately, the generated records of type QueryRequest = {Symbol: string; StartDate: DateTime; EndDate: DateTime} have the following issues:

  1. 缺少symbol
  2. 开始日期早于2000年1月1日
  3. 结束日期晚于2019年1月1日

Original:
{ Symbol = ""
  StartDate = 8/9/2057 4:07:10 AM
  EndDate = 10/14/2013 6:15:32 PM }
Shrunk:
{ Symbol = ""
  StartDate = 8/9/2057 12:00:00 AM
  EndDate = 10/14/2013 12:00:00 AM }

由于我仍处于熟悉F#的过​​程中,因此我将对以下方面的建议/反馈表示赞赏:如何解决上述问题,以及在结构,组成等方面改进代码的机会.

Since I am still in the process of becoming familiar with F#, I would appreciate suggestions/feedback on: how to address the aforementioned issues, and opportunities to improve the code in terms of structure, composition, etc.

namespace Parser

module DataGenerators =
    open System
    open FsCheck

    type QueryRequest = {Symbol: string; StartDate: DateTime; EndDate: DateTime}

    type Tweet =
        static member GenerateRecords (year, month, day, symbol) =
            try
                let startDate = DateTime (year, month, day)                
                let endDate = startDate.AddDays 1.0
                Some {Symbol = symbol; StartDate = startDate; EndDate = endDate}
            with
            | :? ArgumentOutOfRangeException -> None

        static member Combine (years: int list) (months: int list) (days: int list) (symbols: string list) =
            let rec loop acc years months days symbols =
                match years, months, days, symbols with
                | [], [], [], [] -> acc
                | year :: years, month :: months, day :: days, symbol :: symbols -> loop ((year, month, day, symbol) :: acc) years months days symbols
                | _, _, _, _ -> acc

            loop [] years months days symbols

        static member Generate () =
            let years = Gen.choose (2000, 2019) |> Gen.sample 0 10
            let months = Gen.choose (1, 12) |> Gen.sample 0 10
            let days = Gen.choose(1, 31) |> Gen.sample 0 10
            let symbols = Gen.elements ["ORCL"; "IBM"; "AAPL"; "GOOGL"] |> Gen.sample 0 10

            Tweet.Combine years months days symbols
            |> List.map Tweet.GenerateRecords
            |> List.fold (fun acc r -> match r with Some q -> q :: acc | None -> acc) []

推荐答案

我无法重现您的问题,以下内容在执行1000秒钟时会产生true:

I cannot reproduce your issue, the following yields true for 1000s of executions:

Tweet.Generate()
|> List.forall (fun q ->
    q.StartDate <= q.EndDate &&
    q.StartDate >= DateTime(2000, 1, 1) &&
    q.EndDate <= DateTime(2019, 12, 31) &&
    ["ORCL"; "IBM"; "AAPL"; "GOOGL"] |> List.contains q.Symbol)

但是,您可以像这样简化Tweet:

However, you can simplify Tweet like so:

type Tweet =
    static member GenerateRecords ((year, month, day), symbol) =
        try
            let startDate = DateTime (year, month, day)
            let endDate = startDate.AddDays 1.0
            Some {Symbol = symbol; StartDate = startDate; EndDate = endDate}
        with
        | :? ArgumentOutOfRangeException -> None

    static member Generate () =
        let years = Gen.choose (2000, 2019) |> Gen.sample 0 10
        let months = Gen.choose (1, 12) |> Gen.sample 0 10
        let days = Gen.choose(1, 31) |> Gen.sample 0 10
        let symbols = Gen.elements ["ORCL"; "IBM"; "AAPL"; "GOOGL"] |> Gen.sample 0 10
        let dates = List.zip3 years months days
        List.zip dates symbols
        |> List.choose Tweet.GenerateRecords

这篇关于使用FsCheck创建记录的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆