This is an archive of the discontinued LLVM Phabricator instance.

Add ScopedPrinter unit tests
ClosedPublic

Authored by Jaysonyan on Nov 28 2021, 7:11 PM.

Details

Summary

This adds unit tests to the ScopedPrinter class.

Depends on D114223

Diff Detail

Event Timeline

Jaysonyan created this revision.Nov 28 2021, 7:11 PM
Jaysonyan requested review of this revision.Nov 28 2021, 7:11 PM
Herald added a project: Restricted Project. · View Herald TranscriptNov 28 2021, 7:11 PM
Jaysonyan updated this revision to Diff 390241.Nov 28 2021, 7:22 PM

Clean up lambda naming.

jhenderson added inline comments.Nov 29 2021, 2:39 AM
llvm/unittests/Support/ScopedPrinterTest.cpp
21

I don't know what "Fcn" stands for. At a guess, it's either "function" or "functor" or similar. I'd suggest "Func" maybe? Similar throughout.

31

Perhaps avoid the first indent, so that we can see what the initial state is like (or print a string before it).

You also need a test case for unindenting when nothing is left to unindent.

Also missing tests for resetIndent, getIndent and other similar functions that are in the public interface.

48

I'd suggest ordering tests in the same order as the functions in the class.

51

What's the reasoning for the DictScope? I don't see anything in the code that requires it, and it just confuses the test a bit.

128

It may be useful to have an entry in this list with a duplicate value as an earlier one, to show that "first one wins" is the approach taken.

132

I'd suggest using index 1, to show you're not just giving up if the first element doesn't match.

148

I think you need a flag with value 0 in this list, to exercies the if ... continue part.

153–155

You need test cases for when the other input parameters of this function are not the default values.

I believe you may also need soemthing that shows the sort call exists.

221

printList has an overload which takes an additional Printer parameter which doesn't seem to be tested here.

244

I'd split this into three different tests for the three different function names.

252

Might be interesting to show that a 0 offset is still explicitly printed.

278–279

The fact that these two cases are inside the ListScope makes the ListScope look like it's important to the behaviour here, but I don't think it is?

Also, why print twice?

303

Are you sure you need the explicit makeArrayRef function? I thought C-arrays were implicitly convertible? If not, perhaps make them std::array, std::vector or SmallVector to reduce test noise? Applies elsewhere too.

306

I think you're missing a test case for void printBinary(StringRef Label, StringRef Value)

310

I think you need a test case for this if statement: https://github.com/microsoft/llvm/blob/eddbfad05ce3a85732d8bff9f85ef63afc97ad7e/lib/Support/ScopedPrinter.cpp#L25

Also, I think you should have one or more unprintable bytes that get converted to .. Also, I think you should at least one test case that shows what happens when there are too many bytes to fit on the line (probably interesting for both the printBinaryBlock and printBinary cases).

Jaysonyan marked 13 inline comments as done.

Address patch comments.

llvm/unittests/Support/ScopedPrinterTest.cpp
51

It's not required for the ScopedPrinter but it is for JSONScopedPrinter. It's possible to remove but it would just mean that we wouldn't be able to reuse this lambda for the JSONScopedPrinter equivalent test.

278–279

Similar to the outside DictScope it is needed produce valid json when testing the JSONScopedPrinter. It's not really needed for testing ScopedPrinter but it allows us to reuse the lambda for both ScopedPrinter and JSONScopedPrinter.

I had added a second print since I thought it made sense to have multiple elements in a list but I realized that's not necessary.

Looks like you're still missing tests for startLine and getOStream, which should be simple, but for completeness should be added too.

llvm/unittests/Support/ScopedPrinterTest.cpp
30

Now that you've added separate indent/unindent tests, I'd move PrintIndent to be later in this file, to match the function declaration order.

47

I'd recommend one function under test per TEST, i.e. split this and ResetIndent into their own TESTs.

51

Okay, leave as-is.

90–91

Perhaps add one more indent call between these two lines, so that a) you show that you can indent after an unindent, and b) show that reset is not just an unindent alias, but rather a complete reset.

94

I'd be tempted to put one more indent at the end here, to show that the internal representation is really capped at 0, rather than just getIndentLevel's external result.

