diff --git a/diffly/cli.py b/diffly/cli.py index d3560eb..35db432 100644 --- a/diffly/cli.py +++ b/diffly/cli.py @@ -139,7 +139,7 @@ def main( list[str], typer.Option( help=( - "Metric presets to display per numerical column. Repeatable. " + "Metric presets to display per column. Repeatable. " f"Available: {', '.join(DEFAULT_METRICS)}." ) ), diff --git a/diffly/comparison.py b/diffly/comparison.py index 786c4c2..6976b9c 100644 --- a/diffly/comparison.py +++ b/diffly/comparison.py @@ -25,7 +25,7 @@ lazy_len, make_and_validate_mapping, ) -from .metrics import MetricFn, _make_numeric_metric +from .metrics import Metric, MetricFn, _make_numeric_metric if TYPE_CHECKING: # pragma: no cover # NOTE: We cannot import at runtime as we're otherwise running into circular @@ -920,7 +920,7 @@ def summary( right_name: str = Side.RIGHT, slim: bool = False, hidden_columns: list[str] | None = None, - metrics: Mapping[str, MetricFn] | None = None, + metrics: Mapping[str, MetricFn | Metric] | None = None, ) -> Summary: """Generate a summary of all aspects of the comparison. @@ -950,16 +950,18 @@ def summary( advanced users who are familiar with the summary format. hidden_columns: Columns for which no values are printed, e.g. because they contain sensitive information. - metrics: Optional mapping from display label to a metric callable - ``(left_expr, right_expr) -> pl.Expr``. Each callable receives two + metrics: Optional mapping from display label to a metric. A value may be a + callable ``(left_expr, right_expr) -> pl.Expr`` or a + :class:`~diffly.metrics.Metric`. Each callable receives two :class:`polars.Expr` referring to the left and right values of a single - numerical column across all joined rows, and must return a scalar - aggregation expression. See :doc:`/api/metrics` for the full list of - presets and the :data:`~diffly.metrics.MetricFn` type. When ``None`` - (default), no metrics are computed; presets are not applied - automatically. Metrics are only computed for numerical columns. Prefer - short labels — the summary has a fixed width and many or long labels - degrade rendering. + column across all joined rows, and must return a scalar aggregation + expression. Bare callables are only computed for numerical columns; wrap + one in a :class:`~diffly.metrics.Metric` with a column selector to target + other column types (e.g. ``Metric(fn, selector=cs.all())``). + See :doc:`/api/metrics` for the full list of presets and the + :data:`~diffly.metrics.MetricFn` type. When ``None`` (default), no metrics + are computed; presets are not applied automatically. Prefer short labels — + the summary has a fixed width and many or long labels degrade rendering. Returns: A summary which can be printed or written to a file. @@ -976,7 +978,10 @@ def summary( from .summary import Summary resolved_metrics = ( - {label: _make_numeric_metric(fn) for label, fn in metrics.items()} + { + label: v if isinstance(v, Metric) else _make_numeric_metric(v) + for label, v in metrics.items() + } if metrics is not None else None ) diff --git a/diffly/metrics.py b/diffly/metrics.py index 075536e..007f7cf 100644 --- a/diffly/metrics.py +++ b/diffly/metrics.py @@ -12,10 +12,7 @@ @dataclass(frozen=True) class Metric: - """A metric function paired with a column-applicability selector. - - Internal only. - """ + """A metric function paired with a column-applicability selector.""" fn: MetricFn selector: cs.Selector @@ -70,6 +67,53 @@ def mean_relative_deviation(left: pl.Expr, right: pl.Expr) -> pl.Expr: return ((right - left) / left).abs().mean() +def _percentage_string( + fraction: pl.Expr, *, signed: bool = False, percent_sign: bool = True +) -> pl.Expr: + """Format a fraction as a percentage string, optionally with an explicit sign.""" + pct = (fraction * 100).round(2) + body = pl.format("{}%", pct) if percent_sign else pl.format("{}", pct) + if signed: + return pl.when(pct >= 0).then(pl.format("+{}", body)).otherwise(body) + return body + + +def _render_change( + old: pl.Expr, + new: pl.Expr, + format_value: Callable[[pl.Expr, bool], pl.Expr], +) -> pl.Expr: + """Render a change as `` -> ()``. + + ``format_value(value, signed)`` formats a value for display; ``old`` and ``new`` are + rendered unsigned and the delta ``new - old`` is rendered signed (with an explicit + ``+`` or ``-`` prefix). + """ + return pl.format( + "{} -> {} ({})", + format_value(old, False), + format_value(new, False), + format_value(new - old, True), + ) + + +def null_fraction_change(left: pl.Expr, right: pl.Expr) -> pl.Expr: + """Change in the fraction of null entries, rendered as `` -> ()``. + + ``old`` and ``new`` are the null percentages of the left and right side, and + ``delta`` is their signed difference (``+`` when the right side has proportionally + more nulls, ``-`` when it has fewer). Unlike the other presets, this applies to + columns of any type. + """ + return _render_change( + left.is_null().mean(), + right.is_null().mean(), + lambda value, signed: _percentage_string( + value, signed=signed, percent_sign=not signed + ), + ) + + def quantile(q: float) -> MetricFn: """Factory returning a metric that computes the ``q``-quantile of ``right - left``.""" @@ -82,7 +126,7 @@ def _quantile(left: pl.Expr, right: pl.Expr) -> pl.Expr: return _quantile -DEFAULT_METRICS: dict[str, MetricFn] = { +DEFAULT_METRICS: dict[str, MetricFn | Metric] = { "Mean": mean, "Median": median, "Min": min, @@ -90,4 +134,5 @@ def _quantile(left: pl.Expr, right: pl.Expr) -> pl.Expr: "Std": std, "Mean absolute deviation": mean_absolute_deviation, "Mean relative deviation": mean_relative_deviation, + "Null%": Metric(fn=null_fraction_change, selector=cs.all()), } diff --git a/diffly/summary.py b/diffly/summary.py index 3edf645..ac3dda7 100644 --- a/diffly/summary.py +++ b/diffly/summary.py @@ -1131,10 +1131,13 @@ def _format_value(value: Any, *, float_format: str | None = None) -> str: def _format_metric_value(value: Any) -> str: """Format a metric value for the column summary. - Blanks out ``None`` and renders floats with ``.4g`` precision. + Blanks out ``None``, renders string values verbatim, and renders floats with ``.4g`` + precision. """ if value is None: return "" + if isinstance(value, str): + return _yellow(value) return _format_value(value, float_format=".4g") diff --git a/diffly/testing.py b/diffly/testing.py index 367a304..9a36458 100644 --- a/diffly/testing.py +++ b/diffly/testing.py @@ -19,7 +19,7 @@ from ._compat import dy from .comparison import DataFrameComparison, compare_frames -from .metrics import MetricFn +from .metrics import Metric, MetricFn def assert_collection_equal( @@ -40,7 +40,7 @@ def assert_collection_equal( right_name: str = Side.RIGHT, slim: bool = False, hidden_columns: list[str] | None = None, - metrics: Mapping[str, MetricFn] | None = None, + metrics: Mapping[str, MetricFn | Metric] | None = None, ) -> None: """Assert that two :mod:`dataframely` collections are equal. @@ -85,9 +85,11 @@ def assert_collection_equal( hidden_columns: Columns for which no values are printed, e.g. because they contain sensitive information. metrics: Optional mapping from display label to a metric callable - ``(left_expr, right_expr) -> pl.Expr``. See :mod:`diffly.metrics` for - presets. When ``None`` (default), no metrics are computed; presets are - not applied automatically. + ``(left_expr, right_expr) -> pl.Expr`` or a :class:`~diffly.metrics.Metric`. + Bare callables are only computed for numerical columns; wrap one in a + :class:`~diffly.metrics.Metric` with a column selector to target other column + types. See :mod:`diffly.metrics` for presets. When ``None`` (default), no + metrics are computed; presets are not applied automatically. Raises: AssertionError: If the collections are not equal. @@ -174,7 +176,7 @@ def assert_frame_equal( right_name: str = Side.RIGHT, slim: bool = False, hidden_columns: list[str] | None = None, - metrics: Mapping[str, MetricFn] | None = None, + metrics: Mapping[str, MetricFn | Metric] | None = None, ) -> None: """Assert that two :mod:`polars` data frames are equal. @@ -226,9 +228,11 @@ def assert_frame_equal( hidden_columns: Columns for which no values are printed, e.g. because they contain sensitive information. metrics: Optional mapping from display label to a metric callable - ``(left_expr, right_expr) -> pl.Expr``. See :mod:`diffly.metrics` for - presets. When ``None`` (default), no metrics are computed; presets are - not applied automatically. + ``(left_expr, right_expr) -> pl.Expr`` or a :class:`~diffly.metrics.Metric`. + Bare callables are only computed for numerical columns; wrap one in a + :class:`~diffly.metrics.Metric` with a column selector to target other column + types. See :mod:`diffly.metrics` for presets. When ``None`` (default), no + metrics are computed; presets are not applied automatically. Raises: AssertionError: If the data frames are not equal. diff --git a/docs/api/metrics.rst b/docs/api/metrics.rst index 27df193..a90947b 100644 --- a/docs/api/metrics.rst +++ b/docs/api/metrics.rst @@ -4,15 +4,21 @@ Metrics .. currentmodule:: diffly.metrics -Metrics are scalar aggregations computed per numerical column when generating a +Metrics are scalar aggregations computed per column when generating a :meth:`~diffly.comparison.DataFrameComparison.summary`. Pass them via the ``metrics`` argument as a mapping from display label to a :data:`MetricFn` callable. :mod:`diffly.metrics` ships a set of presets; you can also supply your own callable ``(left_expr, right_expr) -> pl.Expr``. +A bare callable is only computed for numerical columns. To target other column +types, wrap it in a :class:`Metric` with a column selector, e.g. +``Metric(fn, selector=cs.string())`` or ``selector=cs.all()``. + .. autodata:: MetricFn :no-value: +.. autoclass:: Metric + Presets ======= @@ -26,4 +32,5 @@ Presets std mean_absolute_deviation mean_relative_deviation + null_fraction_change quantile diff --git a/tests/cli/test_cli.py b/tests/cli/test_cli.py index c65320c..e49c5f0 100644 --- a/tests/cli/test_cli.py +++ b/tests/cli/test_cli.py @@ -80,6 +80,27 @@ def test_cli_hidden_columns_alias_warns(tmp_path: Path) -> None: assert result.exit_code == 0 +def test_cli_null_fraction_metric(tmp_path: Path) -> None: + left = pl.DataFrame({"id": [1, 2, 3], "status": ["a", "b", "c"]}) + right = pl.DataFrame({"id": [1, 2, 3], "status": ["a", None, "x"]}) + left.write_parquet(tmp_path / "left.parquet") + right.write_parquet(tmp_path / "right.parquet") + + result = runner.invoke( + app, + [ + str(tmp_path / "left.parquet"), + str(tmp_path / "right.parquet"), + "--primary-key", + "id", + "--metric", + "Null%", + ], + ) + assert result.exit_code == 0 + assert "Null%" in result.output + + def test_cli_unknown_metric(tmp_path: Path) -> None: left = pl.DataFrame({"id": [1, 2], "x": [1.0, 2.0]}) right = pl.DataFrame({"id": [1, 2], "x": [1.0, 3.0]}) diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_False_slim_False_sample_rows_False_sample_pk_False.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_False_slim_False_sample_rows_False_sample_pk_False.txt new file mode 100644 index 0000000..f3d3d5f --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_False_slim_False_sample_rows_False_sample_pk_False.txt @@ -0,0 +1,28 @@ +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃ Diffly Summary ┃ +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + Primary key: id + + Schemas + ▔▔▔▔▔▔▔ + Schemas match exactly (column count: 3). + + Rows + ▔▔▔▔ + Left count Right count + 5 (no change) 5 + + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃ Null% ┃ str_len_delta ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ + │ price │ 40.00% │ 0.75 │ 20.0% -> 0.0% (-20.0) │ │ + │ status │ 40.00% │ │ 0.0% -> 40.0% (+40.0) │ 0 │ + └────────┴────────────┴──────┴───────────────────────┴───────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_False_slim_False_sample_rows_True_sample_pk_False.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_False_slim_False_sample_rows_True_sample_pk_False.txt new file mode 100644 index 0000000..f3d3d5f --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_False_slim_False_sample_rows_True_sample_pk_False.txt @@ -0,0 +1,28 @@ +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃ Diffly Summary ┃ +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + Primary key: id + + Schemas + ▔▔▔▔▔▔▔ + Schemas match exactly (column count: 3). + + Rows + ▔▔▔▔ + Left count Right count + 5 (no change) 5 + + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃ Null% ┃ str_len_delta ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ + │ price │ 40.00% │ 0.75 │ 20.0% -> 0.0% (-20.0) │ │ + │ status │ 40.00% │ │ 0.0% -> 40.0% (+40.0) │ 0 │ + └────────┴────────────┴──────┴───────────────────────┴───────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_False_slim_True_sample_rows_False_sample_pk_False.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_False_slim_True_sample_rows_False_sample_pk_False.txt new file mode 100644 index 0000000..2f849f9 --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_False_slim_True_sample_rows_False_sample_pk_False.txt @@ -0,0 +1,16 @@ + Rows + ▔▔▔▔ + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃ Null% ┃ str_len_delta ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ + │ price │ 40.00% │ 0.75 │ 20.0% -> 0.0% (-20.0) │ │ + │ status │ 40.00% │ │ 0.0% -> 40.0% (+40.0) │ 0 │ + └────────┴────────────┴──────┴───────────────────────┴───────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_False_slim_True_sample_rows_True_sample_pk_False.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_False_slim_True_sample_rows_True_sample_pk_False.txt new file mode 100644 index 0000000..2f849f9 --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_False_slim_True_sample_rows_True_sample_pk_False.txt @@ -0,0 +1,16 @@ + Rows + ▔▔▔▔ + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃ Null% ┃ str_len_delta ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ + │ price │ 40.00% │ 0.75 │ 20.0% -> 0.0% (-20.0) │ │ + │ status │ 40.00% │ │ 0.0% -> 40.0% (+40.0) │ 0 │ + └────────┴────────────┴──────┴───────────────────────┴───────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_True_slim_False_sample_rows_False_sample_pk_False.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_True_slim_False_sample_rows_False_sample_pk_False.txt new file mode 100644 index 0000000..18568f4 --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_True_slim_False_sample_rows_False_sample_pk_False.txt @@ -0,0 +1,36 @@ +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃ Diffly Summary ┃ +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + Primary key: id + + Schemas + ▔▔▔▔▔▔▔ + Schemas match exactly (column count: 3). + + Rows + ▔▔▔▔ + Left count Right count + 5 (no change) 5 + + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃ Null% ┃ str_len_delta ┃ Top Changes ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩ + │ price │ 40.00% │ 0.75 │ 20.0% -> 0.0% │ │ None -> 30.0 │ + │ │ │ │ (-20.0) │ │ (1x) │ + │ │ │ │ │ │ 40.0 -> 42.0 │ + │ │ │ │ │ │ (1x) │ + │ │ │ │ │ │ 20.0 -> 21.0 │ + │ │ │ │ │ │ (1x) │ + ├────────┼────────────┼──────┼───────────────────┼───────────────┼──────────────────┤ + │ status │ 40.00% │ │ 0.0% -> 40.0% │ 0 │ "d" -> None (1x) │ + │ │ │ │ (+40.0) │ │ "c" -> "x" (1x) │ + │ │ │ │ │ │ "b" -> None (1x) │ + └────────┴────────────┴──────┴───────────────────┴───────────────┴──────────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_True_slim_False_sample_rows_True_sample_pk_True.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_True_slim_False_sample_rows_True_sample_pk_True.txt new file mode 100644 index 0000000..f2a498b --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_True_slim_False_sample_rows_True_sample_pk_True.txt @@ -0,0 +1,39 @@ +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃ Diffly Summary ┃ +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + Primary key: id + + Schemas + ▔▔▔▔▔▔▔ + Schemas match exactly (column count: 3). + + Rows + ▔▔▔▔ + Left count Right count + 5 (no change) 5 + + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃ Null% ┃ str_len_delta ┃ Top Changes ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩ + │ price │ 40.00% │ 0.75 │ 20.0% -> 0.0% │ │ None -> 30.0 │ + │ │ │ │ (-20.0) │ │ (1x, e.g. 3) │ + │ │ │ │ │ │ 40.0 -> 42.0 │ + │ │ │ │ │ │ (1x, e.g. 4) │ + │ │ │ │ │ │ 20.0 -> 21.0 │ + │ │ │ │ │ │ (1x, e.g. 2) │ + ├────────┼────────────┼──────┼───────────────────┼───────────────┼──────────────────┤ + │ status │ 40.00% │ │ 0.0% -> 40.0% │ 0 │ "d" -> None (1x, │ + │ │ │ │ (+40.0) │ │ e.g. 4) │ + │ │ │ │ │ │ "c" -> "x" (1x, │ + │ │ │ │ │ │ e.g. 3) │ + │ │ │ │ │ │ "b" -> None (1x, │ + │ │ │ │ │ │ e.g. 2) │ + └────────┴────────────┴──────┴───────────────────┴───────────────┴──────────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_True_slim_True_sample_rows_False_sample_pk_False.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_True_slim_True_sample_rows_False_sample_pk_False.txt new file mode 100644 index 0000000..06d07fe --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_True_slim_True_sample_rows_False_sample_pk_False.txt @@ -0,0 +1,24 @@ + Rows + ▔▔▔▔ + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃ Null% ┃ str_len_delta ┃ Top Changes ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩ + │ price │ 40.00% │ 0.75 │ 20.0% -> 0.0% │ │ None -> 30.0 │ + │ │ │ │ (-20.0) │ │ (1x) │ + │ │ │ │ │ │ 40.0 -> 42.0 │ + │ │ │ │ │ │ (1x) │ + │ │ │ │ │ │ 20.0 -> 21.0 │ + │ │ │ │ │ │ (1x) │ + ├────────┼────────────┼──────┼───────────────────┼───────────────┼──────────────────┤ + │ status │ 40.00% │ │ 0.0% -> 40.0% │ 0 │ "d" -> None (1x) │ + │ │ │ │ (+40.0) │ │ "c" -> "x" (1x) │ + │ │ │ │ │ │ "b" -> None (1x) │ + └────────┴────────────┴──────┴───────────────────┴───────────────┴──────────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_True_slim_True_sample_rows_True_sample_pk_True.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_True_slim_True_sample_rows_True_sample_pk_True.txt new file mode 100644 index 0000000..01c654b --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_False_top_True_slim_True_sample_rows_True_sample_pk_True.txt @@ -0,0 +1,27 @@ + Rows + ▔▔▔▔ + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃ Null% ┃ str_len_delta ┃ Top Changes ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩ + │ price │ 40.00% │ 0.75 │ 20.0% -> 0.0% │ │ None -> 30.0 │ + │ │ │ │ (-20.0) │ │ (1x, e.g. 3) │ + │ │ │ │ │ │ 40.0 -> 42.0 │ + │ │ │ │ │ │ (1x, e.g. 4) │ + │ │ │ │ │ │ 20.0 -> 21.0 │ + │ │ │ │ │ │ (1x, e.g. 2) │ + ├────────┼────────────┼──────┼───────────────────┼───────────────┼──────────────────┤ + │ status │ 40.00% │ │ 0.0% -> 40.0% │ 0 │ "d" -> None (1x, │ + │ │ │ │ (+40.0) │ │ e.g. 4) │ + │ │ │ │ │ │ "c" -> "x" (1x, │ + │ │ │ │ │ │ e.g. 3) │ + │ │ │ │ │ │ "b" -> None (1x, │ + │ │ │ │ │ │ e.g. 2) │ + └────────┴────────────┴──────┴───────────────────┴───────────────┴──────────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_False_slim_False_sample_rows_False_sample_pk_False.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_False_slim_False_sample_rows_False_sample_pk_False.txt new file mode 100644 index 0000000..f3d3d5f --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_False_slim_False_sample_rows_False_sample_pk_False.txt @@ -0,0 +1,28 @@ +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃ Diffly Summary ┃ +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + Primary key: id + + Schemas + ▔▔▔▔▔▔▔ + Schemas match exactly (column count: 3). + + Rows + ▔▔▔▔ + Left count Right count + 5 (no change) 5 + + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃ Null% ┃ str_len_delta ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ + │ price │ 40.00% │ 0.75 │ 20.0% -> 0.0% (-20.0) │ │ + │ status │ 40.00% │ │ 0.0% -> 40.0% (+40.0) │ 0 │ + └────────┴────────────┴──────┴───────────────────────┴───────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_False_slim_False_sample_rows_True_sample_pk_False.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_False_slim_False_sample_rows_True_sample_pk_False.txt new file mode 100644 index 0000000..f3d3d5f --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_False_slim_False_sample_rows_True_sample_pk_False.txt @@ -0,0 +1,28 @@ +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃ Diffly Summary ┃ +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + Primary key: id + + Schemas + ▔▔▔▔▔▔▔ + Schemas match exactly (column count: 3). + + Rows + ▔▔▔▔ + Left count Right count + 5 (no change) 5 + + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃ Null% ┃ str_len_delta ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ + │ price │ 40.00% │ 0.75 │ 20.0% -> 0.0% (-20.0) │ │ + │ status │ 40.00% │ │ 0.0% -> 40.0% (+40.0) │ 0 │ + └────────┴────────────┴──────┴───────────────────────┴───────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_False_slim_True_sample_rows_False_sample_pk_False.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_False_slim_True_sample_rows_False_sample_pk_False.txt new file mode 100644 index 0000000..2f849f9 --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_False_slim_True_sample_rows_False_sample_pk_False.txt @@ -0,0 +1,16 @@ + Rows + ▔▔▔▔ + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃ Null% ┃ str_len_delta ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ + │ price │ 40.00% │ 0.75 │ 20.0% -> 0.0% (-20.0) │ │ + │ status │ 40.00% │ │ 0.0% -> 40.0% (+40.0) │ 0 │ + └────────┴────────────┴──────┴───────────────────────┴───────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_False_slim_True_sample_rows_True_sample_pk_False.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_False_slim_True_sample_rows_True_sample_pk_False.txt new file mode 100644 index 0000000..2f849f9 --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_False_slim_True_sample_rows_True_sample_pk_False.txt @@ -0,0 +1,16 @@ + Rows + ▔▔▔▔ + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃ Null% ┃ str_len_delta ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ + │ price │ 40.00% │ 0.75 │ 20.0% -> 0.0% (-20.0) │ │ + │ status │ 40.00% │ │ 0.0% -> 40.0% (+40.0) │ 0 │ + └────────┴────────────┴──────┴───────────────────────┴───────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_True_slim_False_sample_rows_False_sample_pk_False.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_True_slim_False_sample_rows_False_sample_pk_False.txt new file mode 100644 index 0000000..18568f4 --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_True_slim_False_sample_rows_False_sample_pk_False.txt @@ -0,0 +1,36 @@ +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃ Diffly Summary ┃ +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + Primary key: id + + Schemas + ▔▔▔▔▔▔▔ + Schemas match exactly (column count: 3). + + Rows + ▔▔▔▔ + Left count Right count + 5 (no change) 5 + + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃ Null% ┃ str_len_delta ┃ Top Changes ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩ + │ price │ 40.00% │ 0.75 │ 20.0% -> 0.0% │ │ None -> 30.0 │ + │ │ │ │ (-20.0) │ │ (1x) │ + │ │ │ │ │ │ 40.0 -> 42.0 │ + │ │ │ │ │ │ (1x) │ + │ │ │ │ │ │ 20.0 -> 21.0 │ + │ │ │ │ │ │ (1x) │ + ├────────┼────────────┼──────┼───────────────────┼───────────────┼──────────────────┤ + │ status │ 40.00% │ │ 0.0% -> 40.0% │ 0 │ "d" -> None (1x) │ + │ │ │ │ (+40.0) │ │ "c" -> "x" (1x) │ + │ │ │ │ │ │ "b" -> None (1x) │ + └────────┴────────────┴──────┴───────────────────┴───────────────┴──────────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_True_slim_False_sample_rows_True_sample_pk_True.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_True_slim_False_sample_rows_True_sample_pk_True.txt new file mode 100644 index 0000000..f2a498b --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_True_slim_False_sample_rows_True_sample_pk_True.txt @@ -0,0 +1,39 @@ +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃ Diffly Summary ┃ +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + Primary key: id + + Schemas + ▔▔▔▔▔▔▔ + Schemas match exactly (column count: 3). + + Rows + ▔▔▔▔ + Left count Right count + 5 (no change) 5 + + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃ Null% ┃ str_len_delta ┃ Top Changes ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩ + │ price │ 40.00% │ 0.75 │ 20.0% -> 0.0% │ │ None -> 30.0 │ + │ │ │ │ (-20.0) │ │ (1x, e.g. 3) │ + │ │ │ │ │ │ 40.0 -> 42.0 │ + │ │ │ │ │ │ (1x, e.g. 4) │ + │ │ │ │ │ │ 20.0 -> 21.0 │ + │ │ │ │ │ │ (1x, e.g. 2) │ + ├────────┼────────────┼──────┼───────────────────┼───────────────┼──────────────────┤ + │ status │ 40.00% │ │ 0.0% -> 40.0% │ 0 │ "d" -> None (1x, │ + │ │ │ │ (+40.0) │ │ e.g. 4) │ + │ │ │ │ │ │ "c" -> "x" (1x, │ + │ │ │ │ │ │ e.g. 3) │ + │ │ │ │ │ │ "b" -> None (1x, │ + │ │ │ │ │ │ e.g. 2) │ + └────────┴────────────┴──────┴───────────────────┴───────────────┴──────────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_True_slim_True_sample_rows_False_sample_pk_False.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_True_slim_True_sample_rows_False_sample_pk_False.txt new file mode 100644 index 0000000..06d07fe --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_True_slim_True_sample_rows_False_sample_pk_False.txt @@ -0,0 +1,24 @@ + Rows + ▔▔▔▔ + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃ Null% ┃ str_len_delta ┃ Top Changes ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩ + │ price │ 40.00% │ 0.75 │ 20.0% -> 0.0% │ │ None -> 30.0 │ + │ │ │ │ (-20.0) │ │ (1x) │ + │ │ │ │ │ │ 40.0 -> 42.0 │ + │ │ │ │ │ │ (1x) │ + │ │ │ │ │ │ 20.0 -> 21.0 │ + │ │ │ │ │ │ (1x) │ + ├────────┼────────────┼──────┼───────────────────┼───────────────┼──────────────────┤ + │ status │ 40.00% │ │ 0.0% -> 40.0% │ 0 │ "d" -> None (1x) │ + │ │ │ │ (+40.0) │ │ "c" -> "x" (1x) │ + │ │ │ │ │ │ "b" -> None (1x) │ + └────────┴────────────┴──────┴───────────────────┴───────────────┴──────────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_True_slim_True_sample_rows_True_sample_pk_True.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_True_slim_True_sample_rows_True_sample_pk_True.txt new file mode 100644 index 0000000..01c654b --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_False_perfect_True_top_True_slim_True_sample_rows_True_sample_pk_True.txt @@ -0,0 +1,27 @@ + Rows + ▔▔▔▔ + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃ Null% ┃ str_len_delta ┃ Top Changes ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩ + │ price │ 40.00% │ 0.75 │ 20.0% -> 0.0% │ │ None -> 30.0 │ + │ │ │ │ (-20.0) │ │ (1x, e.g. 3) │ + │ │ │ │ │ │ 40.0 -> 42.0 │ + │ │ │ │ │ │ (1x, e.g. 4) │ + │ │ │ │ │ │ 20.0 -> 21.0 │ + │ │ │ │ │ │ (1x, e.g. 2) │ + ├────────┼────────────┼──────┼───────────────────┼───────────────┼──────────────────┤ + │ status │ 40.00% │ │ 0.0% -> 40.0% │ 0 │ "d" -> None (1x, │ + │ │ │ │ (+40.0) │ │ e.g. 4) │ + │ │ │ │ │ │ "c" -> "x" (1x, │ + │ │ │ │ │ │ e.g. 3) │ + │ │ │ │ │ │ "b" -> None (1x, │ + │ │ │ │ │ │ e.g. 2) │ + └────────┴────────────┴──────┴───────────────────┴───────────────┴──────────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_False_slim_False_sample_rows_False_sample_pk_False.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_False_slim_False_sample_rows_False_sample_pk_False.txt new file mode 100644 index 0000000..3a2a43b --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_False_slim_False_sample_rows_False_sample_pk_False.txt @@ -0,0 +1,28 @@ +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃  Diffly Summary  ┃ +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + Primary key: id + + Schemas + ▔▔▔▔▔▔▔ + Schemas match exactly (column count: 3). + + Rows + ▔▔▔▔ + Left count Right count + 5 (no change) 5 + + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃  Null% ┃ str_len_delta ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ + │ price  │ 40.00% │ 0.75 │ 20.0% -> 0.0% (-20.0) │ │ + │ status │ 40.00% │ │ 0.0% -> 40.0% (+40.0) │ 0 │ + └────────┴────────────┴──────┴───────────────────────┴───────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_False_slim_False_sample_rows_True_sample_pk_False.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_False_slim_False_sample_rows_True_sample_pk_False.txt new file mode 100644 index 0000000..3a2a43b --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_False_slim_False_sample_rows_True_sample_pk_False.txt @@ -0,0 +1,28 @@ +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃  Diffly Summary  ┃ +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + Primary key: id + + Schemas + ▔▔▔▔▔▔▔ + Schemas match exactly (column count: 3). + + Rows + ▔▔▔▔ + Left count Right count + 5 (no change) 5 + + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃  Null% ┃ str_len_delta ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ + │ price  │ 40.00% │ 0.75 │ 20.0% -> 0.0% (-20.0) │ │ + │ status │ 40.00% │ │ 0.0% -> 40.0% (+40.0) │ 0 │ + └────────┴────────────┴──────┴───────────────────────┴───────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_False_slim_True_sample_rows_False_sample_pk_False.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_False_slim_True_sample_rows_False_sample_pk_False.txt new file mode 100644 index 0000000..1316f6b --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_False_slim_True_sample_rows_False_sample_pk_False.txt @@ -0,0 +1,16 @@ + Rows + ▔▔▔▔ + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃  Null% ┃ str_len_delta ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ + │ price  │ 40.00% │ 0.75 │ 20.0% -> 0.0% (-20.0) │ │ + │ status │ 40.00% │ │ 0.0% -> 40.0% (+40.0) │ 0 │ + └────────┴────────────┴──────┴───────────────────────┴───────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_False_slim_True_sample_rows_True_sample_pk_False.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_False_slim_True_sample_rows_True_sample_pk_False.txt new file mode 100644 index 0000000..1316f6b --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_False_slim_True_sample_rows_True_sample_pk_False.txt @@ -0,0 +1,16 @@ + Rows + ▔▔▔▔ + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃  Null% ┃ str_len_delta ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ + │ price  │ 40.00% │ 0.75 │ 20.0% -> 0.0% (-20.0) │ │ + │ status │ 40.00% │ │ 0.0% -> 40.0% (+40.0) │ 0 │ + └────────┴────────────┴──────┴───────────────────────┴───────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_True_slim_False_sample_rows_False_sample_pk_False.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_True_slim_False_sample_rows_False_sample_pk_False.txt new file mode 100644 index 0000000..bdca125 --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_True_slim_False_sample_rows_False_sample_pk_False.txt @@ -0,0 +1,36 @@ +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃  Diffly Summary  ┃ +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + Primary key: id + + Schemas + ▔▔▔▔▔▔▔ + Schemas match exactly (column count: 3). + + Rows + ▔▔▔▔ + Left count Right count + 5 (no change) 5 + + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃  Null% ┃ str_len_delta ┃  Top Changes ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩ + │ price  │ 40.00% │ 0.75 │ 20.0% -> 0.0% │ │ None -> 30.0 │ + │ │ │ │ (-20.0) │ │ (1x) │ + │ │ │ │ │ │ 40.0 -> 42.0 │ + │ │ │ │ │ │ (1x) │ + │ │ │ │ │ │ 20.0 -> 21.0 │ + │ │ │ │ │ │ (1x) │ + ├────────┼────────────┼──────┼───────────────────┼───────────────┼──────────────────┤ + │ status │ 40.00% │ │ 0.0% -> 40.0% │ 0 │ "d" -> None (1x) │ + │ │ │ │ (+40.0) │ │ "c" -> "x" (1x) │ + │ │ │ │ │ │ "b" -> None (1x) │ + └────────┴────────────┴──────┴───────────────────┴───────────────┴──────────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_True_slim_False_sample_rows_True_sample_pk_True.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_True_slim_False_sample_rows_True_sample_pk_True.txt new file mode 100644 index 0000000..cdd7114 --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_True_slim_False_sample_rows_True_sample_pk_True.txt @@ -0,0 +1,39 @@ +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃  Diffly Summary  ┃ +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + Primary key: id + + Schemas + ▔▔▔▔▔▔▔ + Schemas match exactly (column count: 3). + + Rows + ▔▔▔▔ + Left count Right count + 5 (no change) 5 + + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃  Null% ┃ str_len_delta ┃  Top Changes ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩ + │ price  │ 40.00% │ 0.75 │ 20.0% -> 0.0% │ │ None -> 30.0 │ + │ │ │ │ (-20.0) │ │ (1x, e.g. 3) │ + │ │ │ │ │ │ 40.0 -> 42.0 │ + │ │ │ │ │ │ (1x, e.g. 4) │ + │ │ │ │ │ │ 20.0 -> 21.0 │ + │ │ │ │ │ │ (1x, e.g. 2) │ + ├────────┼────────────┼──────┼───────────────────┼───────────────┼──────────────────┤ + │ status │ 40.00% │ │ 0.0% -> 40.0% │ 0 │ "d" -> None (1x, │ + │ │ │ │ (+40.0) │ │ e.g. 4) │ + │ │ │ │ │ │ "c" -> "x" (1x, │ + │ │ │ │ │ │ e.g. 3) │ + │ │ │ │ │ │ "b" -> None (1x, │ + │ │ │ │ │ │ e.g. 2) │ + └────────┴────────────┴──────┴───────────────────┴───────────────┴──────────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_True_slim_True_sample_rows_False_sample_pk_False.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_True_slim_True_sample_rows_False_sample_pk_False.txt new file mode 100644 index 0000000..370a2d3 --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_True_slim_True_sample_rows_False_sample_pk_False.txt @@ -0,0 +1,24 @@ + Rows + ▔▔▔▔ + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃  Null% ┃ str_len_delta ┃  Top Changes ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩ + │ price  │ 40.00% │ 0.75 │ 20.0% -> 0.0% │ │ None -> 30.0 │ + │ │ │ │ (-20.0) │ │ (1x) │ + │ │ │ │ │ │ 40.0 -> 42.0 │ + │ │ │ │ │ │ (1x) │ + │ │ │ │ │ │ 20.0 -> 21.0 │ + │ │ │ │ │ │ (1x) │ + ├────────┼────────────┼──────┼───────────────────┼───────────────┼──────────────────┤ + │ status │ 40.00% │ │ 0.0% -> 40.0% │ 0 │ "d" -> None (1x) │ + │ │ │ │ (+40.0) │ │ "c" -> "x" (1x) │ + │ │ │ │ │ │ "b" -> None (1x) │ + └────────┴────────────┴──────┴───────────────────┴───────────────┴──────────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_True_slim_True_sample_rows_True_sample_pk_True.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_True_slim_True_sample_rows_True_sample_pk_True.txt new file mode 100644 index 0000000..4a10c0c --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_False_top_True_slim_True_sample_rows_True_sample_pk_True.txt @@ -0,0 +1,27 @@ + Rows + ▔▔▔▔ + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃  Null% ┃ str_len_delta ┃  Top Changes ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩ + │ price  │ 40.00% │ 0.75 │ 20.0% -> 0.0% │ │ None -> 30.0 │ + │ │ │ │ (-20.0) │ │ (1x, e.g. 3) │ + │ │ │ │ │ │ 40.0 -> 42.0 │ + │ │ │ │ │ │ (1x, e.g. 4) │ + │ │ │ │ │ │ 20.0 -> 21.0 │ + │ │ │ │ │ │ (1x, e.g. 2) │ + ├────────┼────────────┼──────┼───────────────────┼───────────────┼──────────────────┤ + │ status │ 40.00% │ │ 0.0% -> 40.0% │ 0 │ "d" -> None (1x, │ + │ │ │ │ (+40.0) │ │ e.g. 4) │ + │ │ │ │ │ │ "c" -> "x" (1x, │ + │ │ │ │ │ │ e.g. 3) │ + │ │ │ │ │ │ "b" -> None (1x, │ + │ │ │ │ │ │ e.g. 2) │ + └────────┴────────────┴──────┴───────────────────┴───────────────┴──────────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_False_slim_False_sample_rows_False_sample_pk_False.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_False_slim_False_sample_rows_False_sample_pk_False.txt new file mode 100644 index 0000000..3a2a43b --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_False_slim_False_sample_rows_False_sample_pk_False.txt @@ -0,0 +1,28 @@ +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃  Diffly Summary  ┃ +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + Primary key: id + + Schemas + ▔▔▔▔▔▔▔ + Schemas match exactly (column count: 3). + + Rows + ▔▔▔▔ + Left count Right count + 5 (no change) 5 + + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃  Null% ┃ str_len_delta ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ + │ price  │ 40.00% │ 0.75 │ 20.0% -> 0.0% (-20.0) │ │ + │ status │ 40.00% │ │ 0.0% -> 40.0% (+40.0) │ 0 │ + └────────┴────────────┴──────┴───────────────────────┴───────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_False_slim_False_sample_rows_True_sample_pk_False.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_False_slim_False_sample_rows_True_sample_pk_False.txt new file mode 100644 index 0000000..3a2a43b --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_False_slim_False_sample_rows_True_sample_pk_False.txt @@ -0,0 +1,28 @@ +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃  Diffly Summary  ┃ +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + Primary key: id + + Schemas + ▔▔▔▔▔▔▔ + Schemas match exactly (column count: 3). + + Rows + ▔▔▔▔ + Left count Right count + 5 (no change) 5 + + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃  Null% ┃ str_len_delta ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ + │ price  │ 40.00% │ 0.75 │ 20.0% -> 0.0% (-20.0) │ │ + │ status │ 40.00% │ │ 0.0% -> 40.0% (+40.0) │ 0 │ + └────────┴────────────┴──────┴───────────────────────┴───────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_False_slim_True_sample_rows_False_sample_pk_False.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_False_slim_True_sample_rows_False_sample_pk_False.txt new file mode 100644 index 0000000..1316f6b --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_False_slim_True_sample_rows_False_sample_pk_False.txt @@ -0,0 +1,16 @@ + Rows + ▔▔▔▔ + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃  Null% ┃ str_len_delta ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ + │ price  │ 40.00% │ 0.75 │ 20.0% -> 0.0% (-20.0) │ │ + │ status │ 40.00% │ │ 0.0% -> 40.0% (+40.0) │ 0 │ + └────────┴────────────┴──────┴───────────────────────┴───────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_False_slim_True_sample_rows_True_sample_pk_False.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_False_slim_True_sample_rows_True_sample_pk_False.txt new file mode 100644 index 0000000..1316f6b --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_False_slim_True_sample_rows_True_sample_pk_False.txt @@ -0,0 +1,16 @@ + Rows + ▔▔▔▔ + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃  Null% ┃ str_len_delta ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ + │ price  │ 40.00% │ 0.75 │ 20.0% -> 0.0% (-20.0) │ │ + │ status │ 40.00% │ │ 0.0% -> 40.0% (+40.0) │ 0 │ + └────────┴────────────┴──────┴───────────────────────┴───────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_True_slim_False_sample_rows_False_sample_pk_False.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_True_slim_False_sample_rows_False_sample_pk_False.txt new file mode 100644 index 0000000..bdca125 --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_True_slim_False_sample_rows_False_sample_pk_False.txt @@ -0,0 +1,36 @@ +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃  Diffly Summary  ┃ +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + Primary key: id + + Schemas + ▔▔▔▔▔▔▔ + Schemas match exactly (column count: 3). + + Rows + ▔▔▔▔ + Left count Right count + 5 (no change) 5 + + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃  Null% ┃ str_len_delta ┃  Top Changes ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩ + │ price  │ 40.00% │ 0.75 │ 20.0% -> 0.0% │ │ None -> 30.0 │ + │ │ │ │ (-20.0) │ │ (1x) │ + │ │ │ │ │ │ 40.0 -> 42.0 │ + │ │ │ │ │ │ (1x) │ + │ │ │ │ │ │ 20.0 -> 21.0 │ + │ │ │ │ │ │ (1x) │ + ├────────┼────────────┼──────┼───────────────────┼───────────────┼──────────────────┤ + │ status │ 40.00% │ │ 0.0% -> 40.0% │ 0 │ "d" -> None (1x) │ + │ │ │ │ (+40.0) │ │ "c" -> "x" (1x) │ + │ │ │ │ │ │ "b" -> None (1x) │ + └────────┴────────────┴──────┴───────────────────┴───────────────┴──────────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_True_slim_False_sample_rows_True_sample_pk_True.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_True_slim_False_sample_rows_True_sample_pk_True.txt new file mode 100644 index 0000000..cdd7114 --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_True_slim_False_sample_rows_True_sample_pk_True.txt @@ -0,0 +1,39 @@ +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃  Diffly Summary  ┃ +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + Primary key: id + + Schemas + ▔▔▔▔▔▔▔ + Schemas match exactly (column count: 3). + + Rows + ▔▔▔▔ + Left count Right count + 5 (no change) 5 + + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃  Null% ┃ str_len_delta ┃  Top Changes ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩ + │ price  │ 40.00% │ 0.75 │ 20.0% -> 0.0% │ │ None -> 30.0 │ + │ │ │ │ (-20.0) │ │ (1x, e.g. 3) │ + │ │ │ │ │ │ 40.0 -> 42.0 │ + │ │ │ │ │ │ (1x, e.g. 4) │ + │ │ │ │ │ │ 20.0 -> 21.0 │ + │ │ │ │ │ │ (1x, e.g. 2) │ + ├────────┼────────────┼──────┼───────────────────┼───────────────┼──────────────────┤ + │ status │ 40.00% │ │ 0.0% -> 40.0% │ 0 │ "d" -> None (1x, │ + │ │ │ │ (+40.0) │ │ e.g. 4) │ + │ │ │ │ │ │ "c" -> "x" (1x, │ + │ │ │ │ │ │ e.g. 3) │ + │ │ │ │ │ │ "b" -> None (1x, │ + │ │ │ │ │ │ e.g. 2) │ + └────────┴────────────┴──────┴───────────────────┴───────────────┴──────────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_True_slim_True_sample_rows_False_sample_pk_False.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_True_slim_True_sample_rows_False_sample_pk_False.txt new file mode 100644 index 0000000..370a2d3 --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_True_slim_True_sample_rows_False_sample_pk_False.txt @@ -0,0 +1,24 @@ + Rows + ▔▔▔▔ + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃  Null% ┃ str_len_delta ┃  Top Changes ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩ + │ price  │ 40.00% │ 0.75 │ 20.0% -> 0.0% │ │ None -> 30.0 │ + │ │ │ │ (-20.0) │ │ (1x) │ + │ │ │ │ │ │ 40.0 -> 42.0 │ + │ │ │ │ │ │ (1x) │ + │ │ │ │ │ │ 20.0 -> 21.0 │ + │ │ │ │ │ │ (1x) │ + ├────────┼────────────┼──────┼───────────────────┼───────────────┼──────────────────┤ + │ status │ 40.00% │ │ 0.0% -> 40.0% │ 0 │ "d" -> None (1x) │ + │ │ │ │ (+40.0) │ │ "c" -> "x" (1x) │ + │ │ │ │ │ │ "b" -> None (1x) │ + └────────┴────────────┴──────┴───────────────────┴───────────────┴──────────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_True_slim_True_sample_rows_True_sample_pk_True.txt b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_True_slim_True_sample_rows_True_sample_pk_True.txt new file mode 100644 index 0000000..4a10c0c --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/gen/pretty_True_perfect_True_top_True_slim_True_sample_rows_True_sample_pk_True.txt @@ -0,0 +1,27 @@ + Rows + ▔▔▔▔ + ┏━┯━┯━┯━┯━┓╌╌╌┏━┯━┯━┯━┯━┓╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮ + ┃ │ │ │ │ ┃ = ┃ │ │ │ │ ┃ 2 equal (40.00%) │ + ┠─┼─┼─┼─┼─┨╌╌╌┠─┼─┼─┼─┼─┨╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌├╴ 5 joined + ┃ │ │ │ │ ┃ ≠ ┃ │ │ │ │ ┃ 3 unequal (60.00%) │ + ┗━┷━┷━┷━┷━┛╌╌╌┗━┷━┷━┷━┷━┛╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯ + + Columns + ▔▔▔▔▔▔▔ + ┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓ + ┃ Column ┃ Match Rate ┃ Mean ┃  Null% ┃ str_len_delta ┃  Top Changes ┃ + ┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩ + │ price  │ 40.00% │ 0.75 │ 20.0% -> 0.0% │ │ None -> 30.0 │ + │ │ │ │ (-20.0) │ │ (1x, e.g. 3) │ + │ │ │ │ │ │ 40.0 -> 42.0 │ + │ │ │ │ │ │ (1x, e.g. 4) │ + │ │ │ │ │ │ 20.0 -> 21.0 │ + │ │ │ │ │ │ (1x, e.g. 2) │ + ├────────┼────────────┼──────┼───────────────────┼───────────────┼──────────────────┤ + │ status │ 40.00% │ │ 0.0% -> 40.0% │ 0 │ "d" -> None (1x, │ + │ │ │ │ (+40.0) │ │ e.g. 4) │ + │ │ │ │ │ │ "c" -> "x" (1x, │ + │ │ │ │ │ │ e.g. 3) │ + │ │ │ │ │ │ "b" -> None (1x, │ + │ │ │ │ │ │ e.g. 2) │ + └────────┴────────────┴──────┴───────────────────┴───────────────┴──────────────────┘ diff --git a/tests/summary/fixtures/metrics_null_fraction/test_metrics_null_fraction.py b/tests/summary/fixtures/metrics_null_fraction/test_metrics_null_fraction.py new file mode 100644 index 0000000..a0a74d8 --- /dev/null +++ b/tests/summary/fixtures/metrics_null_fraction/test_metrics_null_fraction.py @@ -0,0 +1,44 @@ +# Copyright (c) QuantCo 2025-2026 +# SPDX-License-Identifier: BSD-3-Clause + +import polars as pl +import polars.selectors as cs +import pytest + +from diffly import compare_frames, metrics +from diffly.metrics import Metric +from tests.utils import generate_summaries + + +@pytest.mark.generate +def test_generate() -> None: + left = pl.DataFrame( + { + "id": [1, 2, 3, 4, 5], + "price": [10.0, 20.0, None, 40.0, 50.0], + "status": ["a", "b", "c", "d", "e"], + } + ) + right = pl.DataFrame( + { + "id": [1, 2, 3, 4, 5], + "price": [10.0, 21.0, 30.0, 42.0, 50.0], + "status": ["a", None, "x", None, "e"], + } + ) + comp = compare_frames(left, right, primary_key=["id"]) + generate_summaries( + comp, + metrics={ + # Numeric-only preset alongside a metric applied to all columns. + "Mean": metrics.mean, + "Null%": metrics.DEFAULT_METRICS["Null%"], + # A user-supplied metric with a custom (string-only) selector. + "str_len_delta": Metric( + fn=lambda left, right: ( + right.str.len_chars() - left.str.len_chars() + ).mean(), + selector=cs.string(), + ), + }, + ) diff --git a/tests/test_metrics.py b/tests/test_metrics.py index add8bd0..2bd3a14 100644 --- a/tests/test_metrics.py +++ b/tests/test_metrics.py @@ -2,6 +2,7 @@ # SPDX-License-Identifier: BSD-3-Clause import math +from typing import Any import polars as pl import pytest @@ -16,7 +17,7 @@ def frame() -> pl.DataFrame: return pl.DataFrame({"l": [1, 2, 3, None], "r": [1, 2, 5, 4]}) -def _apply(metric: MetricFn, frame: pl.DataFrame) -> float: +def _apply(metric: MetricFn, frame: pl.DataFrame) -> Any: return frame.select(metric(pl.col("l"), pl.col("r"))).item() @@ -64,6 +65,24 @@ def test_mean_relative_deviation_div_by_zero() -> None: assert math.isinf(_apply(metrics.mean_relative_deviation, frame)) +def test_null_fraction_change() -> None: + # left nulls: 1/4 = 25%; right nulls: 3/4 = 75%; delta = +50% + frame = pl.DataFrame({"l": [1, None, 3, 4], "r": [None, None, 3, None]}) + assert _apply(metrics.null_fraction_change, frame) == "25.0% -> 75.0% (+50.0)" + + +def test_null_fraction_change_negative_delta() -> None: + # left nulls: 1/2 = 50%; right nulls: 0%; delta = -50% + frame = pl.DataFrame({"l": [1, None], "r": [1, 2]}) + assert _apply(metrics.null_fraction_change, frame) == "50.0% -> 0.0% (-50.0)" + + +def test_null_fraction_change_non_numeric() -> None: + # Applies to any column type; here strings. left nulls: 0%; right nulls: 50% + frame = pl.DataFrame({"l": ["a", "b"], "r": ["a", None]}) + assert _apply(metrics.null_fraction_change, frame) == "0.0% -> 50.0% (+50.0)" + + def test_quantile(frame: pl.DataFrame) -> None: # deltas [0, 0, 2]: p50 = 0, p100 = 2 assert _apply(metrics.quantile(0.5), frame) == 0