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

Add uniqueness validation for TableView #5170

Merged
merged 3 commits into from
Dec 11, 2024
Merged

Conversation

minhtuev
Copy link
Contributor

@minhtuev minhtuev commented Nov 21, 2024

What changes are proposed in this pull request?

Recently we discovered a rendering bug because two row actions have the same name, so I added uniqueness validation to TableView's properties

  • Updated uniqueness validation for TableView's columns, row actions and tooltips
  • Added unit tests

How is this patch tested? If it is not, please explain why.

  • Added unit tests
  • Tested locally

Release Notes

Is this a user-facing change that should be mentioned in the release notes?

  • No. You can skip the rest of this section.
  • Yes. Give a description of this change to be included in the release
    notes for FiftyOne users.

(Details in 1-2 sentences. You can just refer to another PR with a description
if this PR is part of a larger change.)

What areas of FiftyOne does this PR affect?

  • App: FiftyOne application changes
  • Build: Build and test infrastructure changes
  • Core: Core fiftyone Python library changes
  • Documentation: FiftyOne documentation changes
  • [] Other

Summary by CodeRabbit

  • New Features

    • Enhanced Action, Tooltip, and TableView classes for improved functionality and data integrity.
    • Added duplicate checks for columns, row actions, and tooltips in the TableView.
  • Bug Fixes

    • Improved error handling for duplicate entries in TableView.
  • Tests

    • Introduced a comprehensive test suite for the TableView class, covering addition and duplicate handling of columns, row actions, and tooltips.

@minhtuev minhtuev requested a review from imanjra November 21, 2024 07:31
Copy link
Contributor

coderabbitai bot commented Nov 21, 2024

Walkthrough

The changes involve significant updates to the Action, Tooltip, and TableView classes in the fiftyone/operators/types.py file. Key modifications include the introduction of required parameters in constructors, enhancements to cloning and JSON serialization methods, and the addition of checks to prevent duplicates in the TableView class methods. A new test suite for TableView has also been added, covering various functionalities and error handling scenarios.

Changes

File Change Summary
fiftyone/operators/types.py - Action: Updated constructor to require name, modified clone and to_json methods.
- Tooltip: Updated constructor to require row and column, modified clone and to_json methods.
- TableView: Enhanced methods to prevent duplicate entries and added _tooltip_map for tooltip management.
tests/unittests/operators/tableview_tests.py - Added TableViewTests class to validate functionalities of TableView, including duplicate handling.

Possibly related PRs

Suggested reviewers

  • ritch
  • CamronStaley

Poem

In the garden where data blooms,
Actions and tooltips find their rooms.
With checks in place, no duplicates here,
A table so tidy, let’s give a cheer!
Hops of joy for the code we write,
Making our tables a pure delight! 🐰✨

Warning

Rate limit exceeded

@minhtuev has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 6 minutes and 14 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 22eb1c3 and 2a224ab.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@minhtuev minhtuev force-pushed the feat/unique-row-action-table branch from 1c868d5 to 3012671 Compare November 21, 2024 07:32
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Outside diff range and nitpick comments (4)
tests/unittests/operators/view_tests.py (3)

7-15: Consider adding more edge cases and descriptive assertions.

The basic column uniqueness test is good, but could be enhanced with:

  • Tests for edge cases (empty strings, None values)
  • More descriptive assertion messages
 def test_table_view_basic(self):
     table = TableView()
     table.add_column("column1", label="Column 1")
     table.add_column("column2", label="Column 2")
-    assert table.keys() == ["column1", "column2"]
+    self.assertEqual(
+        table.keys(),
+        ["column1", "column2"],
+        "Table should contain exactly the two added columns"
+    )

     with self.assertRaises(ValueError):
         table.add_column("column1", label="Column 3")

+    # Test edge cases
+    with self.assertRaises(ValueError):
+        table.add_column("", label="Empty Column")
+    
+    with self.assertRaises(ValueError):
+        table.add_column(None, label="None Column")

18-41: Enhance row action tests with property validation.

