-
-
Notifications
You must be signed in to change notification settings - Fork 655
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
variable-length-quantity: create test case generator #674
variable-length-quantity: create test case generator #674
Conversation
Description string | ||
Property string // "encode" or "decode" | ||
Input []uint32 // supports both []byte and []uint32 in JSON. | ||
Expected interface{} // supports []byte, []uint32, or null in JSON. |
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.
two thing stand out to me:
- I was a bit surprised: I thought that since
nil
is assignable to[]uint32
that[]uint32
can be used here - I feel like the schema is not doing well for us. In the old way, where
encode
anddecode
are keys, we can have a different struct for each kind of case. But since now we can only tell by looking atproperty
, we have to make ourOneCase
struct a union of all possible cases. Since you have written more generators than I have, I would ask you: How much does this bother you? And I guess more importantly, does it bother enough that it's worth proposing a change?
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.
[]uint32 can be used here
Actually, I think you are right. I jumped to the more general interface{}, likely because I had to previously for a different generator.
In the old way, where encode and decode are keys, we can have a different struct for each kind of case.
This made it easier, I agree.
does it bother enough that it's worth proposing a change?
Well, I've not thought much about what the change might be. But I do like simplicity, and the newer approach in the JSON is adding complexity to the generators. Perhaps there is a compromise. Do you know the rational for the new way in the JSON ?
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.
Do you know the rational for the new way in the JSON ?
I didn't know off the top of my head, so I went searching. The clearest explanation is probably: exercism/problem-specifications#336 (comment) :
In most of the test suites with more than one type of test, the test's type is encoded
in a property-key, in an object describing a test group.There are two problem with that approach:
- It mixes two different concepts regarding the tests: grouping and identification
- It doesn't allow nesting of test groups. That would be nice to have, but is not really needed.
- It doesn't allow grouping of test of different types, which would be really great.
Moving the test type near the test data, we solved all the above problem easily. It is theoretically sound and adds functionality.
I wonder if it would be too much to ask to have the keys again.
I'm wondering what other statically-typed language has generators. There's https://github.com/exercism/xscala/tree/master/testgen/src/main/scala and https://github.com/exercism/xocaml/tree/master/tools/test-generator, might need to take a look at what they're doing.
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.
I considered another alternative, which is... can we deal with this on the Go side without needing a change in x-common? I tried it in #677.
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.
Yes, I've been looking at that one.
e7ee588
to
d07d9ba
Compare
I pushed an update which has a simpler generator. |
return x, n + 1 | ||
return x, n + 1, nil | ||
} else if n == len(buf)-1 { | ||
// error case |
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.
since this is the last iteration, this isn't necessary, is it?
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.
I just checked - the example solution still passes the tests even if these lines are removed, so I would suggest removing them.
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.
Yes. Will remote those lines.
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.
Doesn't need to be in this PR, but at this point I wonder why the "size" is necessary for the decode cases. Now that we require the decoding to decode all the bytes OR signal an error if it was not possible to decode them all, the size will always equal the input slice, and it doesn't seem useful to return it.
I kind of wonder whether it was possible to split this up into several commits, for example one commit that adds multi-int decoding to the example, but I guess it's hard since the test expectations are also changing with it.
So there is only one thing I would change in this: Removing the unnecessary lines from the for loop in the example (or let me know if I'm wrong and they are actually necessary)
@@ -0,0 +1,115 @@ | |||
// +build ignore |
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.
we don't need to build ignore
generators anymore, now that they're in the separate directory, right? They originally were to stop them from being caught when we go test
, but now no longer necessary.
Doesn't need to be in this PR, maybe I'll make a separate one to remove them.
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.
Ok, can be done with one sweeping commit on all the .meta/gen.go files easily later.
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.
I'll make an issue so I don't forget (or if someone else wants to take it)
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.
ok now that #682 is merged, gonna ask you to remove it from this one
return x, n + 1 | ||
return x, n + 1, nil | ||
} else if n == len(buf)-1 { | ||
// error case |
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.
I just checked - the example solution still passes the tests even if these lines are removed, so I would suggest removing them.
d07d9ba
to
5fd7847
Compare
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.
OK. I still think that returning the number of bytes is something I don't understand, but I suppose it can go separately, since it existed before this PR so this PR doesn't need to be concerned with removing it
another thought: 0-length array in test data meaning error, is it going to be confusing at all?
Well, I did wonder about the 0-length array, whether it was clear enough. Do you think it is worth adding an errorExpected bool for clarity in the test data ? Will be fairly easy to do. |
I would add it - I'm looking at the example of https://github.com/exercism/xgo/blob/master/exercises/largest-series-product/cases_test.go where we could find out via However, just to make sure I'm not falling to confirmation bias, I looked for a counterexample, and I found it in Forth: https://github.com/exercism/xgo/blob/master/exercises/forth/cases_test.go#L15 there is a comment there:
So it looks like there are two possible ways of making it clearer, so we have a choice. |
5fd7847
to
618e4f6
Compare
Ok. I chose to add the nil slice comment, and I updated test program to compare against nil as well. |
I just remembered something... forgot to check that Maybe we should only check it in the first few exercises that have |
618e4f6
to
925762f
Compare
Generate two test case arrays, one for encode and one for decode, from the canonical-data.json. Update example solution to pass the tests. The API changed to use slices in order to match the canonical-data.json test cases. Retain the old functions but rename to decodeInt and encodeInt and utilize these as helpers to support the new slice based API. Update test program to use generated test case arrays. Put FAIL and PASS in test result output. Increment testVersion and targetTestVersion in example solution and test program.
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.
everything seems to be in order.
Accidental close earlier. Sorry. |
Since it was introduced in #322, the decode function returns the number of bytes decoded. The creator of the exercise mentioned that it was to be consistent with the standard library's API. Go standard library example for returning number of bytes: https://golang.org/pkg/io/#Writer Now, since #674, it is required that the entire input array be decoded, or else it is an error. Now the number of bytes decoded doesn't make much sense to return, since now it is known that it will always be the length of the input. Go standard library example for not returning number of bytes (decoding everything): https://golang.org/pkg/encoding/json/#Unmarshal testVersion -> 4 Closes #683
For #605
Generate two test case arrays, one for encode and
one for decode, from the canonical-data.json.
Update example solution to pass the tests.
The API changed to use slices in order to match
the canonical-data.json test cases.
Retain the old functions but rename to decodeInt and encodeInt
and utilize these as helpers to support the new slice based API.
Update test program to use generated test case arrays.
Put FAIL and PASS in test result output.
Increment testVersion and targetTestVersion in
example solution and test program.