Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Skeleton unit tests for annotation processor #40024

Merged
merged 2 commits into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions core/processor/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,17 @@
<artifactId>jboss-logmanager</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.karuslabs</groupId>
<artifactId>elementary</artifactId>
<version>2.0.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-builder</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package io.quarkus.annotation.processor;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;

import javax.tools.JavaFileObject;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

import com.karuslabs.elementary.Results;
import com.karuslabs.elementary.junit.JavacExtension;
import com.karuslabs.elementary.junit.annotations.Classpath;
import com.karuslabs.elementary.junit.annotations.Processors;

import io.quarkus.annotation.processor.fs.CustomMemoryFileSystemProvider;

@ExtendWith(JavacExtension.class)
@Processors({ ExtensionAnnotationProcessor.class })
class ExtensionAnnotationProcessorTest {

@BeforeEach
void beforeEach() {
// This is of limited use, since the filesystem doesn't seem to directly generate files, in the current usage
CustomMemoryFileSystemProvider.reset();
}

@Test
@Classpath("org.acme.examples.ClassWithBuildStep")
void shouldProcessClassWithBuildStepWithoutErrors(Results results) throws IOException {
assertNoErrrors(results);
}

@Test
@Classpath("org.acme.examples.ClassWithBuildStep")
void shouldGenerateABscFile(Results results) throws IOException {
assertNoErrrors(results);
List<JavaFileObject> sources = results.sources;
JavaFileObject bscFile = sources.stream()
.filter(source -> source.getName()
.endsWith(".bsc"))
.findAny()
.orElse(null);
assertNotNull(bscFile);

String contents = removeLineBreaks(new String(bscFile
.openInputStream()
.readAllBytes(), StandardCharsets.UTF_8));
assertEquals("org.acme.examples.ClassWithBuildStep", contents);
}

private String removeLineBreaks(String s) {
return s.replace(System.getProperty("line.separator"), "")
.replace("\n", "");
}

@Test
@Classpath("org.acme.examples.ClassWithoutBuildStep")
void shouldProcessEmptyClassWithoutErrors(Results results) {
assertNoErrrors(results);
}

private static void assertNoErrrors(Results results) {
assertEquals(0, results.find()
.errors()
.count(),
"Errors were: " + results.find()
.errors()
.diagnostics());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
package io.quarkus.annotation.processor.fs;

import java.io.IOException;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.FileStore;
import java.nio.file.FileSystem;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.Paths;
import java.nio.file.WatchService;
import java.nio.file.attribute.UserPrincipalLookupService;
import java.nio.file.spi.FileSystemProvider;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class CustomMemoryFileSystem extends FileSystem {

private final Map<URI, ByteBuffer> fileContents = new HashMap<>();
private final CustomMemoryFileSystemProvider provider;

public CustomMemoryFileSystem(CustomMemoryFileSystemProvider provider) {
this.provider = provider;
}

@Override
public FileSystemProvider provider() {
return provider;
}

@Override
public void close() throws IOException {
// No resources to close
}

@Override
public boolean isOpen() {
return true; // Always open
}

@Override
public boolean isReadOnly() {
return false; // This filesystem is writable
}

@Override
public String getSeparator() {
return "/"; // Unix-style separator
}

@Override
public Iterable<Path> getRootDirectories() {
return Collections.singleton(Paths.get("/")); // Single root directory
}

@Override
public Iterable<FileStore> getFileStores() {
return Collections.emptyList(); // No file stores
}

@Override
public Set<String> supportedFileAttributeViews() {
return Collections.emptySet(); // No supported file attribute views
}

@Override
public Path getPath(String first, String... more) {
String path = first;
for (String segment : more) {
path += "/" + segment;
}
return Paths.get(path);
}

@Override
public PathMatcher getPathMatcher(String syntaxAndPattern) {
return null;
}

@Override
public UserPrincipalLookupService getUserPrincipalLookupService() {
return null;
}

@Override
public WatchService newWatchService() throws IOException {
return null;
}

public void addFile(URI uri, byte[] content) {
fileContents.put(uri, ByteBuffer.wrap(content));
}

static class CustomMemorySeekableByteChannel implements SeekableByteChannel {

private final ByteBuffer buffer;

CustomMemorySeekableByteChannel(ByteBuffer buffer) {
this.buffer = buffer;
}

@Override
public int read(ByteBuffer dst) throws IOException {
int remaining = buffer.remaining();
int count = Math.min(remaining, dst.remaining());
if (count > 0) {
ByteBuffer slice = buffer.slice();
slice.limit(count);
dst.put(slice);
buffer.position(buffer.position() + count);
}
return count;
}

@Override
public int write(ByteBuffer src) throws IOException {
int count = src.remaining();
buffer.put(src);
return count;
}

@Override
public long position() throws IOException {
return buffer.position();
}

@Override
public SeekableByteChannel position(long newPosition) throws IOException {
buffer.position((int) newPosition);
return this;
}

@Override
public long size() throws IOException {
return buffer.limit();
}

@Override
public SeekableByteChannel truncate(long size) throws IOException {
buffer.limit((int) size);
return this;
}

@Override
public boolean isOpen() {
return true; // Always open
}

@Override
public void close() throws IOException {
// No resources to close
}
}

}
Loading
Loading