Skip to content

Commit

Permalink
Using property wrappers like this crashes Xcode
Browse files Browse the repository at this point in the history
At least as of Xcode 11.5. Here's hoping 12 fixes it.
  • Loading branch information
jemmons committed Jul 2, 2020
1 parent 049ff85 commit 196808c
Show file tree
Hide file tree
Showing 3 changed files with 186 additions and 186 deletions.
74 changes: 37 additions & 37 deletions Sources/BagOfTricks/Wrappers/Forgetful.swift
Original file line number Diff line number Diff line change
@@ -1,37 +1,37 @@
import Foundation



@propertyWrapper
public struct Forgetful<Value> {
private var value: Value?
private let factory: () -> Value


public var wrappedValue: Value {
mutating get {
guard let someValue = value else {
return given(factory()) {
value = $0
}
}
return someValue
}
}


public init(wrappedValue: @autoclosure @escaping () -> Value) {
factory = wrappedValue
}


public mutating func forget() {
value = nil
}


public var projectedValue: Self {
get { return self }
set { self = newValue }
}
}
//import Foundation
//
//
//
//@propertyWrapper
//public struct Forgetful<Value> {
// private var value: Value?
// private let factory: () -> Value
//
//
// public var wrappedValue: Value {
// mutating get {
// guard let someValue = value else {
// return given(factory()) {
// value = $0
// }
// }
// return someValue
// }
// }
//
//
// public init(wrappedValue: @autoclosure @escaping () -> Value) {
// factory = wrappedValue
// }
//
//
// public mutating func forget() {
// value = nil
// }
//
//
// public var projectedValue: Self {
// get { return self }
// set { self = newValue }
// }
//}
146 changes: 73 additions & 73 deletions Tests/BagOfTricksTests/ForgetfulTests.swift
Original file line number Diff line number Diff line change
@@ -1,73 +1,73 @@
import XCTest
import BagOfTricks



class ForgetfulTests: XCTestCase {
func testFactoryCalls() {
let factoryCalled = expectation(description: "Forgetful has reinitialized its value")
factoryCalled.expectedFulfillmentCount = 2

var subject = Forgetful<Int>(wrappedValue: {
factoryCalled.fulfill()
return 42
}())

XCTAssertEqual(subject.wrappedValue, 42)
XCTAssertEqual(subject.wrappedValue, 42)
XCTAssertEqual(subject.wrappedValue, 42)
subject.forget()
XCTAssertEqual(subject.wrappedValue, 42)
XCTAssertEqual(subject.wrappedValue, 42)
XCTAssertEqual(subject.wrappedValue, 42)

wait(for: [factoryCalled], timeout: 0)
}


func testForgets() {
class Ref {
var value: String = "hello"
}
let ref = Ref()

var subject = Forgetful(wrappedValue: ref.value)

XCTAssertEqual(subject.wrappedValue, "hello")
ref.value = "foo"
XCTAssertEqual(subject.wrappedValue, "hello")
subject.forget()
XCTAssertEqual(subject.wrappedValue, "foo")
}


func testLazy() {
let subject = Forgetful<Int>(wrappedValue: {
XCTFail()
return 42
}())

XCTAssertNotNil(subject)
}


func testLazyForget() {
let factoryCalled = expectation(description: "Forgetful has reinitialized its value")

var subject = Forgetful<Int>(wrappedValue: {
factoryCalled.fulfill()
return 42
}())

XCTAssertEqual(subject.wrappedValue, 42)
XCTAssertEqual(subject.wrappedValue, 42)
XCTAssertEqual(subject.wrappedValue, 42)
subject.forget()
subject.forget()
subject.forget()
subject.forget()
subject.forget()

wait(for: [factoryCalled], timeout: 0)
}
}
//import XCTest
//import BagOfTricks
//
//
//
//class ForgetfulTests: XCTestCase {
// func testFactoryCalls() {
// let factoryCalled = expectation(description: "Forgetful has reinitialized its value")
// factoryCalled.expectedFulfillmentCount = 2
//
// var subject = Forgetful<Int>(wrappedValue: {
// factoryCalled.fulfill()
// return 42
// }())
//
// XCTAssertEqual(subject.wrappedValue, 42)
// XCTAssertEqual(subject.wrappedValue, 42)
// XCTAssertEqual(subject.wrappedValue, 42)
// subject.forget()
// XCTAssertEqual(subject.wrappedValue, 42)
// XCTAssertEqual(subject.wrappedValue, 42)
// XCTAssertEqual(subject.wrappedValue, 42)
//
// wait(for: [factoryCalled], timeout: 0)
// }
//
//
// func testForgets() {
// class Ref {
// var value: String = "hello"
// }
// let ref = Ref()
//
// var subject = Forgetful(wrappedValue: ref.value)
//
// XCTAssertEqual(subject.wrappedValue, "hello")
// ref.value = "foo"
// XCTAssertEqual(subject.wrappedValue, "hello")
// subject.forget()
// XCTAssertEqual(subject.wrappedValue, "foo")
// }
//
//
// func testLazy() {
// let subject = Forgetful<Int>(wrappedValue: {
// XCTFail()
// return 42
// }())
//
// XCTAssertNotNil(subject)
// }
//
//
// func testLazyForget() {
// let factoryCalled = expectation(description: "Forgetful has reinitialized its value")
//
// var subject = Forgetful<Int>(wrappedValue: {
// factoryCalled.fulfill()
// return 42
// }())
//
// XCTAssertEqual(subject.wrappedValue, 42)
// XCTAssertEqual(subject.wrappedValue, 42)
// XCTAssertEqual(subject.wrappedValue, 42)
// subject.forget()
// subject.forget()
// subject.forget()
// subject.forget()
// subject.forget()
//
// wait(for: [factoryCalled], timeout: 0)
// }
//}
152 changes: 76 additions & 76 deletions Tests/BagOfTricksTests/ForgetfulWrapperTests.swift
Original file line number Diff line number Diff line change
@@ -1,76 +1,76 @@
import XCTest
import BagOfTricks


