Skip to content

Commit 0fb55b7

Browse files
committed
first draft generating code but with errors
known errors: - does not take type parameters into account which are defined next to SubjectT in the kotlin expectation function - inlining xyz(..).transform() calls does not always work because body of IrFunction is empty
1 parent c15a741 commit 0fb55b7

File tree

73 files changed

+1384
-55
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+1384
-55
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
plugins {
2+
id("build-logic.published-java-library")
3+
}
4+
5+
description = "A fluent expectation function API for java with a focus on code completion"
6+
7+
sourceSets {
8+
main {
9+
java {
10+
srcDir(project.layout.projectDirectory.dir("src/main/generated/java").asFile)
11+
}
12+
}
13+
}
14+
15+
dependencies {
16+
api(prefixedProject("logic"))
17+
18+
testImplementation(prefixedProject("specs"))
19+
testImplementation(libs.junit.jupiter)
20+
testRuntimeOnly(libs.junit.platform.launcher)
21+
}
22+
23+
24+
junitjacoco {
25+
additionalProjectSources.addAll(
26+
prefixedProject("translations-en_GB"),
27+
prefixedProject("logic"),
28+
prefixedProject("core"),
29+
)
30+
}
31+
32+
project.afterEvaluate {
33+
tasks.withType<Test>().configureEach {
34+
useJUnitPlatform {
35+
includeEngines = setOf("junit-jupiter")
36+
}
37+
}
38+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package ch.tutteli.atrium.api.fluent.java;
2+
3+
import ch.tutteli.atrium.creating.AssertionContainer;
4+
import ch.tutteli.atrium.creating.Expect;
5+
import ch.tutteli.atrium.logic.AnyKt;
6+
import ch.tutteli.atrium.logic.FeatureKt;
7+
import ch.tutteli.atrium.logic.LogicKt;
8+
import ch.tutteli.atrium.reporting.translating.Untranslatable;
9+
import kotlin.jvm.functions.Function1;
10+
11+
import java.util.function.Function;
12+
13+
public abstract class AbstractAnyExpect<SubjectT, SelfT extends AbstractAnyExpect<SubjectT, SelfT>>
14+
extends AbstractExpect<SubjectT, SelfT> {
15+
16+
public AbstractAnyExpect(Expect<SubjectT> expect) {
17+
super(expect);
18+
}
19+
20+
public SelfT toEqual(SubjectT expected) {
21+
AssertionContainer<SubjectT> container = LogicKt.get_logic(getCoreExpect());
22+
return switchCoreExpect(container.append(AnyKt.toBe(container, expected)));
23+
}
24+
25+
public <NewSubjectT> AnyExpect<NewSubjectT> feature(String description, Function<SubjectT, NewSubjectT> featureExtractor) {
26+
AssertionContainer<SubjectT> container = LogicKt.get_logic(getCoreExpect());
27+
var newCoreExpect = FeatureKt.<SubjectT, NewSubjectT>manualFeature(container, new Untranslatable(description), toKotlinFun(featureExtractor)).transform();
28+
return ExpectFactories.expectAny(newCoreExpect);
29+
}
30+
31+
public <NewSubjectT, NewExpectT extends AbstractExpect<NewSubjectT, NewExpectT>> SelfT feature(
32+
String description,
33+
Function<SubjectT, NewSubjectT> featureExtractor,
34+
ExpectFactory<NewSubjectT, NewExpectT> factory,
35+
ExpectationCreator<NewSubjectT, NewExpectT> creator
36+
) {
37+
AssertionContainer<SubjectT> container = LogicKt.get_logic(getCoreExpect());
38+
return switchCoreExpect(FeatureKt.<SubjectT, NewSubjectT>manualFeature(container, new Untranslatable(description), toKotlinFun(featureExtractor)).collectAndAppend(creator.toKotlin(factory)));
39+
}
40+
41+
private static <T, R> Function1<T, R> toKotlinFun(Function<T, R> f) {
42+
return f::apply;
43+
}
44+
45+
public <NewExpectT extends AbstractExpect<SubjectT, NewExpectT>> NewExpectT asInstanceOf(ExpectFactory<SubjectT, NewExpectT> factory) {
46+
return factory.create(getCoreExpect());
47+
}
48+
49+
50+
public SelfT toEqualNullIfNullGivenElse(ExpectationCreator<SubjectT, SelfT> assertionCreatorOrNull) {
51+
AssertionContainer<SubjectT> container = LogicKt.get_logic(getCoreExpect());
52+
return switchCoreExpect(container.append(AnyKt.toBeNullIfNullGivenElse(container, assertionCreatorOrNull.toKotlin(this::createSelf))));
53+
}
54+
}
55+
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package ch.tutteli.atrium.api.fluent.java;
2+
3+
import ch.tutteli.atrium.creating.AssertionContainer;
4+
import ch.tutteli.atrium.creating.Expect;
5+
import ch.tutteli.atrium.logic.Fun0Kt;
6+
import ch.tutteli.atrium.logic.LogicKt;
7+
import ch.tutteli.atrium.logic.UtilsKt;
8+
import ch.tutteli.atrium.logic.creating.transformers.SubjectChangerBuilder;
9+
import kotlin.Unit;
10+
import kotlin.jvm.JvmClassMappingKt;
11+
import kotlin.jvm.functions.Function0;
12+
13+
public abstract class AbstractBlockExpect<SubjectT extends Block, SelfT extends AbstractBlockExpect<SubjectT, SelfT>> extends AbstractAnyExpect<SubjectT, SelfT> {
14+
15+
public AbstractBlockExpect(Expect<SubjectT> expect) {
16+
super(expect);
17+
}
18+
19+
public <T extends Throwable> AnyExpect<T> toThrow(Class<T> expectedType) {
20+
return ExpectFactories.expectAny(toThrowInternal(expectedType).transform());
21+
}
22+
23+
public <T extends Throwable> AnyExpect<T> toThrow(Class<T> expectedType, ExpectationCreator<T, AnyExpect<T>> expectationCreator) {
24+
return ExpectFactories.expectAny(toThrowInternal(expectedType).transformAndAppend(expectationCreator.toKotlin(ExpectFactories::expectAny)));
25+
}
26+
27+
private <T extends Throwable> SubjectChangerBuilder.ExecutionStep<?, T> toThrowInternal(Class<T> expectedType) {
28+
AssertionContainer<Function0<Unit>> retypedContainer = getFunction0Container();
29+
return Fun0Kt.<T>toThrow(retypedContainer, JvmClassMappingKt.getKotlinClass(expectedType));
30+
}
31+
32+
public <T extends Throwable> AnyExpect<T> notToThrow(Class<T> c) {
33+
return null;
34+
}
35+
36+
private AssertionContainer<Function0<Unit>> getFunction0Container() {
37+
AssertionContainer<SubjectT> container = LogicKt.get_logic(getCoreExpect());
38+
Expect<Function0<Unit>> retypedCoreExpect = UtilsKt.getChangeSubject(container).unreported(subject -> () -> {
39+
subject.action();
40+
return Unit.INSTANCE;
41+
});
42+
return LogicKt.get_logic(retypedCoreExpect);
43+
}
44+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package ch.tutteli.atrium.api.fluent.java;
2+
3+
import ch.tutteli.atrium.creating.AssertionContainer;
4+
import ch.tutteli.atrium.creating.Expect;
5+
import ch.tutteli.atrium.logic.CharSequenceKt;
6+
import ch.tutteli.atrium.logic.ComparableKt;
7+
import ch.tutteli.atrium.logic.LogicKt;
8+
9+
public abstract class AbstractCharSequenceExpect<SubjectT extends CharSequence, SelfT extends AbstractCharSequenceExpect<SubjectT, SelfT>>
10+
extends AbstractAnyExpect<SubjectT, SelfT> {
11+
public AbstractCharSequenceExpect(Expect<SubjectT> expect) {
12+
super(expect);
13+
}
14+
15+
public SelfT toStartWith(CharSequence expectedStart) {
16+
AssertionContainer<SubjectT> container = LogicKt.get_logic(getCoreExpect());
17+
return switchCoreExpect(container.append(CharSequenceKt.startsWith(container, expectedStart)));
18+
}
19+
20+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package ch.tutteli.atrium.api.fluent.java;
2+
3+
import ch.tutteli.atrium.creating.AssertionContainer;
4+
import ch.tutteli.atrium.creating.Expect;
5+
import ch.tutteli.atrium.logic.ComparableKt;
6+
import ch.tutteli.atrium.logic.LogicKt;
7+
8+
public abstract class AbstractComparableExpect<SubjectT extends Comparable<SubjectT>, SelfT extends AbstractComparableExpect<SubjectT, SelfT>>
9+
extends AbstractAnyExpect<SubjectT, SelfT> {
10+
11+
public AbstractComparableExpect(Expect<SubjectT> expect) {
12+
super(expect);
13+
}
14+
15+
public SelfT toBeLessThan(SubjectT expected) {
16+
AssertionContainer<SubjectT> container = LogicKt.get_logic(getCoreExpect());
17+
return switchCoreExpect(container.append(ComparableKt.isLessThan(container, expected)));
18+
}
19+
20+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package ch.tutteli.atrium.api.fluent.java;
2+
3+
import ch.tutteli.atrium.creating.Expect;
4+
5+
public abstract class AbstractExpect<SubjectT, SelfT extends AbstractExpect<SubjectT, SelfT>> {
6+
7+
private Expect<SubjectT> coreExpect;
8+
9+
protected Expect<SubjectT> getCoreExpect(){
10+
return coreExpect;
11+
}
12+
13+
public AbstractExpect(Expect<SubjectT> expect) {
14+
this.coreExpect = expect;
15+
}
16+
17+
public abstract SelfT createSelf(Expect<SubjectT> coreExpect);
18+
19+
@SuppressWarnings("unchecked")
20+
final protected SelfT self() {
21+
return (SelfT) this;
22+
}
23+
24+
final protected SelfT switchCoreExpect(Expect<SubjectT> newExpect) {
25+
coreExpect = newExpect;
26+
return self();
27+
}
28+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package ch.tutteli.atrium.api.fluent.java;
2+
3+
import ch.tutteli.atrium.creating.Expect;
4+
5+
public abstract class AbstractStringExpect<SelfT extends AbstractStringExpect<SelfT>>
6+
extends AbstractCharSequenceExpect<String, SelfT> {
7+
public AbstractStringExpect(Expect<String> expect) {
8+
super(expect);
9+
}
10+
11+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package ch.tutteli.atrium.api.fluent.java;
2+
3+
import ch.tutteli.atrium.creating.Expect;
4+
5+
public class AnyExpect<SubjectT>
6+
extends AbstractAnyExpect<SubjectT, AnyExpect<SubjectT>> {
7+
8+
public AnyExpect(Expect<SubjectT> expect) {
9+
super(expect);
10+
}
11+
12+
@Override
13+
public AnyExpect<SubjectT> createSelf(Expect<SubjectT> expect) {
14+
return new AnyExpect<>(expect);
15+
}
16+
17+
static <SubjectT> AnyExpect<SubjectT> expect(Expect<SubjectT> coreExpect) {
18+
return new AnyExpect<>(coreExpect);
19+
}
20+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package ch.tutteli.atrium.api.fluent.java;
2+
3+
public interface Block {
4+
void action();
5+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package ch.tutteli.atrium.api.fluent.java;
2+
3+
import ch.tutteli.atrium.creating.Expect;
4+
5+
public class BlockExpect<SubjectT extends Block> extends AbstractBlockExpect<SubjectT, BlockExpect<SubjectT>> {
6+
7+
public BlockExpect(Expect<SubjectT> expect) {
8+
super(expect);
9+
}
10+
11+
@Override
12+
public BlockExpect<SubjectT> createSelf(Expect<SubjectT> coreExpect) {
13+
return new BlockExpect<>(coreExpect);
14+
}
15+
}

0 commit comments

Comments
 (0)