Skip to content

Commit

Permalink
Issue #331 - Add test for superclass field ignore
Browse files Browse the repository at this point in the history
  • Loading branch information
boretti committed May 31, 2020
1 parent 8ec638e commit 6de1108
Show file tree
Hide file tree
Showing 5 changed files with 268 additions and 2 deletions.
@@ -0,0 +1,96 @@
/**
* Powerunit - A JDK1.8 test framework
* Copyright (C) 2014 Mathieu Boretti.
*
* This file is part of Powerunit
*
* Powerunit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Powerunit is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Powerunit. If not, see <http://www.gnu.org/licenses/>.
*/
package ch.powerunit.extensions.matchers.multi.children;

import ch.powerunit.TestDelegate;
import ch.powerunit.TestSuite;
import ch.powerunit.extensions.matchers.multi.parentold.Pojo1Matchers;
import ch.powerunit.matchers.MatcherTester;
import static ch.powerunit.matchers.MatcherTester.matcher;
import static ch.powerunit.matchers.MatcherTester.value;

public class Pojo24MatcherTest implements TestSuite {

//@formatter:off
@TestDelegate
public final MatcherTester<?> tester = testerOfMatcher(Pojo24Matchers.Pojo24MatcherImpl.class)
.with(
matcher((Pojo24Matchers.Pojo24MatcherImpl) Pojo24Matchers.pojo24With().msg2ContainsString("12"))
.describedAs("an instance of ch.powerunit.extensions.matchers.multi.children.Pojo24 with\n[parent ANYTHING]\n[msg2 a string containing \"12\"]\n")
.nullRejected("was null")
.accepting(
new Pojo24("12"),
new Pojo24("121"))
.rejecting(
value("").withMessage("was \"\""),
value(new Pojo24()).withMessage("[msg2 was null]\n"),
value(new Pojo24("11")).withMessage("[msg2 was \"11\"]\n")),
matcher((Pojo24Matchers.Pojo24MatcherImpl) Pojo24Matchers.pojo24With(Pojo1Matchers.pojo1With().msg1("x")).msg2ContainsString("12"))
.describedAs("an instance of ch.powerunit.extensions.matchers.multi.children.Pojo24 with\n[parent an instance of ch.powerunit.extensions.matchers.multi.parentold.Pojo1 with\n[msg1 is \"x\"]\n]\n[msg2 a string containing \"12\"]\n")
.nullRejected("was null")
.accepting(
new Pojo24("x","12"),
new Pojo24("x","121"))
.rejecting(
value("").withMessage("was \"\""),
value(new Pojo24()).withMessage("[parent [msg1 was null]\n]\n[msg2 was null]\n"),
value(new Pojo24("11")).withMessage("[parent [msg1 was null]\n]\n[msg2 was \"11\"]\n"),
value(new Pojo24("z","11")).withMessage("[parent [msg1 was \"z\"]\n]\n[msg2 was \"11\"]\n")),
matcher((Pojo24Matchers.Pojo24MatcherImpl) Pojo24Matchers.pojo24WithSameValue(new Pojo24("x")))
.describedAs("an instance of ch.powerunit.extensions.matchers.multi.children.Pojo24 with\n[parent an instance of ch.powerunit.extensions.matchers.multi.parentold.Pojo1 with\n[msg1 is null]\n]\n[msg2 is \"x\"]\n")
.nullRejected("was null")
.accepting(
new Pojo24("x"))
.rejecting(
value("").withMessage("was \"\""),
value(new Pojo24()).withMessage("[msg2 was null]\n"),
value(new Pojo24("11")).withMessage("[msg2 was \"11\"]\n")),
matcher((Pojo24Matchers.Pojo24MatcherImpl) Pojo24Matchers.pojo24WithSameValue(new Pojo24("y","x")))
.describedAs("an instance of ch.powerunit.extensions.matchers.multi.children.Pojo24 with\n[parent an instance of ch.powerunit.extensions.matchers.multi.parentold.Pojo1 with\n[msg1 is \"y\"]\n]\n[msg2 is \"x\"]\n")
.nullRejected("was null")
.accepting(
new Pojo24("y","x"))
.rejecting(
value("").withMessage("was \"\""),
value(new Pojo24()).withMessage("[parent [msg1 was null]\n]\n[msg2 was null]\n"),
value(new Pojo24("11")).withMessage("[parent [msg1 was null]\n]\n[msg2 was \"11\"]\n"),
value(new Pojo24("z","x")).withMessage("[parent [msg1 was \"z\"]\n]\n")),
matcher((Pojo24Matchers.Pojo24MatcherImpl) Pojo24Matchers.pojo24WithSameValue(new Pojo24("y","x"),"msg2"))
.describedAs("an instance of ch.powerunit.extensions.matchers.multi.children.Pojo24 with\n[parent an instance of ch.powerunit.extensions.matchers.multi.parentold.Pojo1 with\n[msg1 is \"y\"]\n]\n[msg2 ANYTHING]\n")
.nullRejected("was null")
.accepting(
new Pojo24("y","x"),
new Pojo24("y","x2"))
.rejecting(
value("").withMessage("was \"\""),
value(new Pojo24()).withMessage("[parent [msg1 was null]\n]\n"),
value(new Pojo24("11")).withMessage("[parent [msg1 was null]\n]\n"),
value(new Pojo24("z","x")).withMessage("[parent [msg1 was \"z\"]\n]\n")),
matcher((Pojo24Matchers.Pojo24MatcherImpl) Pojo24Matchers.pojo24WithSameValue(new Pojo24("y","x"),"msg1"))
.describedAs("an instance of ch.powerunit.extensions.matchers.multi.children.Pojo24 with\n[parent an instance of ch.powerunit.extensions.matchers.multi.parentold.Pojo1 with\n[msg1 is \"y\"]\n]\n[msg2 is \"x\"]\n")
.nullRejected("was null")
.accepting(
new Pojo24("y","x"))
.rejecting(
value("").withMessage("was \"\""),
value(new Pojo24()).withMessage("[parent [msg1 was null]\n]\n[msg2 was null]\n"),
value(new Pojo24("11")).withMessage("[parent [msg1 was null]\n]\n[msg2 was \"11\"]\n")));
//@formatter:on
}
Expand Up @@ -71,6 +71,27 @@ public class Pojo4MatcherTest implements TestSuite {
value("").withMessage("was \"\""),
value(new Pojo4()).withMessage("[parent [msg1 was null]\n]\n[msg2 was null]\n"),
value(new Pojo4("11")).withMessage("[parent [msg1 was null]\n]\n[msg2 was \"11\"]\n"),
value(new Pojo4("z","x")).withMessage("[parent [msg1 was \"z\"]\n]\n")));
value(new Pojo4("z","x")).withMessage("[parent [msg1 was \"z\"]\n]\n")),
matcher((Pojo4Matchers.Pojo4MatcherImpl) Pojo4Matchers.pojo4WithSameValue(new Pojo4("y","x"),"msg2"))
.describedAs("an instance of ch.powerunit.extensions.matchers.multi.children.Pojo4 with\n[parent an instance of ch.powerunit.extensions.matchers.multi.parent.Pojo1 with\n[msg1 is \"y\"]\n]\n[msg2 ANYTHING]\n")
.nullRejected("was null")
.accepting(
new Pojo4("y","x"),
new Pojo4("y","x2"))
.rejecting(
value("").withMessage("was \"\""),
value(new Pojo4()).withMessage("[parent [msg1 was null]\n]\n"),
value(new Pojo4("11")).withMessage("[parent [msg1 was null]\n]\n"),
value(new Pojo4("z","x")).withMessage("[parent [msg1 was \"z\"]\n]\n")),
matcher((Pojo4Matchers.Pojo4MatcherImpl) Pojo4Matchers.pojo4WithSameValue(new Pojo4("y","x"),"msg1"))
.describedAs("an instance of ch.powerunit.extensions.matchers.multi.children.Pojo4 with\n[parent an instance of ch.powerunit.extensions.matchers.multi.parent.Pojo1 with\n[msg1 ANYTHING]\n]\n[msg2 is \"x\"]\n")
.nullRejected("was null")
.accepting(
new Pojo4("y","x"),
new Pojo4("y2","x"))
.rejecting(
value("").withMessage("was \"\""),
value(new Pojo4()).withMessage("[msg2 was null]\n"),
value(new Pojo4("11")).withMessage("[msg2 was \"11\"]\n")));
//@formatter:on
}
@@ -0,0 +1,96 @@
/**
* Powerunit - A JDK1.8 test framework
* Copyright (C) 2014 Mathieu Boretti.
*
* This file is part of Powerunit
*
* Powerunit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Powerunit is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Powerunit. If not, see <http://www.gnu.org/licenses/>.
*/
package ch.powerunit.extensions.matchers.multi.children;

