import copy
import unittest
import compare

class StrictContractTests(unittest.TestCase):
    def test_object_order_ignored(self):
        self.assertTrue(compare.equal({'a':1,'b':[]},{'b':[],'a':1}))
    def test_number_type(self):
        self.assertFalse(compare.equal(1,1.0))
    def test_bool_number(self):
        self.assertFalse(compare.equal(True,1))
    def test_empty_container(self):
        self.assertFalse(compare.equal([],{}))
    def test_array_order(self):
        self.assertFalse(compare.equal(['甲','乙'],['乙','甲']))
    def test_null(self):
        self.assertFalse(compare.equal(None,''))
    def test_missing_member(self):
        self.assertFalse(compare.equal({'a':None},{}))
    def test_precision(self):
        self.assertFalse(compare.equal('9007199254740993.01','9007199254740993.00'))
    def test_source_invalid_id(self):
        with self.assertRaises(AssertionError):
            compare.source_row({'page_id':'1','create_time':'2026-10-10 00:00:00','update_time':'2026-10-10 00:00:00'}, {'owned':{'store':[1]},'independent_final_original_rows':[]},'store','CREATED')
    def test_unproven_epoch(self):
        with self.assertRaises(AssertionError):
            compare.source_row({'page_id':1,'create_time':'2026-10-10 00:00:00','update_time':'2026-10-10 00:00:00'}, {'owned':{'store':[1]},'independent_final_original_rows':[{'page_id':1,'create_time':1}]},'store','EDITED')
    def test_final_real_corpus(self):
        import json
        p=json.loads((compare.ROOT/'final-read-B.json').read_text());e=json.loads((compare.ROOT/'evidence-B.json').read_text())
        self.assertEqual(len(compare.verify_final(p,e)),4)
    def test_final_changed_original_time(self):
        import json
        p=json.loads((compare.ROOT/'final-read-B.json').read_text());e=json.loads((compare.ROOT/'evidence-B.json').read_text())
        p['cases'][0]['original_oracle']['original_row']['update_time']=1
        with self.assertRaises(AssertionError):compare.verify_final(p,e)
    def test_final_wrong_number_type(self):
        import json
        p=json.loads((compare.ROOT/'final-read-B.json').read_text());e=json.loads((compare.ROOT/'evidence-B.json').read_text())
        p['cases'][0]['body']['data']['detail']['page_type']='20'
        with self.assertRaises(AssertionError):compare.verify_final(p,e)
    def test_final_wrong_container(self):
        import json
        p=json.loads((compare.ROOT/'final-read-B.json').read_text());e=json.loads((compare.ROOT/'evidence-B.json').read_text())
        p['cases'][0]['body']['data']['detail']['page_data']['audit']['emptyArray']={}
        with self.assertRaises(AssertionError):compare.verify_final(p,e)
    def test_final_wrong_order(self):
        import json
        p=json.loads((compare.ROOT/'final-read-B.json').read_text());e=json.loads((compare.ROOT/'evidence-B.json').read_text())
        p['cases'][0]['body']['data']['detail']['page_data']['audit']['ordered'].reverse()
        with self.assertRaises(AssertionError):compare.verify_final(p,e)
    def test_final_missing_original_proof(self):
        import json
        p=json.loads((compare.ROOT/'final-read-B.json').read_text());e=json.loads((compare.ROOT/'evidence-B.json').read_text())
        p['fresh_original_rows_unchanged']=False
        with self.assertRaises(AssertionError):compare.verify_final(p,e)
    def test_final_native_failure(self):
        import json
        p=json.loads((compare.ROOT/'final-read-B.json').read_text());e=json.loads((compare.ROOT/'evidence-B.json').read_text())
        p['native_exit']=1
        with self.assertRaises(AssertionError):compare.verify_final(p,e)
    def test_final_missing_case(self):
        import json
        p=json.loads((compare.ROOT/'final-read-B.json').read_text());e=json.loads((compare.ROOT/'evidence-B.json').read_text())
        p['cases'].pop()
        with self.assertRaises(AssertionError):compare.verify_final(p,e)

if __name__=='__main__':unittest.main()
