Introducing Swift Power Assert

Hello everyone. I have created a Power Assert library using Swift's new macro feature.

Power asserts provide descriptive assertion messages for your tests, like the following examples:

#powerAssert(max(a, b) == c)
             |   |  |  |  |
             7   4  7  |  12
                       false

#powerAssert(xs.contains(4))
             |  |        |
             |  false    4
             [1, 2, 3]

#powerAssert("hello".hasPrefix("h") && "goodbye".hasSuffix("y"))
             |       |         |    |  |         |         |
             "hello" true      "h"  |  "goodbye" false     "y"
                                    false

Swift macros are an experimental feature, so you need the pre-release Swift toolchain, but that is all you need to integrate it into a real project and use it as a test library.

Help needed!

Currently, Swift macros manipulate the SwiftSyntax syntax tree, and since the syntax tree does not contain type information, this library heuristically analyses the code for various code patterns.

However, since any code can be passed to the assert function, there must still be many unexpected patterns.

Try out this library and help us validate different code patterns. If you find a pattern that doesn't work correctly, please tell us about it in an issue on GitHub.

Thanks!

62 Likes

Super useful! I look forward to trying this out in my projects, and helping out with fixes if I find any issues

1 Like

I'm a big fan of Spock's assertion error messages. Any chance of changing the spelling to #expect(foo == bar) instead of #powerAssert? I just find it a bit verbose.

1 Like

Thanks, #expect seems good. Actually, I wanted to simply use #assert, but Swift's macros don't expand #assert, so I had no choice but to use #powerAssert.

The assert function is now called #expect. Keep #powerAssert as an alias for #expect.

6 Likes

Awesome! Looking forward to using it once I'm working on a 5.8 project :smiley:

1 Like

FYI, we've fixed the compiler bug, so in recent toolchains it's possible to use #assert.

Doug

10 Likes

Thank you. I am a little worried that if the Compile Time Assertion feature will be officially accepted, it will take precedence over the Compile Time Assertion feature than macro?
Or if Compile Time Assertion is accepted, it will use a different syntax?

If compile time assertions are accepted some day, they could use a different syntax.

Doug

3 Likes

Assert function is now #assert(). Very nice to have a simple API. I will keep #expect() and #powerAssert() as aliases for a while.

5 Likes

The online playground is now available.

This interactive platform allows you to effortlessly test and explore the functionalities of Swift Power Assert.

9 Likes

Xcode 15 beta has been released, and you can now run this library without installing the developer toolchain. I added an Xcode project as a sample project and updated README. Please give it a try.

9 Likes

Hi, I noticed that the Package.swift requires iOS 16, what's reason for this constraint?

The version I can now confirm works is 16+. Until last week, I could only confirm that it worked on a Mac, and it was unknown if it would work on iOS (it probably does).

Since Xcode 15 was released and it now works on iOS, iOS 17 and 16 simulators were the ones I quickly confirmed to work. I have not confirmed the lower version yet, so I set it to 16+ for now. I think it will probably work on lower versions, and I would like to remove that constarint.

1 Like

After confirming that it worked, I relaxed the available version specification as follows. The value specified here is the same as the Package.swift generated by the Xcode 15 macro template. It will probably work with older versions, but for now, I used this value. If anyone wants to use this for versions older than iOS 12, please let me know.

platforms: [
  .macOS(.v10_15),.
  .iOS(.v13), .
  .tvOS(.v13), .watchOS(.v6), [ .macOS(.v10_15), .
  .watchOS(.v6), [ .macCatalyst(.v13), .
  .macCatalyst(.v13)
]
5 Likes

This is truly beautiful. Thank you.

2 Likes

Thank you so much for this!