text: import unittest
  import trafaret as t
  import trafaret_schema
  
  
  class TestConstEnumType(unittest.TestCase):
      def test_const(self):
          check = trafaret_schema.json_schema({
              'const': 'blabla',
          })
          self.assertEqual(check('blabla'), 'blabla')
  
          check = trafaret_schema.json_schema({
              'const': 100,
          })
          self.assertEqual(check(100), 100)
  
      def test_enum(self):
          check = trafaret_schema.json_schema({
              'enum': ['blabla', 200],
          })
          self.assertEqual(check('blabla'), 'blabla')
          self.assertEqual(check(200), 200)
          with self.assertRaises(t.DataError):
              check(300)
  
      def test_type(self):
          check = trafaret_schema.json_schema({'type': 'null'})
          self.assertEqual(check(None), None)
  
          check = trafaret_schema.json_schema({'type': 'boolean'})
          self.assertEqual(check(True), True)
  
          check = trafaret_schema.json_schema({'type': 'object'})
          self.assertEqual(check({}), {})
  
          check = trafaret_schema.json_schema({'type': 'array'})
          self.assertEqual(check([]), [])
  
          check = trafaret_schema.json_schema({'type': 'number'})
          self.assertEqual(check(2.4), 2.4)
  
          check = trafaret_schema.json_schema({'type': 'integer'})
          self.assertEqual(check(200), 200)
          with self.assertRaises(t.DataError):
              check('blabla')
  
          check = trafaret_schema.json_schema({'type': 'string'})
          self.assertEqual(check('a'), 'a')
  
  
  class TestPredicates(unittest.TestCase):
      def test_all_of(self):
          check = trafaret_schema.json_schema({
              'allOf': [
                  {'minLength': 5},
                  {'maxLength': 10},
              ],
          })
          self.assertEqual(check('blabla'), 'blabla')
          with self.assertRaises(t.DataError):
              check('bla')
  
      def test_any_of(self):
          check = trafaret_schema.json_schema({
              'anyOf': [
                  {'minLength': 5},
                  {'maxLength': 3},
              ],
          })
          self.assertEqual(check('blabla'), 'blabla')
          self.assertEqual(check('bla'), 'bla')
          with self.assertRaises(t.DataError):
              check('blab')
  
      def test_not(self):
          check = trafaret_schema.json_schema({
              'not': {'minLength': 5},
          })
          self.assertEqual(check('bla'), 'bla')
          with self.assertRaises(t.DataError):
              check('blabla')
  
  
  
  class TestStringValidation(unittest.TestCase):
      def test_string(self):
          check = trafaret_schema.json_schema({
              'type': 'string',
          })
          self.assertEqual(check('blabla'), 'blabla')
  
      def test_min_length(self):
          check = trafaret_schema.json_schema({
              'type': 'string',
              'minLength': 60,
          })
          with self.assertRaises(t.DataError):
              check('blabla')
  
      def test_max_length(self):
          check = trafaret_schema.json_schema({
              'type': 'string',
              'maxLength': 5,
          })
          with self.assertRaises(t.DataError):
              check('blabla')
  
      def test_pattern(self):
          check = trafaret_schema.json_schema({
              'type': 'string',
              'pattern': 'bla+',
              'maxLength': 10,
              'minLength': 5,
          })
          self.assertEqual(check('blablabla'), 'blablabla')
  
  
  class TestNumberValidation(unittest.TestCase):
      def test_number(self):
          check = trafaret_schema.json_schema({
              'type': 'integer',
          })
          self.assertEqual(check(100), 100)
          with self.assertRaises(t.DataError):
              check(100.4)
  
      def test_minimum(self):
          check = trafaret_schema.json_schema({
              'type': 'number',
              'minimum': 5,
          })
          with self.assertRaises(t.DataError):
              check(1)
  
          check = trafaret_schema.json_schema({
              'type': 'number',
              'exclusiveMinimum': 5,
          })
          with self.assertRaises(t.DataError):
              check(5)
  
      def test_maximum(self):
          check = trafaret_schema.json_schema({
              'type': 'number',
              'maximum': 5,
          })
          with self.assertRaises(t.DataError):
              check(10)
  
          check = trafaret_schema.json_schema({
              'type': 'number',
              'exclusiveMaximum': 5,
          })
          with self.assertRaises(t.DataError):
              check(5)
  
      def test_multiple_of(self):
          check = trafaret_schema.json_schema({
              'type': 'number',
              'multipleOf': 5,
          })
          self.assertEqual(check(10), 10)
          with self.assertRaises(t.DataError):
              check(11)
  
  
  class TestArrays(unittest.TestCase):
      def test_min_items(self):
          check = trafaret_schema.json_schema({
              'type': 'array',
              'minItems': 5,
          })
          with self.assertRaises(t.DataError):
              check([1,2,3,4])
          self.assertEqual(check([1,2,3,4,5]), [1,2,3,4,5])
  
      def test_max_items(self):
          check = trafaret_schema.json_schema({
              'type': 'array',
              'maxItems': 5,
          })
          with self.assertRaises(t.DataError):
              check([1,2,3,4,5,6])
          self.assertEqual(check([1,2,3,4,5]), [1,2,3,4,5])
  
      def test_uniq(self):
          check = trafaret_schema.json_schema({
              'type': 'array',
              'uniqueItems': True,
          })
          with self.assertRaises(t.DataError):
              check([1,2,3,4,5,5])
          self.assertEqual(check([1,2,3,4,5]), [1,2,3,4,5])
  
      def test_contains(self):
          check = trafaret_schema.json_schema({
              'type': 'array',
              'contains': {'type': 'number'},
          })
          with self.assertRaises(t.DataError):
              check(['a','b','c'])
          self.assertEqual(check(['a','b','c',5]), ['a','b','c',5])
  
      def test_simple_items(self):
          check = trafaret_schema.json_schema({
              'type': 'array',
              'items': {'type': 'number'},
          })
          with self.assertRaises(t.DataError):
              check([1,2,'a',4,5,5])
          self.assertEqual(check([1,2,3,4,5]), [1,2,3,4,5])
  
      def test_positional_items(self):
          check = trafaret_schema.json_schema({
              'type': 'array',
              'items': [{'type': 'number'}, {'type': 'string'}],
          })
          with self.assertRaises(t.DataError):
              # bad 2nd position
              check([1,None])
          with self.assertRaises(t.DataError):
              # too long array
              check([1,'a',4,5,5])
          self.assertEqual(check([1,'a']), [1,'a'])
  
      def test_additional_items(self):
          check = trafaret_schema.json_schema({
              'type': 'array',
              'items': [{'type': 'number'}, {'type': 'string'}],
              'additionalItems': {'type': 'number'},
          })
          with self.assertRaises(t.DataError):
              check([1,None,4,5,5])
          with self.assertRaises(t.DataError):
              check([1,'a','a',5,5])
          self.assertEqual(check([1,'a',5,5,5]), [1,'a',5,5,5])
  
  
  class TestObjects(unittest.TestCase):
      def test_max_props(self):
          check = trafaret_schema.json_schema({
              'type': 'object',
              'maxProperties': 1,
          })
          with self.assertRaises(t.DataError):
              check({'a': 1, 'b': 2})
          self.assertEqual(check({'a': 1}), {'a': 1})
  
      def test_min_props(self):
          check = trafaret_schema.json_schema({
              'type': 'object',
              'minProperties': 2,
          })
          with self.assertRaises(t.DataError):
              check({'a': 1})
          self.assertEqual(check({'a': 1, 'b': 2}), {'a': 1, 'b': 2})
  
      def test_required(self):
          check = trafaret_schema.json_schema({
              'type': 'object',
              'required': ['a', 'b'],
          })
          with self.assertRaises(t.DataError):
              check({'a': 1})
          self.assertEqual(check({'a': 1, 'b': 2}), {'a': 1, 'b': 2})
  
      def test_properties(self):
          check = trafaret_schema.json_schema({
              'type': 'object',
              'properties': {'a': {'type': 'number'}},
          })
          with self.assertRaises(t.DataError):
              check({'a': 'b'})
          self.assertEqual(check({'a': 1, 'b': 2}), {'a': 1, 'b': 2})
  
      def test_pattern_properties(self):
          check = trafaret_schema.json_schema({
              'type': 'object',
              'patternProperties': {'a+': {'type': 'number'}},
          })
          with self.assertRaises(t.DataError):
              check({'a': 'b'})
          with self.assertRaises(t.DataError):
              check({'a': 3, 'aaa': 'b'})
          self.assertEqual(check({'a': 1, 'aaa': 3}), {'a': 1, 'aaa': 3})
  
      def test_additional_properties(self):
          check = trafaret_schema.json_schema({
              'type': 'object',
              'properties': {'a': {'type': 'number'}},
              'additionalProperties': {'type': 'boolean'},
          })
          with self.assertRaises(t.DataError):
              check({'a':1, 'b': 2})
          self.assertEqual(check({'a': 1, 'b': True}), {'a': 1, 'b': True})
  
      def test_property_names(self):
          check = trafaret_schema.json_schema({
              'type': 'object',
              'propertyNames': {
                  'type': 'string',
                  'pattern': 'bla+',
              },
          })
          with self.assertRaises(t.DataError):
              check({'a': 'b'})
          self.assertEqual(check({'bla': 1, 'blabla': 3}), {'bla': 1, 'blabla': 3})
  
      def test_dependencies(self):
          check = trafaret_schema.json_schema({
              'type': 'object',
              'properties': {'a': {'type': 'number'}},
              'dependencies': {'a': ['b', 'c']},
          })
          self.assertEqual(check({'bla': 1, 'blabla': 3}), {'bla': 1, 'blabla': 3})
          with self.assertRaises(t.DataError):
              check({'a': 'b'})
          self.assertEqual(check({'a': 1, 'b': 3, 'c': 4}), {'a': 1, 'b': 3, 'c': 4})
  
  
  class TestReferences(unittest.TestCase):
      def test_local_reference(self):
          check = trafaret_schema.json_schema({
              'type': 'object',
              "properties": {
                  "billing_address": { "$ref": "#/definitions/address" },
                  "shipping_address": { "$ref": "#/definitions/address" },
              },
              "definitions": {
                  "address": {
                      "type": "object",
                      "properties": {
                          "street_address": { "type": "string" },
                          "city": { "type": "string" },
                          "state": { "type": "string" },
                      },
  
                      "required": ["city"],
                  },
              },
          })
          data = {
              'billing_address': {'city': 'Samara'},
              'shipping_address': {'city': 'Samara'},
          }
          assert check(data) == data
  
      def test_adjacent_reference(self):
          register = trafaret_schema.Register()
          addresses = trafaret_schema.json_schema({
                  "$id": "http://yuhuhu.com/address",
                  "type": "object",
                  "properties": {
                      "billing_address": { "$ref": "#/definitions/address" },
                      "shipping_address": { "$ref": "#/definitions/address" },
                  },
                  "definitions": {
                      "address": {
                          "type": "object",
                          "properties": {
                              "street_address": { "type": "string" },
                              "city": { "type": "string" },
                              "state": { "type": "string" },
                          },
  
                          "required": ["city"],
                      },
                  },
              },
              context=register,
          )
          person = trafaret_schema.json_schema({
                  "type": "object",
                  "properties": {
                      "name": {"type": "string"},
                      "address": {"$ref":  "http://yuhuhu.com/address#/definitions/address"},
                  },
              },
              context=register,
          )
  
          data = {
              'name': 'Peotr',
              'address': {'city': 'Moscow'},
          }
          assert person.check(data) == data
  
          register.validate_references()
  