Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/i-al-istannen/logging-proxy

An annotation processor that generates proxy classes which log method calls and then delegate to the original implementation
https://github.com/i-al-istannen/logging-proxy

Last synced: 1 day ago
JSON representation

An annotation processor that generates proxy classes which log method calls and then delegate to the original implementation

Awesome Lists containing this project

README

        


Logging Proxy


## What is this?
A small annotation processor (and example usage) that generates proxy classes
at compile-time using an annotation processor.

## Why create this?
This is useful if you load the actual implementation from somewhere else (e.g.
a student submission), but want a simple interface to program tests against.
If you just use your own implementation, the students will only receive the
assertion failures — but no history up to them.
This project automates generating a proxy at compile-time that traces all calls
made by the testing infrastructure and allows you to present the full call
history to students in any way you like.

## Use in your project
1. Add the jitpack repository
```xml


jitpack.io
https://jitpack.io


```
2. Add it as a depdendency
```xml

com.github.I-Al-Istannen
logging-proxy
6880313241395d6350518d0b2b15d5ee068b20e9

```
3. Configure your maven compiler plugin to use the processor
```xml

org.apache.maven.plugins
maven-compiler-plugin



com.github.I-Al-Istannen
logging-proxy
6880313241395d6350518d0b2b15d5ee068b20e9




```

## Example
Consider the following simple shim (or real implementation) for a student task.
```java
@GenerateTestProxy
public class Calculator {
@ProxyMethod
public int add(int a, int b) {
return a + b;
}

public void notLogged() {} // Calls are not logged. Maybe useful for setup methods.

@ProxyMethod
public static int addTwo(int a, int b) {
return a + b;
}
}
```



These annotations are enough to trigger generation of the following proxy class.

```java
package de.ialistannen.loggingproxy.example;
import de.ialistannen.loggingproxy.TestLogger;
class CalculatorProxy {
public int add(int a, int b) {
$testLogger$.onMethodCallStart("add", a, b);
int result = $inner$.add(a, b);
$testLogger$.onMethodReturn("add", result);
return result;
}

public int addStatic(int a, int b) {
$testLogger$.onMethodCallStart("addTwo", a, b);
int result = Calculator.addTwo(a, b);
$testLogger$.onMethodReturn("addTwo", result);
return result;
}

TestLogger $testLogger$;

public CalculatorProxy(TestLogger logger, Calculator inner) {
$testLogger$ = logger;
$inner$ = inner;
}

Calculator $inner$;
}
```

This can then easily be used to test the calculator and provide feedback, for
example using property based testing:
```java
@Property(tries = 5)
void test(@ForAll int a, @ForAll int b) {
CalculatorProxy proxy = new CalculatorProxy(new MyTestLogger(), new Calculator());
assertThat(proxy.add(a, b)).isEqualTo(a + b);
}

@Property(tries = 5)
void testStatic(@ForAll int a, @ForAll int b) {
CalculatorProxy proxy = new CalculatorProxy(new MyTestLogger(), new Calculator());
assertThat(proxy.addStatic(a, b)).isEqualTo(a + b);
}

private static class MyTestLogger implements TestLogger {
@Override
public void onMethodCallStart(String method, Object... arguments) {
String args = Arrays.stream(arguments)
.map(Objects::toString)
.collect(Collectors.joining(", ", "(", ")"));
System.out.println("---> " + method + args);
}

@Override
public void onMethodReturn(String method, Object returnValue) {
System.out.println("<--- " + returnValue);
}
}
```