-
Notifications
You must be signed in to change notification settings - Fork 177
added category resolution on compare #159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
1d15505
7b8b206
ac8a359
8cf1557
316602f
4f03e4a
b459cf7
b8c3267
1944cae
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package de.danielbechler.diff | ||
|
||
import de.danielbechler.diff.introspection.ObjectDiffProperty | ||
import de.danielbechler.diff.node.DiffNode | ||
import de.danielbechler.diff.node.Visit | ||
import de.danielbechler.diff.path.NodePath | ||
import spock.lang.Specification | ||
|
||
class CategoriesTestIT extends Specification{ | ||
|
||
def obj1 = new MyObject("aaa","aaa", "aaa") | ||
def obj2 = new MyObject("bbb","bbb", "bbb") | ||
def differ = ObjectDifferBuilder.startBuilding() | ||
.categories() | ||
.ofNode(NodePath.with("firstString")).toBe("cat1") | ||
.ofNode(NodePath.with("secondString")).toBe("cat1") | ||
.ofNode(NodePath.with("thirdString")).toBe("cat1") | ||
.and() | ||
.build() | ||
|
||
def categoriesVisitor = new DiffNode.Visitor() { | ||
|
||
Map<String, Set<String>> mapCategories = new HashMap<>(); | ||
|
||
@Override | ||
void node(DiffNode node, Visit visit) { | ||
|
||
mapCategories.put(node.getPropertyName(), node.getCategories()) | ||
} | ||
} | ||
|
||
def "should return all categories"(){ | ||
given: | ||
differ.compare(obj1,obj2).visitChildren(categoriesVisitor) | ||
expect : | ||
categoriesVisitor.mapCategories.get("firstString") == ["cat1"] as Set | ||
categoriesVisitor.mapCategories.get("secondString") == ["cat1"] as Set | ||
categoriesVisitor.mapCategories.get("thirdString") == ["cat1","catAnnotation"] as Set | ||
} | ||
|
||
class MyObject{ | ||
|
||
def firstString | ||
def secondString | ||
def thirdString | ||
|
||
MyObject(firstString,secondString,thirdString) { | ||
|
||
this.firstString = firstString | ||
this.secondString = secondString | ||
this.thirdString = thirdString | ||
} | ||
|
||
def getFirstString() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. By the way: these getters and setters are automatically generated by Groovy. The only ones you actually need are those for the thirdString due to the annotation. |
||
return firstString | ||
} | ||
|
||
void setFirstString(firstString) { | ||
this.firstString = firstString | ||
} | ||
|
||
def getSecondString() { | ||
return secondString | ||
} | ||
|
||
void setSecondString(secondString) { | ||
this.secondString = secondString | ||
} | ||
|
||
@ObjectDiffProperty(categories = ["catAnnotation"]) | ||
def getThirdString() { | ||
return thirdString | ||
} | ||
|
||
void setThirdString(thirdString) { | ||
this.thirdString = thirdString | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -160,7 +160,8 @@ public ObjectDiffer build() | |
circularReferenceService, | ||
inclusionService, | ||
returnableNodeService, | ||
introspectionService); | ||
introspectionService, | ||
inclusionService); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can just inject the |
||
differProvider.push(new BeanDiffer( | ||
differDispatcher, | ||
introspectionService, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,13 +24,14 @@ | |
|
||
import java.util.Collection; | ||
import java.util.LinkedList; | ||
import java.util.Set; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since this file doesn't contain any actual changes anymore, could you please bring it back into its original condition, so it doesn't show up in the diff? |
||
|
||
import static de.danielbechler.diff.inclusion.Inclusion.DEFAULT; | ||
import static de.danielbechler.diff.inclusion.Inclusion.EXCLUDED; | ||
import static de.danielbechler.diff.inclusion.Inclusion.INCLUDED; | ||
|
||
@SuppressWarnings("OverlyComplexAnonymousInnerClass") | ||
public class InclusionService implements InclusionConfigurer, IsIgnoredResolver | ||
public class InclusionService implements InclusionConfigurer, IsIgnoredResolver, CategoryResolver | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is no need to add the |
||
{ | ||
private final ObjectDifferBuilder rootConfiguration; | ||
private final CategoryResolver categoryResolver; | ||
|
@@ -279,4 +280,9 @@ public ObjectDifferBuilder and() | |
{ | ||
return rootConfiguration; | ||
} | ||
|
||
public Set<String> resolveCategories(DiffNode node) { | ||
|
||
return categoryResolver.resolveCategories(node); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -67,6 +67,7 @@ public class DiffNode | |
private Class<?> valueType; | ||
private TypeInfo valueTypeInfo; | ||
private IdentityStrategy childIdentityStrategy; | ||
private Set<String> categoriesFromConfig; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The name is a bit too specific for my taste. I would prefer There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, and maybe make it |
||
|
||
public void setChildIdentityStrategy(final IdentityStrategy identityStrategy) | ||
{ | ||
|
@@ -90,6 +91,7 @@ public DiffNode(final DiffNode parentNode, final Accessor accessor, final Class< | |
Assert.notNull(accessor, "accessor"); | ||
this.accessor = accessor; | ||
this.valueType = valueType; | ||
this.categoriesFromConfig = Collections.emptySet(); | ||
setParentNode(parentNode); | ||
} | ||
|
||
|
@@ -102,6 +104,7 @@ private DiffNode() | |
{ | ||
this.parentNode = ROOT; | ||
this.accessor = RootAccessor.getInstance(); | ||
this.categoriesFromConfig = Collections.emptySet(); | ||
} | ||
|
||
/** | ||
|
@@ -573,7 +576,10 @@ public boolean isExcluded() | |
return false; | ||
} | ||
|
||
// TODO These categories should also contain the ones configured via CategoryService | ||
/** | ||
* Returns a {@link java.util.Set} of {@link java.lang.String} | ||
* @return | ||
*/ | ||
public final Set<String> getCategories() | ||
{ | ||
final Set<String> categories = new TreeSet<String>(); | ||
|
@@ -589,6 +595,8 @@ public final Set<String> getCategories() | |
categories.addAll(categoriesFromAccessor); | ||
} | ||
} | ||
categories.addAll(categoriesFromConfig); | ||
|
||
return categories; | ||
} | ||
|
||
|
@@ -732,6 +740,16 @@ else if (childCount() > 1) | |
return sb.toString(); | ||
} | ||
|
||
private Set<String> getCategoriesFromConfig() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This getter is never used, so there is no need for it to exist. |
||
|
||
return categoriesFromConfig; | ||
} | ||
|
||
public void setCategoriesFromConfig(Set<String> categoriesFromConfig) { | ||
|
||
this.categoriesFromConfig = categoriesFromConfig; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unfortunately there is no way to avoid making this method part of the public API, so people will eventually start (ab)using it. That's one of the reasons why I'd prefer a different name for the field, as mentioned above. Although I wouldn't even expose the field via getter or setter at all. If we can't avoid leaking this detail to the outside, let's make it a cool feature: let's say we call the method Calling it I imagine something like this: public final void addCategories(final Collection<String> additionalCategories)
{
Assert.notNull(additionalCategories, "additionalCategories");
this.additionalCategories.addAll(additionalCategories);
} In this example I changed the parameter type from |
||
|
||
/** | ||
* @return Returns the path to the first node in the hierarchy that represents the same object instance as | ||
* this one. (Only if {@link #isCircular()} returns <code>true</code>. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's move this to a new package
categories
, since all the other major configuration sections got their own one as well.