code: def test_train_end_date_with_regressors():
      """Tests make_future_dataframe and train_end_date with regressors"""
      for train_start_date in [
          "2018-01-01",
          datetime.datetime(2018, 1, 1),
      ]:
          data = generate_df_with_reg_for_tests(
              freq="D",
              periods=30,
              train_start_date=train_start_date,
              remove_extra_cols=True,
              mask_test_actuals=True,
          )
          regressor_cols = [
              "regressor1",
              "regressor2",
              "regressor_categ",
          ]
          keep_cols = [TIME_COL, VALUE_COL] + regressor_cols
          df = data["df"][keep_cols].copy()
          # Setting NaN values at the end
          df.loc[df.tail(2).index, "regressor1"] = np.nan
          df.loc[df.tail(4).index, "regressor2"] = np.nan
          df.loc[df.tail(6).index, "regressor_categ"] = np.nan
          df.loc[df.tail(8).index, VALUE_COL] = np.nan
  
          # default train_end_date, default regressor_cols
          with pytest.warns(UserWarning) as record:
              ts = UnivariateTimeSeries()
              ts.load_data(
                  df,
                  TIME_COL,
                  VALUE_COL,
                  train_end_date=None,
                  regressor_cols=None,
              )
              assert (
                  f"{ts.original_value_col} column of the provided time series contains "
                  f"null values at the end, or the input `train_end_date` is beyond the last timestamp available. "
                  f"Setting `train_end_date` to the last timestamp with a non-null value "
                  f"({ts.train_end_date})." in record[0].message.args[0]
              )
              assert ts.train_end_date == dt(2018, 1, 22)
              assert ts.fit_df.shape == (22, 2)
              assert (
                  ts.last_date_for_val
                  == df[df[VALUE_COL].notnull()][TIME_COL].max()
              )
              assert ts.last_date_for_reg is None
              result = ts.make_future_dataframe(
                  periods=10, include_history=True
              )
              expected = pd.DataFrame(
                  {
                      TIME_COL: pd.date_range(
                          start=dt(2018, 1, 1), periods=32, freq="D"
                      ),
                      VALUE_COL: np.concatenate(
                          [ts.fit_y, np.repeat(np.nan, 10)]
                      ),
                  }
              )
              expected.index = expected[TIME_COL]
              expected.index.name = None
              assert_frame_equal(result, expected)
  
          # train_end_date later than last date in df, all available regressor_cols
          with pytest.warns(UserWarning) as record:
              ts = UnivariateTimeSeries()
              train_end_date = dt(2018, 2, 10)
              ts.load_data(
                  df,
                  TIME_COL,
                  VALUE_COL,
                  train_end_date=train_end_date,
                  regressor_cols=regressor_cols,
              )
              assert (
                  f"{VALUE_COL} column of the provided time series contains "
                  f"null values at the end, or the input `train_end_date` is beyond the last timestamp available. "
                  f"Setting `train_end_date` to the last timestamp with a non-null value "
                  f"({dt(2018, 1, 22)})." in record[0].message.args[0]
              )
              assert ts.last_date_for_val == dt(2018, 1, 22)
              assert ts.last_date_for_reg == dt(2018, 1, 28)
              result = ts.make_future_dataframe(
                  periods=10, include_history=False
              )
              expected = df.copy()[22:28]
              expected.loc[expected.tail(6).index, VALUE_COL] = np.nan
              expected.index = expected[TIME_COL]
              expected.index.name = None
              assert_frame_equal(result, expected)
  
          # train_end_date in between last date in df and last date before null
          # user passes no regressor_cols
          with pytest.warns(UserWarning) as record:
              ts = UnivariateTimeSeries()
              train_end_date = dt(2018, 1, 25)
              regressor_cols = []
              ts.load_data(
                  df,
                  TIME_COL,
                  VALUE_COL,
                  train_end_date=train_end_date,
                  regressor_cols=regressor_cols,
              )
              assert (
                  f"{VALUE_COL} column of the provided time series contains trailing NAs."
                  in record[0].message.args[0]
              )
              assert ts.train_end_date == dt(2018, 1, 25)
              assert ts.last_date_for_reg is None
              result = ts.make_future_dataframe(
                  periods=10, include_history=True
              )
              assert (
                  len(ts.fit_y) == 25
              )  # Since `train_end_date` is 2018-01-25.
              expected = pd.DataFrame(
                  {
                      TIME_COL: pd.date_range(
                          start=dt(2018, 1, 1), periods=35, freq="D"
                      ),
                      VALUE_COL: np.concatenate(
                          [ts.fit_y, np.repeat(np.nan, 10)]
                      ),
                  }
              )
              expected.index = expected[TIME_COL]
              expected.index.name = None
              assert_frame_equal(result, expected)
  
          # train end date equal to last date before null
          # user requests a subset of the regressor_cols
          with pytest.warns(UserWarning) as record:
              ts = UnivariateTimeSeries()
              train_end_date = dt(2018, 1, 22)
              regressor_cols = ["regressor2"]
              ts.load_data(
                  df,
                  TIME_COL,
                  VALUE_COL,
                  train_end_date=train_end_date,
                  regressor_cols=regressor_cols,
              )
              assert ts.train_end_date == dt(2018, 1, 22)
              assert ts.last_date_for_reg == dt(2018, 1, 26)
              result = ts.make_future_dataframe(
                  periods=10, include_history=True
              )
              # gathers all warning messages
              all_warnings = ""
              for i in range(len(record)):
                  all_warnings += record[i].message.args[0]
              assert (
                  "Provided periods '10' is more than allowed ('4') due to the length of "
                  "regressor columns. Using '4'." in all_warnings
              )
              expected = ts.df.copy()[
                  [TIME_COL, VALUE_COL, "regressor2"]
              ]
              expected = expected[
                  expected.index <= ts.last_date_for_reg
              ]
              assert_frame_equal(result, expected)
  
          # train_end_date smaller than last date before null
          # user requests regressor_cols that does not exist in df
          with pytest.warns(UserWarning) as record:
              ts = UnivariateTimeSeries()
              train_end_date = dt(2018, 1, 20)
              regressor_cols = [
                  "regressor1",
                  "regressor4",
                  "regressor5",
              ]
              ts.load_data(
                  df,
                  TIME_COL,
                  VALUE_COL,
                  train_end_date=train_end_date,
                  regressor_cols=regressor_cols,
              )
              assert ts.train_end_date == dt(2018, 1, 20)
              assert ts.last_date_for_reg == dt(2018, 1, 28)
              # gathers all warning messages
              all_warnings = ""
              for i in range(len(record)):
                  all_warnings += record[i].message.args[0]
              assert (
                  f"The following columns are not available to use as "
                  f"regressors: ['regressor4', 'regressor5']"
              ) in all_warnings
              result = ts.make_future_dataframe(
                  periods=10, include_history=True
              )
              expected = ts.df.copy()[
                  [TIME_COL, VALUE_COL, "regressor1"]
              ]
              expected = expected[
                  expected.index <= ts.last_date_for_reg
              ]
              assert_frame_equal(result, expected)
  
imports: import datetime
  from datetime import datetime
  import numpy
  import pandas
  import pytest
  from pandas.testing import assert_frame_equal
  from greykite.common.constants import ADJUSTMENT_DELTA_COL
  from greykite.common.constants import END_TIME_COL
  from greykite.common.constants import METRIC_COL
  from greykite.common.constants import START_TIME_COL
  from greykite.common.constants import TIME_COL
  from greykite.common.constants import VALUE_COL
  from greykite.common.python_utils import assert_equal
  from greykite.common.testing_utils import generate_df_for_tests
  from greykite.common.testing_utils import generate_df_with_reg_for_tests
  from greykite.common.time_properties import get_canonical_data
  from greykite.common.viz.timeseries_plotting import add_groupby_column
  from greykite.framework.benchmark.data_loader_ts import DataLoaderTS
  from greykite.framework.constants import MEAN_COL_GROUP
  from greykite.framework.constants import OVERLAY_COL_GROUP
  from greykite.framework.constants import QUANTILE_COL_GROUP
  from greykite.framework.input.univariate_time_series import UnivariateTimeSeries
label_desc: Use image node_id 10 for calling a global function with example usage: test_train_end_date_with_regressors() without return types