Skip to content

Commit

Permalink
implemented junit integration features and fixed bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
maciejmikosik committed Aug 15, 2018
2 parents 0e7d8a7 + 8651bff commit 8af7764
Show file tree
Hide file tree
Showing 13 changed files with 619 additions and 222 deletions.
13 changes: 13 additions & 0 deletions main/doc/eclipse_templates.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Eclipse templates

Creates new class annotated with `@RunWith(QuackeryRunner.class)`. Defines single method annotated with `@Quackery` returning empty suite.

```
@${rw:newType(org.junit.runner.RunWith)}(${qr:newType(org.quackery.junit.QuackeryRunner)}.class)
public class ${primary_type_name} {
@${q:newType(org.quackery.Quackery)}
public static ${test:newType(org.quackery.Test)} test() {
return ${staticImport:importStatic(org.quackery.Suite.suite)}suite(${primary_type_name}.class.getName())${cursor};
}
}
```
46 changes: 25 additions & 21 deletions main/doc/tutorial.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
[built-in contracts](#built-in-contracts) |
[defining you own contracts](#defining-your-own-contracts) |
[running](#running) |
[integration](#integration)
[integration](#integration) |
[extra](#extra)

# built-in contracts
[collection contract](#collection-contract)
Expand Down Expand Up @@ -328,27 +329,30 @@ This means that if you already have junit class with tests.
}
}

You can add quackery tests inside.
You can add quackery tests inside and quackery runner will merge them into one hierarchy.

@RunWith(QuackeryRunner.class)
public class ArrayListTest {
@Quackery
public static org.quackery.Test test() {
return quacksLike(Collection.class)
.test(ArrayList.class);
}
```
@RunWith(QuackeryRunner.class)
public class ArrayListTest {
@Quackery
public static org.quackery.Test test() {
return quacksLike(Collection.class)
.test(ArrayList.class);
}
@Test
public void implements_random_access() {
assertTrue(RandomAccess.class.isAssignableFrom(ArrayList.class));
}
}
@Test
public void implements_random_access() {
assertTrue(RandomAccess.class.isAssignableFrom(ArrayList.class));
}
}
```

There are many problems that may occur during initialization. Method annotated with `@Quackery` could have incorrect signature, have some parameters or throw exception during invocation. All such problems are caught and represented as failing tests. This way they can be reported together with other tests. Default junit runner can detect problems too, missing default constructor for example. Those problems are also caught. However, junit validation happens only if there is at least one method annotated with `@org.junit.Test`. This mean that if you use quackery methods exclusively, you don't even need to provide default constructor.

`@org.junit.Ignore` does not work on methods annotated with `@Quackery`. However ignoring whole class will ignore also quackery tests.

Watch out for name collision between `org.quackery.Test` and `org.junit.Test`!

Quackery merges all test into one hierarchy. There are few things to keep in mind.
# extra

- Watch out for name collision between `org.quackery.Test` and `org.junit.Test`
- `@Ignore` does not work on methods annotated with `@Quackery`.
However it works if you use it at class level.
- You can use `@QuackeryRunner` even on class that only have junit tests.
This makes no difference except one detail.
It does not complain if you have no test methods in class, like default junit4 runner does.
- [Eclipse templates](eclipse_templates.md)
90 changes: 90 additions & 0 deletions main/java/org/quackery/junit/FixBugs.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package org.quackery.junit;

import static org.quackery.Suite.suite;

import java.util.ArrayList;
import java.util.List;

import org.quackery.Case;
import org.quackery.Suite;
import org.quackery.Test;
import org.quackery.run.Visitor;

public class FixBugs {
public static Test fixBugs(Test test) {
return fixNewlineBug(fixEmptySuiteBug(fixEmptyNameBug(test)));
}

public static List<Test> fixBugs(List<Test> tests) {
List<Test> fixed = new ArrayList<>();
for (Test test : tests) {
fixed.add(fixBugs(test));
}
return fixed;
}

private static Test fixNewlineBug(Test test) {
return new Visitor() {
protected Test visit(Suite visiting) {
Suite suite = (Suite) super.visit(visiting);
return suite(fixNewlineBug(suite.name))
.addAll(suite.tests);
}

protected Test visit(final Case visiting) {
return new Case(fixNewlineBug(visiting.name)) {
public void run() throws Throwable {
visiting.run();
}
};
}
}.visit(test);
}

private static String fixNewlineBug(String name) {
return name
.replace('\n', ' ')
.replace('\r', ' ');
}

private static Test fixEmptySuiteBug(Test test) {
return new Visitor() {
protected Test visit(Suite visiting) {
Suite suite = (Suite) super.visit(visiting);
return suite.tests.isEmpty()
? successfulCase(suite.name)
: suite;
}
}.visit(test);
}

private static Case successfulCase(String name) {
return new Case(name) {
public void run() {}
};
}

private static Test fixEmptyNameBug(Test test) {
return new Visitor() {
protected Test visit(Suite visiting) {
Suite suite = (Suite) super.visit(visiting);
return suite(fixEmptyNameBug(suite.name))
.addAll(suite.tests);
}

protected Test visit(final Case visiting) {
return new Case(fixEmptyNameBug(visiting.name)) {
public void run() throws Throwable {
visiting.run();
}
};
}
}.visit(test);
}

private static String fixEmptyNameBug(String name) {
return name.isEmpty()
? "[empty_name]"
: name;
}
}
25 changes: 0 additions & 25 deletions main/java/org/quackery/junit/FixEmptySuiteBug.java

This file was deleted.

33 changes: 0 additions & 33 deletions main/java/org/quackery/junit/FixNewlineBug.java

This file was deleted.

Loading

0 comments on commit 8af7764

Please sign in to comment.