private class Ref {
var value: String?
var count: Int = 0
}
private let ref = Ref()


class ForgetfulWrapperTests: XCTestCase {
// This strange formulation of passing the closure in a param instead of as a default value is [required by SR-10950](https://bugs.swift.org/browse/SR-10950). It will probably be fixed in the next Swift release following 5.1.
@Forgetful(wrappedValue: {
ref.count += 1
return ref.value!
}()) var lazy: String


override func setUp() {
ref.value = nil
ref.count = 0
}


func testIsLazy() {
XCTAssertNil(ref.value)
XCTAssertEqual(ref.count, 0)
ref.value = "foo"
XCTAssertEqual(lazy, "foo")
XCTAssertEqual(ref.count, 1)

_ = lazy
_ = lazy
_ = lazy
XCTAssertEqual(ref.count, 1)

ref.value = "bar"

_ = lazy
XCTAssertEqual(lazy, "foo")
XCTAssertEqual(ref.count, 1)
}


func testForget() {
ref.value = "foo"
_ = lazy
ref.value = "bar"

$lazy.forget()
XCTAssertEqual(lazy, "bar")
XCTAssertEqual(ref.count, 2)
}


func testForgetIsLazy() {
ref.value = "foo"
_ = lazy
ref.value = "bar"
_ = lazy
XCTAssertEqual(lazy, "foo")
XCTAssertEqual(ref.count, 1)

$lazy.forget()
XCTAssertEqual(lazy, "bar")
XCTAssertEqual(ref.count, 2)

_ = lazy
_ = lazy
_ = lazy
XCTAssertEqual(lazy, "bar")
XCTAssertEqual(ref.count, 2)
}

}
//import XCTest
//import BagOfTricks
//
//
//private class Ref {
// var value: String?
// var count: Int = 0
//}
//private let ref = Ref()
//
//
//class ForgetfulWrapperTests: XCTestCase {
// // This strange formulation of passing the closure in a param instead of as a default value is [required by SR-10950](https://bugs.swift.org/browse/SR-10950). It will probably be fixed in the next Swift release following 5.1.
// @Forgetful(wrappedValue: {
// ref.count += 1
// return ref.value!
// }()) var lazy: String
//
//
// override func setUp() {
// ref.value = nil
// ref.count = 0
// }
//
//
// func testIsLazy() {
// XCTAssertNil(ref.value)
// XCTAssertEqual(ref.count, 0)
// ref.value = "foo"
// XCTAssertEqual(lazy, "foo")
// XCTAssertEqual(ref.count, 1)
//
// _ = lazy
// _ = lazy
// _ = lazy
// XCTAssertEqual(ref.count, 1)
//
// ref.value = "bar"
//
// _ = lazy
// XCTAssertEqual(lazy, "foo")
// XCTAssertEqual(ref.count, 1)
// }
//
//
// func testForget() {
// ref.value = "foo"
// _ = lazy
// ref.value = "bar"
//
// $lazy.forget()
// XCTAssertEqual(lazy, "bar")
// XCTAssertEqual(ref.count, 2)
// }
//
//
// func testForgetIsLazy() {
// ref.value = "foo"
// _ = lazy
// ref.value = "bar"
// _ = lazy
// XCTAssertEqual(lazy, "foo")
// XCTAssertEqual(ref.count, 1)
//
// $lazy.forget()
// XCTAssertEqual(lazy, "bar")
// XCTAssertEqual(ref.count, 2)
//
// _ = lazy
// _ = lazy
// _ = lazy
// XCTAssertEqual(lazy, "bar")
// XCTAssertEqual(ref.count, 2)
// }
//
//}

0 comments on commit 196808c

Please sign in to comment.