-
Notifications
You must be signed in to change notification settings - Fork 10
Add ShouldGenerateFile annotation #32
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
Conversation
@kevmoo can you please share your view of this change? I could have done this generator in a separate package that would depend on this one, but I cannot customize the private |
Ooo! |
Need some formatter help! |
Fixed. |
# Conflicts: # analysis_options.yaml
@kevmoo can you please take a look again? I would really like to have this in an established package like yours instead of having to make another package for such tests. Not to mention that this is likely a common need. |
@kevmoo pardon me, all fixed. Same output as on
|
@kevmoo can you please take a look once again? This time I ran your CI on my fork, and it's green: alexeyinkin#3 This PR also adds trailing commas that broke your last run: |
Would love to see this land! I was actually just working on a PR for this very same thing and decided to see if somebody was already working on it. I also +1 the idea of being able to signal to re-generate goldens! I do wonder though, with the environment variable, is there a way to specify only wanting to re-generate select goldens? I.e if I change some functionality and only expect 20/100 test cases to change, how can I generate only those ones? My original plan was to go with another bit passed to the One caveat about the non-environment-variable approach: I think doing it this way should fail the test. This is similar to how (IIRC) Android Lint fails the build when generating a new |
The best way to update only specific goldens is to run the specific tests:
With this feature at hand, any userland awareness of this is redundant. |
# Conflicts: # CHANGELOG.md # pubspec.yaml
@btrautmann while this is being reviewed, you can use a temporary package I created: I use it in my own production packages. I intend to deprecate it if @kevmoo merges this. Use that package if you are developing a package of your own and you cannot afford git dependencies. Otherwise, if you are making an app, you can use the git dependency of my branch: Use the hash of the latest commit from there. |
Will try to get to this today! |
Just wanna say thanks to @alexeyinkin... I've been using the package he published while this PR awaits merge, and it's made my life 100000x easier. Looking forward to this merging! Thanks again @alexeyinkin and @kevmoo! |
When I run this locally I see
🤔 |
I have this even on
So this is not a regression. |
Ack @alexeyinkin, re the print statements One thought: I think tests should FAIL w/ the environment variable set. It's trivial to re-run them. I like the idea that the goldens are wired up to regenerate on CI accidentally or something. I've done similar things in other packages – thoughts? |
I also like the idea that updating goldens should fail the test. It is safer. However, long-term we should make things consistent across Dart and Flutter. In Flutter, I suggest filing an issue for that in Flutter for a wider discussion, and then make this PR consistent with the result of that discussion. |
Any chance we can get this across the finish line? The 3rd party package is now not compatible with latest |
Rebase on latest and let's get this landed! |
@kevmoo, rebased: |
I still see conflicts @alexeyinkin |
@kevmoo the new pr shows |
This PR adds
ShouldGenerateFile
annotation to expect the match of the generated code against the content of an existing file.Rationale
For an example use, see this package: https://github.com/alexeyinkin/dart-enum-map/tree/main/enum_map_gen (made to use a fork of source_gen_test for now)
The package generates code of 160+ lines, so to verify the output it is useful to not only test that the output matches a string, but also to write tests on that output itself.
This file uses the new
ShouldGenerateFile
annotation:https://github.com/alexeyinkin/dart-enum-map/blob/main/enum_map_gen/test/unmodifiable_enum_map/src/input.dart
This is the golden that the output is compared with:
https://github.com/alexeyinkin/dart-enum-map/blob/main/enum_map_gen/test/unmodifiable_enum_map/src/output.dart
This is the test on that golden:
https://github.com/alexeyinkin/dart-enum-map/blob/main/enum_map_gen/test/unmodifiable_enum_map/unmodifiable_enum_map_test.dart
This pair of tests ensures that the output both matches the desired one and works as expected.
Implementation
The new annotation has optional arguments
partOf
andpartOfCurrent
.partOfCurrent
adds to the output file a link back to the input file, so that the input file can have tests written for it, as in the example above.partOf
adds to the output file a link to an arbitrary file, if for some reason tests cannot be written for the input file. I can imagine cases where the input file is suitable forLibraryReader
but not for actual execution, so this may be useful. Although if anyone really wants tests on their output they better refactor their input to be buildable. If in doubt, this functionality can be removed.If both arguments are omitted, the output file is just the generated content with no additions. This is useful if no tests are planned on the output but it is just too large to be inlined in the input file.
Open Questions
1. Definition of 'golden'In the wild, a 'golden' test seems to mean comparison to a known result, most often in separate files. This sense of 'golden' is used in Flutter with its--update-goldens
flag (it is not called--update-golden-files
). But currentShouldGenerate
may also be said to compare with a golden that is just being an inline string. Is it OK to name the new annotationShouldGenerateGolden
or should it beShouldGenerateFile
or anything else?The annotation renamed to
ShouldGenerateFile
.2. Updating golden files
There is a need to automatically generate golden files. Flutter does this with
--update-goldens
flag. If it is set, then the output is not tested against goldens, but they are created or updated with a test's output.The pure Dart does not have this concept, so we cannot use this flag to decide if we need to compare or update goldens.
Ideally we want Dart to also have a concept of golden files and to have a similar flag. Then we could have tapped into it and compare or update accordingly. The concept of golden tests is actually wider than what Flutter assumes (in Flutter it only means screenshot matches), so making Dart aware of golden files feels natural. I believe there are other applications for this in Dart like testing JSON serializers with large output, etc. Maybe we can file a feature request for this in Dart SDK repo?
For now, to generate the output I introduced the support for
SOURCE_GEN_TEST_UPDATE_GOLDENS
environment variable. If it is set to '1', the goldens are updated. This seems to be the easiest way to tell the comparison from the update without touching the code.Is this OK or should we do something else to update the files?