• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hazendaz / jmockit1 / 496

15 Nov 2025 05:33PM UTC coverage: 72.192% (-0.008%) from 72.2%
496

push

github

web-flow
Merge pull request #412 from hazendaz/renovate/major-spring-core

Update spring core to v7 (major)

5677 of 8360 branches covered (67.91%)

Branch coverage included in aggregate %.

11922 of 16018 relevant lines covered (74.43%)

0.74 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/main/src/main/java/mockit/coverage/modification/ClassSelection.java
1
/*
2
 * MIT License
3
 * Copyright (c) 2006-2025 JMockit developers
4
 * See LICENSE file for full license text.
5
 */
6
package mockit.coverage.modification;
7

8
import static java.util.regex.Pattern.compile;
9

10
import static mockit.internal.util.GeneratedClasses.isExternallyGeneratedSubclass;
11

12
import edu.umd.cs.findbugs.annotations.NonNull;
13
import edu.umd.cs.findbugs.annotations.Nullable;
14

15
import java.net.URL;
16
import java.security.CodeSource;
17
import java.security.ProtectionDomain;
18
import java.util.regex.Matcher;
19
import java.util.regex.Pattern;
20

21
import mockit.coverage.Configuration;
22

23
final class ClassSelection {
24
    private static final String THIS_CLASS_NAME = ClassSelection.class.getName();
×
25
    private static final ClassLoader THIS_CLASS_LOADER = ClassSelection.class.getClassLoader();
×
26
    private static final Pattern CSV = compile(",");
×
27
    private static final Pattern DOT = compile("\\.");
×
28
    private static final Pattern STAR = compile("\\*");
×
29
    private static final Pattern TEST_CLASS_NAME = compile(".+Test(\\$.+)?");
×
30

31
    boolean loadedOnly;
32
    @Nullable
33
    private Matcher classesToInclude;
34
    @Nullable
35
    private Matcher classesToExclude;
36
    @NonNull
37
    private final Matcher testCode;
38
    private boolean configurationRead;
39

40
    ClassSelection() {
×
41
        testCode = TEST_CLASS_NAME.matcher("");
×
42
    }
×
43

44
    @Nullable
45
    private static Matcher newMatcherForClassSelection(@NonNull String specification) {
46
        if (specification.isEmpty()) {
×
47
            return null;
×
48
        }
49

50
        String[] specs = CSV.split(specification);
×
51
        StringBuilder finalRegexBuilder = new StringBuilder();
×
52
        String sep = "";
×
53

54
        for (String spec : specs) {
×
55
            String regex = null;
×
56

57
            if (spec.indexOf('\\') >= 0) {
×
58
                regex = spec;
×
59
            } else if (!spec.isEmpty()) {
×
60
                regex = DOT.matcher(spec).replaceAll("\\.");
×
61
                regex = STAR.matcher(regex).replaceAll(".*");
×
62
                regex = regex.replace('?', '.');
×
63
            }
64

65
            if (regex != null) {
×
66
                finalRegexBuilder.append(sep).append(regex);
×
67
                sep = "|";
×
68
            }
69
        }
70

71
        String finalRegex = finalRegexBuilder.toString();
×
72
        return finalRegex.isEmpty() ? null : compile(finalRegex).matcher("");
×
73
    }
74

75
    boolean isSelected(@NonNull String className, @NonNull ProtectionDomain protectionDomain) {
76
        CodeSource codeSource = protectionDomain.getCodeSource();
×
77

78
        if (codeSource == null || isIneligibleForSelection(className)
×
79
                || !canAccessJMockitFromClassToBeMeasured(protectionDomain)) {
×
80
            return false;
×
81
        }
82

83
        URL location = findLocationInCodeSource(className, protectionDomain);
×
84

85
        if (location == null) {
×
86
            return false;
×
87
        }
88

89
        if (!configurationRead) {
×
90
            readConfiguration();
×
91
        }
92

93
        if (isClassExcludedFromCoverage(className)) {
×
94
            return false;
×
95
        }
96

97
        if (classesToInclude != null) {
×
98
            return classesToInclude.reset(className).matches();
×
99
        }
100

101
        return !isClassFromExternalLibrary(location);
×
102
    }
103

104
    private static boolean isIneligibleForSelection(@NonNull String className) {
105
        return className.charAt(0) == '[' || className.startsWith("mockit.") || className.startsWith("org.hamcrest.")
×
106
                || className.startsWith("org.junit.") || className.startsWith("junit.")
×
107
                || className.startsWith("org.testng.") || className.startsWith("org.apache.maven.surefire.")
×
108
                || isExternallyGeneratedSubclass(className);
×
109
    }
110

111
    private static boolean canAccessJMockitFromClassToBeMeasured(@NonNull ProtectionDomain protectionDomain) {
112
        ClassLoader loaderOfClassToBeMeasured = protectionDomain.getClassLoader();
×
113

114
        if (loaderOfClassToBeMeasured != null) {
×
115
            try {
116
                Class<?> thisClass = loaderOfClassToBeMeasured.loadClass(THIS_CLASS_NAME);
×
117
                return thisClass == ClassSelection.class;
×
118
            } catch (ClassNotFoundException ignore) {
×
119
            }
120
        }
121

122
        return false;
×
123
    }
124

125
    @Nullable
126
    private static URL findLocationInCodeSource(@NonNull String className, @NonNull ProtectionDomain protectionDomain) {
127
        URL location = protectionDomain.getCodeSource().getLocation();
×
128

129
        if (location == null) {
×
130
            if (protectionDomain.getClassLoader() == THIS_CLASS_LOADER) {
×
131
                return null; // it's likely a dynamically generated class
×
132
            }
133

134
            // It's from a custom class loader, so it may exist in the classpath.
135
            String classFileName = className.replace('.', '/') + ".class";
×
136
            location = THIS_CLASS_LOADER.getResource(classFileName);
×
137
        }
138

139
        return location;
×
140
    }
141

142
    private boolean isClassExcludedFromCoverage(@NonNull String className) {
143
        return classesToExclude != null && classesToExclude.reset(className).matches()
×
144
                || testCode.reset(className).matches();
×
145
    }
146

147
    private static boolean isClassFromExternalLibrary(@NonNull URL location) {
148
        if ("jar".equals(location.getProtocol())) {
×
149
            return true;
×
150
        }
151

152
        String path = location.getPath();
×
153
        return path.endsWith(".jar") || path.endsWith("/.cp/") || path.endsWith("/test-classes/");
×
154
    }
155

156
    private void readConfiguration() {
157
        String classes = Configuration.getProperty("classes", "");
×
158
        loadedOnly = "loaded".equals(classes);
×
159
        classesToInclude = loadedOnly ? null : newMatcherForClassSelection(classes);
×
160

161
        String excludes = Configuration.getProperty("excludes", "");
×
162
        classesToExclude = newMatcherForClassSelection(excludes);
×
163

164
        configurationRead = true;
×
165
    }
×
166
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc