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

hazendaz / jmockit1 / 531

25 Nov 2025 03:05PM UTC coverage: 72.347% (+0.1%) from 72.2%
531

Pull #422

github

web-flow
Merge cf5b09974 into a5eff4b89
Pull Request #422: Restore @Mock invocation constraints and fix MockedTypeCascade concurrency

5738 of 8420 branches covered (68.15%)

Branch coverage included in aggregate %.

95 of 106 new or added lines in 7 files covered. (89.62%)

1 existing line in 1 file now uncovered.

12013 of 16116 relevant lines covered (74.54%)

0.75 hits per line

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

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

8
import edu.umd.cs.findbugs.annotations.NonNull;
9
import edu.umd.cs.findbugs.annotations.Nullable;
10

11
import java.util.ArrayList;
12
import java.util.IdentityHashMap;
13
import java.util.Iterator;
14
import java.util.LinkedHashSet;
15
import java.util.List;
16
import java.util.Map;
17
import java.util.Map.Entry;
18
import java.util.Set;
19
import java.util.regex.Pattern;
20

21
import mockit.internal.util.ClassLoad;
22

23
import org.checkerframework.checker.index.qual.NonNegative;
24

25
/**
26
 * Holds state associated with fake class containing {@linkplain mockit.Mock annotated fakes}.
27
 */
28
public final class FakeStates {
29
    private static final Pattern SPACE = Pattern.compile(" ");
1✔
30

31
    /**
32
     * For each fake instance and each <code>@Mock</code> method containing the <code>Invocation</code> parameter, a
33
     * runtime state will be kept here.
34
     */
35
    @NonNull
36
    private final Map<Object, List<FakeState>> fakesToFakeStates;
37
    @NonNull
38
    private final Map<Object, List<FakeState>> startupFakesToFakeStates;
39
    @NonNull
40
    private final Set<FakeState> fakeStatesWithExpectations; // Subset of states that declared @Mock invocation limits
41

42
    public FakeStates() {
1✔
43
        startupFakesToFakeStates = new IdentityHashMap<>(2);
1✔
44
        fakesToFakeStates = new IdentityHashMap<>(8);
1✔
45
        fakeStatesWithExpectations = new LinkedHashSet<>(8);
1✔
46
    }
1✔
47

48
    void addStartupFakeAndItsFakeStates(@NonNull Object fake, @NonNull List<FakeState> fakeStates) {
49
        startupFakesToFakeStates.put(fake, fakeStates);
1✔
50
        registerExpectations(fakeStates);
1✔
51
    }
1✔
52

53
    void addFakeAndItsFakeStates(@NonNull Object fake, @NonNull List<FakeState> fakeStates) {
54
        fakesToFakeStates.put(fake, fakeStates);
1✔
55
        registerExpectations(fakeStates);
1✔
56
    }
1✔
57

58
    public void copyFakeStates(@NonNull Object previousFake, @NonNull Object newFake) {
59
        List<FakeState> fakeStates = fakesToFakeStates.get(previousFake);
1✔
60

61
        if (fakeStates != null) {
1!
62
            List<FakeState> copiedFakeStates = new ArrayList<>(fakeStates.size());
×
63

64
            for (FakeState fakeState : fakeStates) {
×
65
                copiedFakeStates.add(new FakeState(fakeState));
×
66
            }
×
67

68
            fakesToFakeStates.put(newFake, copiedFakeStates);
×
NEW
69
            registerExpectations(copiedFakeStates);
×
70
        }
71
    }
1✔
72

73
    public void removeClassState(@NonNull Class<?> redefinedClass,
74
            @Nullable String internalNameForOneOrMoreFakeClasses) {
75
        removeFakeStates(redefinedClass);
1✔
76

77
        if (internalNameForOneOrMoreFakeClasses != null) {
1✔
78
            if (internalNameForOneOrMoreFakeClasses.indexOf(' ') < 0) {
1✔
79
                removeFakeStates(internalNameForOneOrMoreFakeClasses);
1✔
80
            } else {
81
                String[] fakeClassesInternalNames = SPACE.split(internalNameForOneOrMoreFakeClasses);
1✔
82

83
                for (String fakeClassInternalName : fakeClassesInternalNames) {
1✔
84
                    removeFakeStates(fakeClassInternalName);
1✔
85
                }
86
            }
87
        }
88
    }
1✔
89

90
    private void removeFakeStates(@NonNull Class<?> redefinedClass) {
91
        Iterator<List<FakeState>> itr = fakesToFakeStates.values().iterator();
1✔
92

93
        while (itr.hasNext()) {
1✔
94
            List<FakeState> fakeStates = itr.next();
1✔
95
            FakeState fakeState = fakeStates.get(0);
1✔
96

97
            if (fakeState.getRealClass() == redefinedClass) {
1✔
98
                fakeStates.forEach(fakeStatesWithExpectations::remove);
1✔
99
                fakeStates.clear();
1✔
100
                itr.remove();
1✔
101
            }
102
        }
1✔
103
    }
1✔
104

105
    private void removeFakeStates(@NonNull String fakeClassInternalName) {
106
        Class<?> fakeClass = ClassLoad.loadClass(fakeClassInternalName.replace('/', '.'));
1✔
107
        Iterator<Entry<Object, List<FakeState>>> itr = fakesToFakeStates.entrySet().iterator();
1✔
108

109
        while (itr.hasNext()) {
1✔
110
            Entry<Object, List<FakeState>> fakeAndFakeStates = itr.next();
1✔
111
            Object fake = fakeAndFakeStates.getKey();
1✔
112

113
            if (fake.getClass() == fakeClass) {
1✔
114
                fakeAndFakeStates.getValue().forEach(fakeStatesWithExpectations::remove);
1✔
115
                itr.remove();
1✔
116
            }
117
        }
1✔
118
    }
1✔
119

120
    public boolean updateFakeState(@NonNull Object fake, @NonNegative int fakeStateIndex) {
121
        FakeState fakeState = getFakeState(fake, fakeStateIndex);
1✔
122
        return fakeState.update();
1✔
123
    }
124

125
    @NonNull
126
    FakeState getFakeState(@NonNull Object fake, @NonNegative int fakeStateIndex) {
127
        List<FakeState> fakeStates = startupFakesToFakeStates.get(fake);
1✔
128

129
        if (fakeStates == null) {
1✔
130
            fakeStates = fakesToFakeStates.get(fake);
1✔
131
        }
132

133
        FakeState fakeState = fakeStates.get(fakeStateIndex);
1✔
134
        assert fakeState != null;
1!
135
        return fakeState;
1✔
136
    }
137

138
    public void verifyMissingInvocations() {
139
        for (FakeState fakeState : fakeStatesWithExpectations) {
1✔
140
            fakeState.verifyMissingInvocations();
1✔
141
        }
1✔
142
    }
1✔
143

144
    public void resetExpectations() {
145
        for (FakeState fakeState : fakeStatesWithExpectations) {
1✔
146
            fakeState.reset();
1✔
147
        }
1✔
148
    }
1✔
149

150
    private void registerExpectations(@NonNull List<FakeState> fakeStates) {
151
        for (FakeState fakeState : fakeStates) {
1✔
152
            if (fakeState.isWithExpectations()) {
1✔
153
                fakeStatesWithExpectations.add(fakeState);
1✔
154
            }
155
        }
1✔
156
    }
1✔
157
}
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