75 lines
3.9 KiB
Python
75 lines
3.9 KiB
Python
import copy
|
|
import pytest
|
|
from viano_bug_analysis.analysis.database_value_grounding import unsupported_assignments
|
|
from viano_bug_analysis.profiles.database_bindings import fact_bindings
|
|
|
|
|
|
def context():
|
|
case = {'case': {'project': {'type': 'wow', 'profile': 'vcore'}},
|
|
'runtime_facts': {'facts': [{'id': 'F0002', 'name': 'map_id', 'value': 0,
|
|
'provenance': {'kind': 'reproduction_record', 'source_ref': 'reproduction.json'}}]}}
|
|
return {'parameter_grounding': 2, 'case': case,
|
|
'database_fact_bindings': fact_bindings(case),
|
|
'evidence': {'E000001': {'content': {'items': [{'query': {'kind':'database.rows','table':'creature'},
|
|
'result': {'items': [{'row': {'map':1,'phaseMask':1,'zoneId':14}}]}}]}}}}
|
|
|
|
|
|
def rejected(c, text='Use map=0.'):
|
|
return unsupported_assignments({'implementation_guidance':[text]}, c)
|
|
|
|
|
|
def test_canonical_map_zero_authorizes_known_creature_column_without_mutation():
|
|
c=context(); before=copy.deepcopy(c)
|
|
assert c['database_fact_bindings']==[{'fact_id':'F0002','fact_name':'map_id','table':'creature','column':'map'}]
|
|
assert rejected(c)==[] and c==before
|
|
assert rejected(c,'Use map=2.')==['map']
|
|
assert rejected(c,'Use phaseMask=14.')==['phasemask']
|
|
|
|
|
|
def test_legacy_context_preserves_rejection_and_exact_named_fact_needs_v2():
|
|
c=context(); c['parameter_grounding']=1
|
|
assert rejected(c)==['map']
|
|
c['parameter_grounding']=2;c['database_fact_bindings']=[]
|
|
assert rejected(c)==['map']
|
|
c['case']['runtime_facts']['facts'][0]['name']='map'
|
|
assert rejected(c)==[]
|
|
|
|
|
|
@pytest.mark.parametrize('change',[
|
|
lambda c: c['case']['case']['project'].update(profile='other'),
|
|
lambda c: c['case']['runtime_facts']['facts'][0].update(value='0'),
|
|
lambda c: c['case']['runtime_facts']['facts'][0].update(value=False),
|
|
lambda c: c['case']['runtime_facts']['facts'][0].update(name='zone_id'),
|
|
lambda c: c['case']['runtime_facts']['facts'][0]['provenance'].update(kind='tester_assumption'),
|
|
lambda c: c['database_fact_bindings'][0].update(column='phaseMask'),
|
|
lambda c: c['database_fact_bindings'][0].update(fact_id='UNKNOWN'),
|
|
lambda c: c['evidence']['E000001']['content']['items'][0]['query'].update(table='unrelated'),
|
|
lambda c: c['case']['runtime_facts']['facts'].append(copy.deepcopy(c['case']['runtime_facts']['facts'][0])),
|
|
])
|
|
def test_alias_does_not_grant_unbound_or_ambiguous_values(change):
|
|
c=context();change(c)
|
|
assert rejected(c)==['map']
|
|
|
|
|
|
def test_unknown_suffix_is_not_an_alias_and_schema_only_binding_is_supported():
|
|
c=context();f=c['case']['runtime_facts']['facts'][0];f['name']='custom_map_id'
|
|
c['database_fact_bindings']=fact_bindings(c['case'])
|
|
assert c['database_fact_bindings']==[] and rejected(c)==['map']
|
|
f['name']='map_id';c['database_fact_bindings']=fact_bindings(c['case'])
|
|
cap=c['evidence']['E000001']['content']['items'][0]
|
|
cap['query']['kind']='database.schema'
|
|
cap['result']['items']=[{'table':'creature','columns':[{'COLUMN_NAME':'map','COLUMN_TYPE':'smallint(5) unsigned'}]}]
|
|
assert rejected(c)==[]
|
|
|
|
|
|
def test_full_handoff_validator_accepts_bound_map_but_still_rejects_wrong_mask():
|
|
from test_handoff_outcomes import minimal, template
|
|
from viano_bug_analysis.analysis.change_request_contracts import validate_request, ChangeRequestError
|
|
payload,c=minimal();new=context();c.update({k:new[k] for k in ('case','parameter_grounding','database_fact_bindings')})
|
|
c['evidence']['E000001']['content']=new['evidence']['E000001']['content']
|
|
for item in c['evidence']['E000001']['content']['items']:item['source_ref']='code.cpp'
|
|
template(payload,c);payload['implementation_guidance']=['Use map=0 and {{POSITION_X}}.']
|
|
validate_request(payload,c)
|
|
payload['implementation_guidance']=['Use map=0, phaseMask=14 and {{POSITION_X}}.']
|
|
with pytest.raises(ChangeRequestError,match='UNGROUNDED_DATABASE_VALUE'):validate_request(payload,c)
|