New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Modify Prettifier.truncateAt to work on case classes #2155
Modify Prettifier.truncateAt to work on case classes #2155
Conversation
@@ -277,6 +277,8 @@ private[scalactic] class TruncatingPrettifier(sizeLimit: SizeLimit) extends Defa | |||
else | |||
theToString | |||
// SKIP-SCALATESTJS,NATIVE-END | |||
case caseClazz: Product => | |||
s"${caseClazz.productPrefix}(" + caseClazz.productIterator.map(prettify(_, processed + caseClazz.productIterator)).mkString(", ") + ")" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First of all thanks for the PR! To be consistent, I think productIterator here should follow the size limit, and the processed part should be processed + caseClazz. Also, I think it will be good idea to add this to the DefaultPrettifier also. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First of all thanks for the PR! To be consistent, I think productIterator here should follow the size limit
Are you sure about this? There can be un-intended consequences because the ordering is based on the how the fields are defined in the case class so the dropping of specific fields can have surprising behaviour. Also the amount of fields in a case case class is typically are not that large (as opposed to the actual data in the case class). Finally this behaviour would be quite surprising for me, as a user I wouldn't expect truncation to occur on the fields themselves, just the data.
and the processed part should be processed + caseClazz
Nice catch
Also, I think it will be good idea to add this to the DefaultPrettifier also. :)
Sure will do, its trivial to do so.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First of all thanks for the PR! To be consistent, I think productIterator here should follow the size limit
Are you sure about this? There can be un-intended consequences because the ordering is based on the how the fields are defined in the case class. Also the amount of fields in a case case class is typically are not that large (as opposed to the actual data in the case class). Finally this behaviour would be quite surprising for me, as a user I wouldn't expect truncation to occur on the fields themselves, just the data.
and the processed part should be processed + caseClazz
Nice catch
Also, I think it will be good idea to add this to the DefaultPrettifier also. :)
Sure will do, its trivial to do so.
Hmm, that's true. It is just that it seems in-consistent with other guys in the room, but I think your justification makes good sense. :)
50ff18a
to
417bf76
Compare
I have just rebased the original PR fixing the processed + caseClazz issue |
@mdedetrich Do you mind to add it to DefaultPrettifier also? |
Will do, doing it now. |
Done, also added a test for it with a case class that has an |
I just noticed that |
Sure, that will be great. |
c57a2d2
to
67665f7
Compare
Done, rebased and pushed |
Ah yes, indeed you are right. Let me revert |
67665f7
to
4f97740
Compare
Okay, reverted and pushed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me now, let's trigger CI to build again.
Thanks!
@cheeseng The tests are failing but it seems to be unrelated? |
@mdedetrich Actually it does seem to the related:
As DefaultPrettifier will prettify the "test" string nicely now with your enhancement but our tests are still checking for the default case class toString. I'll see how I can help with that. |
Ah yes indeed you are right. It seems to be pretty trivial to fix so I can also do it, let me know. |
@mdedetrich Unfortunately I am currently working on another PR, I think it will be faster if you can help to fix failing tests, fyi you should be able to run the tests and see the failures by:
|
No worries, its an easy change and was an oversight on my part. I will update the PR with fixes to the tests by EOD. |
@cheeseng So I started going through and fixing some tests and noticed that for some cases there are unintended consequences, specifically if the override def toString: String = Prettifier.default(pivot) + " +- " + Prettifier.default(tolerance) and it was this
I guess the following options are
wdyt? |
Hmm, that's a good point. I think a 'good enough' solution for option 2 is to check if the toString is starting with class name followed by a (, if it does we can use your implementation, if not we can just use its toString. What do you think? |
To me this seems to much of a hack/workaround, https://stackoverflow.com/a/22867096 seems to be a more principled approach to this issue although tbh I am more of a fan of either option 1 or option 3. Either way I don't feel that strongly, so if you want to push for 2 with either of the solutions (checking for class name prefix or using the |
getMethod().getDeclaringClass() sounds like a good idea, but I am not sure if it will work with scala-js and scala-native, you may give that a shot, fyi to run scalactic tests you may do:
|
Thanks, I can also use the prefix |
@mdedetrich Actually I wonder if getMethod().getDeclaringClass() for case class will actually return the case class itself, afaik scala compiler generarte the toString for case class when compiling, so the toString declaring class can be the case class itself. Anyway it will be an interesting thing to try. You may use // SKIP-SCALATESTJS,NATIVE-START and // SKIP-SCALATESTJS,NATIVE-END to skip a block of code for scala-js and scala-native, then use //SCALATESTJS,NATIVE-ONLY to include a line for scala-js and scala-native only code (you'll need to do it for everyline for multiline code). |
4f97740
to
7fc9ae6
Compare
@cheeseng So indeed you are correct, since the Scala compiler automatically creates the I have just rebased and pushed the PR fixing up all of the tests, below is a summary of the changes
|
519887e
to
6d84588
Compare
@mdedetrich Looks good to me! What a big set of changes! Started CI build again. |
@mdedetrich Unfortunately Scala 2.10 seems doesn't like this:
Quick fix perhaps just revert it back to string concat with +? |
@cheeseng Oh wow, didn't realize you still compiled for Scala 2.10. Yes I will remove the string interpolation and use concatenation. |
@mdedetrich Yes we're only dropping scala 2.10 build in the upcoming 3.3 release. :) |
6d84588
to
5aebfe8
Compare
@cheeseng Just pushed a rebased PR removing the string interpolation in |
@mdedetrich I have just restarted the CI, good luck! |
@cheesung The tests have passed so all seems good now! |
Thanks @mdedetrich ! @bvenners If this looks good to you please kindly approve and I'll merge it. Thanks! |
@cheeseng Many thanks for the merge! Would it be possible to ping me on this thread when the ScalaTest RC/milestone is released with this change? |
@mdedetrich Sorry I forgot to response here, yes I can try my best to ping you here when the next version is released, thanks again for your contributions! |
@mdedetrich fyi 3.2.14 is released now. Cheers. |
Awesome, thanks! |
Hello, I have just encountered the
Thank you |
In the PR #2131,
Prettifier.truncateAt
was added which allows the truncating of massive collections when they are pretty printed by ScalaTest. Unfortunately the currentPrettifier.truncateAt
doesn't work if collection/s are wrapped inside acase class
(in my case the data I generate is located withincase class
es).Due to Scala having
Product
along with methods for iterating over fields in acase class
, the implementation is quite straight forward (just applyprettify
on every element in theproductIterator
).Note that we DO NOT truncate the number of fields within the case class, only the values behind those fields.