Skip to content

Expand CashFlowStream edge-case and contract test coverage #7

Description

@j-bryan

The dedicated CashFlowStream tests cover the main examples well, but several public branches and behavioral contracts are not exercised directly. These are test coverage limitations, not confirmed production defects.

A focused branch-coverage run identifies unexecuted paths in CashFlowStream.filter(), CashFlowStream.group_by(), and the group_by_period() convenience method. Inspection also shows several documented collection properties that currently rely on a single example rather than boundary or relationship checks.

Suggested deterministic coverage

Filtering

  • Calling filter() with neither a predicate nor keyword criteria raises ValueError.
  • Combining a callable predicate with keyword criteria raises ValueError.
  • Multiple keyword criteria use AND semantics.
  • is_cash=False selects non-cash entries.
  • pro_forma_category=None selects uncategorized entries.
  • String classification inputs are normalized consistently.

These tests would reject defects such as accidentally changing AND semantics to OR or treating False as an omitted argument.

Grouping

  • Calling group_by() with neither selector raises ValueError.
  • Providing both a callable and period raises ValueError.
  • group_by_period(period) produces the same groups as group_by(period=period).
  • Grouping preserves the total entry count and all duplicate entries.

Ordering and ranges

  • Sorting is stable when multiple cashflows have equal keys.
  • Negative indices and stepped or reversed slices match ordinary Python list behavior.
  • date_range(start, end) includes an entry exactly on start and excludes an entry exactly on end.
  • date_range(start, start) returns an empty stream.
  • Zero-valued cashflows are in neither inflows() nor outflows().

Transformations

  • scale() changes only amount and preserves date, label, is_cash, pro-forma category, and tax treatment.
  • Scaling by 1, 0, and a negative factor covers identity, zero, and sign reversal.
  • apply(), flat_apply(), and filter_apply() preserve the documented output ordering.
  • Every non-mutating method leaves the original entry sequence unchanged.

Automatic input exploration

After these properties are explicit, bounded property-based tests could compare:

  • filter(predicate) with a plain list comprehension;
  • sort() with Python sorted();
  • date_range() with the half-open interval predicate;
  • grouped entry counts and duplicate-preserving reconciliation;
  • scaled entry metadata with the original metadata.

Generated inputs should explore empty, singleton, duplicate, equal-key, zero, mixed-sign, and boundary-date cases. Property-based generation should supplement these deterministic oracle cases rather than replace them.

Acceptance criteria

  • Add direct tests for the uncovered selector and convenience-method branches.
  • Add boundary tests for half-open date ranges and zero-valued flows.
  • Add metadata-preservation and stable-order tests.
  • Keep each test focused on one externally meaningful property.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions