import unittest

from experiment import compare_inventory, reference_crc32c, require


class ManifestTests(unittest.TestCase):
    def test_unchanged(self):
        self.assertEqual(compare_inventory({"a": "1"}, {"a": "1"}),
                         {"missing": [], "unexpected": [], "changed": []})

    def test_missing(self):
        self.assertEqual(compare_inventory({"a": "1"}, {})["missing"], ["a"])

    def test_changed(self):
        self.assertEqual(compare_inventory({"a": "1"}, {"a": "2"})["changed"], ["a"])

    def test_unexpected(self):
        self.assertEqual(compare_inventory({}, {"a": "1"})["unexpected"], ["a"])

    def test_address_binding(self):
        self.assertEqual(compare_inventory({"a": "1", "b": "2"}, {"a": "2", "b": "1"})["changed"],
                         ["a", "b"])

    def test_invariant_survives_optimized_python(self):
        with self.assertRaisesRegex(RuntimeError, "control"):
            require(False, "control")

    def test_reference_crc32c(self):
        self.assertEqual(reference_crc32c(b"123456789"), 0xE3069283)
        self.assertEqual(reference_crc32c(b""), 0)


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