text: from avro.compatibility import SchemaCompatibilityResult, SchemaCompatibilityType
  from jsonschema import Draft7Validator
  from karapace.compatibility.jsonschema.checks import compatibility
  from tests.schemas.json_schemas import (
      A_DINT_B_DINT_OBJECT_SCHEMA,
      A_DINT_B_INT_OBJECT_SCHEMA,
      A_DINT_B_NUM_C_DINT_OBJECT_SCHEMA,
      A_DINT_B_NUM_OBJECT_SCHEMA,
      A_DINT_OBJECT_SCHEMA,
      A_INT_B_DINT_OBJECT_SCHEMA,
      A_INT_B_DINT_REQUIRED_OBJECT_SCHEMA,
      A_INT_B_INT_OBJECT_SCHEMA,
      A_INT_B_INT_REQUIRED_OBJECT_SCHEMA,
      A_INT_OBJECT_SCHEMA,
      A_INT_OPEN_OBJECT_SCHEMA,
      A_OBJECT_SCHEMA,
      ARRAY_OF_INT_SCHEMA,
      ARRAY_OF_NUMBER_SCHEMA,
      ARRAY_OF_POSITIVE_INTEGER,
      ARRAY_OF_POSITIVE_INTEGER_THROUGH_REF,
      ARRAY_OF_STRING_SCHEMA,
      ARRAY_SCHEMA,
      B_DINT_OPEN_OBJECT_SCHEMA,
      B_INT_OBJECT_SCHEMA,
      B_INT_OPEN_OBJECT_SCHEMA,
      B_NUM_C_DINT_OPEN_OBJECT_SCHEMA,
      B_NUM_C_INT_OBJECT_SCHEMA,
      B_NUM_C_INT_OPEN_OBJECT_SCHEMA,
      BOOLEAN_SCHEMA,
      BOOLEAN_SCHEMAS,
      EMPTY_OBJECT_SCHEMA,
      EMPTY_SCHEMA,
      ENUM_AB_SCHEMA,
      ENUM_ABC_SCHEMA,
      ENUM_BC_SCHEMA,
      EVERY_TYPE_SCHEMA,
      EXCLUSIVE_MAXIMUM_DECREASED_INTEGER_SCHEMA,
      EXCLUSIVE_MAXIMUM_DECREASED_NUMBER_SCHEMA,
      EXCLUSIVE_MAXIMUM_INTEGER_SCHEMA,
      EXCLUSIVE_MAXIMUM_NUMBER_SCHEMA,
      EXCLUSIVE_MINIMUM_INCREASED_INTEGER_SCHEMA,
      EXCLUSIVE_MINIMUM_INCREASED_NUMBER_SCHEMA,
      EXCLUSIVE_MINIMUM_INTEGER_SCHEMA,
      EXCLUSIVE_MINIMUM_NUMBER_SCHEMA,
      FALSE_SCHEMA,
      INT_SCHEMA,
      MAX_ITEMS_DECREASED_SCHEMA,
      MAX_ITEMS_SCHEMA,
      MAX_LENGTH_DECREASED_SCHEMA,
      MAX_LENGTH_SCHEMA,
      MAX_PROPERTIES_DECREASED_SCHEMA,
      MAX_PROPERTIES_SCHEMA,
      MAXIMUM_DECREASED_INTEGER_SCHEMA,
      MAXIMUM_DECREASED_NUMBER_SCHEMA,
      MAXIMUM_INTEGER_SCHEMA,
      MAXIMUM_NUMBER_SCHEMA,
      MIN_ITEMS_INCREASED_SCHEMA,
      MIN_ITEMS_SCHEMA,
      MIN_LENGTH_INCREASED_SCHEMA,
      MIN_LENGTH_SCHEMA,
      MIN_PATTERN_SCHEMA,
      MIN_PATTERN_STRICT_SCHEMA,
      MIN_PROPERTIES_INCREASED_SCHEMA,
      MIN_PROPERTIES_SCHEMA,
      MINIMUM_INCREASED_INTEGER_SCHEMA,
      MINIMUM_INCREASED_NUMBER_SCHEMA,
      MINIMUM_INTEGER_SCHEMA,
      MINIMUM_NUMBER_SCHEMA,
      NON_OBJECT_SCHEMAS,
      NOT_ARRAY_SCHEMA,
      NOT_BOOLEAN_SCHEMA,
      NOT_INT_SCHEMA,
      NOT_NUMBER_SCHEMA,
      NOT_OBJECT_SCHEMA,
      NOT_OF_EMPTY_SCHEMA,
      NOT_OF_TRUE_SCHEMA,
      NOT_STRING_SCHEMA,
      NUMBER_SCHEMA,
      OBJECT_SCHEMA,
      OBJECT_SCHEMAS,
      ONEOF_ARRAY_A_DINT_B_NUM_SCHEMA,
      ONEOF_ARRAY_B_NUM_C_DINT_OPEN_SCHEMA,
      ONEOF_ARRAY_B_NUM_C_INT_SCHEMA,
      ONEOF_INT_SCHEMA,
      ONEOF_NUMBER_SCHEMA,
      ONEOF_STRING_INT_SCHEMA,
      ONEOF_STRING_SCHEMA,
      PATTERN_PROPERTY_ASTAR_OBJECT_SCHEMA,
      PROPERTY_NAMES_ASTAR_OBJECT_SCHEMA,
      STRING_SCHEMA,
      TRUE_SCHEMA,
      TUPLE_OF_INT_INT_OPEN_SCHEMA,
      TUPLE_OF_INT_INT_SCHEMA,
      TUPLE_OF_INT_OPEN_SCHEMA,
      TUPLE_OF_INT_SCHEMA,
      TUPLE_OF_INT_WITH_ADDITIONAL_INT_SCHEMA,
      TYPES_STRING_INT_SCHEMA,
      TYPES_STRING_SCHEMA,
  )
  
  COMPATIBLE = SchemaCompatibilityResult(SchemaCompatibilityType.compatible)
  
  COMPATIBILIY = "compatibility with schema registry"
  COMPATIBLE_READER_IS_TRUE_SCHEMA = "The reader is a true schema which _accepts_ every value"
  COMPATIBLE_READER_IS_OPEN_AND_IGNORE_UNKNOWN_VALUES = "The reader schema is an open schema and ignores unknown values"
  COMPATIBLE_READER_NEW_FIELD_IS_NOT_REQUIRED = "The new fields in the reader schema are not required"
  COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET = "The reader schema changed a field type which accepts all writer values"
  COMPATIBLE_READER_EVERY_VALUE_IS_ACCEPTED = "Every value produced by the writer is accepted by the reader"
  
  INCOMPATIBLE_READER_IS_FALSE_SCHEMA = "The reader is a false schema which _rejects_ every value"
  INCOMPATIBLE_READER_IS_CLOSED_AND_REMOVED_FIELD = "The does not accepts all fields produced by the writer"
  INCOMPATIBLE_READER_HAS_A_NEW_REQUIRED_FIELDg = "The reader has a new required field"
  INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES = (
      "The reader changed restricted field and only accept a subset of the writer's values"
  )
  INCOMPATIBLE_READER_CHANGED_FIELD_TYPE = "The reader schema changed a field type, the previous values are no longer valid"
  
  
  def schemas_are_compatible(
      reader: Draft7Validator,
      writer: Draft7Validator,
      msg: str,
  ) -> None:
      result = compatibility(reader=reader, writer=writer)
      assert result.locations == COMPATIBLE.locations, msg
      assert result.compatibility == COMPATIBLE.compatibility, msg
      assert result.incompatibilities == COMPATIBLE.incompatibilities, msg
  
  
  def not_schemas_are_compatible(
      reader: Draft7Validator,
      writer: Draft7Validator,
      msg: str,
  ) -> None:
      result = compatibility(reader=reader, writer=writer)
      assert result.locations != COMPATIBLE.locations, msg
      assert result.compatibility != COMPATIBLE.compatibility, msg
      assert result.incompatibilities != COMPATIBLE.incompatibilities, msg
  
  
  def test_reflexivity() -> None:
      reflexivity_msg = "every schema is compatible with itself"
      schemas_are_compatible(
          reader=EVERY_TYPE_SCHEMA,
          writer=EVERY_TYPE_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=NOT_OF_EMPTY_SCHEMA,
          writer=NOT_OF_EMPTY_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=NOT_OF_TRUE_SCHEMA,
          writer=NOT_OF_TRUE_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=FALSE_SCHEMA,
          writer=FALSE_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=TRUE_SCHEMA,
          writer=TRUE_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=EMPTY_SCHEMA,
          writer=EMPTY_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=BOOLEAN_SCHEMA,
          writer=BOOLEAN_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=INT_SCHEMA,
          writer=INT_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=NUMBER_SCHEMA,
          writer=NUMBER_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=STRING_SCHEMA,
          writer=STRING_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=OBJECT_SCHEMA,
          writer=OBJECT_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=ARRAY_SCHEMA,
          writer=ARRAY_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=NOT_BOOLEAN_SCHEMA,
          writer=NOT_BOOLEAN_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=NOT_INT_SCHEMA,
          writer=NOT_INT_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=NOT_NUMBER_SCHEMA,
          writer=NOT_NUMBER_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=NOT_STRING_SCHEMA,
          writer=NOT_STRING_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=NOT_OBJECT_SCHEMA,
          writer=NOT_OBJECT_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=NOT_ARRAY_SCHEMA,
          writer=NOT_ARRAY_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=MAX_LENGTH_SCHEMA,
          writer=MAX_LENGTH_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=MAX_LENGTH_DECREASED_SCHEMA,
          writer=MAX_LENGTH_DECREASED_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=MIN_LENGTH_SCHEMA,
          writer=MIN_LENGTH_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=MIN_LENGTH_INCREASED_SCHEMA,
          writer=MIN_LENGTH_INCREASED_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=MIN_PATTERN_SCHEMA,
          writer=MIN_PATTERN_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=MIN_PATTERN_STRICT_SCHEMA,
          writer=MIN_PATTERN_STRICT_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=MAXIMUM_INTEGER_SCHEMA,
          writer=MAXIMUM_INTEGER_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=MAXIMUM_NUMBER_SCHEMA,
          writer=MAXIMUM_NUMBER_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=MAXIMUM_DECREASED_INTEGER_SCHEMA,
          writer=MAXIMUM_DECREASED_INTEGER_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=MAXIMUM_DECREASED_NUMBER_SCHEMA,
          writer=MAXIMUM_DECREASED_NUMBER_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=MINIMUM_INTEGER_SCHEMA,
          writer=MINIMUM_INTEGER_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=MINIMUM_NUMBER_SCHEMA,
          writer=MINIMUM_NUMBER_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=MINIMUM_INCREASED_INTEGER_SCHEMA,
          writer=MINIMUM_INCREASED_INTEGER_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=MINIMUM_INCREASED_NUMBER_SCHEMA,
          writer=MINIMUM_INCREASED_NUMBER_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=EXCLUSIVE_MAXIMUM_INTEGER_SCHEMA,
          writer=EXCLUSIVE_MAXIMUM_INTEGER_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=EXCLUSIVE_MAXIMUM_NUMBER_SCHEMA,
          writer=EXCLUSIVE_MAXIMUM_NUMBER_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=EXCLUSIVE_MAXIMUM_DECREASED_INTEGER_SCHEMA,
          writer=EXCLUSIVE_MAXIMUM_DECREASED_INTEGER_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=EXCLUSIVE_MAXIMUM_DECREASED_NUMBER_SCHEMA,
          writer=EXCLUSIVE_MAXIMUM_DECREASED_NUMBER_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=EXCLUSIVE_MINIMUM_INTEGER_SCHEMA,
          writer=EXCLUSIVE_MINIMUM_INTEGER_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=EXCLUSIVE_MINIMUM_NUMBER_SCHEMA,
          writer=EXCLUSIVE_MINIMUM_NUMBER_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=EXCLUSIVE_MINIMUM_INCREASED_INTEGER_SCHEMA,
          writer=EXCLUSIVE_MINIMUM_INCREASED_INTEGER_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=EXCLUSIVE_MINIMUM_INCREASED_NUMBER_SCHEMA,
          writer=EXCLUSIVE_MINIMUM_INCREASED_NUMBER_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=MAX_PROPERTIES_SCHEMA,
          writer=MAX_PROPERTIES_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=MAX_PROPERTIES_DECREASED_SCHEMA,
          writer=MAX_PROPERTIES_DECREASED_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=MIN_PROPERTIES_SCHEMA,
          writer=MIN_PROPERTIES_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=MIN_PROPERTIES_INCREASED_SCHEMA,
          writer=MIN_PROPERTIES_INCREASED_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=MAX_ITEMS_SCHEMA,
          writer=MAX_ITEMS_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=MAX_ITEMS_DECREASED_SCHEMA,
          writer=MAX_ITEMS_DECREASED_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=MIN_ITEMS_SCHEMA,
          writer=MIN_ITEMS_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=MIN_ITEMS_INCREASED_SCHEMA,
          writer=MIN_ITEMS_INCREASED_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=TUPLE_OF_INT_INT_SCHEMA,
          writer=TUPLE_OF_INT_INT_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=TUPLE_OF_INT_SCHEMA,
          writer=TUPLE_OF_INT_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=TUPLE_OF_INT_WITH_ADDITIONAL_INT_SCHEMA,
          writer=TUPLE_OF_INT_WITH_ADDITIONAL_INT_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=TUPLE_OF_INT_INT_SCHEMA,
          writer=TUPLE_OF_INT_INT_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=TUPLE_OF_INT_OPEN_SCHEMA,
          writer=TUPLE_OF_INT_OPEN_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=ARRAY_OF_INT_SCHEMA,
          writer=ARRAY_OF_INT_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=ARRAY_OF_NUMBER_SCHEMA,
          writer=ARRAY_OF_NUMBER_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=ARRAY_OF_STRING_SCHEMA,
          writer=ARRAY_OF_STRING_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=ENUM_AB_SCHEMA,
          writer=ENUM_AB_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=ENUM_ABC_SCHEMA,
          writer=ENUM_ABC_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=ENUM_BC_SCHEMA,
          writer=ENUM_BC_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=ONEOF_STRING_SCHEMA,
          writer=ONEOF_STRING_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=ONEOF_STRING_INT_SCHEMA,
          writer=ONEOF_STRING_INT_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=EMPTY_OBJECT_SCHEMA,
          writer=EMPTY_OBJECT_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=A_INT_OBJECT_SCHEMA,
          writer=A_INT_OBJECT_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=A_INT_OPEN_OBJECT_SCHEMA,
          writer=A_INT_OPEN_OBJECT_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=A_INT_B_INT_OBJECT_SCHEMA,
          writer=A_INT_B_INT_OBJECT_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=A_INT_B_INT_REQUIRED_OBJECT_SCHEMA,
          writer=A_INT_B_INT_REQUIRED_OBJECT_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=A_INT_B_DINT_OBJECT_SCHEMA,
          writer=A_INT_B_DINT_OBJECT_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=A_INT_B_DINT_REQUIRED_OBJECT_SCHEMA,
          writer=A_INT_B_DINT_REQUIRED_OBJECT_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=A_DINT_B_DINT_OBJECT_SCHEMA,
          writer=A_DINT_B_DINT_OBJECT_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=A_DINT_B_NUM_OBJECT_SCHEMA,
          writer=A_DINT_B_NUM_OBJECT_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=A_DINT_B_NUM_C_DINT_OBJECT_SCHEMA,
          writer=A_DINT_B_NUM_C_DINT_OBJECT_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=B_NUM_C_DINT_OPEN_OBJECT_SCHEMA,
          writer=B_NUM_C_DINT_OPEN_OBJECT_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=B_NUM_C_INT_OBJECT_SCHEMA,
          writer=B_NUM_C_INT_OBJECT_SCHEMA,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=ARRAY_OF_POSITIVE_INTEGER,
          writer=ARRAY_OF_POSITIVE_INTEGER,
          msg=reflexivity_msg,
      )
      schemas_are_compatible(
          reader=ARRAY_OF_POSITIVE_INTEGER_THROUGH_REF,
          writer=ARRAY_OF_POSITIVE_INTEGER_THROUGH_REF,
          msg=reflexivity_msg,
      )
  
  
  def test_extra_optional_field_with_open_model_is_compatible() -> None:
      # - the reader is an open model, the extra field produced by the writer is
      # automatically accepted
      schemas_are_compatible(
          reader=OBJECT_SCHEMA,
          writer=A_INT_OBJECT_SCHEMA,
          msg=COMPATIBLE_READER_IS_TRUE_SCHEMA,
      )
      schemas_are_compatible(
          reader=TRUE_SCHEMA,
          writer=A_INT_OBJECT_SCHEMA,
          msg=COMPATIBLE_READER_IS_TRUE_SCHEMA,
      )
      schemas_are_compatible(
          reader=EMPTY_SCHEMA,
          writer=A_INT_OBJECT_SCHEMA,
          msg=COMPATIBLE_READER_IS_TRUE_SCHEMA,
      )
  
      # - the writer is a closed model, so the field `b` was never produced, which
      # means that the writer never produced an invalid value.
      # - the reader's `b` field is optional, so the absenced of the field is not
      # a problem, and `a` is ignored because of the open model
      schemas_are_compatible(
          reader=B_INT_OPEN_OBJECT_SCHEMA,
          writer=A_INT_OBJECT_SCHEMA,
          msg=COMPATIBLE_READER_IS_OPEN_AND_IGNORE_UNKNOWN_VALUES,
      )
  
      # - if the model is closed, then `a` must also be accepted
      schemas_are_compatible(
          reader=A_INT_B_INT_OBJECT_SCHEMA,
          writer=A_INT_OBJECT_SCHEMA,
          msg=COMPATIBLE_READER_NEW_FIELD_IS_NOT_REQUIRED,
      )
  
      # Examples a bit more complex
      schemas_are_compatible(
          reader=A_DINT_B_NUM_C_DINT_OBJECT_SCHEMA,
          writer=A_DINT_B_NUM_OBJECT_SCHEMA,
          msg=COMPATIBLE_READER_NEW_FIELD_IS_NOT_REQUIRED,
      )
      schemas_are_compatible(
          reader=B_NUM_C_DINT_OPEN_OBJECT_SCHEMA,
          writer=A_DINT_B_NUM_C_DINT_OBJECT_SCHEMA,
          msg=COMPATIBLE_READER_IS_OPEN_AND_IGNORE_UNKNOWN_VALUES,
      )
      schemas_are_compatible(
          reader=B_NUM_C_INT_OPEN_OBJECT_SCHEMA,
          writer=A_DINT_B_NUM_OBJECT_SCHEMA,
          msg=f"{COMPATIBLE_READER_IS_OPEN_AND_IGNORE_UNKNOWN_VALUES} + {COMPATIBLE_READER_NEW_FIELD_IS_NOT_REQUIRED}",
      )
      schemas_are_compatible(
          reader=B_NUM_C_DINT_OPEN_OBJECT_SCHEMA,
          writer=A_DINT_B_NUM_OBJECT_SCHEMA,
          msg=f"{COMPATIBLE_READER_IS_OPEN_AND_IGNORE_UNKNOWN_VALUES} + {COMPATIBLE_READER_NEW_FIELD_IS_NOT_REQUIRED}",
      )
  
  
  def test_extra_field_with_closed_model_is_incompatible() -> None:
      # The false schema always falways validation, so the values produced by the
      # writer won't be valid.
      # https://json-schema.org/draft/2020-12/json-schema-core.html#rfc.section.4.3.2
      #
      # not_schemas_are_compatible(
      #     reader=FALSE_SCHEMA,
      #     writer=A_INT_OBJECT_SCHEMA,
      #     msg=INCOMPATIBLE_READER_IS_FALSE_SCHEMA,
      # )
      not_schemas_are_compatible(
          reader=A_INT_OBJECT_SCHEMA,
          writer=FALSE_SCHEMA,
          msg=INCOMPATIBLE_READER_IS_FALSE_SCHEMA,
      )
      not_schemas_are_compatible(
          reader=NOT_OF_TRUE_SCHEMA,
          writer=A_INT_OBJECT_SCHEMA,
          msg=INCOMPATIBLE_READER_IS_FALSE_SCHEMA,
      )
      not_schemas_are_compatible(
          reader=NOT_OF_EMPTY_SCHEMA,
          writer=A_INT_OBJECT_SCHEMA,
          msg=INCOMPATIBLE_READER_IS_FALSE_SCHEMA,
      )
      not_schemas_are_compatible(
          reader=B_INT_OBJECT_SCHEMA,
          writer=A_INT_OBJECT_SCHEMA,
          msg=INCOMPATIBLE_READER_IS_CLOSED_AND_REMOVED_FIELD,
      )
      not_schemas_are_compatible(
          reader=B_NUM_C_INT_OBJECT_SCHEMA,
          writer=A_DINT_B_NUM_OBJECT_SCHEMA,
          msg=INCOMPATIBLE_READER_IS_CLOSED_AND_REMOVED_FIELD,
      )
      not_schemas_are_compatible(
          reader=B_NUM_C_INT_OBJECT_SCHEMA,
          writer=A_DINT_B_NUM_C_DINT_OBJECT_SCHEMA,
          msg=INCOMPATIBLE_READER_IS_CLOSED_AND_REMOVED_FIELD,
      )
  
  
  def test_missing_required_field_is_incompatible() -> None:
      not_schemas_are_compatible(
          reader=A_INT_B_INT_REQUIRED_OBJECT_SCHEMA,
          writer=A_INT_OBJECT_SCHEMA,
          msg=INCOMPATIBLE_READER_HAS_A_NEW_REQUIRED_FIELDg,
      )
      # The writer is not producing the value `b`, which is required by the
      # reader
      # not_schemas_are_compatible(
      #     reader=A_INT_B_DINT_REQUIRED_OBJECT_SCHEMA,
      #     writer=A_INT_OBJECT_SCHEMA,
      #     msg=INCOMPATIBLE_READER_HAS_A_NEW_REQUIRED_FIELDg,
      # )
      not_schemas_are_compatible(
          reader=A_INT_OBJECT_SCHEMA,
          writer=A_INT_B_DINT_REQUIRED_OBJECT_SCHEMA,
          msg=INCOMPATIBLE_READER_HAS_A_NEW_REQUIRED_FIELDg,
      )
  
  
  def test_giving_a_default_value_for_a_non_required_field_is_compatible() -> None:
      schemas_are_compatible(
          reader=OBJECT_SCHEMA,
          writer=A_DINT_OBJECT_SCHEMA,
          msg=COMPATIBLE_READER_IS_TRUE_SCHEMA,
      )
      schemas_are_compatible(
          reader=TRUE_SCHEMA,
          writer=A_DINT_OBJECT_SCHEMA,
          msg=COMPATIBLE_READER_IS_TRUE_SCHEMA,
      )
      schemas_are_compatible(
          reader=EMPTY_SCHEMA,
          writer=A_DINT_OBJECT_SCHEMA,
          msg=COMPATIBLE_READER_IS_TRUE_SCHEMA,
      )
      schemas_are_compatible(
          reader=B_DINT_OPEN_OBJECT_SCHEMA,
          writer=A_INT_OBJECT_SCHEMA,
          msg=COMPATIBLE_READER_IS_TRUE_SCHEMA,
      )
      schemas_are_compatible(
          reader=A_INT_B_DINT_OBJECT_SCHEMA,
          writer=A_INT_OBJECT_SCHEMA,
          msg=COMPATIBLE_READER_NEW_FIELD_IS_NOT_REQUIRED,
      )
      schemas_are_compatible(
          reader=A_DINT_B_INT_OBJECT_SCHEMA,
          writer=A_INT_OBJECT_SCHEMA,
          msg=COMPATIBLE_READER_NEW_FIELD_IS_NOT_REQUIRED,
      )
      schemas_are_compatible(
          reader=B_NUM_C_DINT_OPEN_OBJECT_SCHEMA,
          writer=A_DINT_B_NUM_OBJECT_SCHEMA,
          msg=f"{COMPATIBLE_READER_IS_OPEN_AND_IGNORE_UNKNOWN_VALUES} + {COMPATIBLE_READER_NEW_FIELD_IS_NOT_REQUIRED}",
      )
      schemas_are_compatible(
          reader=A_DINT_B_DINT_OBJECT_SCHEMA,
          writer=A_INT_OBJECT_SCHEMA,
          msg=INCOMPATIBLE_READER_CHANGED_FIELD_TYPE,  # field B was anything, now it int
      )
      schemas_are_compatible(
          reader=A_DINT_B_DINT_OBJECT_SCHEMA,
          writer=EMPTY_OBJECT_SCHEMA,
          msg=COMPATIBLE_READER_NEW_FIELD_IS_NOT_REQUIRED,
      )
  
  
  def test_boolean_schemas_are_backward_compatible() -> None:
      # reader is the false schema, which never accepts a value
      # https://json-schema.org/draft/2020-12/json-schema-core.html#rfc.section.4.3.2
      # not_schemas_are_compatible(
      #     reader=FALSE_SCHEMA,
      #     writer=TRUE_SCHEMA,
      #     msg=INCOMPATIBLE_READER_IS_FALSE_SCHEMA,
      # )
      schemas_are_compatible(
          reader=FALSE_SCHEMA,
          writer=TRUE_SCHEMA,
          msg=INCOMPATIBLE_READER_IS_FALSE_SCHEMA,
      )
      schemas_are_compatible(
          reader=TRUE_SCHEMA,
          writer=FALSE_SCHEMA,
          msg=INCOMPATIBLE_READER_IS_FALSE_SCHEMA,
      )
  
  
  def test_from_closed_to_open_is_incompatible() -> None:
      not_schemas_are_compatible(
          reader=B_NUM_C_INT_OBJECT_SCHEMA,
          writer=B_NUM_C_DINT_OPEN_OBJECT_SCHEMA,
          msg="The reader is closed model and rejects the fields ignored by the writer",
      )
  
  
  def test_union_with_incompatible_elements() -> None:
      not_schemas_are_compatible(
          reader=ONEOF_ARRAY_B_NUM_C_INT_SCHEMA,
          writer=ONEOF_ARRAY_A_DINT_B_NUM_SCHEMA,
          msg=INCOMPATIBLE_READER_IS_CLOSED_AND_REMOVED_FIELD,
      )
  
  
  def test_union_with_compatible_elements() -> None:
      schemas_are_compatible(
          reader=ONEOF_ARRAY_B_NUM_C_DINT_OPEN_SCHEMA,
          writer=ONEOF_ARRAY_A_DINT_B_NUM_SCHEMA,
          msg=COMPATIBLE_READER_IS_OPEN_AND_IGNORE_UNKNOWN_VALUES,
      )
  
  
  def test_array_and_tuples_are_incompatible() -> None:
      # both tuple and arrays are represented using lists, this should be
      # compatible
      # schemas_are_compatible(
      #     reader=ARRAY_OF_INT_SCHEMA,
      #     writer=TUPLE_OF_INT_OPEN_SCHEMA,
      #     msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      # )
      # schemas_are_compatible(
      #     reader=ARRAY_OF_INT_SCHEMA,
      #     writer=TUPLE_OF_INT_INT_SCHEMA,
      #     msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      # )
      not_schemas_are_compatible(
          reader=TUPLE_OF_INT_OPEN_SCHEMA,
          writer=ARRAY_OF_INT_SCHEMA,
          msg=COMPATIBILIY,
      )
      not_schemas_are_compatible(
          reader=ARRAY_OF_INT_SCHEMA,
          writer=TUPLE_OF_INT_OPEN_SCHEMA,
          msg=COMPATIBILIY,
      )
  
  
  def test_true_schema_is_compatible_with_object() -> None:
      for schema in OBJECT_SCHEMAS + BOOLEAN_SCHEMAS:
          if schema != TRUE_SCHEMA:
              schemas_are_compatible(
                  reader=TRUE_SCHEMA,
                  writer=schema,
                  msg=COMPATIBILIY,
              )
  
      for schema in NON_OBJECT_SCHEMAS:
          not_schemas_are_compatible(
              reader=TRUE_SCHEMA,
              writer=schema,
              msg=COMPATIBILIY,
          )
  
  
  def test_schema_compatibility_successes() -> None:
      # allowing a broader set of values is compatible
      schemas_are_compatible(
          reader=NUMBER_SCHEMA,
          writer=INT_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
      schemas_are_compatible(
          reader=ARRAY_OF_NUMBER_SCHEMA,
          writer=ARRAY_OF_INT_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
      schemas_are_compatible(
          reader=TUPLE_OF_INT_OPEN_SCHEMA,
          writer=TUPLE_OF_INT_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
      schemas_are_compatible(
          reader=TUPLE_OF_INT_WITH_ADDITIONAL_INT_SCHEMA,
          writer=TUPLE_OF_INT_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
      schemas_are_compatible(
          reader=ENUM_ABC_SCHEMA,
          writer=ENUM_AB_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
      schemas_are_compatible(
          reader=ONEOF_STRING_INT_SCHEMA,
          writer=ONEOF_STRING_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
      schemas_are_compatible(
          reader=ONEOF_STRING_INT_SCHEMA,
          writer=STRING_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
      schemas_are_compatible(
          reader=A_INT_OPEN_OBJECT_SCHEMA,
          writer=A_INT_B_INT_OBJECT_SCHEMA,
          msg=COMPATIBLE_READER_IS_OPEN_AND_IGNORE_UNKNOWN_VALUES,
      )
  
      # requiring less values is compatible
      schemas_are_compatible(
          reader=TUPLE_OF_INT_OPEN_SCHEMA,
          writer=TUPLE_OF_INT_INT_OPEN_SCHEMA,
          msg=COMPATIBLE_READER_IS_OPEN_AND_IGNORE_UNKNOWN_VALUES,
      )
      schemas_are_compatible(
          reader=TUPLE_OF_INT_OPEN_SCHEMA,
          writer=TUPLE_OF_INT_INT_SCHEMA,
          msg=COMPATIBLE_READER_IS_OPEN_AND_IGNORE_UNKNOWN_VALUES,
      )
  
      # equivalences
      schemas_are_compatible(
          reader=ONEOF_STRING_SCHEMA,
          writer=STRING_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
      schemas_are_compatible(
          reader=STRING_SCHEMA,
          writer=ONEOF_STRING_SCHEMA,
          msg=COMPATIBLE_READER_EVERY_VALUE_IS_ACCEPTED,
      )
  
      # new non-required fields is compatible
      schemas_are_compatible(
          reader=A_INT_OBJECT_SCHEMA,
          writer=EMPTY_OBJECT_SCHEMA,
          msg=COMPATIBLE_READER_EVERY_VALUE_IS_ACCEPTED,
      )
      schemas_are_compatible(
          reader=A_INT_B_INT_OBJECT_SCHEMA,
          writer=A_INT_OBJECT_SCHEMA,
          msg=COMPATIBLE_READER_EVERY_VALUE_IS_ACCEPTED,
      )
  
  
  def test_type_narrowing_incompabilities() -> None:
      not_schemas_are_compatible(
          reader=INT_SCHEMA,
          writer=NUMBER_SCHEMA,
          msg=INCOMPATIBLE_READER_CHANGED_FIELD_TYPE,
      )
      not_schemas_are_compatible(
          reader=ARRAY_OF_INT_SCHEMA,
          writer=ARRAY_OF_NUMBER_SCHEMA,
          msg=INCOMPATIBLE_READER_CHANGED_FIELD_TYPE,
      )
      not_schemas_are_compatible(
          reader=ENUM_AB_SCHEMA,
          writer=ENUM_ABC_SCHEMA,
          msg=INCOMPATIBLE_READER_CHANGED_FIELD_TYPE,
      )
      not_schemas_are_compatible(
          reader=ENUM_BC_SCHEMA,
          writer=ENUM_ABC_SCHEMA,
          msg=INCOMPATIBLE_READER_CHANGED_FIELD_TYPE,
      )
      not_schemas_are_compatible(
          reader=ONEOF_INT_SCHEMA,
          writer=ONEOF_NUMBER_SCHEMA,
          msg=INCOMPATIBLE_READER_CHANGED_FIELD_TYPE,
      )
      not_schemas_are_compatible(
          reader=ONEOF_STRING_SCHEMA,
          writer=ONEOF_STRING_INT_SCHEMA,
          msg=INCOMPATIBLE_READER_CHANGED_FIELD_TYPE,
      )
      not_schemas_are_compatible(
          reader=INT_SCHEMA,
          writer=ONEOF_STRING_INT_SCHEMA,
          msg=INCOMPATIBLE_READER_CHANGED_FIELD_TYPE,
      )
  
  
  def test_type_mismatch_incompabilities() -> None:
      not_schemas_are_compatible(
          reader=BOOLEAN_SCHEMA,
          writer=INT_SCHEMA,
          msg=INCOMPATIBLE_READER_CHANGED_FIELD_TYPE,
      )
      not_schemas_are_compatible(
          reader=INT_SCHEMA,
          writer=BOOLEAN_SCHEMA,
          msg=INCOMPATIBLE_READER_CHANGED_FIELD_TYPE,
      )
      not_schemas_are_compatible(
          reader=STRING_SCHEMA,
          writer=BOOLEAN_SCHEMA,
          msg=INCOMPATIBLE_READER_CHANGED_FIELD_TYPE,
      )
      not_schemas_are_compatible(
          reader=STRING_SCHEMA,
          writer=INT_SCHEMA,
          msg=INCOMPATIBLE_READER_CHANGED_FIELD_TYPE,
      )
      not_schemas_are_compatible(
          reader=ARRAY_OF_INT_SCHEMA,
          writer=ARRAY_OF_STRING_SCHEMA,
          msg=INCOMPATIBLE_READER_CHANGED_FIELD_TYPE,
      )
      not_schemas_are_compatible(
          reader=TUPLE_OF_INT_INT_SCHEMA,
          writer=TUPLE_OF_INT_OPEN_SCHEMA,
          msg=INCOMPATIBLE_READER_CHANGED_FIELD_TYPE,
      )
      not_schemas_are_compatible(
          reader=TUPLE_OF_INT_INT_OPEN_SCHEMA,
          writer=TUPLE_OF_INT_OPEN_SCHEMA,
          msg=INCOMPATIBLE_READER_CHANGED_FIELD_TYPE,
      )
      not_schemas_are_compatible(
          reader=INT_SCHEMA,
          writer=ENUM_AB_SCHEMA,
          msg=INCOMPATIBLE_READER_CHANGED_FIELD_TYPE,
      )
      not_schemas_are_compatible(
          reader=ENUM_AB_SCHEMA,
          writer=INT_SCHEMA,
          msg=INCOMPATIBLE_READER_CHANGED_FIELD_TYPE,
      )
  
  
  def test_true_and_false_schemas() -> None:
      schemas_are_compatible(
          writer=NOT_OF_EMPTY_SCHEMA,
          reader=NOT_OF_TRUE_SCHEMA,
          msg="both schemas reject every value",
      )
      # the schemas below are just different ways of representing the same schema
      # schemas_are_compatible(
      #     writer=NOT_OF_TRUE_SCHEMA,
      #     reader=FALSE_SCHEMA,
      #     msg="both schemas reject every value",
      # )
      # schemas_are_compatible(
      #     writer=NOT_OF_EMPTY_SCHEMA,
      #     reader=FALSE_SCHEMA,
      #     msg="both schemas reject every value",
      # )
  
      schemas_are_compatible(
          writer=TRUE_SCHEMA,
          reader=EMPTY_SCHEMA,
          msg="both schemas accept every value",
      )
  
      # the true schema accepts anything ... including nothing
      # schemas_are_compatible(
      #     writer=NOT_OF_EMPTY_SCHEMA,
      #     reader=TRUE_SCHEMA,
      #     msg=COMPATIBLE_READER_EVERY_VALUE_IS_ACCEPTED,
      # )
      # schemas_are_compatible(
      #     writer=NOT_OF_TRUE_SCHEMA,
      #     reader=TRUE_SCHEMA,
      #     msg=COMPATIBLE_READER_EVERY_VALUE_IS_ACCEPTED,
      # )
      # schemas_are_compatible(
      #     writer=NOT_OF_EMPTY_SCHEMA,
      #     reader=TRUE_SCHEMA,
      #     msg=COMPATIBLE_READER_EVERY_VALUE_IS_ACCEPTED,
      # )
  
      # the reader rejects every value
      not_schemas_are_compatible(
          writer=TRUE_SCHEMA,
          reader=NOT_OF_EMPTY_SCHEMA,
          msg=INCOMPATIBLE_READER_IS_FALSE_SCHEMA,
      )
      not_schemas_are_compatible(
          writer=TRUE_SCHEMA,
          reader=NOT_OF_TRUE_SCHEMA,
          msg=INCOMPATIBLE_READER_IS_FALSE_SCHEMA,
      )
  
      not_schemas_are_compatible(
          writer=TRUE_SCHEMA,
          reader=A_INT_B_INT_REQUIRED_OBJECT_SCHEMA,
          msg=INCOMPATIBLE_READER_CHANGED_FIELD_TYPE,
      )
      not_schemas_are_compatible(
          writer=FALSE_SCHEMA,
          reader=A_INT_B_INT_REQUIRED_OBJECT_SCHEMA,
          msg=INCOMPATIBLE_READER_HAS_A_NEW_REQUIRED_FIELDg,
      )
  
      not_schemas_are_compatible(
          writer=NOT_OF_TRUE_SCHEMA,
          reader=FALSE_SCHEMA,
          msg=COMPATIBILIY,
      )
      not_schemas_are_compatible(
          writer=FALSE_SCHEMA,
          reader=NOT_OF_TRUE_SCHEMA,
          msg=COMPATIBILIY,
      )
      not_schemas_are_compatible(
          writer=FALSE_SCHEMA,
          reader=NOT_OF_EMPTY_SCHEMA,
          msg=COMPATIBILIY,
      )
      not_schemas_are_compatible(
          writer=NOT_OF_EMPTY_SCHEMA,
          reader=FALSE_SCHEMA,
          msg=COMPATIBILIY,
      )
      not_schemas_are_compatible(
          writer=TRUE_SCHEMA,
          reader=NOT_OF_EMPTY_SCHEMA,
          msg=COMPATIBILIY,
      )
      not_schemas_are_compatible(
          writer=NOT_OF_EMPTY_SCHEMA,
          reader=TRUE_SCHEMA,
          msg=COMPATIBILIY,
      )
      not_schemas_are_compatible(
          writer=TRUE_SCHEMA,
          reader=NOT_OF_TRUE_SCHEMA,
          msg=COMPATIBILIY,
      )
      not_schemas_are_compatible(
          writer=NOT_OF_TRUE_SCHEMA,
          reader=TRUE_SCHEMA,
          msg=COMPATIBILIY,
      )
      not_schemas_are_compatible(
          writer=TRUE_SCHEMA,
          reader=NOT_OF_EMPTY_SCHEMA,
          msg=COMPATIBILIY,
      )
      not_schemas_are_compatible(
          writer=NOT_OF_EMPTY_SCHEMA,
          reader=TRUE_SCHEMA,
          msg=COMPATIBILIY,
      )
  
  
  def test_schema_restrict_attributes_is_incompatible() -> None:
      not_schemas_are_compatible(
          writer=STRING_SCHEMA,
          reader=MAX_LENGTH_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
      not_schemas_are_compatible(
          writer=MAX_LENGTH_SCHEMA,
          reader=MAX_LENGTH_DECREASED_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
  
      not_schemas_are_compatible(
          writer=STRING_SCHEMA,
          reader=MIN_LENGTH_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
      not_schemas_are_compatible(
          writer=MIN_LENGTH_SCHEMA,
          reader=MIN_LENGTH_INCREASED_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
  
      not_schemas_are_compatible(
          writer=STRING_SCHEMA,
          reader=MIN_PATTERN_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
      not_schemas_are_compatible(
          writer=MIN_PATTERN_SCHEMA,
          reader=MIN_PATTERN_STRICT_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
  
      not_schemas_are_compatible(
          writer=INT_SCHEMA,
          reader=MAXIMUM_INTEGER_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
      not_schemas_are_compatible(
          writer=INT_SCHEMA,
          reader=MAXIMUM_NUMBER_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
      not_schemas_are_compatible(
          writer=NUMBER_SCHEMA,
          reader=MAXIMUM_NUMBER_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
      not_schemas_are_compatible(
          writer=MAXIMUM_NUMBER_SCHEMA,
          reader=MAXIMUM_DECREASED_NUMBER_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
  
      not_schemas_are_compatible(
          writer=INT_SCHEMA,
          reader=MINIMUM_NUMBER_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
      not_schemas_are_compatible(
          writer=NUMBER_SCHEMA,
          reader=MINIMUM_NUMBER_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
      not_schemas_are_compatible(
          writer=MINIMUM_NUMBER_SCHEMA,
          reader=MINIMUM_INCREASED_NUMBER_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
  
      not_schemas_are_compatible(
          writer=INT_SCHEMA,
          reader=EXCLUSIVE_MAXIMUM_NUMBER_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
      not_schemas_are_compatible(
          writer=NUMBER_SCHEMA,
          reader=EXCLUSIVE_MAXIMUM_NUMBER_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
      not_schemas_are_compatible(
          writer=EXCLUSIVE_MAXIMUM_NUMBER_SCHEMA,
          reader=EXCLUSIVE_MAXIMUM_DECREASED_NUMBER_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
  
      not_schemas_are_compatible(
          writer=NUMBER_SCHEMA,
          reader=EXCLUSIVE_MINIMUM_NUMBER_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
      not_schemas_are_compatible(
          writer=INT_SCHEMA,
          reader=EXCLUSIVE_MINIMUM_NUMBER_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
      not_schemas_are_compatible(
          writer=EXCLUSIVE_MINIMUM_NUMBER_SCHEMA,
          reader=EXCLUSIVE_MINIMUM_INCREASED_NUMBER_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
  
      not_schemas_are_compatible(
          writer=OBJECT_SCHEMA,
          reader=MAX_PROPERTIES_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
      not_schemas_are_compatible(
          writer=MAX_PROPERTIES_SCHEMA,
          reader=MAX_PROPERTIES_DECREASED_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
  
      not_schemas_are_compatible(
          writer=OBJECT_SCHEMA,
          reader=MIN_PROPERTIES_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
      not_schemas_are_compatible(
          writer=MIN_PROPERTIES_SCHEMA,
          reader=MIN_PROPERTIES_INCREASED_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
  
      not_schemas_are_compatible(
          writer=ARRAY_SCHEMA,
          reader=MAX_ITEMS_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
      not_schemas_are_compatible(
          writer=MAX_ITEMS_SCHEMA,
          reader=MAX_ITEMS_DECREASED_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
  
      not_schemas_are_compatible(
          writer=ARRAY_SCHEMA,
          reader=MIN_ITEMS_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
      not_schemas_are_compatible(
          writer=MIN_ITEMS_SCHEMA,
          reader=MIN_ITEMS_INCREASED_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
  
  
  def test_schema_broadenning_attributes_is_compatible() -> None:
      schemas_are_compatible(
          writer=MAX_LENGTH_SCHEMA,
          reader=STRING_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
      schemas_are_compatible(
          writer=MAX_LENGTH_DECREASED_SCHEMA,
          reader=MAX_LENGTH_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
  
      schemas_are_compatible(
          writer=MIN_LENGTH_SCHEMA,
          reader=STRING_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
      schemas_are_compatible(
          writer=MIN_LENGTH_INCREASED_SCHEMA,
          reader=MIN_LENGTH_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
  
      schemas_are_compatible(
          writer=MIN_PATTERN_SCHEMA,
          reader=STRING_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
  
      schemas_are_compatible(
          writer=MAXIMUM_INTEGER_SCHEMA,
          reader=INT_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
      schemas_are_compatible(
          writer=MAXIMUM_NUMBER_SCHEMA,
          reader=NUMBER_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
      schemas_are_compatible(
          writer=MAXIMUM_DECREASED_NUMBER_SCHEMA,
          reader=MAXIMUM_NUMBER_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
  
      schemas_are_compatible(
          writer=MINIMUM_INTEGER_SCHEMA,
          reader=INT_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
      schemas_are_compatible(
          writer=MINIMUM_NUMBER_SCHEMA,
          reader=NUMBER_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
      schemas_are_compatible(
          writer=MINIMUM_INCREASED_NUMBER_SCHEMA,
          reader=MINIMUM_NUMBER_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
  
      schemas_are_compatible(
          writer=EXCLUSIVE_MAXIMUM_INTEGER_SCHEMA,
          reader=INT_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
      schemas_are_compatible(
          writer=EXCLUSIVE_MAXIMUM_NUMBER_SCHEMA,
          reader=NUMBER_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
      schemas_are_compatible(
          writer=EXCLUSIVE_MAXIMUM_DECREASED_NUMBER_SCHEMA,
          reader=EXCLUSIVE_MAXIMUM_NUMBER_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
  
      schemas_are_compatible(
          writer=EXCLUSIVE_MINIMUM_NUMBER_SCHEMA,
          reader=NUMBER_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
      schemas_are_compatible(
          writer=EXCLUSIVE_MINIMUM_INTEGER_SCHEMA,
          reader=INT_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
      schemas_are_compatible(
          writer=EXCLUSIVE_MINIMUM_INCREASED_NUMBER_SCHEMA,
          reader=EXCLUSIVE_MINIMUM_NUMBER_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
  
      schemas_are_compatible(
          writer=MAX_PROPERTIES_SCHEMA,
          reader=OBJECT_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
      schemas_are_compatible(
          writer=MAX_PROPERTIES_DECREASED_SCHEMA,
          reader=MAX_PROPERTIES_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
  
      schemas_are_compatible(
          writer=MIN_PROPERTIES_SCHEMA,
          reader=OBJECT_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
      schemas_are_compatible(
          writer=MIN_PROPERTIES_INCREASED_SCHEMA,
          reader=MIN_PROPERTIES_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
  
      schemas_are_compatible(
          writer=MAX_ITEMS_SCHEMA,
          reader=ARRAY_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
      schemas_are_compatible(
          writer=MAX_ITEMS_DECREASED_SCHEMA,
          reader=MAX_ITEMS_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
  
      schemas_are_compatible(
          writer=MIN_ITEMS_SCHEMA,
          reader=ARRAY_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
      schemas_are_compatible(
          writer=MIN_ITEMS_INCREASED_SCHEMA,
          reader=MIN_ITEMS_SCHEMA,
          msg=COMPATIBLE_READER_FIELD_TYPE_IS_A_SUPERSET,
      )
  
  
  def test_pattern_properties():
      schemas_are_compatible(
          reader=OBJECT_SCHEMA,
          writer=PATTERN_PROPERTY_ASTAR_OBJECT_SCHEMA,
          msg=COMPATIBLE_READER_IS_OPEN_AND_IGNORE_UNKNOWN_VALUES,
      )
      # In backward compatibility mode it is allowed to delete fields
      schemas_are_compatible(
          reader=A_OBJECT_SCHEMA,
          writer=PATTERN_PROPERTY_ASTAR_OBJECT_SCHEMA,
          msg=COMPATIBILIY,
      )
      # In backward compatibility mode it is allowed to add optional fields
      schemas_are_compatible(
          reader=PATTERN_PROPERTY_ASTAR_OBJECT_SCHEMA,
          writer=A_OBJECT_SCHEMA,
          msg=COMPATIBILIY,
      )
  
      # - writer accept any value for `a`
      # - reader requires it to be an `int`, therefore the other values became
      # invalid
      not_schemas_are_compatible(
          reader=A_INT_OBJECT_SCHEMA,
          writer=PATTERN_PROPERTY_ASTAR_OBJECT_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
  
      # - writer has property `b`
      # - reader only accepts properties with match regex `a*`
      not_schemas_are_compatible(
          reader=PATTERN_PROPERTY_ASTAR_OBJECT_SCHEMA,
          writer=B_INT_OBJECT_SCHEMA,
          msg=INCOMPATIBLE_READER_IS_CLOSED_AND_REMOVED_FIELD,
      )
  
  
  def test_object_properties():
      not_schemas_are_compatible(
          reader=A_OBJECT_SCHEMA,
          writer=OBJECT_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
      schemas_are_compatible(
          reader=OBJECT_SCHEMA,
          writer=A_OBJECT_SCHEMA,
          msg=COMPATIBILIY,
      )
      not_schemas_are_compatible(
          reader=A_INT_OBJECT_SCHEMA,
          writer=OBJECT_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
      not_schemas_are_compatible(
          reader=B_INT_OBJECT_SCHEMA,
          writer=OBJECT_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
  
  
  def test_property_names():
      schemas_are_compatible(
          reader=OBJECT_SCHEMA,
          writer=PROPERTY_NAMES_ASTAR_OBJECT_SCHEMA,
          msg=COMPATIBLE_READER_IS_OPEN_AND_IGNORE_UNKNOWN_VALUES,
      )
      not_schemas_are_compatible(
          reader=A_OBJECT_SCHEMA,
          writer=PROPERTY_NAMES_ASTAR_OBJECT_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
      schemas_are_compatible(
          reader=PROPERTY_NAMES_ASTAR_OBJECT_SCHEMA,
          writer=A_OBJECT_SCHEMA,
          msg=COMPATIBILIY,
      )
  
      # - writer accept any value for `a`
      # - reader requires it to be an `int`, therefore the other values became
      # invalid
      not_schemas_are_compatible(
          reader=A_INT_OBJECT_SCHEMA,
          writer=PROPERTY_NAMES_ASTAR_OBJECT_SCHEMA,
          msg=INCOMPATIBLE_READER_RESTRICTED_ACCEPTED_VALUES,
      )
  
      # - writer has property `b`
      # - reader only accepts properties with match regex `a*`
      schemas_are_compatible(
          reader=PROPERTY_NAMES_ASTAR_OBJECT_SCHEMA,
          writer=B_INT_OBJECT_SCHEMA,
          msg=COMPATIBILIY,
      )
  
  
  def test_type_with_list():
      # "type": [] is treated as a shortcut for anyOf
      schemas_are_compatible(
          reader=STRING_SCHEMA,
          writer=TYPES_STRING_SCHEMA,
          msg=COMPATIBLE_READER_EVERY_VALUE_IS_ACCEPTED,
      )
      schemas_are_compatible(
          reader=TYPES_STRING_INT_SCHEMA,
          writer=TYPES_STRING_SCHEMA,
          msg=COMPATIBLE_READER_EVERY_VALUE_IS_ACCEPTED,
      )
  
  
  def test_ref():
      schemas_are_compatible(
          reader=ARRAY_OF_POSITIVE_INTEGER,
          writer=ARRAY_OF_POSITIVE_INTEGER_THROUGH_REF,
          msg="the schemas are the same",
      )
      schemas_are_compatible(
          reader=ARRAY_OF_POSITIVE_INTEGER_THROUGH_REF,
          writer=ARRAY_OF_POSITIVE_INTEGER,
          msg="the schemas are the same",
      )
  