Skip to content

Commit 0638abd

Browse files
Merge branch 'release/5.5.1'
2 parents 453fab6 + db2b0f7 commit 0638abd

File tree

8 files changed

+295
-316
lines changed

8 files changed

+295
-316
lines changed

Package.resolved

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Sources/Core/0_Validatable/*SomeValidatable.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
internal implementation.
3030
*/
3131
public
32-
protocol SomeValidatable
32+
protocol SomeValidatable: Equatable
3333
{
3434
func validate() throws
3535
}

Sources/Core/1_Entity/*SomeValidatableEntity.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ extension SomeValidatableEntity
4949
Returns list of all members that have to be involved in
5050
automatic entity validation.
5151
*/
52-
var allValidatableMembers: [SomeValidatable]
52+
var allValidatableMembers: [any SomeValidatable]
5353
{
5454
return allMembers
55-
.compactMap{ $0 as? SomeValidatable }
55+
.compactMap{ $0 as? (any SomeValidatable) }
5656
}
5757
}
5858

Sources/Core/2_ValueWrappers/*Persistence.swift

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,28 @@ extension SomeStorageKey
4646
// MARK: - ValueStorage
4747

4848
public
49-
enum ValueStorage
49+
enum ValueStorage: Equatable
5050
{
5151
case appStorageStandard(key: SomeStorageKey)
5252
case appStorage(key: SomeStorageKey, storageName: String)
5353
//case keychain(key: SomeStorageKey)
54+
55+
public
56+
static
57+
func == (lhs: ValueStorage, rhs: ValueStorage) -> Bool
58+
{
59+
switch (lhs, rhs)
60+
{
61+
case (.appStorageStandard(let lhsKey), .appStorageStandard(let rhsKey)):
62+
return lhsKey.name == rhsKey.name
63+
64+
case (.appStorage(let lhsKey, let lhsStorageName), .appStorage(let rhsKey, let rhsStorageName)):
65+
return (lhsKey.name == rhsKey.name && lhsStorageName == rhsStorageName)
66+
67+
default:
68+
return false
69+
}
70+
}
5471
}
5572

5673
//---

Sources/Core/2_ValueWrappers/*SomeValidatableValueWrapper.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
*/
2626

