SuggestionLookup.java

1
package org.egothor.methodatlas.ai;
2
3
import java.util.HashMap;
4
import java.util.Map;
5
import java.util.Objects;
6
import java.util.Optional;
7
8
/**
9
 * Immutable lookup structure providing efficient access to AI-generated method
10
 * suggestions by method name.
11
 *
12
 * <p>
13
 * This class acts as an adapter between the class-level suggestion model
14
 * returned by the AI subsystem ({@link AiClassSuggestion}) and the per-method
15
 * processing logic used by {@code MethodAtlasApp}. It converts the list of
16
 * {@link AiMethodSuggestion} objects into a name-indexed lookup map so that
17
 * suggestions can be retrieved in constant time during traversal of parsed test
18
 * methods.
19
 * </p>
20
 *
21
 * <h2>Design Characteristics</h2>
22
 *
23
 * <ul>
24
 * <li>immutable after construction</li>
25
 * <li>null-safe for missing or malformed AI responses</li>
26
 * <li>optimized for repeated method-level lookups</li>
27
 * </ul>
28
 *
29
 * <p>
30
 * If the AI response contains duplicate suggestions for the same method, only
31
 * the first occurrence is retained.
32
 * </p>
33
 *
34
 * @see AiClassSuggestion
35
 * @see AiMethodSuggestion
36
 */
37
public final class SuggestionLookup {
38
39
    private final Map<String, AiMethodSuggestion> byMethodName;
40
41
    /**
42
     * Creates a new immutable lookup instance backed by the supplied map.
43
     *
44
     * <p>
45
     * The internal map is defensively copied to guarantee immutability of the
46
     * lookup structure.
47
     * </p>
48
     *
49
     * @param byMethodName mapping from method names to AI suggestions
50
     */
51
    private SuggestionLookup(Map<String, AiMethodSuggestion> byMethodName) {
52
        this.byMethodName = Map.copyOf(byMethodName);
53
    }
54
55
    /**
56
     * Creates a lookup instance from a class-level AI suggestion result.
57
     *
58
     * <p>
59
     * The method extracts all method suggestions contained in the supplied
60
     * {@link AiClassSuggestion} and indexes them by method name. Entries with
61
     * {@code null} suggestions, missing method names, or blank method names are
62
     * ignored.
63
     * </p>
64
     *
65
     * <p>
66
     * If the suggestion contains no method entries, an empty lookup instance is
67
     * returned.
68
     * </p>
69
     *
70
     * @param suggestion AI classification result for a test class
71
     * @return lookup structure providing fast access to method suggestions
72
     */
73
    public static SuggestionLookup from(AiClassSuggestion suggestion) {
74 6 1. from : removed conditional - replaced equality check with false → SURVIVED
2. from : removed conditional - replaced equality check with true → KILLED
3. from : removed conditional - replaced equality check with false → KILLED
4. from : removed conditional - replaced equality check with true → KILLED
5. from : removed conditional - replaced equality check with true → KILLED
6. from : removed conditional - replaced equality check with false → KILLED
        if (suggestion == null || suggestion.methods() == null || suggestion.methods().isEmpty()) {
75 1 1. from : replaced return value with null for org/egothor/methodatlas/ai/SuggestionLookup::from → KILLED
            return new SuggestionLookup(Map.of());
76
        }
77
78
        Map<String, AiMethodSuggestion> map = new HashMap<>();
79
        for (AiMethodSuggestion methodSuggestion : suggestion.methods()) {
80 2 1. from : removed conditional - replaced equality check with false → KILLED
2. from : removed conditional - replaced equality check with true → KILLED
            if (methodSuggestion == null) {
81
                continue;
82
            }
83 4 1. from : removed conditional - replaced equality check with false → SURVIVED
2. from : removed conditional - replaced equality check with true → KILLED
3. from : removed conditional - replaced equality check with false → KILLED
4. from : removed conditional - replaced equality check with true → KILLED
            if (methodSuggestion.methodName() == null || methodSuggestion.methodName().isBlank()) {
84
                continue;
85
            }
86
            map.putIfAbsent(methodSuggestion.methodName(), methodSuggestion);
87
        }
88
89 1 1. from : replaced return value with null for org/egothor/methodatlas/ai/SuggestionLookup::from → KILLED
        return new SuggestionLookup(map);
90
    }
91
92
    /**
93
     * Retrieves the AI suggestion for the specified method name.
94
     *
95
     * <p>
96
     * If no suggestion exists for the method, an empty {@link Optional} is
97
     * returned.
98
     * </p>
99
     *
100
     * @param methodName name of the method being queried
101
     * @return optional containing the suggestion if present
102
     *
103
     * @throws NullPointerException if {@code methodName} is {@code null}
104
     */
105
    public Optional<AiMethodSuggestion> find(String methodName) {
106
        Objects.requireNonNull(methodName, "methodName");
107 1 1. find : replaced return value with Optional.empty for org/egothor/methodatlas/ai/SuggestionLookup::find → KILLED
        return Optional.ofNullable(byMethodName.get(methodName));
108
    }
109
}

