How to get scalacheck to work on class with a Seq?












1















I have a case class that I am trying to test via ScalaCheck. The case class contains other classes.



Here are the classes:



case class Shop(name: String = "", colors: Seq[Color] = Nil)
case class Color(colorName: String = "", shades: Seq[Shade] = Nil)
case class Shade(shadeName: String, value: Int)


I have generators for each one



implicit def shopGen: Gen[Shop] = 
for {
name <- Gen.alphaStr.suchThat(_.length > 0)
colors <- Gen.listOf(colorsGen)
} yield Shop(name, colors)

implicit def colorsGen: Gen[Color] =
for {
colorName <- Gen.alphaStr.suchThat(_.length > 0)
shades <- Gen.listOf(shadesGen)
} yield Color(colorName, shades)

implicit def shadesGen: Gen[Shade] =
for {
shadeName <- Gen.alphaStr.suchThat(_.length > 0) //**Note this**
value <- Gen.choose(1, Int.MaxValue)
} yield Shade(shadeName, value)


When I write my test and simply do the below:



  property("Shops must encode/decode to/from JSON") {
"test" mustBe "test
}


I get an error and the test hangs and stops after 51 tries. The error I get is Gave up after 1 successful property evaluation. 51 evaluations were discarded.



If I remove Gen.alphaStr.suchThat(_.length > 0) from shadesGen and just replace it with Gen.alphaStr then it works.



Question




  1. Why does having Gen.alphaStr work for shadesGen, however, Gen.alphaStr.suchThat(_.length > 0) does not?

  2. Also when I run test multiple times (with Gen.alphaStr) some pass while some don't. Why is this?










share|improve this question

























  • What is the property you are testing? How do you test the property? When you don't show your code, we find it difficult to help you.

    – Bob Dalgleish
    Nov 22 '18 at 17:45











  • I can put anything there. but still it fails. I've updated the question.

    – Anthony
    Nov 22 '18 at 18:00











  • "Gave up" is the clue -- it means you are discarding too many data values, likely with the suchThat() filter. Change to a generator that never fails.

    – Bob Dalgleish
    Nov 22 '18 at 18:03











  • "Change to a generator that never fails" by this do you mean Gen.alphaStr instead of Gen.alphaStr.suchThat(_.length > 0) ? The former works for me but when I run multiple test runs, it sometimes fails.

    – Anthony
    Nov 22 '18 at 18:10






  • 1





    Does it always fail with "Gave up ..."? If so, there must be some other filtering going on.

    – Bob Dalgleish
    Nov 22 '18 at 18:23
















1















I have a case class that I am trying to test via ScalaCheck. The case class contains other classes.



Here are the classes:



case class Shop(name: String = "", colors: Seq[Color] = Nil)
case class Color(colorName: String = "", shades: Seq[Shade] = Nil)
case class Shade(shadeName: String, value: Int)


I have generators for each one



implicit def shopGen: Gen[Shop] = 
for {
name <- Gen.alphaStr.suchThat(_.length > 0)
colors <- Gen.listOf(colorsGen)
} yield Shop(name, colors)

implicit def colorsGen: Gen[Color] =
for {
colorName <- Gen.alphaStr.suchThat(_.length > 0)
shades <- Gen.listOf(shadesGen)
} yield Color(colorName, shades)

implicit def shadesGen: Gen[Shade] =
for {
shadeName <- Gen.alphaStr.suchThat(_.length > 0) //**Note this**
value <- Gen.choose(1, Int.MaxValue)
} yield Shade(shadeName, value)


When I write my test and simply do the below:



  property("Shops must encode/decode to/from JSON") {
"test" mustBe "test
}


I get an error and the test hangs and stops after 51 tries. The error I get is Gave up after 1 successful property evaluation. 51 evaluations were discarded.



If I remove Gen.alphaStr.suchThat(_.length > 0) from shadesGen and just replace it with Gen.alphaStr then it works.



Question




  1. Why does having Gen.alphaStr work for shadesGen, however, Gen.alphaStr.suchThat(_.length > 0) does not?

  2. Also when I run test multiple times (with Gen.alphaStr) some pass while some don't. Why is this?










