@@ -448,6 +448,77 @@ def test_strict_plan_loader_rejects_runtime_type_confusion() -> None:
448448 assert caught .value .code == "invalid_transformation_plan"
449449
450450
451+ def test_strict_plan_loader_rejects_unhashable_enum_values () -> None :
452+ typed_value = TypedValue .binary64 (1 ).as_dict ()
453+ literal = {"kind" : "literal" , "value" : typed_value }
454+ variable = {"kind" : "variable" , "variable" : "q1" }
455+ comparison = {
456+ "expression" : "comparison" ,
457+ "left" : variable ,
458+ "operator" : "=" ,
459+ "right" : literal ,
460+ }
461+ invalid_operations = [
462+ {
463+ "op" : "conditional_assign" ,
464+ "condition" : {** comparison , "operator" : []},
465+ "target" : "q1" ,
466+ "value" : literal ,
467+ },
468+ {
469+ "op" : "conditional_assign" ,
470+ "condition" : {
471+ "expression" : "boolean" ,
472+ "operator" : {},
473+ "operands" : [comparison , comparison ],
474+ },
475+ "target" : "q1" ,
476+ "value" : literal ,
477+ },
478+ {
479+ "op" : "assign" ,
480+ "target" : "q2" ,
481+ "target_mode" : [],
482+ "value" : literal ,
483+ },
484+ {
485+ "op" : "set_measurement_level" ,
486+ "variable" : "q1" ,
487+ "level" : {},
488+ },
489+ {
490+ "op" : "recode" ,
491+ "source" : "q1" ,
492+ "target" : "q2" ,
493+ "target_mode" : [],
494+ "rules" : [{
495+ "match" : {"kind" : "values" , "values" : [typed_value ]},
496+ "result" : {"kind" : "literal" , "value" : typed_value },
497+ }],
498+ "unmatched" : {"kind" : "copy" },
499+ },
500+ ]
501+
502+ raw_plans = [
503+ {
504+ "contract" : "openstatspec-transformation-plan-v0.2" ,
505+ "input_alias" : "parent" ,
506+ "operations" : [operation ],
507+ }
508+ for operation in invalid_operations
509+ ]
510+ raw_plans .append ({
511+ "contract" : [],
512+ "input_alias" : "parent" ,
513+ "operations" : [{"op" : "execute" }],
514+ })
515+
516+ for raw in raw_plans :
517+ with pytest .raises (TransformationFrontendError ) as caught :
518+ transformation_plan_from_dict (raw )
519+ assert caught .value .code == "invalid_transformation_plan"
520+
521+
451522def test_v02_plan_and_schema_reject_decimal_format_that_cannot_fit () -> None :
452523 raw = {
453524 "contract" : "openstatspec-transformation-plan-v0.2" ,
0 commit comments