import ch.powerunit.TestDelegate;
import ch.powerunit.TestSuite;
import ch.powerunit.extensions.matchers.multi.parentold.Pojo1Matchers;
import ch.powerunit.matchers.MatcherTester;
import static ch.powerunit.matchers.MatcherTester.matcher;
import static ch.powerunit.matchers.MatcherTester.value;

public class Pojo24MatcherTest implements TestSuite {

//@formatter:off
@TestDelegate
public final MatcherTester<?> tester = testerOfMatcher(Pojo24Matchers.Pojo24MatcherImpl.class)
.with(
matcher((Pojo24Matchers.Pojo24MatcherImpl) Pojo24Matchers.pojo24With().msg2ContainsString("12"))
.describedAs("an instance of ch.powerunit.extensions.matchers.multi.children.Pojo24 with\n[parent ANYTHING]\n[msg2 a string containing \"12\"]\n")
.nullRejected("was null")
.accepting(
new Pojo24("12"),
new Pojo24("121"))
.rejecting(
value("").withMessage("was \"\""),
value(new Pojo24()).withMessage("[msg2 was null]\n"),
value(new Pojo24("11")).withMessage("[msg2 was \"11\"]\n")),
matcher((Pojo24Matchers.Pojo24MatcherImpl) Pojo24Matchers.pojo24With(Pojo1Matchers.pojo1With().msg1("x")).msg2ContainsString("12"))
.describedAs("an instance of ch.powerunit.extensions.matchers.multi.children.Pojo24 with\n[parent an instance of ch.powerunit.extensions.matchers.multi.parentold.Pojo1 with\n[msg1 is \"x\"]\n]\n[msg2 a string containing \"12\"]\n")
.nullRejected("was null")
.accepting(
new Pojo24("x","12"),
new Pojo24("x","121"))
.rejecting(
value("").withMessage("was \"\""),
value(new Pojo24()).withMessage("[parent [msg1 was null]\n]\n[msg2 was null]\n"),
value(new Pojo24("11")).withMessage("[parent [msg1 was null]\n]\n[msg2 was \"11\"]\n"),
value(new Pojo24("z","11")).withMessage("[parent [msg1 was \"z\"]\n]\n[msg2 was \"11\"]\n")),
matcher((Pojo24Matchers.Pojo24MatcherImpl) Pojo24Matchers.pojo24WithSameValue(new Pojo24("x")))
.describedAs("an instance of ch.powerunit.extensions.matchers.multi.children.Pojo24 with\n[parent an instance of ch.powerunit.extensions.matchers.multi.parentold.Pojo1 with\n[msg1 is null]\n]\n[msg2 is \"x\"]\n")
.nullRejected("was null")
.accepting(
new Pojo24("x"))
.rejecting(
value("").withMessage("was \"\""),
value(new Pojo24()).withMessage("[msg2 was null]\n"),
value(new Pojo24("11")).withMessage("[msg2 was \"11\"]\n")),
matcher((Pojo24Matchers.Pojo24MatcherImpl) Pojo24Matchers.pojo24WithSameValue(new Pojo24("y","x")))
.describedAs("an instance of ch.powerunit.extensions.matchers.multi.children.Pojo24 with\n[parent an instance of ch.powerunit.extensions.matchers.multi.parentold.Pojo1 with\n[msg1 is \"y\"]\n]\n[msg2 is \"x\"]\n")
.nullRejected("was null")
.accepting(
new Pojo24("y","x"))
.rejecting(
value("").withMessage("was \"\""),
value(new Pojo24()).withMessage("[parent [msg1 was null]\n]\n[msg2 was null]\n"),
value(new Pojo24("11")).withMessage("[parent [msg1 was null]\n]\n[msg2 was \"11\"]\n"),
value(new Pojo24("z","x")).withMessage("[parent [msg1 was \"z\"]\n]\n")),
matcher((Pojo24Matchers.Pojo24MatcherImpl) Pojo24Matchers.pojo24WithSameValue(new Pojo24("y","x"),"msg2"))
.describedAs("an instance of ch.powerunit.extensions.matchers.multi.children.Pojo24 with\n[parent an instance of ch.powerunit.extensions.matchers.multi.parentold.Pojo1 with\n[msg1 is \"y\"]\n]\n[msg2 ANYTHING]\n")
.nullRejected("was null")
.accepting(
new Pojo24("y","x"),
new Pojo24("y","x2"))
.rejecting(
value("").withMessage("was \"\""),
value(new Pojo24()).withMessage("[parent [msg1 was null]\n]\n"),
value(new Pojo24("11")).withMessage("[parent [msg1 was null]\n]\n"),
value(new Pojo24("z","x")).withMessage("[parent [msg1 was \"z\"]\n]\n")),
matcher((Pojo24Matchers.Pojo24MatcherImpl) Pojo24Matchers.pojo24WithSameValue(new Pojo24("y","x"),"msg1"))
.describedAs("an instance of ch.powerunit.extensions.matchers.multi.children.Pojo24 with\n[parent an instance of ch.powerunit.extensions.matchers.multi.parentold.Pojo1 with\n[msg1 is \"y\"]\n]\n[msg2 is \"x\"]\n")
.nullRejected("was null")
.accepting(
new Pojo24("y","x"))
.rejecting(
value("").withMessage("was \"\""),
value(new Pojo24()).withMessage("[parent [msg1 was null]\n]\n[msg2 was null]\n"),
value(new Pojo24("11")).withMessage("[parent [msg1 was null]\n]\n[msg2 was \"11\"]\n")));
//@formatter:on
}
Expand Up @@ -71,6 +71,27 @@ public class Pojo4MatcherTest implements TestSuite {
value("").withMessage("was \"\""),
value(new Pojo4()).withMessage("[parent [msg1 was null]\n]\n[msg2 was null]\n"),
value(new Pojo4("11")).withMessage("[parent [msg1 was null]\n]\n[msg2 was \"11\"]\n"),
value(new Pojo4("z","x")).withMessage("[parent [msg1 was \"z\"]\n]\n")));
value(new Pojo4("z","x")).withMessage("[parent [msg1 was \"z\"]\n]\n")),
matcher((Pojo4Matchers.Pojo4MatcherImpl) Pojo4Matchers.pojo4WithSameValue(new Pojo4("y","x"),"msg2"))
.describedAs("an instance of ch.powerunit.extensions.matchers.multi.children.Pojo4 with\n[parent an instance of ch.powerunit.extensions.matchers.multi.parent.Pojo1 with\n[msg1 is \"y\"]\n]\n[msg2 ANYTHING]\n")
.nullRejected("was null")
.accepting(
new Pojo4("y","x"),
new Pojo4("y","x2"))
.rejecting(
value("").withMessage("was \"\""),
value(new Pojo4()).withMessage("[parent [msg1 was null]\n]\n"),
value(new Pojo4("11")).withMessage("[parent [msg1 was null]\n]\n"),
value(new Pojo4("z","x")).withMessage("[parent [msg1 was \"z\"]\n]\n")),
matcher((Pojo4Matchers.Pojo4MatcherImpl) Pojo4Matchers.pojo4WithSameValue(new Pojo4("y","x"),"msg1"))
.describedAs("an instance of ch.powerunit.extensions.matchers.multi.children.Pojo4 with\n[parent an instance of ch.powerunit.extensions.matchers.multi.parent.Pojo1 with\n[msg1 ANYTHING]\n]\n[msg2 is \"x\"]\n")
.nullRejected("was null")
.accepting(
new Pojo4("y","x"),
new Pojo4("y2","x"))
.rejecting(
value("").withMessage("was \"\""),
value(new Pojo4()).withMessage("[msg2 was null]\n"),
value(new Pojo4("11")).withMessage("[msg2 was \"11\"]\n")));
//@formatter:on
}
32 changes: 32 additions & 0 deletions src/site/apt/link.apt
@@ -1,5 +1,7 @@
Detection of Matcher for Class

