#!/usr/bin/env python3
import copy
import json
import unittest
from pathlib import Path
from compare import compare


class MutationTests(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        base = Path(__file__).parent
        cls.b = json.loads((base / 'evidence-B.json').read_text())
        cls.c = json.loads((base / 'evidence-C.json').read_text())

    def reject(self, mutate):
        c = copy.deepcopy(self.c)
        mutate(c)
        with self.assertRaises(AssertionError):
            compare(self.b, c)

    def test_green(self): compare(self.b, self.c)
    def test_case_missing(self): self.reject(lambda c: c['cases'].pop())
    def test_wire_type(self): self.reject(lambda c: c['cases'][0]['body']['data']['nutrition_value']['power_wire'].__setitem__('wa', '0'))
    def test_wire_array_object(self): self.reject(lambda c: c['cases'][0]['raw_json_shape'].__setitem__('object', []))
    def test_meal_order(self): self.reject(lambda c: c['cases'][0]['body']['data']['lists'].reverse())
    def test_independent_decimal(self): self.reject(lambda c: c['proofs'][0]['values'].__setitem__('ree', '1483.34'))
    def test_store_not_ignored(self): self.reject(lambda c: c['proofs'][0]['values'].__setitem__('store_id', 10001))
    def test_history_increment(self): self.reject(lambda c: c['proofs'][4].__setitem__('history_rows', 1))
    def test_history_prefix(self): self.reject(lambda c: c['proofs'][4].__setitem__('earlier_history_original_rows_unchanged', False))
    def test_dml_scope(self): self.reject(lambda c: c['write_audit'][0].__setitem__('owned_scope_verified', False))
    def test_cleanup(self): self.reject(lambda c: c['fresh_pdo_cleanup']['fresh_pdo_owned_rows'].__setitem__('user', 1))
    def test_natural_hash(self): self.reject(lambda c: c['fresh_pdo_cleanup'].__setitem__('five_input_tables_and_dictionaries_full_sha_unchanged', False))
    def test_trace_not_silently_ignored(self): self.reject(lambda c: c['cases'][0].__setitem__('trace_format_valid', False))


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