Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions sdmetrics/reports/base_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ def generate(self, real_data, synthetic_data, metadata, verbose=True):
verbose (bool):
Whether or not to print report summary and progress.
"""
real_data = deepcopy(real_data)
synthetic_data = deepcopy(synthetic_data)
self._validate(real_data, synthetic_data, metadata)
self._skipped_properties = self._get_skipped_properties(metadata)
self._original_datetime_columns = self.convert_datetimes(
Expand Down
18 changes: 18 additions & 0 deletions tests/integration/reports/multi_table/test_diagnostic_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,3 +373,21 @@ def test_metadata_without_relationship(self):

# Run and Assert
report.generate(real_data, synthetic_data, metadata)


def test_report_keeps_data_unchanged():
"""Test that the diagnostic report does not modify the input data."""
# Setup
real_data, synthetic_data, metadata = load_demo(modality='multi_table')
real_data_copy = {table_name: table.copy() for table_name, table in real_data.items()}
synthetic_data_copy = {table_name: table.copy() for table_name, table in synthetic_data.items()}
report = DiagnosticReport()

# Run
report.generate(real_data, synthetic_data, metadata, verbose=True)

# Assert
for table_name in real_data:
pd.testing.assert_frame_equal(real_data[table_name], real_data_copy[table_name])
for table_name in synthetic_data:
pd.testing.assert_frame_equal(synthetic_data[table_name], synthetic_data_copy[table_name])
18 changes: 18 additions & 0 deletions tests/integration/reports/multi_table/test_quality_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -564,3 +564,21 @@ def test_with_large_dataset():
assert np.isclose(report_2.get_score(), score_1_run_1, atol=0.001)
assert np.isclose(cpt_report_1, cpt_report_2, atol=0.001)
assert np.isclose(intertable_trends_1, intertable_trends_2, atol=0.001)


def test_report_keeps_data_unchanged():
"""Test that the quality report does not modify the input data."""
# Setup
real_data, synthetic_data, metadata = load_demo(modality='multi_table')
real_data_copy = {table_name: table.copy() for table_name, table in real_data.items()}
synthetic_data_copy = {table_name: table.copy() for table_name, table in synthetic_data.items()}
report = QualityReport()

# Run
report.generate(real_data, synthetic_data, metadata, verbose=True)

# Assert
for table_name in real_data:
pd.testing.assert_frame_equal(real_data[table_name], real_data_copy[table_name])
for table_name in synthetic_data:
pd.testing.assert_frame_equal(synthetic_data[table_name], synthetic_data_copy[table_name])
31 changes: 25 additions & 6 deletions tests/unit/reports/test_base_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,14 +305,19 @@ def test_generate(self, version_mock, time_mock, datetime_mock):
base_report.generate(real_data, synthetic_data, metadata, verbose=False)

# Assert
mock_validate.assert_called_once_with(real_data, synthetic_data, metadata)
mock_validate.assert_called_once()
copied_real_data, copied_synthetic_data, _ = mock_validate.call_args.args
pd.testing.assert_frame_equal(copied_real_data, real_data)
pd.testing.assert_frame_equal(copied_synthetic_data, synthetic_data)
assert copied_real_data is not real_data
assert copied_synthetic_data is not synthetic_data
mock__print_results.assert_called_once_with(False)
base_report._properties['Property 1'].get_score.assert_called_with(
real_data, synthetic_data, metadata, progress_bar=None
copied_real_data, copied_synthetic_data, metadata, progress_bar=None
)
assert base_report._properties['Property 1'].num_rows_subsample == 1000
base_report._properties['Property 2'].get_score.assert_called_with(
real_data, synthetic_data, metadata, progress_bar=None
copied_real_data, copied_synthetic_data, metadata, progress_bar=None
)
assert base_report._properties['Property 2'].num_rows_subsample == 1000
expected_info = {
Expand Down Expand Up @@ -377,11 +382,20 @@ def test_generate_multi_table_details(self, version_mock, time_mock, datetime_mo
base_report.generate(real_data, synthetic_data, metadata, verbose=False)

# Assert
copied_real_data, copied_synthetic_data, _ = base_report._validate.call_args.args
for table_name, table in real_data.items():
pd.testing.assert_frame_equal(copied_real_data[table_name], table)
pd.testing.assert_frame_equal(
copied_synthetic_data[table_name], synthetic_data[table_name]
)

assert copied_real_data is not real_data
assert copied_synthetic_data is not synthetic_data
base_report._properties['Property 1'].get_score.assert_called_with(
real_data, synthetic_data, metadata, progress_bar=None
copied_real_data, copied_synthetic_data, metadata, progress_bar=None
)
base_report._properties['Property 2'].get_score.assert_called_with(
real_data, synthetic_data, metadata, progress_bar=None
copied_real_data, copied_synthetic_data, metadata, progress_bar=None
)
expected_info = {
'report_type': 'BaseReport',
Expand Down Expand Up @@ -483,14 +497,19 @@ def test_generate_verbose_with_skipped_property(self, mock_tqdm, mock_write):
base_report.generate(real_data, synthetic_data, metadata, verbose=True)

# Assert
copied_real_data, copied_synthetic_data, _ = base_report._validate.call_args.args
pd.testing.assert_frame_equal(copied_real_data, real_data)
pd.testing.assert_frame_equal(copied_synthetic_data, synthetic_data)
assert copied_real_data is not real_data
assert copied_synthetic_data is not synthetic_data
base_report._properties['Property 1'].get_score.assert_not_called()
base_report._properties['Property 1']._get_num_iterations.assert_not_called()
assert base_report._properties['Property 1'].details.empty
assert not base_report._properties['Property 1'].is_computed
assert base_report._skipped_properties == {'Property 1'}
base_report._get_skipped_properties.assert_called_once_with(metadata)
base_report._properties['Property 2'].get_score.assert_called_once_with(
real_data, synthetic_data, metadata, progress_bar=mock_tqdm.return_value
copied_real_data, copied_synthetic_data, metadata, progress_bar=mock_tqdm.return_value
)
mock_write.assert_any_call('Generating report ...\n\n')
mock_write.assert_any_call(
Expand Down