share|improve this question

























  • What is the property you are testing? How do you test the property? When you don't show your code, we find it difficult to help you.

    – Bob Dalgleish
    Nov 22 '18 at 17:45











  • I can put anything there. but still it fails. I've updated the question.

    – Anthony
    Nov 22 '18 at 18:00











  • "Gave up" is the clue -- it means you are discarding too many data values, likely with the suchThat() filter. Change to a generator that never fails.

    – Bob Dalgleish
    Nov 22 '18 at 18:03











  • "Change to a generator that never fails" by this do you mean Gen.alphaStr instead of Gen.alphaStr.suchThat(_.length > 0) ? The former works for me but when I run multiple test runs, it sometimes fails.

    – Anthony
    Nov 22 '18 at 18:10






  • 1





    Does it always fail with "Gave up ..."? If so, there must be some other filtering going on.

    – Bob Dalgleish
    Nov 22 '18 at 18:23














1












1








1








I have a case class that I am trying to test via ScalaCheck. The case class contains other classes.



Here are the classes:



case class Shop(name: String = "", colors: Seq[Color] = Nil)
case class Color(colorName: String = "", shades: Seq[Shade] = Nil)
case class Shade(shadeName: String, value: Int)


I have generators for each one



implicit def shopGen: Gen[Shop] = 
for {
name <- Gen.alphaStr.suchThat(_.length > 0)
colors <- Gen.listOf(colorsGen)
} yield Shop(name, colors)

implicit def colorsGen: Gen[Color] =
for {
colorName <- Gen.alphaStr.suchThat(_.length > 0)
shades <- Gen.listOf(shadesGen)
} yield Color(colorName, shades)

implicit def shadesGen: Gen[Shade] =
for {
shadeName <- Gen.alphaStr.suchThat(_.length > 0) //**Note this**
value <- Gen.choose(1, Int.MaxValue)
} yield Shade(shadeName, value)


When I write my test and simply do the below:



  property("Shops must encode/decode to/from JSON") {
"test" mustBe "test
}


I get an error and the test hangs and stops after 51 tries. The error I get is Gave up after 1 successful property evaluation. 51 evaluations were discarded.



If I remove Gen.alphaStr.suchThat(_.length > 0) from shadesGen and just replace it with Gen.alphaStr then it works.



Question




  1. Why does having Gen.alphaStr work for shadesGen, however, Gen.alphaStr.suchThat(_.length > 0) does not?

  2. Also when I run test multiple times (with Gen.alphaStr) some pass while some don't. Why is this?










share|improve this question
















I have a case class that I am trying to test via ScalaCheck. The case class contains other classes.



Here are the classes:



case class Shop(name: String = "", colors: Seq[Color] = Nil)
case class Color(colorName: String = "", shades: Seq[Shade] = Nil)
case class Shade(shadeName: String, value: Int)


I have generators for each one



implicit def shopGen: Gen[Shop] = 
for {
name <- Gen.alphaStr.suchThat(_.length > 0)
colors <- Gen.listOf(colorsGen)
} yield Shop(name, colors)

implicit def colorsGen: Gen[Color] =
for {
colorName <- Gen.alphaStr.suchThat(_.length > 0)
shades <- Gen.listOf(shadesGen)
} yield Color(colorName, shades)

implicit def shadesGen: Gen[Shade] =
for {
shadeName <- Gen.alphaStr.suchThat(_.length > 0) //**Note this**
value <- Gen.choose(1, Int.MaxValue)
} yield Shade(shadeName, value)


When I write my test and simply do the below:



  property("Shops must encode/decode to/from JSON") {
"test" mustBe "test
}


I get an error and the test hangs and stops after 51 tries. The error I get is Gave up after 1 successful property evaluation. 51 evaluations were discarded.



If I remove Gen.alphaStr.suchThat(_.length > 0) from shadesGen and just replace it with Gen.alphaStr then it works.



Question




  1. Why does having Gen.alphaStr work for shadesGen, however, Gen.alphaStr.suchThat(_.length > 0) does not?

  2. Also when I run test multiple times (with Gen.alphaStr) some pass while some don't. Why is this?







scala scalacheck






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 22 '18 at 18:00







Anthony

















asked Nov 22 '18 at 17:31









AnthonyAnthony

10.1k2294184




