code: def test_bad_extra_range_name(self) -> None:
      p = figure()
      p.xaxis.x_range_name = "junk"
      with mock.patch("bokeh.core.validation.check.log") as mock_logger:
          issues = check_integrity([p])
          process_validation_issues(issues)
      assert mock_logger.error.call_count == 1
      assert mock_logger.error.call_args[0][0].startswith(
          "E-1020 (BAD_EXTRA_RANGE_NAME): An extra range name is configured with a name that does not correspond to any range: x_range_name='junk' [LinearAxis",
      )
  
      p = figure()
      p.extra_x_ranges["foo"] = Range1d()
      p.grid.x_range_name = "junk"
      with mock.patch("bokeh.core.validation.check.log") as mock_logger:
          issues = check_integrity([p])
          process_validation_issues(issues)
      assert mock_logger.error.call_count == 1
      assert mock_logger.error.call_args[0][0].startswith(
          "E-1020 (BAD_EXTRA_RANGE_NAME): An extra range name is configured with a name that does not correspond to any range: x_range_name='junk' [Grid",
      )
      assert mock_logger.error.call_args[0][0].count("Grid") == 2
  
imports: from __future__ import annotations
  import pytest
  from math import isnan
  from unittest import mock
  from unittest.mock import MagicMock, patch
  import xyzservices.providers
  from bokeh.core.validation import check_integrity, process_validation_issues
  from bokeh.models import CategoricalScale, CustomJS, DataRange1d, FactorRange, GlyphRenderer, Label, LinearAxis, LinearScale, LogScale, PanTool, Plot, Range1d, ResetTool, Title, WMTSTileSource, ZoomInTool, ZoomOutTool
  from bokeh.plotting import figure
  import bokeh.models.plots
label_desc: Use image node_id 4 for calling the TestPlotValidation obj's underlying member method code with example usage: obj.test_bad_extra_range_name() without return types