net.goui.flogger.testing.LevelClass Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2023, David Beaumont (https://github.com/hagbard).
*
* This program and the accompanying materials are made available under the terms of the
* Eclipse Public License v. 2.0 available at https://www.eclipse.org/legal/epl-2.0, or the
* Apache License, Version 2.0 available at https://www.apache.org/licenses/LICENSE-2.0.
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
******************************************************************************/
package net.goui.flogger.testing;
import java.util.logging.Level;
/**
* Represents the smallest equivalence class of log levels which all backends should be able to
* support.
*
* Since assertions are carried out on logged values, it is important that the test API expresses
* its contract in a way that is compatible with all supported logging backends. In particular,
* testing the log statements:
*
*
{@code
* logger.atFine().log("Detailed message ...");
* logger.atFinest().log("Very detailed message ...");
* }
*
* Cannot allow the use of {@link Level#FINE} and {@link Level#FINEST}, because some backends do
* not distinguish these levels. And assertions like:
*
*
{@code
* assertThat(logs).everyLog().above(Level.FINEST).hasSomeProperty(...);
* }
*
* Would be brittle if you moved to a backend which could not distinguish between {@link
* Level#FINER} and {@link Level#FINEST}.
*
*
Limiting the available level classes is not unreasonable because the finest log levels are not
* semantically important for testing, and tests which specify levels too precisely are going to be
* brittle in the face of simple refactoring.
*
*
Note that the names here reflect the JDK log level names to best match the calling code being
* testing, and enum entries are explicitly ordered in ascending severity so that {@code
* x.compareTo(y)} works as expected. However, for readability in projects which use {@code Log4J},
* there are aliased fields for some of the levels (e.g. {@code DEBUG} == {@code FINE}), which match
* the mapping used by Flogger to convert between levels.
*/
public enum LevelClass {
/**
* A level class for the most detailed logs, often disabled unless fine-grained debug information
* is required.
*
*
All remaining log levels below {@link #FINE}.
*
*
Note that in the JDK, this includes {@link Level#FINER}, and prevents the testing of
* differences between {@code FINEST} and {@code FINER} logs. However, users should probably not
* being trying to write tests which care about this distinction as they are likely to be brittle.
*/
FINEST(Level.FINEST),
/**
* A level class indicating logs suitable for high level debugging and are typically disabled
* under normal circumstances.
*
*
Log levels below {@link #INFO} but:
*
*
* - JDK level {@code FINE} and above (including {@code CONFIG}).
*
- Log4J level {@code DEBUG} and above.
*
- Android log level {@code DEBUG}.
*
*/
FINE(Level.FINE),
/**
* A level class indicating informational logs which require no action but are typically always
* enabled.
*
* Log levels below {@link #WARNING} but:
*
*
* - JDK level {@code INFO} and above.
*
- Log4J level {@code INFO} and above.
*
- Android log level {@code INFO}.
*
*/
INFO(Level.INFO),
/**
* A level class indicating warnings that are actionable, but not as urgent as {@link #SEVERE}.
*
* Log levels below {@link #SEVERE} but:
*
*
* - JDK level {@code WARNING} and above.
*
- Log4J level {@code WARN} and above.
*
- Android log level {@code WARN}.
*
*/
WARNING(Level.WARNING),
/**
* The highest level class, indicating serious and urgent problems.
*
*
* - JDK level {@code SEVERE} and above.
*
- Log4J level {@code ERROR} and above, including {@code FATAL}(†).
*
- Android log level {@code ERROR}, including {@code ASSERT}(†).
*
*
* (†) Since Flogger does not emit these log levels, it should not affect testing. Of course if
* this API were used to test non-Flogger logs, this might become important.
*/
SEVERE(Level.SEVERE);
private final Level jdkLevel;
LevelClass(Level jdkLevel) {
this.jdkLevel = jdkLevel;
}
public Level toJdkLogLevel() {
return jdkLevel;
}
/** An alias for {@link #FINEST}, for users who wish to use Log4J style names in tests. */
public static final LevelClass TRACE = FINEST;
/** An alias for {@link #FINE}, for users who wish to use Log4J style names in tests. */
public static final LevelClass DEBUG = FINE;
/** An alias for {@link #SEVERE}, for users who wish to use Log4J style names in tests. */
public static final LevelClass ERROR = SEVERE;
}