104–105

Perhaps add another setPrefix call followed by a print here, to show that the existing prefix can be changed.

I'd also consider calling printIndent in addition to, or instead of printString, since printIndent explicitly adds the prefix itself.

121

As the value you look up is actually "2", you need this duplicate case to match it, so that you still show the "first one wins" behaviour.

125–126

More unnecessary(?) makeArrayRef calls.

154

Lots of makeArrayRef calls in this test, which could be simplified by using std::vector or other containers.

172–179

Not wanting to be too picky, but this still doesn't exercise all arguments (there are three EnumMask arguments, and you only test with two).

Jaysonyan marked 10 inline comments as done.

Add missing tests and update existing ones.

llvm/unittests/Support/ScopedPrinterTest.cpp
125–126

After trying for a bit, I don't think I can get rid of these makeArrayRef calls. I think it can't implicitly cast to an ArrayRef because the printEnum method takes in a template list rather than a list of concrete type.

154

Similar comment about template lists not allowing for implicit casts to ArrayRef.

Update printEnum test

Jaysonyan updated this revision to Diff 391218.Dec 1 2021, 10:53 PM

Add more printList(...) tests.

Nearly there, just one actual comment.

llvm/unittests/Support/ScopedPrinterTest.cpp
87

Variable names in this test seem wrong.

I wonder if you should change all the expected strings to be called ExpectedOut? And similarly perhaps the functions could have a common name (I don't have any concrete suggestions yet)?

125–126

Okay, thanks for the explanation.

393

Mutters about silly std::vector<bool> standard specialization...

614

startLine not adding a new line implicitly is not what I expected!

Jaysonyan updated this revision to Diff 391387.Dec 2 2021, 10:47 AM

Renamed lambda and expected output variables

Jaysonyan marked 5 inline comments as done.Dec 2 2021, 10:47 AM
Jaysonyan added inline comments.
llvm/unittests/Support/ScopedPrinterTest.cpp
87

My mistake, I've updated all expect strings to be ExpectedOut (and will update json versions to be JSONExpectedOut) and the function names to be all called PrintFunc which also matches the alias for the function_ref inside the test fixture.

393

Haha I learned about this quirk while working on this change.

Esme added a subscriber: Esme.EditedDec 2 2021, 10:35 PM

Should unit tests be added for to_hexString(), to_string() and enumToString() (from D114840)? Although they are not part of the ScopedPrinter class but just in ScopedPrinter.h.

jhenderson accepted this revision.Dec 3 2021, 12:46 AM

Should unit tests be added for to_hexString(), to_string() and enumToString() (from D114840)? Although they are not part of the ScopedPrinter class but just in ScopedPrinter.h.

Yes, they should be added, but I'd be inclined to say that they should be in a separate patch, allowing us to focus this on the ScopedPrinter class specifically.

@Jaysonyan - I spotted a unit test failure in the pre-merge checks above. You should take a look and address it. I think it's a classic case of a compiler treating a uint8_t/int8_t as char variants, and printing them as such. At a guess, this is a bug in the main code that the test is highlighting, rather than a bug in your change though. Is this bug present with the virtualization patch? In theory, this patch should be standalone, so I think a separate precursor small bug fix would be beneficial, so that this unit test patch can be submitted immediately.

Aside from that, looks good.

This revision is now accepted and ready to land.Dec 3 2021, 12:46 AM
jhenderson added inline comments.Dec 3 2021, 1:21 AM
llvm/unittests/Support/ScopedPrinterTest.cpp
51

Actually, revisiting this, now that I've looked at the other related patches again. Is the only reason we need it because we don't add it within the JSONScopedPrinter constructor? If we added it there, could we omit it from here? See also my comments in D114225.

Jaysonyan updated this revision to Diff 391756.Dec 3 2021, 3:10 PM
Jaysonyan marked 2 inline comments as done.
Jaysonyan edited the summary of this revision. (Show Details)

Add APSInt test.

Yes, they should be added, but I'd be inclined to say that they should be in a separate patch, allowing us to focus this on the ScopedPrinter class specifically.

I can add these in a separate patch then.

@Jaysonyan - I spotted a unit test failure in the pre-merge checks above. You should take a look and address it. I think it's a classic case of a compiler treating a uint8_t/int8_t as char variants, and printing them as such. At a guess, this is a bug in the main code that the test is highlighting, rather than a bug in your change though. Is this bug present with the virtualization patch? In theory, this patch should be standalone, so I think a separate precursor small bug fix would be beneficial, so that this unit test patch can be submitted immediately.

This was working locally and I believe that this might because I didn't mention that this diff depends on the virtualization diff. I've added that to the description and hopefully the failing test will fix itself. That being said, I think this indicates that the virtualization patch (D114223) includes a functional change (calling printList with uint_8/int8_t). Although I believe this would be closer to fixing an unrealized bug.

Yes, they should be added, but I'd be inclined to say that they should be in a separate patch, allowing us to focus this on the ScopedPrinter class specifically.

I can add these in a separate patch then.

@Jaysonyan - I spotted a unit test failure in the pre-merge checks above. You should take a look and address it. I think it's a classic case of a compiler treating a uint8_t/int8_t as char variants, and printing them as such. At a guess, this is a bug in the main code that the test is highlighting, rather than a bug in your change though. Is this bug present with the virtualization patch? In theory, this patch should be standalone, so I think a separate precursor small bug fix would be beneficial, so that this unit test patch can be submitted immediately.

This was working locally and I believe that this might because I didn't mention that this diff depends on the virtualization diff. I've added that to the description and hopefully the failing test will fix itself. That being said, I think this indicates that the virtualization patch (D114223) includes a functional change (calling printList with uint_8/int8_t). Although I believe this would be closer to fixing an unrealized bug.

Agreed that this was probably a bug-fix. Might be worth highlighting this in a comment in the patch description.

llvm/unittests/Support/ScopedPrinterTest.cpp
51

Did this comment get missed?

Jaysonyan updated this revision to Diff 392286.Dec 6 2021, 10:38 PM

Update test fixture to hold ScopedPrinter as member.

Jaysonyan added inline comments.Dec 6 2021, 10:48 PM
llvm/unittests/Support/ScopedPrinterTest.cpp
51

Sorry, meant to wait to arrive at a conclusion on the discussion in D114225. I realized the ctor solution (while useful for D114225) isn't perfect for testing. Since at the time that we check the output the JSONScopedPrinter won't have gone out of scope yet so the ListScope/DictScope it's holding on to won't have outputted the closing }/].

