code: def test_general_feature_generates_correct_output(self) -> None:
      name = "general_feature"
      categories = ["cat1", "cat2", "cat3", "cat4"]
      attribution = torch.Tensor(1, 4)
      attribution.fill_(0.5)
      data = torch.rand(1, 4)
      contribution = torch.rand(1).item()
      attr_squeezed = attribution.squeeze(0)
  
      expected_modified = [
          x * 100
          for x in (attr_squeezed / attr_squeezed.norm()).tolist()
      ]
      expected_base = [
          f"{c}: {d:.2f}"
          for c, d in zip(categories, data.squeeze().tolist())
      ]
  
      feature = GeneralFeature(name, categories)
  
      feature_output = feature.visualize(
          attribution=attribution,
          data=data,
          contribution_frac=contribution,
      )
  
      expected_feature_output = FeatureOutput(
          name=name,
          base=expected_base,
          modified=expected_modified,
          type="general",
          contribution=contribution,
      )
  
      self.assertEqual(expected_feature_output, feature_output)
  
file_path: captum/tests/insights/test_features.py
imports: from unittest.mock import patch
  import torch
  from captum.insights.attr_vis.features import _convert_figure_base64, EmptyFeature, FeatureOutput, GeneralFeature, ImageFeature, TextFeature
  from matplotlib.figure import Figure
  from tests.helpers.basic import BaseTest
label_desc: Use image node_id 1 for calling the TestGeneralFeature obj's underlying member method code with example usage: obj.test_general_feature_generates_correct_output() without return types