@@ -45,12 +45,15 @@ def test_infinite_loop_risk_matches_plain_while_true(self):
4545 pattern = _compiled_rule ("Infinite Loop Risk" )
4646 self .assertIsNotNone (pattern .search ("while True:" ))
4747 self .assertIsNotNone (pattern .search (" while True: # daemon" ))
48+ self .assertIsNotNone (pattern .search ("while 1:" ))
49+ self .assertIsNotNone (pattern .search (" while 1: # spin" ))
4850
4951 def test_infinite_loop_risk_ignores_noncanonical_loops (self ):
5052 pattern = _compiled_rule ("Infinite Loop Risk" )
5153 self .assertIsNone (pattern .search ("while not stopped:" ))
5254 self .assertIsNone (pattern .search ("if cond: while True:" ))
5355 self .assertIsNone (pattern .search ("while True: do_work()" ))
56+ self .assertIsNone (pattern .search ("while 1: do_work()" ))
5457
5558 def test_hardcoded_ticker_symbol_matches_real_single_symbol_assignments (self ):
5659 pattern = _compiled_rule ("Hardcoded Ticker Symbol" )
@@ -67,6 +70,8 @@ def test_sleep_without_kill_switch_matches_hardcoded_sleep_calls(self):
6770 pattern = _compiled_rule ("Sleep Without Kill Switch" )
6871 self .assertIsNotNone (pattern .search ("time.sleep(5)" ))
6972 self .assertIsNotNone (pattern .search ("time.sleep(0.25) # poll" ))
73+ self .assertIsNotNone (pattern .search ("time.sleep(0.5)" ))
74+ self .assertIsNotNone (pattern .search ("time.sleep(1.0)" ))
7075
7176 def test_sleep_without_kill_switch_ignores_variable_or_inline_sleep (self ):
7277 pattern = _compiled_rule ("Sleep Without Kill Switch" )
@@ -89,5 +94,56 @@ def test_no_position_size_limit_ignores_capped_or_risk_budget_sizing(self):
8994 self .assertIsNone (pattern .search ("qty = clip(balance / price, 0, max_qty)" ))
9095
9196
97+ # --- Extended Hours Without Limit Order ---
98+ def test_extended_hours_matches_true_assignments (self ):
99+ pattern = _compiled_rule ("Extended Hours Without Limit Order" )
100+ self .assertIsNotNone (pattern .search ("extended_hours=True" ))
101+ self .assertIsNotNone (pattern .search ("extended_hours = True" ))
102+ self .assertIsNotNone (pattern .search ('extended_hours: True' ))
103+
104+ def test_extended_hours_ignores_false_or_variable (self ):
105+ pattern = _compiled_rule ("Extended Hours Without Limit Order" )
106+ self .assertIsNone (pattern .search ("extended_hours=False" ))
107+ self .assertIsNone (pattern .search ("extended_hours = use_ext" ))
108+
109+ # --- Leverage Without Cap ---
110+ def test_leverage_without_cap_matches_bare_numeric (self ):
111+ pattern = _compiled_rule ("Leverage Without Cap" )
112+ self .assertIsNotNone (pattern .search ("leverage = 4" ))
113+ self .assertIsNotNone (pattern .search ("margin_multiplier = 10" ))
114+ self .assertIsNotNone (pattern .search ("margin_ratio = 2" ))
115+
116+ def test_leverage_without_cap_ignores_capped_or_config (self ):
117+ pattern = _compiled_rule ("Leverage Without Cap" )
118+ self .assertIsNone (pattern .search ("leverage = min(4, max_leverage)" ))
119+ self .assertIsNone (pattern .search ("leverage = config.get('leverage')" ))
120+ self .assertIsNone (pattern .search ("margin_multiplier = env.MAX_LEVERAGE" ))
121+
122+ # --- Hardcoded Notional Amount ---
123+ def test_hardcoded_notional_matches_large_values (self ):
124+ pattern = _compiled_rule ("Hardcoded Notional Amount" )
125+ self .assertIsNotNone (pattern .search ("notional = 100000" ))
126+ self .assertIsNotNone (pattern .search ("order_value = 50000" ))
127+ self .assertIsNotNone (pattern .search ("trade_value = 25000" ))
128+
129+ def test_hardcoded_notional_ignores_small_or_variable (self ):
130+ pattern = _compiled_rule ("Hardcoded Notional Amount" )
131+ self .assertIsNone (pattern .search ("notional = 999" ))
132+ self .assertIsNone (pattern .search ("notional = computed_value" ))
133+ self .assertIsNone (pattern .search ("order_value = get_notional()" ))
134+
135+ # --- Hardcoded Crypto Pair ---
136+ def test_hardcoded_crypto_pair_matches_common_pairs (self ):
137+ pattern = _compiled_rule ("Hardcoded Crypto Pair" )
138+ self .assertIsNotNone (pattern .search ('symbol="BTCUSDT"' ))
139+ self .assertIsNotNone (pattern .search ("pair='ETH/USD'" ))
140+ self .assertIsNotNone (pattern .search ('ticker="SOLUSDC"' ))
141+
142+ def test_hardcoded_crypto_pair_ignores_variables_and_equity_tickers (self ):
143+ pattern = _compiled_rule ("Hardcoded Crypto Pair" )
144+ self .assertIsNone (pattern .search ("symbol = get_pair()" ))
145+ self .assertIsNone (pattern .search ('symbol="AAPL"' ))
146+
147+
92148if __name__ == "__main__" :
93149 unittest .main ()
0 commit comments