All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.test4j.mock.processor.filer.MocksFiler Maven / Gradle / Ivy

package org.test4j.mock.processor.filer;

import com.squareup.javapoet.*;
import org.test4j.mock.faking.fluent.MocksApply;
import org.test4j.mock.processor.MockProcessor;
import org.test4j.mock.processor.filer.file.MockClassFiler;
import org.test4j.mock.processor.filer.file.MockTypeFiler;
import org.test4j.mock.processor.filer.file.MockUpFiler;

import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import java.util.*;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.function.Consumer;

import static org.test4j.mock.processor.MockProcessor.error;
import static org.test4j.mock.processor.filer.ClassNames.MockUp_Suffix;
import static org.test4j.mock.processor.filer.ClassNames.Mock_Package_WithDot;

public class MocksFiler {
    private static Set Has_Mocks = new ConcurrentSkipListSet<>();
    private ClassName fullName;
    private String suffix;
    private Map mocks = new HashMap<>();

    public MocksFiler(String fullName, String suffix, Set mocks) {
        this.fullName = ClassNames.getClassName(fullName);
        this.suffix = suffix;
        this.addToMockClass(mocks);
    }

    private void addToMockClass(Collection mocks) {
        for (String mock : mocks) {
            this.addMockFile(mock);
        }
    }

    private void addMockFile(String mock) {
        if (mock == null || mock.isEmpty()) {
            return;
        }
        ClassName mockClassName = ClassNames.getClassName(Mock_Package_WithDot + mock + MockUp_Suffix);
        this.mocks.put(mock, mockClassName);
    }

    public void writeFiler() {
        TypeSpec.Builder builder = TypeSpec.classBuilder(this.fullName.simpleName() + this.suffix)
            .addModifiers(Modifier.PUBLIC)
            .superclass(MocksApply.class);

        this.build(builder);
        builder.addField(this.m_mocksField(this.fullName.simpleName() + this.suffix));
        JavaFile.Builder javaBuilder = JavaFile.builder(this.fullName.packageName(), builder.build());
        MockProcessor.writeFiler(javaBuilder.build());
    }

    private void build(TypeSpec.Builder builder) {
        for (Map.Entry entry : this.mocks.entrySet()) {
            builder.addMethod(this.m_mockUp1(entry.getKey(), entry.getValue()));
            builder.addMethod(this.m_mockUp2(entry.getKey(), entry.getValue()));
            builder.addField(this.m_mockUpField(entry.getKey(), entry.getValue()));
        }
        while (!this.mocks.isEmpty()) {
            Iterator> it = this.mocks.entrySet().iterator();
            Map.Entry entry = it.next();
            it.remove();
            MockUpFiler mockUpFiler = this.generateMockUp(entry.getKey());
            if (mockUpFiler == null) {
                continue;
            }
            mockUpFiler.writeFiler();
            this.addMockFile(mockUpFiler.getSuperClass());
        }
    }

    private static final String Mock1_JavaDoc = "" +
        " mock {@link $T} 多个方法, 示例代码\n" +
        " 
\n" +
        " mocks.$L(fake->{\n" +
        "      fake.toMockMethod1.restReturn(\"返回值1\",\"返回值2\");\n" +
        "      fake.toMockMethod2.restReturn(\"返回值1\",\"返回值2\");\n" +
        " });\n" +
        " 
\n\n" + " @param faker {@link $LMockUp} 构造\n" + " @param targets 指定, 表示对特定$L实例进行mock;否则,表示对所有$L实例进行mock"; private static final String Mock2_JavaDoc = "" + " mock {@link $T} 单个方法, 示例代码\n" + "
\n" +
        " mocks.$L().toMockMethod1.restReturn(\"返回值1\",\"返回值2\");\n" +
        " 
\n\n" + " @param targets 指定, 表示对特定$L实例进行mock;否则,表示对所有$L实例进行mock"; private MethodSpec m_mockUp1(String toFaked, ClassName mockUp) { ClassName name = ClassNames.getClassName(toFaked); return MethodSpec.methodBuilder(name.simpleName()) .addModifiers(Modifier.PUBLIC, Modifier.FINAL) .addJavadoc(Mock1_JavaDoc, name, name.simpleName(), name.simpleName(), name.simpleName(), name.simpleName()) .addParameter(ParameterizedTypeName.get(ClassName.get(Consumer.class), mockUp), "faker") .addParameter(ArrayTypeName.of(Object.class), "targets") .varargs(true) .returns(TypeVariableName.get(this.fullName.simpleName() + this.suffix)) .addStatement("return super.apply(faker, new $T(targets))", mockUp) .build(); } private MethodSpec m_mockUp2(String toFaked, ClassName mockUp) { ClassName name = ClassNames.getClassName(toFaked); return MethodSpec.methodBuilder(name.simpleName()) .addModifiers(Modifier.PUBLIC, Modifier.FINAL) .addJavadoc(Mock2_JavaDoc, name, name.simpleName(), name.simpleName(), name.simpleName()) .addParameter(ArrayTypeName.of(Object.class), "targets") .varargs(true) .returns(mockUp) .addStatement("return new $T(targets)", mockUp) .build(); } private FieldSpec m_mockUpField(String toFaked, ClassName mockUp) { ClassName name = ClassNames.getClassName(toFaked); return FieldSpec.builder(mockUp, name.simpleName(), Modifier.FINAL, Modifier.PUBLIC) .addJavadoc("@see #$L(Object...), 无参模式 ", name.simpleName()) .initializer("$L()", name.simpleName()) .build(); } // /** // * 构造私有函数 // * // * @param mocksClass // * @return // */ // private MethodSpec m_privateConstructor() { // return MethodSpec.constructorBuilder() // .addModifiers(Modifier.PRIVATE) // .build(); // } /** * 构造public static final XyzMocks mocks = new XyzMocks() 单例变量 * * @param mocksClass * @return */ private FieldSpec m_mocksField(String mocksClass) { return FieldSpec.builder(ClassNames.getClassName(mocksClass), "mocks", Modifier.FINAL, Modifier.STATIC, Modifier.PUBLIC) .addJavadoc("$L全局变量, 方便引用", mocksClass) .initializer("new $L()", mocksClass) .build(); } private MockUpFiler generateMockUp(String className) { if (Has_Mocks.contains(className)) { return null; } Has_Mocks.add(className); try { return new MockClassFiler(Class.forName(className)); } catch (ClassNotFoundException e) { TypeElement typeElement = MockProcessor.getTypeElement(className); if (typeElement == null) { error("ClassNotFoundException", e); } else { return new MockTypeFiler(typeElement); } } return null; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy