001package arez.persist.runtime; 002 003import java.lang.reflect.Field; 004import javax.annotation.Nonnull; 005import javax.annotation.Nullable; 006 007/** 008 * Utility class for interacting with ArezPersist config settings in tests. 009 */ 010@SuppressWarnings( "WeakerAccess" ) 011@GwtIncompatible 012public final class ArezPersistTestUtil 013{ 014 private ArezPersistTestUtil() 015 { 016 } 017 018 /** 019 * Interface to intercept log messages emitted by ArezPersist runtime. 020 */ 021 public interface Logger 022 { 023 void log( @Nonnull String message, @Nullable Throwable throwable ); 024 } 025 026 /** 027 * Reset the state of ArezPersist config to either production or development state. 028 * 029 * @param production true to set it to production environment configuration, false to set it to development environment config. 030 */ 031 public static void resetConfig( final boolean production ) 032 { 033 if ( ArezPersistConfig.isProductionEnvironment() ) 034 { 035 throw new IllegalStateException( "Unable to reset config as ArezPersist is in production mode" ); 036 } 037 038 if ( production ) 039 { 040 noCheckApiInvariants(); 041 } 042 else 043 { 044 checkApiInvariants(); 045 } 046 enableApplicationStore(); 047 resetState(); 048 } 049 050 /** 051 * Reset the state of ArezPersist. 052 * This occasionally needs to be invoked after changing configuration settings in tests. 053 */ 054 public static void resetState() 055 { 056 setLogger( null ); 057 Registry.reset(); 058 } 059 060 /** 061 * Specify logger to use to capture logging in tests 062 * 063 * @param logger the logger. 064 */ 065 public static void setLogger( @Nullable final Logger logger ) 066 { 067 if ( ArezPersistConfig.isProductionEnvironment() ) 068 { 069 throw new IllegalStateException( "Unable to call ArezTestUtil.setLogger() as ArezPersist is in production mode" ); 070 } 071 072 final LogUtil.ProxyLogger proxyLogger = (LogUtil.ProxyLogger) LogUtil.getLogger(); 073 proxyLogger.setLogger( null == logger ? null : logger::log ); 074 } 075 076 /** 077 * Set the `arez.persist.enable_application_store` setting to true. 078 */ 079 public static void enableApplicationStore() 080 { 081 setEnableApplicationStore( true ); 082 } 083 084 /** 085 * Set the `arez.persist.enable_application_store` setting to false. 086 */ 087 public static void disableApplicationStore() 088 { 089 setEnableApplicationStore( false ); 090 } 091 092 /** 093 * Configure the `arez.persist.enable_application_store` setting. 094 * 095 * @param setting the setting. 096 */ 097 private static void setEnableApplicationStore( final boolean setting ) 098 { 099 setConstant( "ENABLE_APPLICATION_STORE", setting ); 100 } 101 102 /** 103 * Set the `arez.persist.check_api_invariants` setting to true. 104 */ 105 public static void checkApiInvariants() 106 { 107 setCheckApiInvariants( true ); 108 } 109 110 /** 111 * Set the `arez.persist.check_api_invariants` setting to false. 112 */ 113 public static void noCheckApiInvariants() 114 { 115 setCheckApiInvariants( false ); 116 } 117 118 /** 119 * Configure the `arez.persist.check_api_invariants` setting. 120 * 121 * @param setting the setting. 122 */ 123 private static void setCheckApiInvariants( final boolean setting ) 124 { 125 setConstant( "CHECK_API_INVARIANTS", setting ); 126 } 127 128 /** 129 * Set the specified field name on ArezPersistConfig. 130 */ 131 @SuppressWarnings( "NonJREEmulationClassesInClientCode" ) 132 private static void setConstant( @Nonnull final String fieldName, final boolean value ) 133 { 134 if ( ArezPersistConfig.isProductionEnvironment() ) 135 { 136 throw new IllegalStateException( "Unable to change constant " + fieldName + 137 " as ArezPersist is in production mode" ); 138 } 139 else 140 { 141 try 142 { 143 final Field field = ArezPersistConfig.class.getDeclaredField( fieldName ); 144 field.setAccessible( true ); 145 field.set( null, value ); 146 } 147 catch ( final NoSuchFieldException | IllegalAccessException e ) 148 { 149 throw new IllegalStateException( "Unable to change constant " + fieldName, e ); 150 } 151 } 152 } 153}