While the uniqueness check is good, consider validating that the added actions retain their properties correctly.

 table.add_row_action(
     "action1",
     on_click=mock_on_click,
     icon="icon1",
     color="primary",
     tooltip="Action 1",
 )
+# Validate action properties
+action = table.row_actions[0]  # Assuming this accessor exists
+self.assertEqual(action.icon, "icon1", "Action icon should match")
+self.assertEqual(action.color, "primary", "Action color should match")
+self.assertEqual(action.tooltip, "Action 1", "Action tooltip should match")

42-46: Enhance tooltip tests with coordinate validation.

Consider adding tests for:

  • Invalid coordinates (negative values)
  • Tooltip content verification
  • Out-of-bounds coordinates
 table.add_tooltip(1, 1, "Tooltip 1")
 table.add_tooltip(1, 2, "Tooltip 2")

 with self.assertRaises(ValueError):
     table.add_tooltip(1, 1, "Tooltip 3")
+
+# Test invalid coordinates
+with self.assertRaises(ValueError):
+    table.add_tooltip(-1, 1, "Invalid Row")
+
+with self.assertRaises(ValueError):
+    table.add_tooltip(1, -1, "Invalid Column")
+
+# Verify tooltip content
+tooltip = table.get_tooltip(1, 1)  # Assuming this accessor exists
+self.assertEqual(tooltip, "Tooltip 1", "Tooltip content should match")
fiftyone/operators/types.py (1)

1883-1886: Optimize duplicate checks in TableView methods

The added duplicate checks in add_column, add_row_action, and add_tooltip methods iterate over lists, which could affect performance with large datasets. Consider using sets or dictionaries for faster lookups.

Apply this diff to improve performance:

class TableView(View):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.columns = kwargs.get("columns", [])
+       self.column_keys = set()
        self.row_actions = kwargs.get("row_actions", [])
+       self.row_action_names = set()
        self.tooltips = kwargs.get("tooltips", [])
+       self.tooltip_keys = set()

    def add_column(self, key, **kwargs):
        if key in self.column_keys:
            raise ValueError(f"Column with key '{key}' already exists")
        column = Column(key, **kwargs)
        self.columns.append(column)
+       self.column_keys.add(key)
        return column

    def add_row_action(self, name, on_click, label=None, icon=None, tooltip=None, **kwargs):
        if name in self.row_action_names:
            raise ValueError(f"Action with name '{name}' already exists")
        row_action = Action(
            name=name,
            on_click=on_click,
            label=label,
            icon=icon,
            tooltip=tooltip,
            **kwargs,
        )
        self.row_actions.append(row_action)
+       self.row_action_names.add(name)
        return row_action

    def add_tooltip(self, row, column, value, **kwargs):
+       key = (row, column)
+       if key in self.tooltip_keys:
            raise ValueError(f"Tooltip for row '{row}' and column '{column}' already exists")
        tooltip = Tooltip(row=row, column=column, value=value, **kwargs)
        self.tooltips.append(tooltip)
+       self.tooltip_keys.add(key)
        return tooltip

Also applies to: 1894-1897, 1908-1915

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between ea92c74 and 3012671.

📒 Files selected for processing (2)
  • fiftyone/operators/types.py (5 hunks)
  • tests/unittests/operators/view_tests.py (1 hunks)
🧰 Additional context used
🪛 Ruff
tests/unittests/operators/view_tests.py

16-16: Do not assign a lambda expression, use a def

Rewrite mock_on_click as a def

(E731)

🔇 Additional comments (1)
tests/unittests/operators/view_tests.py (1)

1-6: LGTM! Clean test class setup with appropriate imports.

with self.assertRaises(ValueError):
table.add_column("column1", label="Column 3")

mock_on_click = lambda: None
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Replace lambda with a proper function definition.

Per Python style guidelines, avoid assigning lambdas to variables.

-mock_on_click = lambda: None
+def mock_on_click():
+    pass
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
mock_on_click = lambda: None
def mock_on_click():
pass
🧰 Tools
🪛 Ruff

16-16: Do not assign a lambda expression, use a def

Rewrite mock_on_click as a def

