code: def migrate_and_assert(
      cls: type[MigrateViz],
      source: dict[str, Any],
      target: dict[str, Any],
  ) -> None:
      from superset.models.slice import Slice
  
      dumped_form_data = json.dumps(source)
  
      slc = Slice(
          viz_type=cls.source_viz_type,
          datasource_type="table",
          params=dumped_form_data,
          query_context=f'{{"form_data": {dumped_form_data}}}',
      )
  
      # upgrade
      cls.upgrade_slice(slc)
  
      # verify form_data
      new_form_data = json.loads(slc.params)
      assert new_form_data == target
      assert new_form_data["form_data_bak"] == source
  
      # verify query_context
      new_query_context = json.loads(slc.query_context)
      assert (
          new_query_context["form_data"]["viz_type"]
          == cls.target_viz_type
      )
  
      # downgrade
      cls.downgrade_slice(slc)
      assert slc.viz_type == cls.source_viz_type
      assert json.loads(slc.params) == source
  
imports: import json
  from typing import Any
  from superset.migrations.shared.migrate_viz import MigrateViz
label_desc: Use image node_id 1 for calling a global function with example usage: migrate_and_assert(cls, source, target) without return types