1717package de.danielbechler.diff
1818
1919import de.danielbechler.diff.collection.CollectionItemElementSelector
20- import de.danielbechler.diff.visitor.PrintingVisitor
2120import spock.lang.Specification
2221
2322import static de.danielbechler.diff.PhoneBookSetup.Contact
@@ -27,12 +26,15 @@ import static de.danielbechler.diff.PhoneBookSetup.Contact
2726 */
2827class InclusionAndExclusionITCase extends Specification {
2928
29+ static final GEORGE_SELECTOR = new CollectionItemElementSelector (new Contact (id : ' george' ))
30+ static final KRAMER_SELECTOR = new CollectionItemElementSelector (new Contact (id : ' kramer' ))
31+
3032 def builder = ObjectDifferBuilder . startBuilding()
3133 def configurable = builder. configure()
3234 def working = PhoneBookSetup . getWorking()
3335 def base = PhoneBookSetup . getBase()
3436
35- def " Sanity check" () {
37+ def " sanity check" () {
3638 when :
3739 def node = ObjectDifferBuilder . buildDefault(). compare(working, base)
3840
@@ -44,12 +46,13 @@ class InclusionAndExclusionITCase extends Specification {
4446 node. getChild(' contacts' ). childCount() == 2
4547
4648 and : " only Georges name should have changed"
47- node. getChild(' contacts' ). getChild(new CollectionItemElementSelector ( new Contact ( id : ' george ' )) ). childCount() == 1
48- node. getChild(' contacts' ). getChild(new CollectionItemElementSelector ( new Contact ( id : ' george ' )) ). getChild(' name' ). changed
49+ node. getChild(' contacts' ). getChild(GEORGE_SELECTOR ). childCount() == 1
50+ node. getChild(' contacts' ). getChild(GEORGE_SELECTOR ). getChild(' name' ). changed
4951
5052 and : " only Kramers number should have changed"
51- node. getChild(' contacts' ). getChild(new CollectionItemElementSelector (new Contact (id : ' kramer' ))). childCount() == 1
52- node. getChild(' contacts' ). getChild(new CollectionItemElementSelector (new Contact (id : ' kramer' ))). getChild(' number' ). changed
53+
54+ node. getChild(' contacts' ). getChild(KRAMER_SELECTOR ). childCount() == 1
55+ node. getChild(' contacts' ). getChild(KRAMER_SELECTOR ). getChild(' number' ). changed
5356 }
5457
5558 def " Property with specific name excluded via configuration" () {
@@ -60,7 +63,7 @@ class InclusionAndExclusionITCase extends Specification {
6063 def node = builder. build(). compare(working, base)
6164
6265 then : " Georges name change should be ignored"
63- node. getChild(' contacts' ). getChild(new CollectionItemElementSelector ( new Contact ( id : ' george ' )) ) == null
66+ node. getChild(' contacts' ). getChild(GEORGE_SELECTOR ) == null
6467
6568 and : " The name change of the phone book should be ignored too"
6669 node. getChild(' name' ) == null
@@ -74,7 +77,7 @@ class InclusionAndExclusionITCase extends Specification {
7477 def node = builder. build(). compare(working, base)
7578
7679 then : " Kramers changed number should be ignored"
77- node. getChild(' contacts' ). getChild(new CollectionItemElementSelector ( new Contact ( id : ' kramer ' )) ) == null
80+ node. getChild(' contacts' ). getChild(KRAMER_SELECTOR ) == null
7881 }
7982
8083 def " Type excluded via configuration" () {
@@ -93,14 +96,14 @@ class InclusionAndExclusionITCase extends Specification {
9396 configurable. inclusion(). toExclude(). node(NodePath
9497 .startBuilding()
9598 .propertyName(' contacts' )
96- .collectionItem( new Contact ( id : ' george ' ) )
99+ .element( GEORGE_SELECTOR )
97100 .build())
98101
99102 when :
100103 def node = builder. build(). compare(working, base)
101104
102105 then :
103- node. getChild(' contacts' ). getChild(new CollectionItemElementSelector ( new Contact ( id : ' george ' )) ) == null
106+ node. getChild(' contacts' ). getChild(GEORGE_SELECTOR ) == null
104107 }
105108
106109 def " Property excluded via @ObjectDiffProperty annotation" () {
@@ -139,7 +142,15 @@ class InclusionAndExclusionITCase extends Specification {
139142 }
140143
141144 def " including an element via path includes all its children" () {
145+ given :
146+ configurable. inclusion(). toInclude(). node(NodePath . with(' contacts' ))
147+
148+ when :
149+ def node = builder. build(). compare(working, base)
142150
151+ then :
152+ node. getChild(' contacts' ). changed
153+ node. getChild(" contacts" ). childCount() == 2
143154 }
144155
145156 def " including an element via category" () {
@@ -172,25 +183,61 @@ class InclusionAndExclusionITCase extends Specification {
172183
173184 def " include all but some specific elements" () {
174185 given :
175- configurable. inclusion(). toInclude(). node(NodePath . startBuilding(). propertyName(' contacts' ). any() . build())
176- configurable. inclusion(). toExclude(). node(NodePath . startBuilding(). propertyName(' contacts' ). collectionItem( new Contact ( id : ' kramer ' ) ). build())
186+ configurable. inclusion(). toInclude(). node(NodePath . startBuilding(). propertyName(' contacts' ). build())
187+ configurable. inclusion(). toExclude(). node(NodePath . startBuilding(). propertyName(' contacts' ). element( KRAMER_SELECTOR ). build())
177188
178189 when :
179190 def node = builder. build(). compare(working, base)
180191
181- and :
182- node. visit(new PrintingVisitor (working, base))
183-
184192 then :
185193 node. getChild(' contacts' ). changed
186194 node. getChild(' contacts' ). childCount() == 1
187195 }
188196
189- def " including an element via category only includes properties if any of their parent elements is also somehow included" () {
197+ def " when an element is included by property name, all its children will be implicitly included" () {
198+ given :
199+ configurable. inclusion(). toInclude(). node(NodePath . startBuilding(). propertyName(' contacts' ). build())
200+
201+ when :
202+ def node = builder. build(). compare(working, base)
203+
204+ then :
205+ node. childCount() == 1
206+ node. getChild(' contacts' ). childCount() == 2
207+ node. getChild(' contacts' ). getChild(GEORGE_SELECTOR ). changed
208+ node. getChild(' contacts' ). getChild(KRAMER_SELECTOR ). changed
209+ }
210+
211+ def " when an element is included by category, all its children will be implicitly included" () {
212+ given :
213+ configurable. categories(). ofNode(NodePath . startBuilding(). propertyName(' contacts' ). build()). toBe(' identifier' )
214+ configurable. inclusion(). toInclude(). categories(' identifier' )
215+
216+ when :
217+ def node = builder. build(). compare(working, base)
218+
219+ then :
220+ node. childCount() == 1
221+ node. getChild(' contacts' ). changed
222+ }
223+
224+ def " when a child of an explicitly excluded element is included it should be excluded as well" () {
225+ given :
226+ configurable. inclusion(). toExclude(). node(NodePath . startBuilding(). propertyName(' contacts' ). build())
227+ configurable. inclusion(). toInclude(). node(NodePath . startBuilding(). propertyName(' contacts' ). element(GEORGE_SELECTOR ). build())
228+
229+ when :
230+ def node = builder. build(). compare(working, base)
231+
232+ then :
233+ node. getChild(' contacts' ) == null
234+ }
235+
236+ def " including a category includes matching properties only if they can be reached due to other inclusion rules" () {
190237 def includedCategory = " representation"
191238 def nodePathToKramer = NodePath . startBuilding()
192239 .propertyName(" contacts" )
193- .collectionItem( new Contact ( id : " kramer " ) )
240+ .element( KRAMER_SELECTOR )
194241 .build()
195242
196243 given :
0 commit comments