(E731)

fiftyone/operators/types.py Outdated Show resolved Hide resolved
Comment on lines +1852 to +1862
def __init__(self, row, column, **kwargs):
super().__init__(**kwargs)
self.row = row
self.column = column

def clone(self):
clone = Tooltip(**self._kwargs)
clone = Tooltip(self.row, self.column, **self._kwargs)
return clone

def to_json(self):
return {**super().to_json()}
return {**super().to_json(), "row": self.row, "column": self.column}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Mandatory row and column parameters in Tooltip constructor may break existing code

The Tooltip class constructor now requires row and column parameters, which could break existing code where Tooltip is instantiated without these parameters. To maintain backward compatibility, consider making row and column optional parameters with default values.

Apply this diff to make row and column optional:

-def __init__(self, row, column, **kwargs):
+def __init__(self, row=None, column=None, **kwargs):
    super().__init__(**kwargs)
    self.row = row
    self.column = column
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def __init__(self, row, column, **kwargs):
super().__init__(**kwargs)
self.row = row
self.column = column
def clone(self):
clone = Tooltip(**self._kwargs)
clone = Tooltip(self.row, self.column, **self._kwargs)
return clone
def to_json(self):
return {**super().to_json()}
return {**super().to_json(), "row": self.row, "column": self.column}
def __init__(self, row=None, column=None, **kwargs):
super().__init__(**kwargs)
self.row = row
self.column = column
def clone(self):
clone = Tooltip(self.row, self.column, **self._kwargs)
return clone
def to_json(self):
return {**super().to_json(), "row": self.row, "column": self.column}

Comment on lines +1831 to +1841
def __init__(self, name, **kwargs):
super().__init__(**kwargs)
self.name = name

def clone(self):
clone = Action(**self._kwargs)
clone = Action(self.name, **self._kwargs)
return clone

def to_json(self):
return {**super().to_json()}

return {**super().to_json(), "name": self.name}

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Mandatory name parameter in Action constructor may break existing code

The Action class constructor now requires a name parameter, which could potentially break existing code where Action is instantiated without this parameter. To maintain backward compatibility, consider making name an optional parameter with a default value.

Apply this diff to make name optional:

-def __init__(self, name, **kwargs):
+def __init__(self, name=None, **kwargs):
    super().__init__(**kwargs)
    self.name = name
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def __init__(self, name, **kwargs):
super().__init__(**kwargs)
self.name = name
def clone(self):
clone = Action(**self._kwargs)
clone = Action(self.name, **self._kwargs)
return clone
def to_json(self):
return {**super().to_json()}
return {**super().to_json(), "name": self.name}
def __init__(self, name=None, **kwargs):
super().__init__(**kwargs)
self.name = name
def clone(self):
clone = Action(self.name, **self._kwargs)
return clone
def to_json(self):
return {**super().to_json(), "name": self.name}

@minhtuev minhtuev force-pushed the feat/unique-row-action-table branch from 3012671 to 4c430c2 Compare November 21, 2024 07:52
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (4)
tests/unittests/operators/view_tests.py (3)

7-11: Consider adding assertions for column labels

The test verifies column keys but doesn't validate that the column labels were set correctly.

 def test_table_view_basic(self):
     table = TableView()
     table.add_column("column1", label="Column 1")
     table.add_column("column2", label="Column 2")
     assert table.keys() == ["column1", "column2"]
+    assert table.get_column("column1").label == "Column 1"
+    assert table.get_column("column2").label == "Column 2"

13-14: Enhance error validation

Consider validating the error message to ensure it provides clear feedback about the duplicate column.

 with self.assertRaises(ValueError):
     table.add_column("column1", label="Column 3")
+with self.assertRaisesRegex(ValueError, "Column 'column1' already exists"):
+    table.add_column("column1", label="Column 3")

18-40: Consider splitting row action tests

The row action tests could be organized into separate test methods for better clarity and maintainability:

  1. Test successful addition of row actions
  2. Test duplicate prevention
  3. Test action properties validation

Example refactor:

