@@ -29,6 +29,51 @@ struct MailboxInfoTests {
2929 )
3030 }
3131
32+ @Test (
33+ " attribute implies " ,
34+ arguments: [
35+ ImpliesFixture (
36+ name: " NoInferiors implies HasNoChildren " ,
37+ attribute: . noInferiors,
38+ other: . hasNoChildren,
39+ expectation: true
40+ ) ,
41+ ImpliesFixture (
42+ name: " NonExistent implies NoSelect " ,
43+ attribute: . nonExistent,
44+ other: . noSelect,
45+ expectation: true
46+ ) ,
47+ ImpliesFixture (
48+ name: " HasNoChildren does NOT imply NoInferiors " ,
49+ attribute: . hasNoChildren,
50+ other: . noInferiors,
51+ expectation: false
52+ ) ,
53+ ImpliesFixture (
54+ name: " NoSelect does NOT imply NonExistent " ,
55+ attribute: . noSelect,
56+ other: . nonExistent,
57+ expectation: false
58+ ) ,
59+ ImpliesFixture (
60+ name: " Marked does NOT imply HasNoChildren " ,
61+ attribute: . marked,
62+ other: . hasNoChildren,
63+ expectation: false
64+ ) ,
65+ ImpliesFixture (
66+ name: " NoInferiors (uppercase) implies HasNoChildren " ,
67+ attribute: MailboxInfo . Attribute ( #"\NOINFERIORS"# ) ,
68+ other: . hasNoChildren,
69+ expectation: true
70+ ) ,
71+ ]
72+ )
73+ func attributeImplies( _ fixture: ImpliesFixture ) {
74+ #expect( fixture. attribute. implies ( fixture. other) == fixture. expectation)
75+ }
76+
3277 @Test ( arguments: [
3378 EncodeFixture . mailboxInfo (
3479 MailboxInfo ( attributes: [ ] , path: try ! . init( name: . inbox) , extensions: [ : ] ) ,
@@ -153,6 +198,103 @@ struct MailboxInfoTests {
153198 func parseFlags( _ fixture: ParseFixture < [ MailboxInfo . Attribute ] > ) {
154199 fixture. checkParsing ( )
155200 }
201+
202+ @Test (
203+ " sequence containsEffective " ,
204+ arguments: [
205+ ContainsEffectiveFixture (
206+ name: " empty array " ,
207+ attributes: [ ] ,
208+ query: . hasNoChildren,
209+ expectation: false
210+ ) ,
211+ ContainsEffectiveFixture (
212+ name: " direct match " ,
213+ attributes: [ . hasNoChildren] ,
214+ query: . hasNoChildren,
215+ expectation: true
216+ ) ,
217+ ContainsEffectiveFixture (
218+ name: " NoInferiors contains HasNoChildren " ,
219+ attributes: [ . noInferiors] ,
220+ query: . hasNoChildren,
221+ expectation: true
222+ ) ,
223+ ContainsEffectiveFixture (
224+ name: " NonExistent contains NoSelect " ,
225+ attributes: [ . nonExistent] ,
226+ query: . noSelect,
227+ expectation: true
228+ ) ,
229+ ContainsEffectiveFixture (
230+ name: " HasNoChildren does NOT contain NoInferiors " ,
231+ attributes: [ . hasNoChildren] ,
232+ query: . noInferiors,
233+ expectation: false
234+ ) ,
235+ ContainsEffectiveFixture (
236+ name: " NoSelect does NOT contain NonExistent " ,
237+ attributes: [ . noSelect] ,
238+ query: . nonExistent,
239+ expectation: false
240+ ) ,
241+ ContainsEffectiveFixture (
242+ name: " multiple attributes with one triggering implication " ,
243+ attributes: [ . marked, . nonExistent] ,
244+ query: . noSelect,
245+ expectation: true
246+ ) ,
247+ ContainsEffectiveFixture (
248+ name: " case-insensitive implication check " ,
249+ attributes: [ MailboxInfo . Attribute ( #"\NOINFERIORS"# ) ] ,
250+ query: . hasNoChildren,
251+ expectation: true
252+ ) ,
253+ ]
254+ )
255+ func sequenceContainsEffective( _ fixture: ContainsEffectiveFixture ) {
256+ #expect( fixture. attributes. containsEffective ( fixture. query) == fixture. expectation)
257+ }
258+
259+ @Test ( " mailbox hasEffectiveAttribute " )
260+ func mailboxHasEffectiveAttribute( ) {
261+ let mailbox1 = MailboxInfo (
262+ attributes: [ . noInferiors] ,
263+ path: try ! . init( name: . inbox) ,
264+ extensions: [ : ]
265+ )
266+ #expect( mailbox1. hasEffectiveAttribute ( . hasNoChildren) , " NoInferiors should imply HasNoChildren " )
267+ #expect( !mailbox1. hasEffectiveAttribute ( . marked) , " should not have unrelated attribute " )
268+
269+ let mailbox2 = MailboxInfo (
270+ attributes: [ . noSelect] ,
271+ path: try ! . init( name: . inbox) ,
272+ extensions: [ : ]
273+ )
274+ #expect( !mailbox2. hasEffectiveAttribute ( . nonExistent) , " NoSelect does NOT imply NonExistent " )
275+ }
276+ }
277+
278+ // MARK: - Fixtures
279+
280+ extension MailboxInfoTests {
281+ struct ImpliesFixture : Sendable , CustomTestStringConvertible {
282+ var name : String
283+ var attribute : MailboxInfo . Attribute
284+ var other : MailboxInfo . Attribute
285+ var expectation : Bool
286+
287+ var testDescription : String { name }
288+ }
289+
290+ struct ContainsEffectiveFixture : Sendable , CustomTestStringConvertible {
291+ var name : String
292+ var attributes : [ MailboxInfo . Attribute ]
293+ var query : MailboxInfo . Attribute
294+ var expectation : Bool
295+
296+ var testDescription : String { name }
297+ }
156298}
157299
158300// MARK: -
0 commit comments