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

leeonky / test-charm-java / 323

30 Sep 2025 05:15PM UTC coverage: 74.637% (+0.1%) from 74.512%
323

push

circleci

leeonky
Use descendantForRead in consistent provider

16 of 17 new or added lines in 4 files covered. (94.12%)

29 existing lines in 7 files now uncovered.

8531 of 11430 relevant lines covered (74.64%)

0.75 hits per line

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

89.69
/jfactory/src/main/java/com/github/leeonky/jfactory/DefaultConsistency.java
1
package com.github.leeonky.jfactory;
2

3
import com.github.leeonky.util.BeanClass;
4
import com.github.leeonky.util.Sneaky;
5

6
import java.util.*;
7
import java.util.function.Function;
8
import java.util.function.Predicate;
9

10
import static com.github.leeonky.jfactory.ConsistencyItem.guessCustomerPositionStackTrace;
11
import static com.github.leeonky.jfactory.PropertyChain.propertyChain;
12
import static java.util.Arrays.asList;
13
import static java.util.Collections.singletonList;
14
import static java.util.stream.Collectors.toCollection;
15
import static java.util.stream.Collectors.toList;
16

17
class DefaultConsistency<T> implements Consistency<T> {
18
    private final List<ConsistencyItem<T>> items = new ArrayList<>();
1✔
19
    private final List<DefaultListConsistency<T>> list = new ArrayList<>();
1✔
20
    private final BeanClass<T> type;
21
    private final List<StackTraceElement> locations = new ArrayList<>();
1✔
22

23
    static final Function<Object, Object> LINK_COMPOSER = s -> s;
1✔
24
    static final Function<Object, Object> LINK_DECOMPOSER = s -> s;
1✔
25

26
    DefaultConsistency(Class<T> type) {
27
        this(BeanClass.create(type));
1✔
28
    }
1✔
29

30
    DefaultConsistency(BeanClass<T> type) {
31
        this(type, singletonList(guessCustomerPositionStackTrace()));
1✔
32
    }
1✔
33

34
    DefaultConsistency(BeanClass<T> type, List<StackTraceElement> locations) {
1✔
35
        this.type = type;
1✔
36
        this.locations.addAll(locations);
1✔
37
    }
1✔
38

39
    @Override
40
    public BeanClass<T> type() {
41
        return type;
1✔
42
    }
43

44
    @Override
45
    @SuppressWarnings("unchecked")
46
    public Consistency<T> direct(String property) {
47
        return property(property).read((Function<Object, T>) LINK_COMPOSER).write((Function<T, Object>) LINK_DECOMPOSER);
1✔
48
    }
49

50
    @Override
51
    public <P> C1<T, P> property(String property) {
52
        ConsistencyItem<T> item = new ConsistencyItem<>(singletonList(propertyChain(property)), this);
1✔
53
        items.add(item);
1✔
54
        return new C1<>(this, item);
1✔
55
    }
56

57
    @Override
58
    public <P1, P2> C2<T, P1, P2> properties(String property1, String property2) {
59
        ConsistencyItem<T> item = new ConsistencyItem<>(asList(propertyChain(property1), propertyChain(property2)), this);
1✔
60
        items.add(item);
1✔
61
        return new C2<>(this, item);
1✔
62
    }
63

64
    @Override
65
    public <P1, P2, P3> C3<T, P1, P2, P3> properties(String property1, String property2, String property3) {
66
        ConsistencyItem<T> item = new ConsistencyItem<>(asList(propertyChain(property1), propertyChain(property2), propertyChain(property3)), this);
1✔
67
        items.add(item);
1✔
68
        return new C3<>(this, item);
1✔
69
    }
70

71
    @Override
72
    public CN<T> properties(String... properties) {
73
        ConsistencyItem<T> item = new ConsistencyItem<>(Arrays.stream(properties).map(PropertyChain::propertyChain).collect(toList()), this);
1✔
74
        items.add(item);
1✔
75
        return new CN<>(this, item);
1✔
76
    }
77

78
    boolean merge(DefaultConsistency<?> another) {
79
        if (items.stream().anyMatch(item -> another.items.stream().anyMatch(item::same))) {
1✔
80
            another.items.forEach(item -> items.add(Sneaky.cast(item)));
1✔
81
            return true;
1✔
82
        }
83
        return false;
1✔
84
    }
85

86
    String info() {
UNCOV
87
        StringBuilder builder = new StringBuilder();
×
UNCOV
88
        builder.append("  ").append(type().getName()).append(":");
×
UNCOV
89
        for (StackTraceElement location : locations) {
×
UNCOV
90
            builder.append("\n    ").append(location.getClassName()).append(".").append(location.getMethodName())
×
UNCOV
91
                    .append("(").append(location.getFileName()).append(":").append(location.getLineNumber()).append(")");
×
UNCOV
92
        }
×
UNCOV
93
        return builder.toString();
×
94
    }
95

96
    DefaultConsistency<T> absoluteProperty(PropertyChain base) {
97
        DefaultConsistency<T> absolute = new DefaultConsistency<>(type(), locations);
1✔
98
        items.forEach(item -> absolute.items.add(item.absoluteProperty(base)));
1✔
99
        return absolute;
1✔
100
    }
101

102
    Resolver resolver(ObjectProducer<?> root) {
103
        return new Resolver(root);
1✔
104
    }
105

106
    @Override
107
    public ListConsistencyBuilder<T> list(String property) {
108
        DefaultListConsistency<T> listConsistency = new DefaultListConsistency<>(property, this);
1✔
109
        list.add(listConsistency);
1✔
110
        return new ListConsistencyBuilder<>(this, listConsistency);
1✔
111
    }
112

113
    DefaultConsistency<T> processListConsistency(ObjectProducer<?> producer) {
114
        for (DefaultListConsistency<T> listConsistency : list)
1✔
115
            listConsistency.resolveToItems(producer);
1✔
116
        return this;
1✔
117
    }
118

119
    interface Identity {
120
        default Object identity() {
UNCOV
121
            return this;
×
122
        }
123

124
        default boolean same(Identity another) {
125
            return another != null && identity() == another.identity();
1✔
126
        }
127

128
        StackTraceElement getLocation();
129
    }
130

131
    interface Composer<T> extends Function<Object[], T>, Identity {
132
    }
133

134
    interface Decomposer<T> extends Function<T, Object[]>, Identity {
135
    }
136

137
    class Resolver {
138
        private final Set<ConsistencyItem<T>.Resolver> providers;
139
        private final Set<ConsistencyItem<T>.Resolver> consumers;
140

141
        Resolver(ObjectProducer<?> root) {
1✔
142
            List<ConsistencyItem<T>.Resolver> itemResolvers = items.stream().map(i -> i.resolver(root, this)).collect(toList());
1✔
143
            providers = itemResolvers.stream().filter(ConsistencyItem.Resolver::hasComposer).collect(toCollection(LinkedHashSet::new));
1✔
144
            consumers = itemResolvers.stream().filter(ConsistencyItem.Resolver::hasDecomposer).collect(toCollection(LinkedHashSet::new));
1✔
145
        }
1✔
146

147
        Set<PropertyChain> resolve(ConsistencyItem<T>.Resolver provider) {
148
            Set<PropertyChain> resolved = new HashSet<>();
1✔
149
            for (ConsistencyItem<T>.Resolver consumer : consumers)
1✔
150
                if (consumer != provider)
1✔
151
                    resolved.addAll(consumer.resolve(provider));
1✔
152
            return resolved;
1✔
153
        }
154

155
        Optional<ConsistencyItem<T>.Resolver> searchProvider(Predicate<ConsistencyItem<?>.Resolver> condition) {
156
            return providers.stream().filter(condition).min(this::onlyComposerFirstOrder);
1✔
157
        }
158

159
        ConsistencyItem<T>.Resolver defaultProvider() {
160
            return providers.stream().min(this::onlyComposerFirstOrder).get();
1✔
161
        }
162

163
        private int onlyComposerFirstOrder(ConsistencyItem<T>.Resolver r1, ConsistencyItem<T>.Resolver r2) {
164
            if (!r1.hasDecomposer())
1✔
165
                return -1;
1✔
166
            return !r2.hasDecomposer() ? 1 : 0;
1✔
167
        }
168

169
        Optional<ConsistencyItem<T>.Resolver> propertyRelated(PropertyChain property) {
170
            return providers.stream().filter(p -> p.containsProperty(property)).findFirst();
1✔
171
        }
172
    }
173
}
174