def test_add_row_action_success(self):
    table = TableView()
    def mock_on_click(): pass
    table.add_row_action(
        "action1",
        on_click=mock_on_click,
        icon="icon1",
        color="primary",
        tooltip="Action 1",
    )
    action = table.get_row_action("action1")
    assert action.icon == "icon1"
    assert action.color == "primary"
    assert action.tooltip == "Action 1"

def test_add_row_action_duplicate(self):
    table = TableView()
    def mock_on_click(): pass
    table.add_row_action("action1", on_click=mock_on_click)
    with self.assertRaisesRegex(ValueError, "Row action 'action1' already exists"):
        table.add_row_action("action1", on_click=mock_on_click)
fiftyone/operators/types.py (1)

Line range hint 1883-1915: LGTM! The TableView uniqueness validation looks good.

The implementation correctly validates uniqueness for columns, row actions, and tooltips. The validation logic is consistent across all three methods and raises appropriate errors when duplicates are found.

Consider enhancing the error messages to provide more context about the duplicate items:

-                raise ValueError(f"Column with key '{key}' already exists")
+                raise ValueError(f"Cannot add column: A column with key '{key}' already exists")

-                raise ValueError(f"Action with name '{name}' already exists")
+                raise ValueError(f"Cannot add row action: An action with name '{name}' already exists")

-                    f"Tooltip for row '{row}' and column '{column}' already exists"
+                    f"Cannot add tooltip: A tooltip for row '{row}' and column '{column}' already exists"
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 3012671 and 4c430c2.

📒 Files selected for processing (2)
  • fiftyone/operators/types.py (4 hunks)
  • tests/unittests/operators/view_tests.py (1 hunks)
🧰 Additional context used
🪛 Ruff
tests/unittests/operators/view_tests.py

16-16: Do not assign a lambda expression, use a def

Rewrite mock_on_click as a def

(E731)

🔇 Additional comments (3)
tests/unittests/operators/view_tests.py (1)

16-16: Lambda usage was previously flagged

🧰 Tools
🪛 Ruff

16-16: Do not assign a lambda expression, use a def

Rewrite mock_on_click as a def

(E731)

fiftyone/operators/types.py (2)

1831-1841: LGTM! The Action class changes look good.

The implementation correctly stores and handles the name parameter, which is essential for uniqueness validation in TableView.


1852-1862: LGTM! The Tooltip class changes look good.

The implementation correctly stores and handles the row and column parameters, which are essential for uniqueness validation in TableView.

Comment on lines 42 to 46
table.add_tooltip(1, 1, "Tooltip 1")
table.add_tooltip(1, 2, "Tooltip 2")

with self.assertRaises(ValueError):
table.add_tooltip(1, 1, "Tooltip 3")
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Enhance tooltip test coverage

Consider adding the following test cases:

  1. Validate tooltip content after addition
  2. Test invalid row/column indices
  3. Test edge cases (e.g., zero or negative indices)
def test_tooltip_validation(self):
    table = TableView()
    table.add_column("column1")
    
    # Test successful addition
    table.add_tooltip(1, 1, "Tooltip 1")
    assert table.get_tooltip(1, 1) == "Tooltip 1"
    
    # Test invalid indices
    with self.assertRaises(ValueError):
        table.add_tooltip(-1, 1, "Invalid")
    with self.assertRaises(ValueError):
        table.add_tooltip(1, 0, "Invalid")

@minhtuev minhtuev force-pushed the feat/unique-row-action-table branch from a6fbc02 to 22eb1c3 Compare November 21, 2024 08:19
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (4)
tests/unittests/operators/types_tests.py (3)

7-15: Consider adding more edge cases to column validation tests.

While the basic column validation is well tested, consider adding test cases for:

  • Empty column names
  • None values
  • Special characters in column names
def test_table_view_column_edge_cases(self):
    table = TableView()
    
    # Test empty column name
    with self.assertRaises(ValueError):
        table.add_column("", label="Empty")
    
    # Test None column name
    with self.assertRaises(ValueError):
        table.add_column(None, label="None")
    
    # Test special characters
    table.add_column("column@#$%", label="Special")
    assert "column@#$%" in table.keys()