As an alternative solution I've added the DictScope inside verifyJSONScopedPrinter so that the DictScope goes out of scope by the time we check the output and so I've removed the unneeded calls to DictScope inside the lambdas.

jhenderson added inline comments.Dec 7 2021, 1:18 AM
llvm/unittests/Support/ScopedPrinterTest.cpp
27

I'm liking the simplicity we're heading towards here, with this function and the members. As a next step, how about you add a "verifyAll" function which takes the expected strings (one for each type) and then calls the corresponding verify* function. This has the advantage of removing additional function calls from each test. The tests then just need to define the two strings and call the "verifyAll" function.

You could even go as far as have the fixture store StringRef members (default to empty) for ExpectedScopedPrinter, ExpectedJSON etc, and have the tests set those, rather than pass them into the function, although I'm not sure there's a huge amount of benefit to that.

40

I'm in two minds about this following suggestion, so feel free to take it or leave it.

W.flush() is in every single lambda that I bothered checking. If we moved it to the verify* function(s), we'd avoid the need for it to be repeated here. The downside is of course that both verify functions will need it, but I think that's better than the repetition. What do you think?

51

No worries. I made this comment before seeing your comments elsewhere.

Jaysonyan updated this revision to Diff 392672.Dec 8 2021, 12:57 AM
Jaysonyan marked 6 inline comments as done.

Add W.flush() to verifyScopedPrinter() method.

llvm/unittests/Support/ScopedPrinterTest.cpp
27

Added verifyAll in D114224! I'll leave the expected output vars as parameters for now since both approaches seem relatively equivalent.

40

That seems reasonable to me! Added.

jhenderson accepted this revision.Dec 9 2021, 6:06 AM

Latest version looks good again.

This revision was automatically updated to reflect the committed changes.