class_docstr: Base class for testing FXRateReader implementations.
  
  To test a new FXRateReader implementation, subclass from this base class
  and implement the ``reader`` property, returning an FXRateReader that uses
  the data stored in ``cls.fx_rates``.
code: def test_scalar_lookup(self):
      reader = self.reader
  
      rates = self.FX_RATES_RATE_NAMES
      quotes = self.FX_RATES_CURRENCIES
      bases = self.FX_RATES_CURRENCIES + [None]
      dates = pd.date_range(
          self.FX_RATES_START_DATE - pd.Timedelta("1 day"),
          self.FX_RATES_END_DATE + pd.Timedelta("1 day"),
      )
      cases = itertools.product(rates, quotes, bases, dates)
  
      for rate, quote, base, dt in cases:
          dts = pd.DatetimeIndex([dt], tz="UTC")
          bases = np.array([base], dtype=object)
  
          result = reader.get_rates(rate, quote, bases, dts)
          assert_equal(result.shape, (1, 1))
  
          result_scalar = result[0, 0]
          if dt >= self.FX_RATES_START_DATE and quote == base:
              assert_equal(result_scalar, 1.0)
  
          expected = self.get_expected_fx_rate_scalar(
              rate, quote, base, dt
          )
          assert_equal(result_scalar, expected)
  
          col_result = reader.get_rates_columnar(
              rate, quote, bases, dts
          )
          assert_equal(col_result, result.ravel())
  
          alt_result_scalar = reader.get_rate_scalar(
              rate, quote, base, dt
          )
          assert_equal(result_scalar, alt_result_scalar)
  
imports: import itertools
  import pandas
  import numpy
  from zipline.data.fx import DEFAULT_FX_RATE
  from zipline.testing.predicates import assert_equal
  import zipline.testing.fixtures
label_desc: Use image node_id 3 for calling the _FXReaderTestCase obj's underlying member method code with example usage: obj.test_scalar_lookup() without return types