10.1k2294184













  • What is the property you are testing? How do you test the property? When you don't show your code, we find it difficult to help you.

    – Bob Dalgleish
    Nov 22 '18 at 17:45











  • I can put anything there. but still it fails. I've updated the question.

    – Anthony
    Nov 22 '18 at 18:00











  • "Gave up" is the clue -- it means you are discarding too many data values, likely with the suchThat() filter. Change to a generator that never fails.

    – Bob Dalgleish
    Nov 22 '18 at 18:03











  • "Change to a generator that never fails" by this do you mean Gen.alphaStr instead of Gen.alphaStr.suchThat(_.length > 0) ? The former works for me but when I run multiple test runs, it sometimes fails.

    – Anthony
    Nov 22 '18 at 18:10






  • 1





    Does it always fail with "Gave up ..."? If so, there must be some other filtering going on.

    – Bob Dalgleish
    Nov 22 '18 at 18:23



















  • What is the property you are testing? How do you test the property? When you don't show your code, we find it difficult to help you.

    – Bob Dalgleish
    Nov 22 '18 at 17:45











  • I can put anything there. but still it fails. I've updated the question.

    – Anthony
    Nov 22 '18 at 18:00











  • "Gave up" is the clue -- it means you are discarding too many data values, likely with the suchThat() filter. Change to a generator that never fails.

    – Bob Dalgleish
    Nov 22 '18 at 18:03











  • "Change to a generator that never fails" by this do you mean Gen.alphaStr instead of Gen.alphaStr.suchThat(_.length > 0) ? The former works for me but when I run multiple test runs, it sometimes fails.

    – Anthony
    Nov 22 '18 at 18:10






  • 1





    Does it always fail with "Gave up ..."? If so, there must be some other filtering going on.

    – Bob Dalgleish
    Nov 22 '18 at 18:23

















What is the property you are testing? How do you test the property? When you don't show your code, we find it difficult to help you.

– Bob Dalgleish
Nov 22 '18 at 17:45





What is the property you are testing? How do you test the property? When you don't show your code, we find it difficult to help you.

– Bob Dalgleish
Nov 22 '18 at 17:45













I can put anything there. but still it fails. I've updated the question.

– Anthony
Nov 22 '18 at 18:00





I can put anything there. but still it fails. I've updated the question.

– Anthony
Nov 22 '18 at 18:00













"Gave up" is the clue -- it means you are discarding too many data values, likely with the suchThat() filter. Change to a generator that never fails.

– Bob Dalgleish
Nov 22 '18 at 18:03





"Gave up" is the clue -- it means you are discarding too many data values, likely with the suchThat() filter. Change to a generator that never fails.

– Bob Dalgleish
Nov 22 '18 at 18:03













"Change to a generator that never fails" by this do you mean Gen.alphaStr instead of Gen.alphaStr.suchThat(_.length > 0) ? The former works for me but when I run multiple test runs, it sometimes fails.

– Anthony
Nov 22 '18 at 18:10





"Change to a generator that never fails" by this do you mean Gen.alphaStr instead of Gen.alphaStr.suchThat(_.length > 0) ? The former works for me but when I run multiple test runs, it sometimes fails.

– Anthony
Nov 22 '18 at 18:10




1




1





Does it always fail with "Gave up ..."? If so, there must be some other filtering going on.

– Bob Dalgleish
Nov 22 '18 at 18:23





Does it always fail with "Gave up ..."? If so, there must be some other filtering going on.

– Bob Dalgleish
Nov 22 '18 at 18:23












1 Answer
1






active

oldest

votes


















1














You probably see this behavior because of the way listOf is implemented. Inside it is based on buildableOf which is in turn based on buildableOfN which has following comment:




... If the given generator fails generating a value, the
complete container generator will also fail.




Your data structure is essentially a list of lists so even one bad generation will curse the whole data-structure to be discarded. And obviously most of the failures happens at the bottom level. That's why removing the filter for shadeName helps. So to make it work you should generate more valid strings. You may change Gen.alphaStr to some custom-made generator based on nonEmptyListOf such as:



def nonemptyAlphaStr:Gen[String] = Gen.nonEmptyListOf(alphaChar).map(_.mkString)


Another simple way to work this around is to use retryUntil instead of suchThat such as in:



implicit def shadesGen: Gen[Shade] =
for {
//shadeName <- Gen.alphaStr.suchThat(_.length > 0) //**Note this**
shadeName <- Gen.alphaStr.retryUntil(_.length > 0)
value <- Gen.choose(1, Int.MaxValue)
} yield Shade(shadeName, value)





