Skip to content

Instantly share code, notes, and snippets.

@gokselkoksal
Last active September 16, 2022 03:54
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save gokselkoksal/a384ffe46ccd656de95ee144f0bf7304 to your computer and use it in GitHub Desktop.
Save gokselkoksal/a384ffe46ccd656de95ee144f0bf7304 to your computer and use it in GitHub Desktop.
import XCTest
struct Scenario: ScenarioGivenContinuation, ScenarioWhenContinuation {
init(_ description: String) {
print("Scenario: \(description)")
}
struct Given: ScenarioWhenContinuation {
fileprivate init(description: String, setup: () throws -> Void) rethrows {
let message = "Given \(description)"
print(message)
try XCTContext.runActivity(named: message) { _ in
try setup()
}
}
}
struct When: ScenarioThenContinuation {
fileprivate init(description: String, action: () throws -> Void) rethrows {
let message = "When \(description)"
print(message)
try XCTContext.runActivity(named: message) { _ in
try action()
}
}
}
struct Then: ScenarioWhenContinuation {
fileprivate init(description: String, assert: () throws -> Void) rethrows {
let message = "Then \(description)"
print(message)
try XCTContext.runActivity(named: message) { _ in
try assert()
}
}
}
}
protocol ScenarioGivenContinuation {
func given(_ description: String, _ setup: () throws -> Void) rethrows -> Scenario.Given
}
protocol ScenarioWhenContinuation {
func when(_ description: String, _ action: () throws -> Void) rethrows -> Scenario.When
}
protocol ScenarioThenContinuation {
func then(_ description: String, _ assert: () throws -> Void) rethrows -> Scenario.Then
}
extension ScenarioGivenContinuation {
func given(_ description: String) -> Scenario.Given {
Scenario.Given(description: description, setup: { })
}
func given(_ description: String, _ setup: () throws -> Void) rethrows -> Scenario.Given {
try Scenario.Given(description: description, setup: setup)
}
}
extension ScenarioWhenContinuation {
func when(_ description: String, _ action: () throws -> Void) rethrows -> Scenario.When {
try Scenario.When(description: description, action: action)
}
}
extension ScenarioThenContinuation {
@discardableResult
func then(_ description: String, _ assert: () throws -> Void) rethrows -> Scenario.Then {
try Scenario.Then(description: description, assert: assert)
}
}
// MARK: - Usage:
final class PostTests: XCTestCase {
struct Post {
var message: String
var isLiked: Bool
}
func test_like_toggle() throws {
var post = Post(message: "Test", isLiked: false)
let toggleLike: () -> Void = {
post.isLiked = !post.isLiked
}
try Scenario("User likes a post")
.given("the user is on home screen") {
try self.switchToHomeScreen()
}
.when("the user taps on like button") {
toggleLike()
}
.then("expect post.isLiked=true") {
XCTAssertTrue(post.isLiked)
}
.when("user taps on like button again") {
toggleLike()
}
.then("expect post.isLiked=false") {
XCTAssertFalse(post.isLiked)
}
}
private func switchToHomeScreen() throws { }
}
PostTests.defaultTestSuite.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment