code: def test_fillna_with_expression(self, null_locs):
      shape = (4, 4)
      mask = self.build_mask(self.ones_mask(shape=(4, 4)))
      state = np.random.RandomState(4)
      assets = self.asset_finder.retrieve_all(mask.columns)
  
      def rand_vals(dtype):
          return state.randint(1, 100, shape).astype(dtype)
  
      floats = np.arange(16, dtype=float).reshape(shape)
      floats[null_locs] = np.nan
      float_fillval = rand_vals(float)
      float_expected = np.where(null_locs, float_fillval, floats)
      float_expected_1d = np.where(
          null_locs, float_fillval[:, [0]], floats
      )
  
      dates = (
          np.arange(16, dtype="i8")
          .view("M8[D]")
          .astype("M8[ns]")
          .reshape(shape)
      )
      dates[null_locs] = NaTns
      date_fillval = rand_vals("M8[D]").astype("M8[ns]")
      date_expected = np.where(null_locs, date_fillval, dates)
      date_expected_1d = np.where(
          null_locs, date_fillval[:, [1]], dates
      )
  
      strs = np.arange(16).astype(str).astype(object).reshape(shape)
      strs[null_locs] = None
      str_fillval = rand_vals(str)
      str_expected = np.where(null_locs, str_fillval, strs)
      str_expected_1d = np.where(null_locs, str_fillval[:, [2]], strs)
  
      ints = np.arange(16).reshape(shape)
      ints[null_locs] = -1
      int_fillval = rand_vals(int64_dtype)
      int_expected = np.where(null_locs, int_fillval, ints)
      int_expected_1d = np.where(null_locs, int_fillval[:, [3]], ints)
  
      terms = {
          "floats": Floats().fillna(AltFloats()),
          "floats_1d": Floats().fillna(AltFloats()[assets[0]]),
          "dates": Dates().fillna(AltDates()),
          "dates_1d": Dates().fillna(AltDates()[assets[1]]),
          "strs": Strs().fillna(AltStrs()),
          "strs_1d": Strs().fillna(AltStrs()[assets[2]]),
          "ints": Ints().fillna(AltInts()),
          "ints_1d": Ints().fillna(AltInts()[assets[3]]),
      }
  
      expected = {
          "floats": float_expected,
          "floats_1d": float_expected_1d,
          "dates": date_expected,
          "dates_1d": date_expected_1d,
          "strs": self.make_labelarray(str_expected),
          "strs_1d": self.make_labelarray(str_expected_1d),
          "ints": int_expected,
          "ints_1d": int_expected_1d,
      }
  
      self.check_terms(
          terms,
          expected,
          initial_workspace={
              Floats(): floats,
              Dates(): dates,
              Strs(): self.make_labelarray(strs),
              Ints(): ints,
              AltFloats(): float_fillval,
              AltDates(): date_fillval,
              AltStrs(): self.make_labelarray(str_fillval),
              AltInts(): int_fillval,
          },
          mask=mask,
      )
  
imports: import numpy
  from zipline.lib.labelarray import LabelArray
  from zipline.pipeline import Classifier, Factor, Filter
  from zipline.testing import parameter_space
  from zipline.utils.numpy_utils import categorical_dtype, datetime64ns_dtype, float64_dtype, int64_dtype, NaTns
  from .base import BaseUSEquityPipelineTestCase
label_desc: Use image node_id 2 for calling the FillNATestCase obj's underlying member method code with example usage: obj.test_fillna_with_expression(null_locs) and returns: state