share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53435893%2fhow-to-get-scalacheck-to-work-on-class-with-a-seq%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    You probably see this behavior because of the way listOf is implemented. Inside it is based on buildableOf which is in turn based on buildableOfN which has following comment:




    ... If the given generator fails generating a value, the
    complete container generator will also fail.




    Your data structure is essentially a list of lists so even one bad generation will curse the whole data-structure to be discarded. And obviously most of the failures happens at the bottom level. That's why removing the filter for shadeName helps. So to make it work you should generate more valid strings. You may change Gen.alphaStr to some custom-made generator based on nonEmptyListOf such as:



    def nonemptyAlphaStr:Gen[String] = Gen.nonEmptyListOf(alphaChar).map(_.mkString)


    Another simple way to work this around is to use retryUntil instead of suchThat such as in:



    implicit def shadesGen: Gen[Shade] =
    for {
    //shadeName <- Gen.alphaStr.suchThat(_.length > 0) //**Note this**
    shadeName <- Gen.alphaStr.retryUntil(_.length > 0)
    value <- Gen.choose(1, Int.MaxValue)
    } yield Shade(shadeName, value)





    share|improve this answer




























      1














      You probably see this behavior because of the way listOf is implemented. Inside it is based on buildableOf which is in turn based on buildableOfN which has following comment:




      ... If the given generator fails generating a value, the
      complete container generator will also fail.




      Your data structure is essentially a list of lists so even one bad generation will curse the whole data-structure to be discarded. And obviously most of the failures happens at the bottom level. That's why removing the filter for shadeName helps. So to make it work you should generate more valid strings. You may change Gen.alphaStr to some custom-made generator based on nonEmptyListOf such as:



      def nonemptyAlphaStr:Gen[String] = Gen.nonEmptyListOf(alphaChar).map(_.mkString)


      Another simple way to work this around is to use retryUntil instead of suchThat such as in:



      implicit def shadesGen: Gen[Shade] =
      for {
      //shadeName <- Gen.alphaStr.suchThat(_.length > 0) //**Note this**
      shadeName <- Gen.alphaStr.retryUntil(_.length > 0)
      value <- Gen.choose(1, Int.MaxValue)
      } yield Shade(shadeName, value)





      share|improve this answer


























        1












        1








        1







        You probably see this behavior because of the way listOf is implemented. Inside it is based on buildableOf which is in turn based on buildableOfN which has following comment:




        ... If the given generator fails generating a value, the
        complete container generator will also fail.




        Your data structure is essentially a list of lists so even one bad generation will curse the whole data-structure to be discarded. And obviously most of the failures happens at the bottom level. That's why removing the filter for shadeName helps. So to make it work you should generate more valid strings. You may change Gen.alphaStr to some custom-made generator based on nonEmptyListOf such as:



        def nonemptyAlphaStr:Gen[String] = Gen.nonEmptyListOf(alphaChar).map(_.mkString)


        Another simple way to work this around is to use retryUntil instead of suchThat such as in:



        implicit def shadesGen: Gen[Shade] =
        for {
        //shadeName <- Gen.alphaStr.suchThat(_.length > 0) //**Note this**
        shadeName <- Gen.alphaStr.retryUntil(_.length > 0)
        value <- Gen.choose(1, Int.MaxValue)
        } yield Shade(shadeName, value)





        share|improve this answer













        You probably see this behavior because of the way listOf is implemented. Inside it is based on buildableOf which is in turn based on buildableOfN which has following comment:




        ... If the given generator fails generating a value, the
        complete container generator will also fail.




        Your data structure is essentially a list of lists so even one bad generation will curse the whole data-structure to be discarded. And obviously most of the failures happens at the bottom level. That's why removing the filter for shadeName helps. So to make it work you should generate more valid strings. You may change Gen.alphaStr to some custom-made generator based on nonEmptyListOf such as:



        def nonemptyAlphaStr:Gen[String] = Gen.nonEmptyListOf(alphaChar).map(_.mkString)


        Another simple way to work this around is to use retryUntil instead of suchThat such as in:



        implicit def shadesGen: Gen[Shade] =
        for {
        //shadeName <- Gen.alphaStr.suchThat(_.length > 0) //**Note this**
        shadeName <- Gen.alphaStr.retryUntil(_.length > 0)
        value <- Gen.choose(1, Int.MaxValue)
        } yield Shade(shadeName, value)






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 26 '18 at 3:55









        SergGrSergGr

        21.4k22243




        21.4k22243
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53435893%2fhow-to-get-scalacheck-to-work-on-class-with-a-seq%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            這個網誌中的熱門文章

            Tangent Lines Diagram Along Smooth Curve

            Yusuf al-Mu'taman ibn Hud

            Zucchini