001package arez;
002
003import javax.annotation.Nonnull;
004import javax.annotation.Nullable;
005
006/**
007 * Utility class for interacting with Arez config settings in tests.
008 */
009@SuppressWarnings( "WeakerAccess" )
010public final class ArezTestUtil
011{
012  private ArezTestUtil()
013  {
014  }
015
016  /**
017   * Interface to intercept log messages emitted by Arez runtime.
018   */
019  public interface Logger
020  {
021    void log( @Nonnull String message, @Nullable Throwable throwable );
022  }
023
024  /**
025   * Reset the state of Arez config to either production or development state.
026   *
027   * @param productionMode true to set it to production mode configuration, false to set it to development mode config.
028   */
029  public static void resetConfig( final boolean productionMode )
030  {
031    if ( ArezConfig.isProductionEnvironment() )
032    {
033      /*
034       * This should really never happen but if it does add assertion (so code stops in debugger) or
035       * failing that throw an exception.
036       */
037      assert ArezConfig.isDevelopmentEnvironment();
038      throw new IllegalStateException( "Unable to reset config as Arez is in production mode" );
039    }
040
041    if ( productionMode )
042    {
043      disableNames();
044      disableVerify();
045      disablePropertyIntrospectors();
046      noEnforceTransactionType();
047      disableSpies();
048      makeCollectionPropertiesModifiable();
049      disableNativeComponents();
050      disableRegistries();
051      noCheckInvariants();
052      noCheckApiInvariants();
053    }
054    else
055    {
056      enableNames();
057      enableVerify();
058      enablePropertyIntrospectors();
059      enforceTransactionType();
060      enableSpies();
061      makeCollectionPropertiesUnmodifiable();
062      enableNativeComponents();
063      enableRegistries();
064      checkInvariants();
065      checkApiInvariants();
066    }
067    enableObserverErrorHandlers();
068    enableReferences();
069    enableTaskInterceptor();
070    purgeTasksWhenRunawayDetected();
071    disableZones();
072    resetState();
073  }
074
075  /**
076   * Reset the state of Arez.
077   * This occasionally needs to be invoked after changing configuration settings in tests.
078   */
079  private static void resetState()
080  {
081    setLogger( null );
082    Transaction.setTransaction( null );
083    ZoneHolder.reset();
084    ArezContextHolder.reset();
085  }
086
087  /**
088   * Specify logger to use to capture logging in tests.
089   *
090   * @param logger the logger.
091   */
092  public static void setLogger( @Nullable final Logger logger )
093  {
094    if ( ArezConfig.isProductionEnvironment() )
095    {
096      /*
097       * This should really never happen but if it does add assertion (so code stops in debugger) or
098       * failing that throw an exception.
099       */
100      assert ArezConfig.isDevelopmentEnvironment();
101      throw new IllegalStateException( "Unable to call ArezTestUtil.setLogger() as Arez is in production mode" );
102    }
103
104    final ArezLogger.ProxyLogger proxyLogger = (ArezLogger.ProxyLogger) ArezLogger.getLogger();
105    proxyLogger.setLogger( null == logger ? null : logger::log );
106  }
107
108  /**
109   * Set the `arez.enable_names` setting to true.
110   */
111  public static void enableNames()
112  {
113    ArezConfig.setEnableNames( true );
114  }
115
116  /**
117   * Set the `arez.enable_names` setting to false.
118   */
119  public static void disableNames()
120  {
121    ArezConfig.setEnableNames( false );
122  }
123
124  /**
125   * Set the `arez.enable_references` setting to true.
126   */
127  public static void enableReferences()
128  {
129    ArezConfig.setEnableReferences( true );
130  }
131
132  /**
133   * Set the `arez.enable_references` setting to false.
134   */
135  public static void disableReferences()
136  {
137    ArezConfig.setEnableReferences( false );
138  }
139
140  /**
141   * Set the `arez.enable_verify` setting to true.
142   */
143  public static void enableVerify()
144  {
145    ArezConfig.setEnableVerify( true );
146  }
147
148  /**
149   * Set the `arez.enable_verify` setting to false.
150   */
151  public static void disableVerify()
152  {
153    ArezConfig.setEnableVerify( false );
154  }
155
156  /**
157   * Set the `arez.enable_property_introspection` setting to true.
158   */
159  public static void enablePropertyIntrospectors()
160  {
161    ArezConfig.setEnablePropertyIntrospection( true );
162  }
163
164  /**
165   * Set the `arez.enable_property_introspection` setting to false.
166   */
167  public static void disablePropertyIntrospectors()
168  {
169    ArezConfig.setEnablePropertyIntrospection( false );
170  }
171
172  /**
173   * Set the `arez.purge_tasks_when_runaway_detected` setting to true.
174   */
175  public static void purgeTasksWhenRunawayDetected()
176  {
177    ArezConfig.setPurgeOnRunaway( true );
178  }
179
180  /**
181   * Set the `arez.purge_tasks_when_runaway_detected` setting to false.
182   */
183  public static void noPurgeTasksWhenRunawayDetected()
184  {
185    ArezConfig.setPurgeOnRunaway( false );
186  }
187
188  /**
189   * Set the `arez.enforce_transaction_type` setting to true.
190   */
191  public static void enforceTransactionType()
192  {
193    ArezConfig.setEnforceTransactionType( true );
194  }
195
196  /**
197   * Set the `arez.enforce_transaction_type` setting to false.
198   */
199  public static void noEnforceTransactionType()
200  {
201    ArezConfig.setEnforceTransactionType( false );
202  }
203
204  /**
205   * Set the `arez.enable_spies` setting to true.
206   */
207  public static void enableSpies()
208  {
209    ArezConfig.setEnableSpies( true );
210    resetState();
211  }
212
213  /**
214   * Set the `arez.enable_spies` setting to false.
215   */
216  public static void disableSpies()
217  {
218    ArezConfig.setEnableSpies( false );
219    resetState();
220  }
221
222  /**
223   * Set the `arez.enable_zones` setting to true.
224   * This will result in the Arez state being reset to align with this setting. The
225   * normal practice is to invoke this at the start of a test.
226   */
227  public static void enableZones()
228  {
229    ArezConfig.setEnableZones( true );
230    resetState();
231  }
232
233  /**
234   * Set the `arez.enable_zones` setting to false.
235   * This will result in the Arez state being reset to align with this setting. The
236   * normal practice is to invoke this at the start of a test.
237   */
238  public static void disableZones()
239  {
240    ArezConfig.setEnableZones( false );
241    resetState();
242  }
243
244  /**
245   * Set the `arez.collections_properties_unmodifiable` setting to true.
246   */
247  public static void makeCollectionPropertiesModifiable()
248  {
249    ArezConfig.setCollectionPropertiesUnmodifiable( false );
250  }
251
252  /**
253   * Set the `arez.collections_properties_unmodifiable` setting to false.
254   */
255  public static void makeCollectionPropertiesUnmodifiable()
256  {
257    ArezConfig.setCollectionPropertiesUnmodifiable( true );
258  }
259
260  /**
261   * Set the `arez.enable_native_components` setting to true.
262   * This will result in the Arez state being reset to align with this setting. The
263   * normal practice is to invoke this at the start of a test.
264   */
265  public static void enableNativeComponents()
266  {
267    ArezConfig.setEnableNativeComponents( true );
268    resetState();
269  }
270
271  /**
272   * Set the `arez.enable_native_components` setting to false.
273   * This will result in the Arez state being reset to align with this setting. The
274   * normal practice is to invoke this at the start of a test.
275   */
276  public static void disableNativeComponents()
277  {
278    ArezConfig.setEnableNativeComponents( false );
279    resetState();
280  }
281
282  /**
283   * Set the `arez.enable_registries` setting to true.
284   * This will result in the Arez state being reset to align with this setting. The
285   * normal practice is to invoke this at the start of a test.
286   */
287  public static void enableRegistries()
288  {
289    ArezConfig.setEnableRegistries( true );
290    resetState();
291  }
292
293  /**
294   * Set the `arez.enable_registries` setting to false.
295   * This will result in the Arez state being reset to align with this setting. The
296   * normal practice is to invoke this at the start of a test.
297   */
298  public static void disableRegistries()
299  {
300    ArezConfig.setEnableRegistries( false );
301    resetState();
302  }
303
304  /**
305   * Set the `arez.enable_task_interceptor` setting to true.
306   */
307  public static void enableTaskInterceptor()
308  {
309    ArezConfig.setEnableTaskInterceptor( true );
310    resetState();
311  }
312
313  /**
314   * Set the `arez.enable_task_interceptor` setting to false.
315   */
316  public static void disableTaskInterceptor()
317  {
318    ArezConfig.setEnableTaskInterceptor( false );
319    resetState();
320  }
321
322  /**
323   * Set the `arez.enable_observer_error_handlers` setting to true.
324   */
325  public static void enableObserverErrorHandlers()
326  {
327    ArezConfig.setEnableObserverErrorHandlers( true );
328  }
329
330  /**
331   * Set the `arez.enable_observer_error_handlers` setting to false.
332   */
333  public static void disableObserverErrorHandlers()
334  {
335    ArezConfig.setEnableObserverErrorHandlers( false );
336  }
337
338  /**
339   * Set the `arez.check_invariants` setting to true.
340   */
341  public static void checkInvariants()
342  {
343    ArezConfig.setCheckInvariants( true );
344  }
345
346  /**
347   * Set the `arez.check_invariants` setting to false.
348   */
349  public static void noCheckInvariants()
350  {
351    ArezConfig.setCheckInvariants( false );
352  }
353
354  /**
355   * Set the `arez.check_expensive_invariants` setting to true.
356   */
357  public static void checkExpensiveInvariants()
358  {
359    ArezConfig.setCheckExpensiveInvariants( true );
360  }
361
362  /**
363   * Set the `arez.check_expensive_invariants` setting to false.
364   */
365  public static void noCheckExpensiveInvariants()
366  {
367    ArezConfig.setCheckExpensiveInvariants( false );
368  }
369
370  /**
371   * Set the `arez.check_api_invariants` setting to true.
372   */
373  public static void checkApiInvariants()
374  {
375    ArezConfig.setCheckApiInvariants( true );
376  }
377
378  /**
379   * Set the `arez.check_api_invariants` setting to false.
380   */
381  public static void noCheckApiInvariants()
382  {
383    ArezConfig.setCheckApiInvariants( false );
384  }
385}