Skip to content
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

fix: use semantic instead of literal comparison in DefaultEqualityTester #1665

Merged
merged 2 commits into from May 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -1,18 +1,19 @@
package com.linkedin.metadata.dao.equality;

import com.linkedin.data.template.DataTemplate;
import javax.annotation.Nonnull;


/**
* A {@link EqualityTester} that always returns false.
*/
public class AlwaysFalseEqualityTester<T> implements EqualityTester<T> {
public class AlwaysFalseEqualityTester<T extends DataTemplate> implements EqualityTester<T> {

/**
* Creates a new instance of {@link AlwaysFalseEqualityTester}.
*/
public static <CLASS> AlwaysFalseEqualityTester<CLASS> newInstance() {
return new AlwaysFalseEqualityTester<CLASS>();
public static <CLASS extends DataTemplate> AlwaysFalseEqualityTester<CLASS> newInstance() {
return new AlwaysFalseEqualityTester<>();
}

@Override
Expand Down
@@ -1,21 +1,24 @@
package com.linkedin.metadata.dao.equality;

import com.linkedin.data.template.DataTemplate;
import com.linkedin.data.template.DataTemplateUtil;
import javax.annotation.Nonnull;

/**
* A {@link EqualityTester} that relies on the default implementation of {@link Object#equals(Object)}.
* A {@link EqualityTester} that uses {@link DataTemplateUtil#areEqual(DataTemplate, DataTemplate)} to check for
* semantic equality.
*/
public class DefaultEqualityTester<T> implements EqualityTester<T> {
public class DefaultEqualityTester<T extends DataTemplate> implements EqualityTester<T> {

/**
* Creates a new instance of {@link DefaultEqualityTester}.
*/
public static <CLASS> DefaultEqualityTester<CLASS> newInstance() {
return new DefaultEqualityTester<CLASS>();
public static <CLASS extends DataTemplate> DefaultEqualityTester<CLASS> newInstance() {
return new DefaultEqualityTester<>();
}

@Override
public boolean equals(@Nonnull T o1, @Nonnull T o2) {
return o1.equals(o2);
return DataTemplateUtil.areEqual(o1, o2);
mars-lan marked this conversation as resolved.
Show resolved Hide resolved
}
}
@@ -1,12 +1,13 @@
package com.linkedin.metadata.dao.equality;

import com.linkedin.data.template.DataTemplate;
import javax.annotation.Nonnull;


/**
* An interface for testing equality between two objects of the same type.
*/
public interface EqualityTester<T> {
public interface EqualityTester<T extends DataTemplate> {

boolean equals(@Nonnull T o1, @Nonnull T o2);
}
@@ -0,0 +1,29 @@
package com.linkedin.metadata.dao.equality;

import com.linkedin.metadata.dao.utils.RecordUtils;
import com.linkedin.testing.AspectBaz;
import java.io.IOException;
import org.testng.annotations.Test;

import static com.linkedin.metadata.utils.TestUtils.*;
import static com.linkedin.testing.TestUtils.*;
import static org.testng.Assert.*;


public class DefaultEqualityTesterTest {

@Test
public void testSemanticEquality() throws IOException, CloneNotSupportedException {
// "longField" is backed by Integer in DataMap when deserialized from JSON
AspectBaz fromJson = RecordUtils.toRecordTemplate(AspectBaz.class, loadJsonFromResource("baz.json"));
assertEquals(fromJson.data().get("longField").getClass(), Integer.class);

// Clone and change the value in DataMap to Long
AspectBaz cloned = fromJson.clone();
cloned.setLongField(1234L);
assertEquals(cloned.data().get("longField").getClass(), Long.class);

// The two should still be semantically equal
assertTrue(new DefaultEqualityTester().equals(fromJson, cloned));
}
}