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

leeonky / test-charm-java / 332

02 Oct 2025 03:38PM UTC coverage: 74.653% (-0.03%) from 74.68%
332

push

circleci

leeonky
Refactor

10 of 10 new or added lines in 3 files covered. (100.0%)

16 existing lines in 5 files now uncovered.

8559 of 11465 relevant lines covered (74.65%)

0.75 hits per line

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

97.06
/jfactory/src/main/java/com/github/leeonky/jfactory/PropertySpec.java
1
package com.github.leeonky.jfactory;
2

3
import com.github.leeonky.util.BeanClass;
4
import com.github.leeonky.util.GenericBeanClass;
5
import com.github.leeonky.util.PropertyWriter;
6

7
import java.util.List;
8
import java.util.function.Consumer;
9
import java.util.function.Function;
10
import java.util.function.Supplier;
11

12
import static com.github.leeonky.util.Sneaky.cast;
13
import static java.lang.String.format;
14

15
public class PropertySpec<T> {
16
    private final Spec<T> spec;
17
    private final PropertyChain property;
18

19
    PropertySpec(Spec<T> spec, PropertyChain property) {
1✔
20
        this.spec = spec;
1✔
21
        this.property = property;
1✔
22
    }
1✔
23

24
    public Spec<T> value(Object value) {
25
        return value(() -> value);
1✔
26
    }
27

28
    @SuppressWarnings("unchecked")
29
    public <V> Spec<T> value(Supplier<V> value) {
30
        if (value == null)
1✔
31
            return value(() -> null);
1✔
32
        return appendProducer((jFactory, producer, property) ->
1✔
33
                new UnFixedValueProducer<>(value, (BeanClass<V>) producer.getPropertyWriterType(property)));
1✔
34
    }
35

36
    @Deprecated
37
    /**
38
     * reference spec and trait via string
39
     */
40
    public <V> Spec<T> is(Class<? extends Spec<V>> specClass) {
41
        return appendProducer(jFactory -> createCreateProducer(jFactory.spec(specClass)));
1✔
42
    }
43

44
    public Spec<T> is(String... traitsAndSpec) {
45
        return appendProducer(jFactory -> createCreateProducer(jFactory.spec(traitsAndSpec)));
1✔
46
    }
47

48
    public <V> IsSpec2<V> from(String... traitsAndSpec) {
49
        return spec.newIsSpec(traitsAndSpec, this);
1✔
50
    }
51

52
    public Spec<T> optional(String... traitsAndSpec) {
53
        if (property.isSingle()) {
1✔
54
            return spec.append((jFactory, objectProducer) -> objectProducer.changeChild(property.toString(),
1✔
55
                    new OptionalSpecDefaultValueProducer<>(objectProducer.getPropertyWriterType(property.toString()), traitsAndSpec)));
1✔
56
        } else if (property.isDefaultPropertyCollection()) {
1✔
57
            return spec.append((jFactory, objectProducer) -> {
1✔
58
                PropertyWriter<T> propertyWriter = objectProducer.getType().getPropertyWriter((String) property.head());
1✔
59
                if (!propertyWriter.getType().isCollection() && propertyWriter.getType().is(Object.class)) {
1✔
60
                    Factory<Object> factory = jFactory.specFactory(traitsAndSpec[traitsAndSpec.length - 1]);
1✔
61
                    propertyWriter = propertyWriter.decorateType(GenericBeanClass.create(List.class, factory.getType().getGenericType()));
1✔
62
                } else if (propertyWriter.getType().isCollection() && propertyWriter.getType().getElementType().is(Object.class)) {
1✔
63
                    Factory<Object> factory = jFactory.specFactory(traitsAndSpec[traitsAndSpec.length - 1]);
1✔
64
                    propertyWriter = propertyWriter.decorateType(GenericBeanClass.create(propertyWriter.getType().getType(), factory.getType().getGenericType()));
1✔
65
                }
66
                CollectionProducer<?, ?> collectionProducer = BeanClass.cast(objectProducer.forceChildOrDefaultCollection(propertyWriter),
1✔
67
                        CollectionProducer.class).orElseThrow(() ->
1✔
UNCOV
68
                        new IllegalArgumentException(format("%s.%s is not list", spec.getType().getName(), property.head())));
×
69
                OptionalSpecDefaultValueProducer<?> optionalSpecDefaultValueProducer =
1✔
70
                        new OptionalSpecDefaultValueProducer<>(propertyWriter.getType(), traitsAndSpec);
1✔
71
                collectionProducer.changeElementPopulationFactory(index -> optionalSpecDefaultValueProducer);
1✔
72
            });
1✔
73
        }
UNCOV
74
        throw new IllegalArgumentException(format("Not support property chain '%s' in current operation", property));
×
75
    }
76

77
    @Deprecated
78
    /**
79
     * reference spec and trait via string
80
     */
81
    public <V, S extends Spec<V>> IsSpec<V, S> from(Class<S> specClass) {
82
        return spec.newIsSpec(specClass, this);
1✔
83
    }
84

85
    public Spec<T> defaultValue(Object value) {
86
        return defaultValue(() -> value);
1✔
87
    }
88

89
    @SuppressWarnings("unchecked")
90
    public <V> Spec<T> defaultValue(Supplier<V> supplier) {
91
        if (supplier == null)
1✔
UNCOV
92
            return defaultValue((Object) null);
×
93
        return appendProducer((jFactory, producer, property) ->
1✔
94
                new DefaultValueProducer<>((BeanClass<V>) producer.getPropertyWriterType(property), supplier));
1✔
95
    }
96

97
    public Spec<T> byFactory() {
98
        return appendProducer((jFactory, producer, property) ->
1✔
99
                producer.newDefaultValueProducer(cast(producer.getType().getPropertyWriter(property))).orElseGet(() ->
1✔
100
                        createCreateProducer(jFactory.type(producer.getPropertyWriterType(property).getType()))));
1✔
101
    }
102

103
    public Spec<T> byFactory(Function<Builder<?>, Builder<?>> builder) {
104
        return appendProducer((jFactory, producer, property) ->
1✔
105
                producer.newDefaultValueProducer(cast(producer.getType().getPropertyWriter(property))).orElseGet(() ->
1✔
106
                        createQueryOrCreateProducer(builder.apply(jFactory.type(
1✔
107
                                producer.getPropertyWriterType(property).getType())))));
1✔
108
    }
109

110
    public Spec<T> dependsOn(String dependency) {
111
        spec.consistent(Object.class)
1✔
112
                .property(property.toString()).write(Function.identity())
1✔
113
                .property(dependency).read(Function.identity());
1✔
114
        return spec;
1✔
115
    }
116

117
    public Spec<T> dependsOn(String dependency, Function<Object, Object> rule) {
118
        spec.consistent(Object.class)
1✔
119
                .property(property.toString()).write(Function.identity())
1✔
120
                .property(dependency).read(rule);
1✔
121
        return spec;
1✔
122
    }
123

124
    public Spec<T> dependsOn(List<String> dependencies, Function<Object[], Object> rule) {
125
        spec.consistent(Object.class)
1✔
126
                .property(property.toString()).write(Function.identity())
1✔
127
                .properties(dependencies.toArray(new String[0])).read(rule);
1✔
128
        return spec;
1✔
129
    }
130

131
    private Spec<T> appendProducer(Fuc<JFactory, Producer<?>, String, Producer<?>> producerFactory) {
132
        if (property.isSingle() || property.isTopLevelPropertyCollection())
1✔
133
            return spec.append((jFactory, objectProducer) -> objectProducer.changeDescendant(property,
1✔
134
                    ((nextToLast, property) -> producerFactory.apply(jFactory, nextToLast, property))));
1✔
135
        if (property.isDefaultPropertyCollection()) {
1✔
136
            return spec.append((jFactory, objectProducer) -> {
1✔
137
                PropertyWriter<T> propertyWriter = objectProducer.getType().getPropertyWriter((String) property.head());
1✔
138
                if (!propertyWriter.getType().isCollection() && propertyWriter.getType().is(Object.class)) {
1✔
139
                    Producer<?> element = producerFactory.apply(jFactory, objectProducer, "0");
1✔
140
                    propertyWriter = propertyWriter.decorateType(GenericBeanClass.create(List.class, element.getType().getGenericType()));
1✔
141
                }
142
                CollectionProducer<?, ?> collectionProducer = BeanClass.cast(objectProducer.forceChildOrDefaultCollection(propertyWriter),
1✔
143
                        CollectionProducer.class).orElseThrow(() ->
1✔
144
                        new IllegalArgumentException(format("%s.%s is not list", spec.getType().getName(), property.head())));
1✔
145
                collectionProducer.changeElementPopulationFactory(index ->
1✔
146
                        producerFactory.apply(jFactory, collectionProducer, index.getName()));
1✔
147
            });
1✔
148
        }
149
        if (property.isTopLevelDefaultPropertyCollection()) {
1✔
150
            return spec.append((jFactory, objectProducer) -> {
1✔
151
                objectProducer.changeElementPopulationFactory(propertyWriter ->
1✔
152
                        producerFactory.apply(jFactory, objectProducer, propertyWriter.getName()));
1✔
153
            });
1✔
154
        }
155
        throw new IllegalArgumentException(format("Not support property chain '%s' in current operation", property));
1✔
156
    }
157

158
    private Spec<T> appendProducer(Function<JFactory, Producer<?>> producerFactory) {
159
        return appendProducer((jFactory, producer, s) -> producerFactory.apply(jFactory));
1✔
160
    }
161

162
    @SuppressWarnings("unchecked")
163
    private <V> Producer<V> createQueryOrCreateProducer(Builder<V> builder) {
164
        Builder<V> builderWithArgs = builder.args(spec.params(property.toString()));
1✔
165
        return builderWithArgs.queryAll().stream().findFirst().<Producer<V>>map(object ->
1✔
166
                        new BuilderValueProducer<>((BeanClass<V>) BeanClass.create(object.getClass()), builderWithArgs))
1✔
167
                .orElseGet(builderWithArgs::createProducer);
1✔
168
    }
169

170
    private <V> Producer<V> createCreateProducer(Builder<V> builder) {
171
        return builder.args(spec.params(property.toString())).createProducer();
1✔
172
    }
173

174
    public Spec<T> reverseAssociation(String association) {
175
        return spec.append((jFactory, producer) -> producer.appendReverseAssociation(property, association));
1✔
176
    }
177

178
    public Spec<T> ignore() {
179
        return spec.append((jFactory, objectProducer) -> objectProducer.ignoreProperty(property.toString()));
1✔
180
    }
181

182
    @FunctionalInterface
183
    interface Fuc<P1, P2, P3, R> {
184
        R apply(P1 p1, P2 p2, P3 p3);
185
    }
186

187
    public class IsSpec<V, S extends Spec<V>> {
188
        private final Class<S> specClass;
189
        private final String position;
190

191
        public IsSpec(Class<S> spec) {
1✔
192
            position = Thread.currentThread().getStackTrace()[4].toString();
1✔
193
            specClass = spec;
1✔
194
        }
1✔
195

196
        public Spec<T> which(Consumer<S> trait) {
197
            spec.consume(this);
1✔
198
            return appendProducer(jFactory -> createCreateProducer(jFactory.spec(specClass, trait)));
1✔
199
        }
200

201
        public Spec<T> and(Function<Builder<V>, Builder<V>> builder) {
202
            spec.consume(this);
1✔
203
            return appendProducer(jFactory -> createQueryOrCreateProducer(builder.apply(jFactory.spec(specClass))));
1✔
204
        }
205

206
        public String getPosition() {
207
            return position;
1✔
208
        }
209
    }
210

211
    public class IsSpec2<V> {
212
        private final String[] spec;
213
        private final String position;
214

215
        public IsSpec2(String[] spec) {
1✔
216
            position = Thread.currentThread().getStackTrace()[4].toString();
1✔
217
            this.spec = spec;
1✔
218
        }
1✔
219

220
        public Spec<T> and(Function<Builder<V>, Builder<V>> builder) {
221
            PropertySpec.this.spec.consume(this);
1✔
222
            return appendProducer(jFactory -> createQueryOrCreateProducer(builder.apply(jFactory.spec(spec))));
1✔
223
        }
224

225
        public String getPosition() {
226
            return position;
1✔
227
        }
228
    }
229
}
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