18-41: Consider extracting row action creation into a helper method.

The row action creation code is repeated. Consider extracting it into a helper method to improve test readability and maintainability.

def _create_row_action(self, action_id, icon, color, tooltip):
    def mock_on_click():
        pass
    
    return {
        "id": action_id,
        "on_click": mock_on_click,
        "icon": icon,
        "color": color,
        "tooltip": tooltip
    }

42-46: Add boundary tests for tooltip coordinates.

Consider adding test cases for:

  • Invalid row/column indices (negative or out of bounds)
  • Empty tooltip text
def test_table_view_tooltip_edge_cases(self):
    table = TableView()
    table.add_column("column1", label="Column 1")
    
    # Test negative indices
    with self.assertRaises(ValueError):
        table.add_tooltip(-1, 1, "Invalid")
    
    # Test out of bounds
    with self.assertRaises(ValueError):
        table.add_tooltip(1, 999, "Invalid")
    
    # Test empty tooltip
    with self.assertRaises(ValueError):
        table.add_tooltip(1, 1, "")
fiftyone/operators/types.py (1)

Line range hint 1878-1929: LGTM! TableView changes prevent duplicates effectively

The implementation successfully prevents duplicate entries for columns, row actions, and tooltips. The _tooltip_map provides efficient O(1) lookup for tooltip existence checks.

Consider standardizing the error message format across all three validation checks. Currently, they slightly differ:

-            raise ValueError(f"Column with key '{key}' already exists")
-            raise ValueError(f"Action with name '{name}' already exists")
-            raise ValueError(
-                f"Tooltip for row '{row}' and column '{column}' already exists"
-            )
+            raise ValueError(f"Duplicate column: key '{key}' already exists")
+            raise ValueError(f"Duplicate action: name '{name}' already exists")
+            raise ValueError(f"Duplicate tooltip: position (row '{row}', column '{column}') already exists")
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between a6fbc02 and 22eb1c3.

📒 Files selected for processing (2)
  • fiftyone/operators/types.py (4 hunks)
  • tests/unittests/operators/types_tests.py (1 hunks)
🧰 Additional context used
🪛 Ruff
tests/unittests/operators/types_tests.py

16-16: Do not assign a lambda expression, use a def

Rewrite mock_on_click as a def

(E731)

🔇 Additional comments (4)
tests/unittests/operators/types_tests.py (2)

1-6: LGTM! Clean test structure and imports.

The test file follows Python testing best practices with clear imports and class structure.


7-46: Verify test coverage aligns with PR objectives.

The test suite effectively covers the uniqueness validation requirements for TableView:

  • Column uniqueness ✓
  • Row action uniqueness ✓
  • Tooltip uniqueness ✓

However, let's verify there are no missing test cases from the implementation.

✅ Verification successful

Test coverage is complete and aligns with implementation

The test suite comprehensively covers all uniqueness validations present in the TableView implementation:

  • Column uniqueness: Tests add_column() duplicate key rejection ✓
  • Row action uniqueness: Tests add_row_action() duplicate name rejection ✓
  • Tooltip uniqueness: Tests add_tooltip() duplicate position rejection ✓

The implementation shows exactly these three validation points raising ValueError, and the test suite has explicit assertions for each case.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for validation-related code in TableView implementation
ast-grep --pattern 'def add_$_(self, $$$): 
  $$$
  raise ValueError($$$)
  $$$' fiftyone/operators/types.py

Length of output: 110


Script:

#!/bin/bash
# Let's try a different approach to find the TableView implementation and its validation logic
rg -A 5 "class TableView" fiftyone/operators/types.py

Length of output: 256


Script:

#!/bin/bash
# Search for add_* methods in TableView
rg "def add_" fiftyone/operators/types.py

Length of output: 252


Script:

#!/bin/bash
# Search for ValueError raises in TableView methods
rg "raise ValueError" fiftyone/operators/types.py

Length of output: 419

🧰 Tools
🪛 Ruff

16-16: Do not assign a lambda expression, use a def