* General concepts

<Since version 0.2.0, the detection of link between classes has been enhanced.>

Conceptually, for every fields or parent classes, the annotation processor will try to find a Matcher to compare the values. This is done by detecting the relation
Expand Down Expand Up @@ -48,3 +50,33 @@ Detection of Matcher for Class

* The method <<<pojo4WithSameValue()>>> start a DSL to compare for same value. The <<<pojo6WithSameValue()>>> from <<<Pojo1Matchers>>> will be used for the control
of <<<field1>>>.


[]

[]

* Limitations

** Circular references

It is possible to create classes that may produce <<<StackOverflowError>>> for the <<<hasSameValue>>> matcher. This is the case with bidirectional class references or
as a more generic case, circular references. It is almost impossible to detect these case at compile time ; For example, event if a class <<<A>>> has a field of class
<<<B>>> and class <<<B>>> a field of class <<<A>>>, it is not possible to assume we have a bidirectional referencing (the issue is only when an instance of <<<A>>>
references a specific instance of <<<B>>> and this instance of <<<B>>> references the previous instance of <<<A>>>.

*** Handling this case with version 0.2.0

In version 0.2.0, there are two different ways to manage these link :

* At compile time, based on the structure on the link, it is possible to annotated one of the referencing fields with <<<@IgnoreInMatcher>>>. The field will be
ignored which will break the circular reference.
* At runtime time, modify manually (using the DSL), the returned matcher, to break the cycle.

*** Handling this case with version latter 0.3.0

Since version 0.3.0, an additional <<<hasSameValue>>> methods is available to specify fields (based on field name) to be ignored. The two previous options are still
available, but it is also possible to use this ignore parameter. It is possible to chain the ignore by using a syntax like <<<fieldName.fieldNameChildren>>>.

<In case one of the referenced fields or the super class use an old version of the generated matchers and doesn't support the ignore feature, this feature is also
not available on fields of the referenced fields or on fields of the super class.>

0 comments on commit 6de1108

Please sign in to comment.