-
Notifications
You must be signed in to change notification settings - Fork 448
General index consistency tests #39
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
FWIW I've been using this to check collection consistency: https://github.com/karwa/swift-checkit/blob/master/Sources/Checkit/CollectionChecker.swift I posted about it on the forums - I think it would be a super-useful thing to have a package of generic code which exercises standard library protocols in order to check semantics. For example, it's also useful to check that successive indexes all compare as greater than the last, that empty collections do the right thing, etc. |
@karwa I totally agree! Within the Swift we rely on suite of tests to validate all of the collections in the Standard Library: https://github.com/apple/swift/tree/main/stdlib/private/StdlibCollectionUnittest. It'd be awesome to have package version of this code. |
@karwa Both of these things are covered by I would also like to see this as a separate package! That probably still shouldn't stop us from pursuing this in the short term? There's a pretty direct need for this in the One thing I would like to see in whatever we end up with is a way to also pass indices to test against, like I do here. Having consistency between the index methods is a good start but it doesn't show that the collection does what it says it does, e.g. |
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.
This is great, @timvermeulen! I'd love to see this as a separate package eventually (including things like verifying performance for random-access collections, where possible), and it's great to start here.
file: StaticString = #file, line: UInt = #line | ||
) where C: BidirectionalCollection { | ||
for c in collections { | ||
let indices = indices?(c) ?? (c.indices + [c.endIndex]) |
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 find it a bit confusing that this shares the name of c.indices
but has one more element — could this be allIndexes
/ allValidIndices
/ indicesIncludingEnd
, etc?
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.
Great idea, I'll go with indicesIncludingEnd
. This also makes the - 1
on the next line less confusing.
index, indices[offset], | ||
"Index mismatch at offset \(offset) in `indices`", | ||
file: file, line: line) | ||
} |
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 think we need a check that c.count
equals c.indices.count
here.
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.
Nice find!
I mean, there is a package already - It also has a couple of other things - a I would be very happy if anybody wanted to fork it, improve it, or use it as part of another test package. It's open-source, after all. |
This is a stab at making the index tests from
ChainTests
available to other collections as well (for now justchain
andproduct
).validateIndexTraversals
validates a collection by taking an array of its indices as the source of truth, and verifying that all index operations (with just about any combination of arguments possible) are consistent with these indices.validateIndexTraversals
doesn't just usec.indices + [c.endIndex]
as the indices to test against because that might not catch a bug in the implementation ofindices
itself (or e.g.index(after:)
orIndex.==
). Having to provide an array of indices that are known to be correct prevents these kinds of bugs from slipping through. As an example, the index array of aChain2
instance is computed like this:The previous bugs in
Chain2
andProduct2
would all have been caught by this, so this would give me a bit more confidence before attemptingProduct2.index(_:offsetBy:)
🙂Checklist