Mutations

74

1.1
Location : from
Killed by : org.egothor.methodatlas.ai.SuggestionLookupTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.ai.SuggestionLookupTest]/[method:from_nullSuggestion_returnsEmptyLookup()]
removed conditional - replaced equality check with true → KILLED

2.2
Location : from
Killed by : org.egothor.methodatlas.ai.SuggestionLookupTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.ai.SuggestionLookupTest]/[method:find_existingMethod_returnsSuggestion()]
removed conditional - replaced equality check with false → KILLED

3.3
Location : from
Killed by : org.egothor.methodatlas.ai.SuggestionLookupTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.ai.SuggestionLookupTest]/[method:from_nullMethods_returnsEmptyLookup()]
removed conditional - replaced equality check with true → KILLED

4.4
Location : from
Killed by : none
removed conditional - replaced equality check with false → SURVIVED
Covering tests

5.5
Location : from
Killed by : org.egothor.methodatlas.ai.SuggestionLookupTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.ai.SuggestionLookupTest]/[method:find_existingMethod_returnsSuggestion()]
removed conditional - replaced equality check with true → KILLED

6.6
Location : from
Killed by : org.egothor.methodatlas.ai.SuggestionLookupTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.ai.SuggestionLookupTest]/[method:find_existingMethod_returnsSuggestion()]
removed conditional - replaced equality check with false → KILLED

75

1.1
Location : from
Killed by : org.egothor.methodatlas.ai.SuggestionLookupTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.ai.SuggestionLookupTest]/[method:from_nullSuggestion_returnsEmptyLookup()]
replaced return value with null for org/egothor/methodatlas/ai/SuggestionLookup::from → KILLED

80

1.1
Location : from
Killed by : org.egothor.methodatlas.ai.SuggestionLookupTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.ai.SuggestionLookupTest]/[method:from_filtersNullBlankAndMissingMethodNames()]
removed conditional - replaced equality check with false → KILLED

2.2
Location : from
Killed by : org.egothor.methodatlas.ai.SuggestionLookupTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.ai.SuggestionLookupTest]/[method:find_existingMethod_returnsSuggestion()]
removed conditional - replaced equality check with true → KILLED

83

1.1
Location : from
Killed by : org.egothor.methodatlas.ai.SuggestionLookupTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.ai.SuggestionLookupTest]/[method:find_existingMethod_returnsSuggestion()]
removed conditional - replaced equality check with true → KILLED

2.2
Location : from
Killed by : org.egothor.methodatlas.ai.SuggestionLookupTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.ai.SuggestionLookupTest]/[method:find_existingMethod_returnsSuggestion()]
removed conditional - replaced equality check with false → KILLED

3.3
Location : from
Killed by : none
removed conditional - replaced equality check with false → SURVIVED
Covering tests

4.4
Location : from
Killed by : org.egothor.methodatlas.ai.SuggestionLookupTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.ai.SuggestionLookupTest]/[method:from_filtersNullBlankAndMissingMethodNames()]
removed conditional - replaced equality check with true → KILLED

89

1.1
Location : from
Killed by : org.egothor.methodatlas.ai.SuggestionLookupTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.ai.SuggestionLookupTest]/[method:find_missingMethod_returnsEmptyOptional()]
replaced return value with null for org/egothor/methodatlas/ai/SuggestionLookup::from → KILLED

107

1.1
Location : find
Killed by : org.egothor.methodatlas.ai.SuggestionLookupTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.ai.SuggestionLookupTest]/[method:find_existingMethod_returnsSuggestion()]
replaced return value with Optional.empty for org/egothor/methodatlas/ai/SuggestionLookup::find → KILLED

Active mutators

Tests examined


Report generated by PIT 1.22.1