175
class DecorateConsistency<T> implements Consistency<T> {
176
    private final Consistency<T> delegate;
177

178
    DecorateConsistency(Consistency<T> delegate) {
1✔
179
        this.delegate = delegate;
1✔
180
    }
1✔
181

182
    @Override
183
    public BeanClass<T> type() {
UNCOV
184
        return delegate.type();
×
185
    }
186

187
    @Override
188
    public Consistency<T> direct(String property) {
189
        return delegate.direct(property);
1✔
190
    }
191

192
    @Override
193
    public <P> C1<T, P> property(String property) {
194
        return delegate.property(property);
1✔
195
    }
196

197
    @Override
198
    public <P1, P2> C2<T, P1, P2> properties(String property1, String property2) {
199
        return delegate.properties(property1, property2);
1✔
200
    }
201

202
    @Override
203
    public <P1, P2, P3> C3<T, P1, P2, P3> properties(String property1, String property2, String property3) {
204
        return delegate.properties(property1, property2, property3);
1✔
205
    }
206

207
    @Override
208
    public CN<T> properties(String... properties) {
209
        return delegate.properties(properties);
1✔
210
    }
211

212
    @Override
213
    public ListConsistencyBuilder<T> list(String property) {
UNCOV
214
        return delegate.list(property);
×
215
    }
216
}
217

