[Pitch] Introduce ConditionTrait.evaluate()

I'm proposing adding an evaluate() method to ConditionTrait to be able to evaluate the condition explicitly. This helps enable third-party libraries to take advantage of test traits.

The pull request is here, and the full pitch is here.

3 Likes

Absolutely necessary, however, I like the name result() better than evaluate() (and Result rather than EvaluationResult).

Why?

If you shadow Swift.Result, then this addition becomes a source-breaking change for swift-testing clients that use Swift.Result.

If it were called result then I think it should be a property rather than a function. But it involves invoking a callback of unknown complexity, and I generally prefer that properties have straightforward implementations to match the mental model of "I'm just accessing a property". So I prefer it as a function.

I considered calling it Result, and if it were nested as ConditionTrait.Result I think that would not be source breaking. But I do think that would be confusing, especially since it doesn't work like Swift.Result because it's a tuple. I considered using Swift.Result itself but that would require conforming Comment to Error which I don't think is appropriate.

I also initially used a Result-like enum, but it was pointed out that we may eventually want to return a comment in the success case as well, and with the enum that would be a source-breaking change.

I would like to suggest conditionWasMet instead of just wasMet. The latter reads too vague to me.

I did not know that was in Swift. I guess evaluate() and EvaluationResult is acceptable in this instance.

Having it as a function is the correct implementation.

I'm on the fence about that, as it comes down to how you name the condition/trait variable. I also like isMet rather than wasMet, and I think

  • condition.evaluate().wasMet > condition.evaluate().conditionWasMet

But also:

  • trait.evaluate().conditionWasMet > trait.evaluate().wasMet

I propose test() and TestResult instead of evaluate() and EvaluationResult. Therefore conditionWasMet/conditionIsMet to be better regardless of variable name and in terms of clarity, but I also acknowledge that the current terminology of evaluate() and EvaluationResult is acceptable.

I'm intrigued, can you please say some more about this or give some examples?

test() and TestResult would likely be confusing in the context of Swift Testing, where we already have a Test type and @Test macro.

@smontgomery and I were looking at the implementation on Friday and it may be the case that we don't even really need the comment member of the tuple, in which case evaluate() could simply return a Bool (which would make it a bit easier to reason with, probably.)

2 Likes

My specific use case is a library I'm working on for doing structured tests similar to RSpec or Quick. Since I'm breaking tests up into elements smaller than a function, and also because there's currently no public API for creating a corresponding Test object, I thought it would be useful to have my test elements explicitly support Swift Testing traits.

Some traits are easier to use that way than others. Bug is simply a struct with three public properties, which then conforms to Trait via extension. On the other hand, ConditionTrait isn't very usable in this context because the logic for evaluating the condition exists solely in prepare(for:), which has to be passed a Test instance, and we're back to the problem of no public API to create a Test. But it doesn't actually use the test you give it, hence this proposal.

A broad future direction for Swift Testing is to act as a host and low-level interface for testing libraries that don't rely on it or XCTest otherwise, but want to work (as) seamlessly (as possible) with swift test, the Swift VS Code plugin, etc.

This pitch is in line with those goals because we recognize some libraries will want to make use of the Swift Testing runner infrastructure, but if your ultimate goal is to build something independently of Swift Testing, then we may be able to meet your specific needs in a different way.

I don't want to derail this thread with a discussion about "broad future directions", but I'd be happy to discuss with you in DMs, on Slack[1], etc.


  1. Swift IRC server when!? ↩ī¸Ž

What I have in mind is not so much independent, rather compatible with both Swift Testing and XCTest as much as possible.

1 Like