Skip to content

Commit

Permalink
Merge pull request quarkusio#40024 from holly-cummins/annotation-proc…
Browse files Browse the repository at this point in the history
…essor-tests

Skeleton unit tests for annotation processor
  • Loading branch information
geoand authored Apr 17, 2024
2 parents 1e73223 + b9207f7 commit 7f99015
Show file tree
Hide file tree
Showing 10 changed files with 656 additions and 119 deletions.
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

0 comments on commit 7f99015

Please sign in to comment.