218
class IdentityAction implements DefaultConsistency.Identity {
219
    protected final Object identity;
220
    private final StackTraceElement location;
221

222
    public IdentityAction(Object identity) {
1✔
223
        this.identity = Objects.requireNonNull(identity);
1✔
224
        location = guessCustomerPositionStackTrace();
1✔
225
    }
1✔
226

227
    @Override
228
    public Object identity() {
229
        return identity;
1✔
230
    }
231

232
    @Override
233
    public StackTraceElement getLocation() {
234
        return location;
1✔
235
    }
236
}
237

238
class ComposerWrapper<T> extends IdentityAction implements DefaultConsistency.Composer<T> {
239
    private final Function<Object[], T> action;
240

241
    ComposerWrapper(Function<Object[], T> action, Object identity) {
242
        super(identity);
1✔
243
        this.action = Objects.requireNonNull(action);
1✔
244
    }
1✔
245

246
    @Override
247
    public T apply(Object[] objects) {
248
        return action.apply(objects);
1✔
249
    }
250
}
251

252
class DecomposerWrapper<T> extends IdentityAction implements DefaultConsistency.Decomposer<T> {
253
    private final Function<T, Object[]> action;
254

255
    DecomposerWrapper(Function<T, Object[]> action, Object identity) {
256
        super(identity);
1✔
257
        this.action = Objects.requireNonNull(action);
1✔
258
    }
1✔
259

260
    @Override
261
    public Object[] apply(T t) {
262
        return action.apply(t);
1✔
263
    }
264
}
265

266
class MultiPropertyConsistency<T, C extends MultiPropertyConsistency<T, C>> extends DecorateConsistency<T> {
267
    final ConsistencyItem<T> lastItem;
268

269
    MultiPropertyConsistency(Consistency<T> origin, ConsistencyItem<T> lastItem) {
270
        super(origin);
1✔
271
        this.lastItem = lastItem;
1✔
272
    }
1✔
273

274
    @SuppressWarnings("unchecked")
275
    public C read(Function<Object[], T> composer) {
276
        lastItem.setComposer(new ComposerWrapper<>(composer, composer));
1✔
277
        return (C) this;
1✔
278
    }
279

280
    @SuppressWarnings("unchecked")
281
    public C write(Function<T, Object[]> decomposer) {
282
        lastItem.setDecomposer(new DecomposerWrapper<>(decomposer, decomposer));
1✔
283
        return (C) this;
1✔
284
    }
285
}
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