Skip to content

Commit 3c30f8e

Browse files
igerberclaude
andcommitted
Add survey test coverage for TripleDiff covariates and EfficientDiD aggregations from PR #226 review (round 12)
- TripleDifference: reg method with covariates + survey test - TripleDifference: scale invariance test for survey weights - EfficientDiD: survey tests for event_study, group, and all aggregations - All assert finite ATT/SE and survey metadata presence Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 4f04832 commit 3c30f8e

1 file changed

Lines changed: 106 additions & 0 deletions

File tree

tests/test_survey_phase3.py

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,29 @@ def test_summary_includes_survey(self, ddd_survey_data):
532532
)
533533
assert "Survey Design" in result.summary()
534534

535+
def test_reg_with_covariates_survey(self, ddd_survey_data):
536+
"""TripleDifference reg method works with covariates + survey."""
537+
from diff_diff import TripleDifference
538+
539+
# Add a covariate that affects the outcome
540+
ddd_survey_data["x1"] = np.random.randn(len(ddd_survey_data)) * 0.5
541+
ddd_survey_data["outcome"] += 0.3 * ddd_survey_data["x1"]
542+
sd = SurveyDesign(weights="weight", strata="stratum")
543+
result = TripleDifference(estimation_method="reg").fit(
544+
ddd_survey_data,
545+
"outcome",
546+
"group",
547+
"partition",
548+
"time",
549+
covariates=["x1"],
550+
survey_design=sd,
551+
)
552+
assert np.isfinite(result.att)
553+
assert np.isfinite(result.se)
554+
assert result.survey_metadata is not None
555+
# Survey df should be used for inference
556+
assert result.survey_metadata.df_survey is not None
557+
535558

536559
# =============================================================================
537560
# ContinuousDiD
@@ -691,6 +714,64 @@ def test_no_survey_metadata_is_none(self, staggered_survey_data):
691714
)
692715
assert result.survey_metadata is None
693716

717+
def test_survey_event_study_aggregation(self, staggered_survey_data):
718+
"""EfficientDiD survey with aggregate='event_study' produces finite results."""
719+
from diff_diff import EfficientDiD
720+
721+
sd = SurveyDesign(weights="weight")
722+
result = EfficientDiD(n_bootstrap=0).fit(
723+
staggered_survey_data,
724+
"outcome",
725+
"unit",
726+
"time",
727+
"first_treat",
728+
aggregate="event_study",
729+
survey_design=sd,
730+
)
731+
assert result.event_study_effects is not None
732+
for e, eff in result.event_study_effects.items():
733+
assert np.isfinite(eff["effect"])
734+
assert np.isfinite(eff["se"])
735+
assert eff["se"] > 0
736+
737+
def test_survey_group_aggregation(self, staggered_survey_data):
738+
"""EfficientDiD survey with aggregate='group' produces finite results."""
739+
from diff_diff import EfficientDiD
740+
741+
sd = SurveyDesign(weights="weight")
742+
result = EfficientDiD(n_bootstrap=0).fit(
743+
staggered_survey_data,
744+
"outcome",
745+
"unit",
746+
"time",
747+
"first_treat",
748+
aggregate="group",
749+
survey_design=sd,
750+
)
751+
assert result.group_effects is not None
752+
for g, eff in result.group_effects.items():
753+
assert np.isfinite(eff["effect"])
754+
assert np.isfinite(eff["se"])
755+
756+
def test_survey_all_aggregation(self, staggered_survey_data):
757+
"""EfficientDiD survey with aggregate='all' produces finite results."""
758+
from diff_diff import EfficientDiD
759+
760+
sd = SurveyDesign(weights="weight")
761+
result = EfficientDiD(n_bootstrap=0).fit(
762+
staggered_survey_data,
763+
"outcome",
764+
"unit",
765+
"time",
766+
"first_treat",
767+
aggregate="all",
768+
survey_design=sd,
769+
)
770+
assert result.event_study_effects is not None
771+
assert result.group_effects is not None
772+
assert np.isfinite(result.overall_att)
773+
assert np.isfinite(result.overall_se)
774+
694775

695776
# =============================================================================
696777
# Scale Invariance (applies to all estimators)
@@ -754,6 +835,31 @@ def test_efficient_did_scale_invariance(self, staggered_survey_data):
754835
assert abs(r1.overall_att - r2.overall_att) < 1e-10
755836
assert abs(r1.overall_se - r2.overall_se) < 1e-8
756837

838+
def test_triple_diff_scale_invariance(self, ddd_survey_data):
839+
from diff_diff import TripleDifference
840+
841+
sd1 = SurveyDesign(weights="weight")
842+
r1 = TripleDifference(estimation_method="reg").fit(
843+
ddd_survey_data,
844+
"outcome",
845+
"group",
846+
"partition",
847+
"time",
848+
survey_design=sd1,
849+
)
850+
ddd_survey_data["weight_x10"] = ddd_survey_data["weight"] * 10.0
851+
sd2 = SurveyDesign(weights="weight_x10")
852+
r2 = TripleDifference(estimation_method="reg").fit(
853+
ddd_survey_data,
854+
"outcome",
855+
"group",
856+
"partition",
857+
"time",
858+
survey_design=sd2,
859+
)
860+
assert abs(r1.att - r2.att) < 1e-10
861+
assert abs(r1.se - r2.se) < 1e-8
862+
757863

758864
# =============================================================================
759865
# Regression Tests (PR #226 review feedback)

0 commit comments

Comments
 (0)