Rewrite mock_on_click as a def

(E731)

fiftyone/operators/types.py (2)

1831-1841: LGTM! Action class changes enforce uniqueness

The mandatory name parameter in the constructor ensures each action has a unique identifier, which aligns with the PR's objective of preventing duplicate row actions. The clone and to_json methods correctly handle the new name field.


1852-1862: LGTM! Tooltip class changes support position-based uniqueness

The mandatory row and column parameters in the constructor ensure each tooltip is uniquely identified by its position. The clone and to_json methods correctly handle these new fields, supporting the TableView's uniqueness validation.

with self.assertRaises(ValueError):
table.add_column("column1", label="Column 3")

mock_on_click = lambda: None
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Replace lambda with a proper function definition.

Following Python best practices and addressing the static analysis warning (E731), replace the lambda with a proper function definition.

-        mock_on_click = lambda: None
+        def mock_on_click():
+            pass
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
mock_on_click = lambda: None
def mock_on_click():
pass
🧰 Tools
🪛 Ruff

16-16: Do not assign a lambda expression, use a def

Rewrite mock_on_click as a def

(E731)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (3)
tests/unittests/operators/tableview_tests.py (3)

7-11: Consider splitting the test method into smaller, focused test methods.

The current test method covers multiple behaviors (columns, actions, tooltips). Following testing best practices, consider splitting it into separate methods:

  • test_column_uniqueness
  • test_row_action_uniqueness
  • test_tooltip_uniqueness

This improves test maintainability and makes failures more specific.


13-14: Consider adding more column uniqueness test cases.

While the basic duplicate column test is good, consider adding tests for:

  • Case sensitivity (e.g., "Column1" vs "column1")
  • Whitespace handling (e.g., "column1" vs " column1 ")
  • Empty or None column names

42-46: Consider adding boundary tests for tooltip coordinates.

While the basic tooltip uniqueness test is good, consider adding tests for:

  • Invalid coordinates (negative or out of bounds)
  • Empty or None tooltip text
  • Unicode characters in tooltips
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 22eb1c3 and 2a224ab.

📒 Files selected for processing (1)
  • tests/unittests/operators/tableview_tests.py (1 hunks)
🧰 Additional context used
🪛 Ruff
tests/unittests/operators/tableview_tests.py

16-16: Do not assign a lambda expression, use a def

Rewrite mock_on_click as a def

(E731)

🔇 Additional comments (2)
tests/unittests/operators/tableview_tests.py (2)

1-6: LGTM! Clean and focused test class setup.

The imports are minimal and the test class follows good testing practices.


18-40: LGTM! Comprehensive row action testing.

The test thoroughly validates row action uniqueness and includes all relevant properties (icon, color, tooltip).

with self.assertRaises(ValueError):
table.add_column("column1", label="Column 3")

mock_on_click = lambda: None
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Replace lambda with a proper function definition.

Instead of using a lambda expression, define a proper function for better readability and maintainability.

-        mock_on_click = lambda: None
+        def mock_on_click():
+            pass
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
mock_on_click = lambda: None
def mock_on_click():
pass
🧰 Tools
🪛 Ruff

16-16: Do not assign a lambda expression, use a def

Rewrite mock_on_click as a def

(E731)

@kaixi-wang
Copy link
Contributor

Do you know how multiple row actions with the same name are getting added? Would adding this constraints just cause things not to load at all?

@minhtuev
Copy link
Contributor Author

@kaixi-wang : we had a PR last week where in QP panel we added multiple actions with the same name and caused a bug

@minhtuev minhtuev changed the base branch from release/v1.1.0 to develop November 27, 2024 17:37
Copy link
Contributor

@imanjra imanjra left a comment

Choose a reason for hiding this comment

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

LGTM

@minhtuev minhtuev merged commit 0a86bcf into develop Dec 11, 2024
13 checks passed
@minhtuev minhtuev deleted the feat/unique-row-action-table branch December 11, 2024 07:05
@coderabbitai coderabbitai bot mentioned this pull request Jan 7, 2025
6 tasks
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