Class Wrapper<T>
java.lang.Object
io.github.valentinherrmann.levenshtein.Wrapper<T>
- Type Parameters:
T- the type of the class the element (e.g. method) belongs to.
- Direct Known Subclasses:
AttributeWrapper, ClassWrapper, ConstructorWrapper, MethodWrapper
Abstract base class for wrapping and verifying Java reflection elements (classes, methods, fields, constructors).
Provides name and modifier deviation detection using Levenshtein distance or similar fuzzy matching.
Tracks whether an element exists exactly, deviates (can be used even though not 100% matches the signature),
or is missing.
The (potentially expensive) lookup in the student code runs only once per wrapper, on first use.
-
Field Summary
FieldsModifier and TypeFieldDescriptionprotected WrapperProperty.ExistenceThe overall existence (considering all parts state of the wrapped element (EXACT, DEVIATES, MISSING, or UNCHECKED).protected WrapperProperty<String> The expected and actual modifiers (e.g., "public static final") of the wrapped element.protected WrapperProperty<String> The expected and actual name of the wrapped element. -
Constructor Summary
ConstructorsConstructorDescriptionWrapper(ClassWrapper<T> parentClass, String expectedName, String... expectedModifiers) Constructs a new Wrapper for a reflection element with expected name and modifiers. -
Method Summary
Modifier and TypeMethodDescriptionabstract StringReturns a string representation of the actual element signature found.protected final voidRuns the lookup in the student code exactly once.abstract StringReturns a string representation of the expected element signature.protected abstract voidSearches for the wrapped element using deviation detection (e.g., Levenshtein distance).Retrieves the actual modifiers of the element found in the student code.Retrieves the actual name of the element found in the student code.Retrieves the expected name of this wrapped element instead of exposing thenameproperty directly.Retrieves the overall existence state of this wrapped element.Retrieves the parent class wrapper containing this element.protected booleanhasUnexpectedModifier(String modifier) Returns whether the actual element has the given modifier although it is neither expected, optional nor implicit.protected intThe modifier bits that the actual element has implicitly, e.g.protected booleanisModifierExpected(String modifier) Returns whether the given modifier keyword is part of the expected modifiers.protected booleanWhether an unexpectedstaticis reported withLevenshteinSettings.UnexpectedModifiers.IGNORE(the behaviour before unexpected modifiers were reported in general).protected abstract voidParses and updates the existence state based on all properties.protected voidparseExistence(WrapperProperty<?>... properties) Helper method to parse existence state from multiple wrapper properties.protected intThe modifier bits that are meaningful for this kind of element.toString()Returns a string representation of this wrapped element showing its existence state.protected WrapperProperty.ExistenceReturns the state that decides whether the element can be used in behavioral tests.abstract voidverifyExistence(boolean throwAssertion) Verifies that the wrapped element exists in the actual class.protected voidverifyExistence(String failMessage, boolean throwAssertion) Verifies existence with a custom failure message.voidverifyModifiers(int modifierBitmask) Verifies that the actual modifiers match the expected modifiers.
-
Field Details
-
name
The expected and actual name of the wrapped element. -
modifiers
The expected and actual modifiers (e.g., "public static final") of the wrapped element. -
existence
The overall existence (considering all parts state of the wrapped element (EXACT, DEVIATES, MISSING, or UNCHECKED). DEVIATES means that the element was found but has some deviations from the expected signature, but can still be used for further testing. UNCHECKED means that existence has not yet been verified and is a state which should not be shown to users.
-
-
Constructor Details
-
Wrapper
Constructs a new Wrapper for a reflection element with expected name and modifiers.- Parameters:
parentClass- the class wrapper containing this elementexpectedName- the expected name of the elementexpectedModifiers- the expected modifiers (e.g., "public", "static", "final"); a single string may also contain several space separated modifiers. A?suffix marks an optional modifier that may be present or absent (e.g."final?").- Throws:
IllegalArgumentException- if an expected modifier is unknown (a typo in the test specification), if a visibility is marked optional or if a modifier is both required and optional
-
-
Method Details
-
verifyExistence
public abstract void verifyExistence(boolean throwAssertion) Verifies that the wrapped element exists in the actual class. Subclasses must implement this to perform element-specific existence checks.- Parameters:
throwAssertion- if true, throws an AssertJ assertion failure when the element is missing. Usually set to true for behavioral tests, and false for structural tests to allow further deviation analysis.
-
verifyExistence
Verifies existence with a custom failure message. Runs the lookup if it has not run yet, then throws an assertion if the element is not usable and throwAssertion is true.- Parameters:
failMessage- the custom failure message to display if the element is missingthrowAssertion- if true, throws an AssertJ assertion failure when the element is missing. Usually set to true for behavioral tests, and false for structural tests to allow further deviation analysis.
-
usability
Returns the state that decides whether the element can be used in behavioral tests. By default this is the overall existence; subclasses may relax it (a class whose superclass deviates can still be instantiated, for example).- Returns:
- the existence state relevant for using the element
-
ensureChecked
protected final void ensureChecked()Runs the lookup in the student code exactly once. -
getOverallExistence
Retrieves the overall existence state of this wrapped element. Triggers deviation detection if not yet checked. Worst part-wise existence determines the overall existence.- Returns:
- the existence state (EXACT, DEVIATES or MISSING)
-
findWithDeviation
protected abstract void findWithDeviation()Searches for the wrapped element using deviation detection (e.g., Levenshtein distance). Subclasses must implement this to perform element-specific searches and update the property states. Called at most once per wrapper, seeensureChecked(). -
relevantModifierMask
protected int relevantModifierMask()The modifier bits that are meaningful for this kind of element. Other bits of the bitmask are ignored: for methods, the bits ofvolatileandtransientmean bridge and varargs. The default fits classes; methods, attributes and constructors override it.- Returns:
- the mask of relevant modifier bits
-
implicitModifiers
protected int implicitModifiers()The modifier bits that the actual element has implicitly, e.g.abstractfor interfaces orstatic finalfor constants of interfaces. They are never reported as unexpected. Called after the element was found.- Returns:
- the mask of implicit modifier bits
-
legacyReportsUnexpectedStatic
protected boolean legacyReportsUnexpectedStatic()Whether an unexpectedstaticis reported withLevenshteinSettings.UnexpectedModifiers.IGNORE(the behaviour before unexpected modifiers were reported in general). Attributes and methods turn it on.- Returns:
- true if an unexpected
staticis reported in the legacy mode
-
verifyModifiers
public void verifyModifiers(int modifierBitmask) Verifies that the actual modifiers match the expected modifiers.- An expected modifier that is missing is a deviation (
WrapperProperty.Existence.DEVIATES): behaviour tests go on with the actual element, e.g. a method that should bestaticis called on the default object. - An actual modifier that is neither expected, optional (
"final?") nor implicit (seeimplicitModifiers()) is a deviation as well. A different visibility is only reported as a missing expected visibility. - If no modifier is specified at all (neither required nor optional), package-private access is expected. Otherwise a visibility is only checked if one is specified.
LevenshteinSettings.UnexpectedModifiers.IGNOREthe previous behaviour applies: a missingstaticmakes the elementWrapperProperty.Existence.MISSINGand only an unexpectedstaticof attributes and methods is reported.- Parameters:
modifierBitmask- the actual modifiers as a bitmask (fromMember.getModifiers())
- An expected modifier that is missing is a deviation (
-
hasUnexpectedModifier
Returns whether the actual element has the given modifier although it is neither expected, optional nor implicit. Only meaningful after the lookup ran.- Parameters:
modifier- the modifier keyword, e.g."static"- Returns:
- true if the modifier was reported as unexpected
-
getMissingModifiers
-
getUnexpectedModifiers
-
isModifierExpected
Returns whether the given modifier keyword is part of the expected modifiers.- Parameters:
modifier- the modifier keyword, e.g."abstract"- Returns:
- true if it was expected
-
getParentClassWrapper
Retrieves the parent class wrapper containing this element. If this wrapper is itself a ClassWrapper, returns itself; otherwise returns the parent.- Returns:
- the parent ClassWrapper
-
toString
Returns a string representation of this wrapped element showing its existence state. The returned string is formatted to be shown to users, indicating whether the element matches exactly, deviates, is missing, or is unchecked. Reuses
expectedToString()andactualToString()for representing the two states.For
WrapperProperty.Existence.EXACTmatches, shows expected (= actual) values.For
WrapperProperty.Existence.DEVIATES, shows both expected and actual values.For
WrapperProperty.Existence.MISSING, shows what was expected. -
expectedToString
Returns a string representation of the expected element signature. Subclasses must implement this to provide element-specific formatting.- Returns:
- a string showing the expected element details
-
actualToString
Returns a string representation of the actual element signature found. Subclasses must implement this to provide element-specific formatting.- Returns:
- a string showing the actual element details
-
parseExistence
protected abstract void parseExistence()Parses and updates the existence state based on all properties. Subclasses must implement this to define how to aggregate property states. -
parseExistence
Helper method to parse existence state from multiple wrapper properties. Selects the worst existence state among all provided properties; unchecked properties are ignored.- Parameters:
properties- the wrapper properties to check
-
getExpectedName
-
getActualName
Retrieves the actual name of the element found in the student code.- Returns:
- the actual name, or
nullif the element is missing
-
getActualModifiers
Retrieves the actual modifiers of the element found in the student code.- Returns:
- the actual modifiers (e.g.
"public static"), ornullif the element is missing
-