com.navercorp.fixturemonkey.FixtureMonkey Maven / Gradle / Ivy
/*
* Fixture Monkey
*
* Copyright (c) 2021-present NAVER Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.navercorp.fixturemonkey;
import static java.util.stream.Collectors.toList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Stream;
import org.apiguardian.api.API;
import org.apiguardian.api.API.Status;
import net.jqwik.api.Arbitrary;
import com.navercorp.fixturemonkey.api.ObjectBuilder;
import com.navercorp.fixturemonkey.api.context.MonkeyContext;
import com.navercorp.fixturemonkey.api.matcher.MatcherOperator;
import com.navercorp.fixturemonkey.api.option.FixtureMonkeyOptions;
import com.navercorp.fixturemonkey.api.property.RootProperty;
import com.navercorp.fixturemonkey.api.type.LazyAnnotatedType;
import com.navercorp.fixturemonkey.api.type.TypeReference;
import com.navercorp.fixturemonkey.builder.ArbitraryBuilderContext;
import com.navercorp.fixturemonkey.builder.DefaultArbitraryBuilder;
import com.navercorp.fixturemonkey.builder.JavaTypeDefaultTypeArbitraryBuilder;
import com.navercorp.fixturemonkey.customizer.ArbitraryManipulator;
import com.navercorp.fixturemonkey.customizer.MonkeyManipulatorFactory;
import com.navercorp.fixturemonkey.experimental.ExperimentalArbitraryBuilder;
import com.navercorp.fixturemonkey.resolver.ArbitraryResolver;
import com.navercorp.fixturemonkey.resolver.ManipulatorOptimizer;
@API(since = "0.4.0", status = Status.MAINTAINED)
public final class FixtureMonkey {
private final FixtureMonkeyOptions fixtureMonkeyOptions;
private final ManipulatorOptimizer manipulatorOptimizer;
private final MonkeyContext monkeyContext;
private final MonkeyManipulatorFactory monkeyManipulatorFactory;
public FixtureMonkey(
FixtureMonkeyOptions fixtureMonkeyOptions,
ManipulatorOptimizer manipulatorOptimizer,
List>>> registeredArbitraryBuilders,
MonkeyManipulatorFactory monkeyManipulatorFactory
) {
this.fixtureMonkeyOptions = fixtureMonkeyOptions;
this.manipulatorOptimizer = manipulatorOptimizer;
this.monkeyContext = MonkeyContext.builder(fixtureMonkeyOptions).build();
this.monkeyManipulatorFactory = monkeyManipulatorFactory;
initializeRegisteredArbitraryBuilders(registeredArbitraryBuilders);
}
public static FixtureMonkeyBuilder builder() {
return new FixtureMonkeyBuilder();
}
public static FixtureMonkey create() {
return builder().build();
}
public ArbitraryBuilder giveMeBuilder(Class type) {
TypeReference typeReference = new TypeReference(type) {
};
return giveMeBuilder(typeReference);
}
public ArbitraryBuilder giveMeBuilder(TypeReference type) {
RootProperty rootProperty = new RootProperty(type.getAnnotatedType());
ArbitraryBuilderContext builderContext = monkeyContext.getRegisteredArbitraryBuilders().stream()
.filter(it -> it.match(rootProperty))
.map(MatcherOperator::getOperator)
.findAny()
.map(DefaultArbitraryBuilder.class::cast)
.map(DefaultArbitraryBuilder::getContext)
.orElse(ArbitraryBuilderContext.newBuilderContext(monkeyContext));
return new DefaultArbitraryBuilder<>(
rootProperty,
new ArbitraryResolver(
manipulatorOptimizer,
monkeyManipulatorFactory,
monkeyContext
),
monkeyManipulatorFactory,
builderContext.copy(),
monkeyContext,
fixtureMonkeyOptions.getInstantiatorProcessor()
);
}
public ArbitraryBuilder giveMeBuilder(T value) {
ArbitraryBuilderContext context = ArbitraryBuilderContext.newBuilderContext(monkeyContext);
ArbitraryManipulator arbitraryManipulator =
monkeyManipulatorFactory.newArbitraryManipulator("$", value);
context.addManipulator(arbitraryManipulator);
return new DefaultArbitraryBuilder<>(
new RootProperty(new LazyAnnotatedType<>(() -> value)),
new ArbitraryResolver(
manipulatorOptimizer,
monkeyManipulatorFactory,
monkeyContext
),
monkeyManipulatorFactory,
context,
monkeyContext,
fixtureMonkeyOptions.getInstantiatorProcessor()
);
}
public ExperimentalArbitraryBuilder giveMeExperimentalBuilder(Class type) {
return (ExperimentalArbitraryBuilder)giveMeBuilder(type);
}
public ExperimentalArbitraryBuilder giveMeExperimentalBuilder(TypeReference type) {
return (ExperimentalArbitraryBuilder)giveMeBuilder(type);
}
public JavaTypeArbitraryBuilder giveMeJavaBuilder(Class type) {
return new JavaTypeDefaultTypeArbitraryBuilder<>(this.giveMeBuilder(type));
}
public JavaTypeArbitraryBuilder giveMeJavaBuilder(TypeReference type) {
return new JavaTypeDefaultTypeArbitraryBuilder<>(this.giveMeBuilder(type));
}
public Stream giveMe(Class type) {
return Stream.generate(() -> this.giveMeBuilder(type).sample());
}
public Stream giveMe(TypeReference typeReference) {
return Stream.generate(() -> this.giveMeBuilder(typeReference).sample());
}
public List giveMe(Class type, int size) {
return this.giveMe(type).limit(size).collect(toList());
}
public List giveMe(TypeReference typeReference, int size) {
return this.giveMe(typeReference).limit(size).collect(toList());
}
public T giveMeOne(Class type) {
return this.giveMe(type, 1).get(0);
}
public T giveMeOne(TypeReference typeReference) {
return this.giveMe(typeReference, 1).get(0);
}
public Arbitrary giveMeArbitrary(Class type) {
return this.giveMeBuilder(type).build();
}
public Arbitrary giveMeArbitrary(TypeReference typeReference) {
return this.giveMeBuilder(typeReference).build();
}
private void initializeRegisteredArbitraryBuilders(
List>>> registeredArbitraryBuilders
) {
List extends MatcherOperator extends ObjectBuilder>>> generatedRegisteredArbitraryBuilder =
registeredArbitraryBuilders.stream()
.map(it -> new MatcherOperator<>(it.getMatcher(), (ObjectBuilder>)(it.getOperator().apply(this))))
.collect(toList());
for (int i = generatedRegisteredArbitraryBuilder.size() - 1; i >= 0; i--) {
monkeyContext.getRegisteredArbitraryBuilders().add(generatedRegisteredArbitraryBuilder.get(i));
}
}
}