code: def test_theming_a_model_via_base(self) -> None:
      theme = Theme(
          json={
              "attrs": {
                  "ThemedModel": {
                      "string": "w00t",
                  },
              },
          }
      )
      obj = SubOfThemedModel()
      changes = dict(calls=[])
  
      def record_trigger(attr, old, new_):
          changes["calls"].append((attr, old, new_))
  
      obj.on_change("string", record_trigger)
      assert "hello" == obj.string
      theme.apply_to_model(obj)
      assert "w00t" == obj.string
      assert [("string", "hello", "w00t")] == changes["calls"]
  
imports: from __future__ import annotations
  import pytest
  import os
  import tempfile
  from bokeh.core.properties import Int, String
  from bokeh.core.property_mixins import FillProps, LineProps, TextProps
  from bokeh.document import Document
  from bokeh.model import Model
  from bokeh.plotting import figure
  from bokeh.util.deprecation import BokehDeprecationWarning
  from bokeh.themes import Theme, built_in_themes, DARK_MINIMAL, LIGHT_MINIMAL
label_desc: Use image node_id 10 for calling the TestThemes obj's underlying member method code with example usage: obj.test_theming_a_model_via_base() without return types