Home / Class/ TestProject Class — spring-boot Architecture

TestProject Class — spring-boot Architecture

Architecture documentation for the TestProject class in TestProject.java from the spring-boot codebase.

Entity Profile

Relationship Graph

Source Code

configuration-metadata/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/TestProject.java lines 51–146

public class TestProject {

	private static final Class<?>[] ALWAYS_INCLUDE = { TestConfigurationProperties.class,
			TestNestedConfigurationProperty.class };

	private SourceFiles sources;

	public TestProject(Class<?>... classes) {
		this.sources = SourceFiles.none().and(sourceFilesOf(ALWAYS_INCLUDE)).and(sourceFilesOf(classes));
	}

	public ConfigurationMetadata compile() {
		return compile(null);
	}

	public ConfigurationMetadata compile(ConfigurationMetadata previousMetadata) {
		TestConfigurationMetadataAnnotationProcessor processor = new TestConfigurationMetadataAnnotationProcessor();
		TestCompiler compiler = TestCompiler.forSystem().withProcessors(processor);
		if (previousMetadata != null) {
			compiler = compiler.withResources(
					ResourceFile.of("META-INF/spring-configuration-metadata.json", asBytes(previousMetadata)));
		}
		AtomicReference<ConfigurationMetadata> configurationMetadata = new AtomicReference<>();
		compiler.compile(this.sources,
				(compiled) -> configurationMetadata.set(CompiledMetadataReader.getMetadata(compiled)));
		return configurationMetadata.get();
	}

	private byte[] asBytes(ConfigurationMetadata previousMetadata) {
		ByteArrayOutputStream output = new ByteArrayOutputStream();
		try {
			new JsonMarshaller().write(previousMetadata, output);
		}
		catch (IOException ex) {
			throw new UncheckedIOException(ex);
		}
		return output.toByteArray();
	}

	/**
	 * Add source code at the end of file, just before last '}'
	 * @param target the target
	 * @param snippetStream the snippet stream
	 * @throws Exception if the source cannot be added
	 */
	public void addSourceCode(Class<?> target, InputStream snippetStream) throws Exception {
		SourceFile sourceFile = SourceFile.forTestClass(target);
		String contents = sourceFile.getContent();
		int insertAt = contents.lastIndexOf('}');
		String additionalSource = FileCopyUtils.copyToString(new InputStreamReader(snippetStream));
		contents = contents.substring(0, insertAt) + additionalSource + contents.substring(insertAt);
		this.sources = this.sources.and(SourceFile.of(contents));
	}

	/**
	 * Delete source file for given class from project.
	 * @param type the class to delete
	 */
	public void delete(Class<?> type) {
		SourceFile[] newSources = this.sources.stream()
			.filter((sourceFile) -> !sourceFile.getPath().equals(SourceFile.forTestClass(type).getPath()))
			.toArray(SourceFile[]::new);
		this.sources = SourceFiles.of(newSources);
	}

	/**
	 * Restore source code of given class to its original contents.
	 * @param type the class to revert
	 */
	public void revert(Class<?> type) {
		Assert.isTrue(this.sources.stream().anyMatch((sourceFile) -> sourceFile.getClassName().equals(type.getName())),
				"Source file for type '" + type + "' does not exist");
		this.sources = this.sources.and(SourceFile.forTestClass(type));
	}

	/**
	 * Add source code of given class to this project.
	 * @param type the class to add
	 */
	public void add(Class<?> type) {
		Assert.isTrue(this.sources.stream().noneMatch((sourceFile) -> sourceFile.getClassName().equals(type.getName())),
				"Source file for type '" + type + "' already exists");
		this.sources = this.sources.and(SourceFile.forTestClass(type));
	}

	public void replaceText(Class<?> type, String find, String replace) {
		SourceFile sourceFile = SourceFile.forTestClass(type);
		String contents = sourceFile.getContent().replace(find, replace);
		this.sources = this.sources.and(SourceFile.of(contents));
	}

	private List<SourceFile> sourceFilesOf(Class<?>... types) {
		return Arrays.stream(types).map(SourceFile::forTestClass).toList();
	}

}

Domain

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free