@@ -52,6 +52,219 @@ public void TestComparer()
5252 lfu . TryGet ( "A" , out var value ) . Should ( ) . BeTrue ( ) ;
5353 }
5454
55+ [ Fact ]
56+ public void TestExpireAfterAccess ( )
57+ {
58+ ICache < string , int > expireAfterAccess = new ConcurrentLfuBuilder < string , int > ( )
59+ . WithExpireAfterAccess ( TimeSpan . FromSeconds ( 1 ) )
60+ . Build ( ) ;
61+
62+ expireAfterAccess . Policy . ExpireAfterAccess . HasValue . Should ( ) . BeTrue ( ) ;
63+ expireAfterAccess . Policy . ExpireAfterAccess . Value . TimeToLive . Should ( ) . Be ( TimeSpan . FromSeconds ( 1 ) ) ;
64+ expireAfterAccess . Policy . ExpireAfterWrite . HasValue . Should ( ) . BeFalse ( ) ;
65+ }
66+
67+ [ Fact ]
68+ public void TestExpireAfterReadAndExpireAfterWriteThrows ( )
69+ {
70+ var builder = new ConcurrentLfuBuilder < string , int > ( )
71+ . WithExpireAfterAccess ( TimeSpan . FromSeconds ( 1 ) )
72+ . WithExpireAfterWrite ( TimeSpan . FromSeconds ( 2 ) ) ;
73+
74+ Action act = ( ) => builder . Build ( ) ;
75+ act . Should ( ) . Throw < InvalidOperationException > ( ) ;
76+ }
77+
78+ [ Fact ]
79+ public void TestExpireAfter ( )
80+ {
81+ ICache < string , int > expireAfter = new ConcurrentLfuBuilder < string , int > ( )
82+ . WithExpireAfter ( new TestExpiryCalculator < string , int > ( ( k , v ) => Duration . FromMinutes ( 5 ) ) )
83+ . Build ( ) ;
84+
85+ expireAfter . Policy . ExpireAfter . HasValue . Should ( ) . BeTrue ( ) ;
86+
87+ expireAfter . Policy . ExpireAfterAccess . HasValue . Should ( ) . BeFalse ( ) ;
88+ expireAfter . Policy . ExpireAfterWrite . HasValue . Should ( ) . BeFalse ( ) ;
89+ }
90+
91+ [ Fact ]
92+ public void TestAsyncExpireAfter ( )
93+ {
94+ IAsyncCache < string , int > expireAfter = new ConcurrentLfuBuilder < string , int > ( )
95+ . AsAsyncCache ( )
96+ . WithExpireAfter ( new TestExpiryCalculator < string , int > ( ( k , v ) => Duration . FromMinutes ( 5 ) ) )
97+ . Build ( ) ;
98+
99+ expireAfter . Policy . ExpireAfter . HasValue . Should ( ) . BeTrue ( ) ;
100+
101+ expireAfter . Policy . ExpireAfterAccess . HasValue . Should ( ) . BeFalse ( ) ;
102+ expireAfter . Policy . ExpireAfterWrite . HasValue . Should ( ) . BeFalse ( ) ;
103+ }
104+
105+
106+ [ Fact ]
107+ public void TestExpireAfterWriteAndExpireAfterThrows ( )
108+ {
109+ var builder = new ConcurrentLfuBuilder < string , int > ( )
110+ . WithExpireAfterWrite ( TimeSpan . FromSeconds ( 1 ) )
111+ . WithExpireAfter ( new TestExpiryCalculator < string , int > ( ( k , v ) => Duration . FromMinutes ( 5 ) ) ) ;
112+
113+ Action act = ( ) => builder . Build ( ) ;
114+ act . Should ( ) . Throw < InvalidOperationException > ( ) ;
115+ }
116+
117+ [ Fact ]
118+ public void TestExpireAfterAccessAndExpireAfterThrows ( )
119+ {
120+ var builder = new ConcurrentLfuBuilder < string , int > ( )
121+ . WithExpireAfterAccess ( TimeSpan . FromSeconds ( 1 ) )
122+ . WithExpireAfter ( new TestExpiryCalculator < string , int > ( ( k , v ) => Duration . FromMinutes ( 5 ) ) ) ;
123+
124+ Action act = ( ) => builder . Build ( ) ;
125+ act . Should ( ) . Throw < InvalidOperationException > ( ) ;
126+ }
127+
128+ [ Fact ]
129+ public void TestExpireAfterAccessAndWriteAndExpireAfterThrows ( )
130+ {
131+ var builder = new ConcurrentLfuBuilder < string , int > ( )
132+ . WithExpireAfterWrite ( TimeSpan . FromSeconds ( 1 ) )
133+ . WithExpireAfterAccess ( TimeSpan . FromSeconds ( 1 ) )
134+ . WithExpireAfter ( new TestExpiryCalculator < string , int > ( ( k , v ) => Duration . FromMinutes ( 5 ) ) ) ;
135+
136+ Action act = ( ) => builder . Build ( ) ;
137+ act . Should ( ) . Throw < InvalidOperationException > ( ) ;
138+ }
139+
140+ [ Fact ]
141+ public void TestScopedWithExpireAfterThrows ( )
142+ {
143+ var builder = new ConcurrentLfuBuilder < string , Disposable > ( )
144+ . WithExpireAfter ( new TestExpiryCalculator < string , Disposable > ( ( k , v ) => Duration . FromMinutes ( 5 ) ) )
145+ . AsScopedCache ( ) ;
146+
147+ Action act = ( ) => builder . Build ( ) ;
148+ act . Should ( ) . Throw < InvalidOperationException > ( ) ;
149+ }
150+
151+ [ Fact ]
152+ public void TestScopedAtomicWithExpireAfterThrows ( )
153+ {
154+ var builder = new ConcurrentLfuBuilder < string , Disposable > ( )
155+ . WithExpireAfter ( new TestExpiryCalculator < string , Disposable > ( ( k , v ) => Duration . FromMinutes ( 5 ) ) )
156+ . AsScopedCache ( )
157+ . WithAtomicGetOrAdd ( ) ;
158+
159+ Action act = ( ) => builder . Build ( ) ;
160+ act . Should ( ) . Throw < InvalidOperationException > ( ) ;
161+ }
162+
163+ [ Fact ]
164+ public void TestAsyncScopedWithExpireAfterThrows ( )
165+ {
166+ var builder = new ConcurrentLfuBuilder < string , Disposable > ( )
167+ . WithExpireAfter ( new TestExpiryCalculator < string , Disposable > ( ( k , v ) => Duration . FromMinutes ( 5 ) ) )
168+ . AsAsyncCache ( )
169+ . AsScopedCache ( ) ;
170+
171+ Action act = ( ) => builder . Build ( ) ;
172+ act . Should ( ) . Throw < InvalidOperationException > ( ) ;
173+ }
174+
175+ [ Fact ]
176+ public void TestAsyncScopedAtomicWithExpireAfterThrows ( )
177+ {
178+ var builder = new ConcurrentLfuBuilder < string , Disposable > ( )
179+ . WithExpireAfter ( new TestExpiryCalculator < string , Disposable > ( ( k , v ) => Duration . FromMinutes ( 5 ) ) )
180+ . AsAsyncCache ( )
181+ . AsScopedCache ( )
182+ . WithAtomicGetOrAdd ( ) ;
183+
184+ Action act = ( ) => builder . Build ( ) ;
185+ act . Should ( ) . Throw < InvalidOperationException > ( ) ;
186+ }
187+
188+ [ Fact ]
189+ public void TestScopedWithExpireAfterWrite ( )
190+ {
191+ var expireAfterWrite = new ConcurrentLfuBuilder < string , Disposable > ( )
192+ . WithExpireAfterWrite ( TimeSpan . FromSeconds ( 1 ) )
193+ . AsScopedCache ( )
194+ . Build ( ) ;
195+
196+ expireAfterWrite . Policy . ExpireAfterWrite . HasValue . Should ( ) . BeTrue ( ) ;
197+ expireAfterWrite . Policy . ExpireAfterWrite . Value . TimeToLive . Should ( ) . Be ( TimeSpan . FromSeconds ( 1 ) ) ;
198+ expireAfterWrite . Policy . ExpireAfterAccess . HasValue . Should ( ) . BeFalse ( ) ;
199+ }
200+
201+ [ Fact ]
202+ public void TestScopedWithExpireAfterAccess ( )
203+ {
204+ var expireAfterAccess = new ConcurrentLfuBuilder < string , Disposable > ( )
205+ . WithExpireAfterAccess ( TimeSpan . FromSeconds ( 1 ) )
206+ . AsScopedCache ( )
207+ . Build ( ) ;
208+
209+ expireAfterAccess . Policy . ExpireAfterAccess . HasValue . Should ( ) . BeTrue ( ) ;
210+ expireAfterAccess . Policy . ExpireAfterAccess . Value . TimeToLive . Should ( ) . Be ( TimeSpan . FromSeconds ( 1 ) ) ;
211+ expireAfterAccess . Policy . ExpireAfterWrite . HasValue . Should ( ) . BeFalse ( ) ;
212+ }
213+
214+ [ Fact ]
215+ public void TestAtomicWithExpireAfterWrite ( )
216+ {
217+ var expireAfterWrite = new ConcurrentLfuBuilder < string , Disposable > ( )
218+ . WithExpireAfterWrite ( TimeSpan . FromSeconds ( 1 ) )
219+ . WithAtomicGetOrAdd ( )
220+ . Build ( ) ;
221+
222+ expireAfterWrite . Policy . ExpireAfterWrite . HasValue . Should ( ) . BeTrue ( ) ;
223+ expireAfterWrite . Policy . ExpireAfterWrite . Value . TimeToLive . Should ( ) . Be ( TimeSpan . FromSeconds ( 1 ) ) ;
224+ expireAfterWrite . Policy . ExpireAfterAccess . HasValue . Should ( ) . BeFalse ( ) ;
225+ }
226+
227+ [ Fact ]
228+ public void TestAtomicWithExpireAfterAccess ( )
229+ {
230+ var expireAfterAccess = new ConcurrentLfuBuilder < string , Disposable > ( )
231+ . WithExpireAfterAccess ( TimeSpan . FromSeconds ( 1 ) )
232+ . WithAtomicGetOrAdd ( )
233+ . Build ( ) ;
234+
235+ expireAfterAccess . Policy . ExpireAfterAccess . HasValue . Should ( ) . BeTrue ( ) ;
236+ expireAfterAccess . Policy . ExpireAfterAccess . Value . TimeToLive . Should ( ) . Be ( TimeSpan . FromSeconds ( 1 ) ) ;
237+ expireAfterAccess . Policy . ExpireAfterWrite . HasValue . Should ( ) . BeFalse ( ) ;
238+ }
239+
240+ [ Fact ]
241+ public void TestScopedAtomicWithExpireAfterWrite ( )
242+ {
243+ var expireAfterWrite = new ConcurrentLfuBuilder < string , Disposable > ( )
244+ . WithExpireAfterWrite ( TimeSpan . FromSeconds ( 1 ) )
245+ . AsScopedCache ( )
246+ . WithAtomicGetOrAdd ( )
247+ . Build ( ) ;
248+
249+ expireAfterWrite . Policy . ExpireAfterWrite . HasValue . Should ( ) . BeTrue ( ) ;
250+ expireAfterWrite . Policy . ExpireAfterWrite . Value . TimeToLive . Should ( ) . Be ( TimeSpan . FromSeconds ( 1 ) ) ;
251+ expireAfterWrite . Policy . ExpireAfterAccess . HasValue . Should ( ) . BeFalse ( ) ;
252+ }
253+
254+ [ Fact ]
255+ public void TestScopedAtomicWithExpireAfterAccess ( )
256+ {
257+ var expireAfterAccess = new ConcurrentLfuBuilder < string , Disposable > ( )
258+ . WithExpireAfterAccess ( TimeSpan . FromSeconds ( 1 ) )
259+ . AsScopedCache ( )
260+ . WithAtomicGetOrAdd ( )
261+ . Build ( ) ;
262+
263+ expireAfterAccess . Policy . ExpireAfterAccess . HasValue . Should ( ) . BeTrue ( ) ;
264+ expireAfterAccess . Policy . ExpireAfterAccess . Value . TimeToLive . Should ( ) . Be ( TimeSpan . FromSeconds ( 1 ) ) ;
265+ expireAfterAccess . Policy . ExpireAfterWrite . HasValue . Should ( ) . BeFalse ( ) ;
266+ }
267+
55268 // 1
56269 [ Fact ]
57270 public void WithScopedValues ( )
0 commit comments