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

Fixed TODO to improve unordered string comparision #186

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

kavvya97
Copy link

Setup

  • Java version: 11.0.20.1
  • Maven version: Apache Maven 3.6.3

Description

This PR addresses the following TODO in the test utility function:

https://github.com/kavvya97/NonDex/blob/8843b436802af4a0850f63d6ae0f231164dafe78/nondex-test/src/test/java/edu/illinois/nondex/core/AbstractCollectionTest.java#L63

The function assertEqualstUnordered checks whether the contents of two data structures are equal without considering the order of the elements. Currently, it converts the content of both structures into string form and checks if the strings have the same length. If they do, it tokenizes one of them by splitting on commas to obtain multiple key=value elements. Then, it checks if each element is present in the other string as a substring.

https://github.com/kavvya97/NonDex/blob/8843b436802af4a0850f63d6ae0f231164dafe78/nondex-test/src/test/java/edu/illinois/nondex/core/AbstractCollectionTest.java#L66

However, this approach doesn't account for duplicates or substrings in the data structures. For example, consider the two strings:
"{0=0, 0=0, 1=1, 2=2}" and "{0=0, 1=1, 2=2, 1=1}". These two strings should not be considered equal, but the current test considers them equal.

Fix

Both strings are tokenized in the same manner as described above. The tokenized strings are then sorted and checked for equality. This approach will detect cases where duplicates differ between the two strings.

Verification

  • The fix did not introduce any regressions in existing tests that use this utility.
  • An additional test was implemented to handle corner cases, such as the example mentioned above. The existing implementation of assertEqualstUnordered fails this test.

Copy link
Contributor

@darko-marinov darko-marinov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this method used?

@@ -148,6 +148,17 @@ public void testEntrySet() {
"{0=0, 1=1, 2=2, 3=3, 4=4, 5=5, 6=6, 7=7, 8=8, 9=9}", entrySet.toString());
}

@Test
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use @Test(expected=....) to simplify the test when it should pass when an exception is thrown.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will incorporate these changes

Arrays.sort(actualTokenized);
Arrays.sort(expectedTokenized);
if (Arrays.equals(actualTokenized, expectedTokenized)) {
Assert.assertTrue(msg + ": " + expectedTokenized + "=/= " + actualTokenized, true);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assertTrue(message, true) can never fail. What is the goal of this assert?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems you want to use assertArraysEquals.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure. we will incorportate this


protected void assertEqualstUnordered(String msg, String expected, String actual) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is assertEqualsUnordered used?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The class HashMapTest utilizes this function in the following test method
smokeTest
testKeySet
testValues

@kavvya97 kavvya97 force-pushed the nondex_todo_fixAssertEqualsUnordered branch from d01c6b6 to c1f2556 Compare November 2, 2023 02:15
Copy link
Contributor

@darko-marinov darko-marinov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The assertions look much better now. Let's clean the names.

@@ -148,6 +148,12 @@ public void testEntrySet() {
"{0=0, 1=1, 2=2, 3=3, 4=4, 5=5, 6=6, 7=7, 8=8, 9=9}", entrySet.toString());
}

@Test(expected = AssertionError.class)
public void testAssertEqualsUnorderedFailsWithDuplicates() {
this.assertEqualstUnordered("the strings are not a permutation of each other",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rename to assertEqualsUnordered (without t).


protected void assertEqualstUnordered(String msg, String expected, String actual) {
String trimmed = expected.substring(1, expected.length() - 1);
String[] actualTokenized = this.formatString(actual);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is formatString the best name? The method seems to be splitting a collection into elements. Even the input is not an arbitrary msg.

@kavvya97 kavvya97 force-pushed the nondex_todo_fixAssertEqualsUnordered branch from c1f2556 to b17b73c Compare November 3, 2023 01:01
Assert.assertEquals(msg + ": " + expected + " =/= " + actual, expected.length(), actual.length());
String trimmed = expected.substring(1, expected.length() - 1);
private String[] trimAndSplitStrings(String msg) {
String trimmed = msg.substring(1, msg.length() - 1);
String[] elems = trimmed.split(",");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can it split(", ") and then not even require the loop for trim()?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes that should work. Will update the PR

@@ -46,7 +48,7 @@ protected void assertParameterized(T ds, Object derived, String str) {
case FULL:
String tempStr = derived.toString();
Assert.assertNotEquals("FULL is improperly running", str, tempStr);
this.assertEqualstUnordered("Does not match permutation", str, tempStr);
this.assertEqualsUnordered("Does not match permutation", str, tempStr);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any idea why they ever called it Equalst? Was it a misspelling or some joke about EqualsString? Does the Git log show anything useful?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello Professor, I checked the git blame and from that I can infer that it was initially called as such. this was the first time when the function was commited/created
d4f6e03#diff-b6d9573a5585dde09208a701b942a04b7e8017e4916381997baa33cf6d32edabR38

@kavvya97 kavvya97 force-pushed the nondex_todo_fixAssertEqualsUnordered branch from b17b73c to f1d52fd Compare November 6, 2023 04:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants