-
-
Notifications
You must be signed in to change notification settings - Fork 84
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
Code coverage for GoAWK #144
Comments
Hi @xonixx, wow, this looks very interesting -- nice work. I'll take a closer look later this week and get back to you. |
I'll leave more comments later, but in the meantime I'm having trouble using
Do you know why? How did you run |
Just put a commit with a fix. Basically When you re-run the test, please |
Thanks for that (it works). I've gone through your code, and have a few high-level thoughts. There are two approaches we could go here:
The advantage of leaving it in a branch is you'll be able to iterate faster, and code review won't be nearly as strict (I'm fairly strict about what I include in I think if we want it in master, there are a few structural things I'd like to see addressed.
type Parser {
p *parser
}
func NewParser(config *ParserConfig) *Parser { ... }
func (p *Parser) ParseFile(path string, source io.Reader) error { ... }
func (p *Parser) Program() *Program { ... } Or similar, so that we can incrementally parse files and the parser can store their filenames. We'd need to adjust
I'm interested to hear your thoughts on which way you'd rather go: keeping this work in a branch, or getting it cleaned up and merged into master. And any thoughts you have on the specific points too. |
I would prefer to merge in master, therefore I'm ready to address all required issues for this. (Of course, provided that I have enough time and I am alive, since there is a war in my country...) Now I work on a test suite. I believe the complete e2e test suite for this functionality would be very useful (if not critical) for the rewrite. I'll take a look at all items deeper later. However couple comments right away. Indeed the most problems I've got is because of item 3 of your list. In fact this was my first iteration before the "hack". But it failed miserably when I realized that I can't simply re-resolve the "merged" program. So yeah, decoupling of parse / resolve steps needed. Regarding 4. I'm not quite sure if Go does this - need to check. But the interesting thing is that its coverage format is designed in a way to support this! This is specifically useful for my scenario, where for testing purposes I run awk program many times with different inputs using this technique. So here is how this looks in real life. But I'm totally fine with changing the default behavior here and hiding it behind a flag. |
I think the most reasonable would be to start from item 3, namely decoupling of parse / resolve steps. What do you think @benhoyt? |
All the best for you and your family -- war is like nothing we've experienced in far-away New Zealand. Yes, decoupling that in a separate PR sounds like the right way to go, thanks! Ideally it'd be in |
Hey @benhoyt. I would like to proceed with the coverage effort. If you don't mind I would tackle the first item in a separate PR too. So this would be sort of refactoring and I hope I will improve with I already spent some time working on this, and seems like I have sort of a problem, would like to hear your thoughts. So I started from adding the new API like you proposed: type Parser {
p *parser
}
func NewParser(config *ParserConfig) *Parser { ... }
func (p *Parser) ParseFile(path string, source io.Reader) error { ... }
func (p *Parser) Program() *Program { ... } My understanding was that each call to But this doesn't seem to work because resulting positions in each AST would start from zero, so when merged - will be no way to tell the actual file/line as we do now by translating the global position in merged source to local position in a file. So the alternative understanding of how this might work that I came to - is it'll be something similar to what we have now, only in terms of new API. Namely, the Or maybe you think of some other logic? I've also analyzed the possibilty to feed the parser/lexer with more and more text so eventually feeding same parser with all the source files. But looks like the parser/lexer API is designed in a way to only allow to parse single string, since it comes in the constructor. |
Actually I've found a reasonable approach to this, and prepared a PR #150. |
One more PR for #144 that addresses couple of minor things, missed in #154 In this PR: 1. Remove unintuitive behavior (outputting annotated code when only `-covermode` flag set) - just use `-d` flag 2. Update cover.png screenshot: now we show if/for/while conditions in green (covered) 3. Fix for `./goawk -covermode=set 'BEGIN { print 123 }'` to not hang waiting for stdin. This started to happen because processing stops if `prog.Actions == nil` and we by mistake were changing it to empty slice during coverage annotation.
In this branch I'm working on code coverage functionality for GoAWK, similar to the one built in the Golang itself (https://go.dev/blog/cover).
In fact, I was able to make the
go tool cover
to produce the meaningful HTML coverage report for AWK.I wonder if you @benhoyt would be interested in adding this to the project. My solution is a bit hacky here and there, but the approach seems to work well.
I'm still working on adding tests and documentation, and maybe some minor code adjustments, but I would be glad to start getting some feedback from you @benhoyt.
The text was updated successfully, but these errors were encountered: