@@ -3,19 +3,81 @@ import Foundation
33/// Encapsulates the failure message that matchers can report to the end user.
44///
55/// This is shared state between Nimble and matchers that mutate this value.
6- public class FailureMessage : NSObject {
7- public var expected : String = " expected "
8- public var actualValue : String ? = " " // empty string -> use default; nil -> exclude
9- public var to : String = " to "
10- public var postfixMessage : String = " match "
11- public var postfixActual : String = " "
6+ public final class FailureMessage : NSObject , @unchecked Sendable {
7+ private let lock = NSRecursiveLock ( )
8+
9+ private var _expected : String = " expected "
10+ private var _actualValue : String ? = " " // empty string -> use default; nil -> exclude
11+ private var _to : String = " to "
12+ private var _postfixMessage : String = " match "
13+ private var _postfixActual : String = " "
1214 /// An optional message that will be appended as a new line and provides additional details
1315 /// about the failure. This message will only be visible in the issue navigator / in logs but
1416 /// not directly in the source editor since only a single line is presented there.
15- public var extendedMessage : String ?
16- public var userDescription : String ?
17+ private var _extendedMessage : String ?
18+ private var _userDescription : String ?
1719
18- public var stringValue : String {
20+ public var expected : String {
21+ get {
22+ return lock. sync { return _expected }
23+ }
24+ set {
25+ lock. sync { _expected = newValue }
26+ }
27+ }
28+ public var actualValue : String ? {
29+ get {
30+ return lock. sync { return _actualValue }
31+ }
32+ set {
33+ lock. sync { _actualValue = newValue }
34+ }
35+ } // empty string -> use default; nil -> exclude
36+ public var to : String {
37+ get {
38+ return lock. sync { return _to }
39+ }
40+ set {
41+ lock. sync { _to = newValue }
42+ }
43+ }
44+ public var postfixMessage : String {
45+ get {
46+ return lock. sync { return _postfixMessage }
47+ }
48+ set {
49+ lock. sync { _postfixMessage = newValue }
50+ }
51+ }
52+ public var postfixActual : String {
53+ get {
54+ return lock. sync { return _postfixActual }
55+ }
56+ set {
57+ lock. sync { _postfixActual = newValue }
58+ }
59+ }
60+ /// An optional message that will be appended as a new line and provides additional details
61+ /// about the failure. This message will only be visible in the issue navigator / in logs but
62+ /// not directly in the source editor since only a single line is presented there.
63+ public var extendedMessage : String ? {
64+ get {
65+ return lock. sync { return _extendedMessage }
66+ }
67+ set {
68+ lock. sync { _extendedMessage = newValue }
69+ }
70+ }
71+ public var userDescription : String ? {
72+ get {
73+ return lock. sync { return _userDescription }
74+ }
75+ set {
76+ lock. sync { _userDescription = newValue }
77+ }
78+ }
79+
80+ private var _stringValue : String {
1981 get {
2082 if let value = _stringValueOverride {
2183 return value
@@ -27,66 +89,112 @@ public class FailureMessage: NSObject {
2789 _stringValueOverride = newValue
2890 }
2991 }
92+ public var stringValue : String {
93+ get {
94+ return lock. sync { return _stringValue }
95+ }
96+ set {
97+ lock. sync { _stringValue = newValue }
98+ }
99+ }
30100
31- internal var _stringValueOverride : String ?
32- internal var hasOverriddenStringValue : Bool {
101+ private var _stringValueOverride : String ?
102+ private var _hasOverriddenStringValue : Bool {
33103 return _stringValueOverride != nil
34104 }
35105
106+ internal var hasOverriddenStringValue : Bool {
107+ return lock. sync { return _hasOverriddenStringValue }
108+ }
109+
36110 public override init ( ) {
111+ super. init ( )
37112 }
38113
39114 public init ( stringValue: String ) {
40115 _stringValueOverride = stringValue
41116 }
42117
43- internal func stripNewlines( _ str: String ) -> String {
118+ private func stripNewlines( _ str: String ) -> String {
44119 let whitespaces = CharacterSet . whitespacesAndNewlines
45120 return str
46121 . components ( separatedBy: " \n " )
47122 . map { line in line. trimmingCharacters ( in: whitespaces) }
48123 . joined ( separator: " " )
49124 }
50125
51- internal func computeStringValue( ) -> String {
52- var value = " \( expected) \( to) \( postfixMessage) "
53- if let actualValue = actualValue {
54- value = " \( expected) \( to) \( postfixMessage) , got \( actualValue) \( postfixActual) "
55- }
56- value = stripNewlines ( value)
126+ private func computeStringValue( ) -> String {
127+ return lock. sync {
128+ var value = " \( _expected) \( _to) \( _postfixMessage) "
129+ if let actualValue = _actualValue {
130+ value = " \( _expected) \( _to) \( _postfixMessage) , got \( actualValue) \( _postfixActual) "
131+ }
132+ value = stripNewlines ( value)
57133
58- if let extendedMessage = extendedMessage {
59- value += " \n \( extendedMessage) "
60- }
134+ if let extendedMessage = _extendedMessage {
135+ value += " \n \( extendedMessage) "
136+ }
61137
62- if let userDescription = userDescription {
63- return " \( userDescription) \n \( value) "
64- }
138+ if let userDescription = _userDescription {
139+ return " \( userDescription) \n \( value) "
140+ }
65141
66- return value
142+ return value
143+ }
67144 }
68145
69146 internal func appendMessage( _ msg: String ) {
70- if hasOverriddenStringValue {
71- stringValue += " \( msg) "
72- } else if actualValue != nil {
73- postfixActual += msg
74- } else {
75- postfixMessage += msg
147+ lock. sync {
148+ if _hasOverriddenStringValue {
149+ _stringValue += " \( msg) "
150+ } else if _actualValue != nil {
151+ _postfixActual += msg
152+ } else {
153+ _postfixMessage += msg
154+ }
76155 }
77156 }
78157
79158 internal func appendDetails( _ msg: String ) {
80- if hasOverriddenStringValue {
81- if let desc = userDescription {
82- stringValue = " \( desc) \n \( stringValue) "
159+ lock. sync {
160+ if _hasOverriddenStringValue {
161+ if let desc = _userDescription {
162+ _stringValue = " \( desc) \n \( _stringValue) "
163+ }
164+ _stringValue += " \n \( msg) "
165+ } else {
166+ if let desc = _userDescription {
167+ _userDescription = desc
168+ }
169+ _extendedMessage = msg
170+ }
171+ }
172+ }
173+
174+ internal func toExpectationMessage( ) -> ExpectationMessage {
175+ lock. sync {
176+ let defaultMessage = FailureMessage ( )
177+ if _expected != defaultMessage. _expected || _hasOverriddenStringValue {
178+ return . fail( _stringValue)
179+ }
180+
181+ var message : ExpectationMessage = . fail( _userDescription ?? " " )
182+ if _actualValue != " " && _actualValue != nil {
183+ message = . expectedCustomValueTo( _postfixMessage, actual: _actualValue ?? " " )
184+ } else if _postfixMessage != defaultMessage. _postfixMessage {
185+ if _actualValue == nil {
186+ message = . expectedTo( _postfixMessage)
187+ } else {
188+ message = . expectedActualValueTo( _postfixMessage)
189+ }
190+ }
191+ if _postfixActual != defaultMessage. _postfixActual {
192+ message = . appends( message, _postfixActual)
83193 }
84- stringValue += " \n \( msg) "
85- } else {
86- if let desc = userDescription {
87- userDescription = desc
194+ if let extended = _extendedMessage {
195+ message = . details( message, extended)
88196 }
89- extendedMessage = msg
197+ return message
90198 }
91199 }
92200}
0 commit comments