'Tests for the built-in factor `RollingLinearRegressionOfReturns`.'

@parameter_space(returns_length=[2, 3], regression_length=[3, 4])
def test_regression_of_returns_factor(self, returns_length, regression_length):

    assets = self.assets
    my_asset = self.my_asset
    my_asset_column = self.my_asset_column
    dates = self.dates
    start_date = self.pipeline_start_date
    end_date = self.pipeline_end_date
    start_date_index = self.start_date_index
    end_date_index = self.end_date_index
    num_days = self.num_days
    run_pipeline = self.run_pipeline
    outputs = ['beta', 'alpha', 'r_value', 'p_value', 'stderr']
    returns = Returns(window_length=returns_length)
    masks = (self.cascading_mask, self.alternating_mask, NotSpecified)
    expected_mask_results = (self.expected_cascading_mask_result, self.expected_alternating_mask_result, self.expected_no_mask_result)
    for (mask, expected_mask) in zip(masks, expected_mask_results):
        regression_factor = RollingLinearRegressionOfReturns(target=my_asset, returns_length=returns_length, regression_length=regression_length, mask=mask)
        columns = {output: getattr(regression_factor, output) for output in outputs}
        pipeline = Pipeline(columns=columns)
        if (mask is not NotSpecified):
            pipeline.add(mask, 'mask')
        results = run_pipeline(pipeline, start_date, end_date)
        if (mask is not NotSpecified):
            mask_results = results['mask'].unstack()
            check_arrays(mask_results.values, expected_mask)
        output_results = {}
        expected_output_results = {}
        for output in outputs:
            output_results[output] = results[output].unstack()
            expected_output_results[output] = full_like(output_results[output], nan)
        results = run_pipeline(Pipeline(columns={'returns': returns}), dates[(start_date_index - (regression_length - 1))], dates[end_date_index])
        returns_results = results['returns'].unstack()
        for day in range(num_days):
            todays_returns = returns_results.iloc[day:(day + regression_length)]
            my_asset_returns = todays_returns.iloc[:, my_asset_column]
            for (asset, other_asset_returns) in todays_returns.iteritems():
                asset_column = (int(asset) - 1)
                expected_regression_results = linregress(y=other_asset_returns, x=my_asset_returns)
                for (i, output) in enumerate(outputs):
                    expected_output_results[output][(day, asset_column)] = expected_regression_results[i]
        for output in outputs:
            output_result = output_results[output]
            expected_output_result = DataFrame(where(expected_mask, expected_output_results[output], nan), index=dates[start_date_index:(end_date_index + 1)], columns=assets)
            assert_frame_equal(output_result, expected_output_result)