2727
public
28-
protocol SomeValidatableValueWrapper: Codable
28+
protocol SomeValidatableValueWrapper: Codable, Equatable
2929
{
3030
associatedtype Value: SomeValidatableValue
3131

Sources/Core/3_Value/*SomeValidatableValue.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ import XCERequirement
3232
Describes custom value type for a wrapper.
3333
*/
3434
public
35-
protocol SomeValidatableValue: DisplayNamed
35+
protocol SomeValidatableValue: DisplayNamed, Equatable
3636
{
37-
associatedtype Raw: Codable
37+
associatedtype Raw: Codable, Equatable
3838

39-
associatedtype Valid: Codable
39+
associatedtype Valid: Codable, Equatable
4040

4141
static
4242
var isSecret: Bool { get }

Tests/AllTests/EntityTests.swift

Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
/*
2+
3+
MIT License
4+
5+
Copyright (c) 2016 Maxim Khatskevich ([email protected])
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy
8+
of this software and associated documentation files (the "Software"), to deal
9+
in the Software without restriction, including without limitation the rights
10+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the Software is
12+
furnished to do so, subject to the following conditions:
13+
14+
The above copyright notice and this permission notice shall be included in all
15+
copies or substantial portions of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
SOFTWARE.
24+
25+
*/
26+
27+
import XCTest
28+
29+
@testable
30+
import XCEValidatableValue
31+
32+
//---
33+
34+
class EntityTests: XCTestCase {}
35+
36+
//---
37+
38+
extension EntityTests
39+
{
40+
func testMembersGetters()
41+
{
42+
enum FirstName: SomeValidatableValue
43+
{
44+
typealias Raw = String
45+
}
46+
47+
struct TheEntity: SomeValidatableEntity
48+
{
49+
var wrap1: NonRequired<FirstName>
50+
var wrap1Opt: NonRequired<FirstName>?
51+
var wrap2: Required<FirstName>
52+
var wrap2Opt: Required<FirstName>?
53+
var somethingElse: String?
54+
}
55+
56+
let entity = TheEntity(
57+
wrap1: .init(""),
58+
wrap1Opt: .init(""),
59+
wrap2: .init(""),
60+
wrap2Opt: .init(""),
61+
somethingElse: "else"
62+
)
63+
64+
//---
65+
66+
let allMembers = entity.allMembers
67+
let valMembers = entity.allValidatableMembers
68+
69+
XCTAssertEqual(allMembers.count, 5)
70+
XCTAssertEqual(valMembers.count, 4)
71+
}
72+
73+
// func testDisplayName()
74+
// {
75+
// struct SomeEntity: SomeValidatableEntity {}
76+
//
77+
// XCTAssert(SomeEntity.displayName == SomeEntity.intrinsicDisplayName)
78+
//
79+
// //---
80+
//
81+
// struct CustomNamedEntity: SomeValidatableEntity
82+
// {
83+
// static
84+
// let someStr = "This is a custom named Entity"
85+
//
86+
// static
87+
// let displayName = someStr
88+
// }
89+
//
90+
// XCTAssert(CustomNamedEntity.displayName != CustomNamedEntity.intrinsicDisplayName)
91+
// XCTAssert(CustomNamedEntity.displayName == CustomNamedEntity.someStr)
92+
// }
93+
//
94+
// func testDefaultValueReport()
95+
// {
96+
// struct SomeEntity: SomeValidatableEntity {}
97+
//
98+
// let defaultReport = SomeEntity.defaultReport(with: [])
99+
//
100+
// let report = SomeEntity.prepareReport(with: [])
101+
//
102+
// XCTAssert(report == defaultReport)
103+
// }
104+
//
105+
// func testCustomEntityReport()
106+
// {
107+
// struct SomeEntity: SomeValidatableEntity
108+
// {
109+
// static
110+
// let customReport = ("This is", "it!")
111+
//
112+
// //---
113+
//
114+
// static
115+
// var onCustomizeReport: OnCustomizeEntityReport
116+
// {
117+
// // by default, we don't adjust anything in the report
118+
// return {
119+
//
120+
// _, report in
121+
//
122+
// //---
123+
//
124+
// report = customReport
125+
// }
126+
// }
127+
// }
128+
//
129+
// let defaultReport = SomeEntity.defaultReport(with: [])
130+
//
131+
// let report = SomeEntity.prepareReport(with: [])
132+
//
133+
// XCTAssert(report != defaultReport)
134+
// XCTAssert(report == SomeEntity.customReport)
135+
// }
136+
//
137+
// func testManualValidation()
138+
// {
139+
// struct ManualValidationEntity: SomeValidatableEntity
140+
// {
141+
// static
142+
// let someStr = "Is invalid"
143+
//
144+
// func validate() throws
145+
// {
146+
// let issues: [Error] = [
147+
// ValidationError.valueIsNotValid(
148+
// origin: "Some wrapper",
149+
// value: "Some value",
150+
// failedConditions: ["Test condition"],
151+
// report: (title: "Some test value", message: type(of: self).someStr)
152+
// )
153+
// ]
154+
//
155+
// throw issues.asValidationIssues(for: self)
156+
// }
157+
// }
158+
//
159+
// //---
160+
//
161+
// do
162+
// {
163+
// try ManualValidationEntity().validate()
164+
//
165+
// XCTFail("Should not get here ever")
166+
// }
167+
// catch ValidationError.entityIsNotValid(
168+
// let origin,
169+
// let issues,
170+
// _
171+
// )
172+
// {
173+
// XCTAssert(origin == ManualValidationEntity.displayName)
174+
// XCTAssert(issues.count == 1) // exactly as we've sent
175+
//
176+
// let report = (issues[0] as! ValidationError).report
177+
//
178+
// XCTAssert(report.message == ManualValidationEntity.someStr)
179+
// }
180+
// catch
181+
// {
182+
// print(error)
183+
// XCTFail("Should not get here ever")
184+
// }
185+
// }
186+
//
187+
// func testAutoValidatable()
188+
// {
189+
// struct SimpleWrapper: SomeValidatableValue,
190+
// SomeValidatable
191+
// {
192+
// static
193+
// let someStr = "Is invalid"
194+
//
195+
// enum Specification: SomeValueSpecification
196+
// {
197+
// typealias RawValue = String?
198+
// }
199+
//
200+
// var rawValue: Specification.RawValue
201+
//
202+
// init(wrappedValue: Specification.RawValue) { self.rawValue = wrappedValue }
203+
//
204+
// func validate() throws
205+
// {
206+
// if
207+
// rawValue == nil
208+
// {
209+
// throw ValidationError.mandatoryValueIsNotSet(
210+
// origin: type(of: self).displayName,
211+
// report: (
212+
// title: "Mandatory value is missing",
213+
// message: type(of: self).someStr
214+
// )
215+
// )
216+
// }
217+
// }
218+
// }
219+
//
220+
// struct AutoValidationEntity: SomeValidatableEntity
221+
// {
222+
// let stringWrapper: SimpleWrapper
223+
// }
224+
//
225+
// //---
226+
//
227+
// do
228+
// {
229+
// try AutoValidationEntity
230+
// .init(stringWrapper: SimpleWrapper(wrappedValue: nil))
231+
// .validate()
232+
//
233+
// XCTFail("Should not get here ever")
234+
// }
235+
// catch ValidationError.entityIsNotValid(
236+
// let origin,
237+
// let issues,
238+
// _
239+
// )
240+
// {
241+
// XCTAssert(origin == AutoValidationEntity.displayName)
242+
// XCTAssert(issues.count == 1)
243+
//
244+
// let report = (issues[0] as! ValidationError).report
245+
//
246+
// XCTAssert(report.message == SimpleWrapper.someStr)
247+
// }
248+
// catch
249+
// {
250+
// print(error)
251+
// XCTFail("Should not get here ever")
252+
// }
253+
//
254+
// //---
255+
//
256+
// do
257+
// {
258+
// try AutoValidationEntity
259+
// .init(stringWrapper: SimpleWrapper(wrappedValue: "Some valid value"))
260+
// .validate()
261+
// }
262+
// catch
263+
// {
264+
// print(error)
265+
// XCTFail("Should not get here ever")
266+
// }
267+
// }
268+
}

0 commit comments

Comments
 (0)