#!/usr/bin/env python
# -*- coding: utf-8 -*-
#Author: Tim Henderson
#Email: tadh@case.edu
#Copyright (C) 2012 All Rights Reserved
#For licensing see the LICENSE file in the top level directory.

from json_validator import validate_json
import json_validator as vlib

def test_one_item_valid():
    schema = {
        "name" : vlib.value_checker("value")
    }
    ok, errors = validate_json(schema, {"name":"value"})
    assert ok
    assert len(errors) == 0

def test_one_item_invalid():
    schema = {
        "name" : 
          lambda b: (
            (True, list()) 
              if (b == 'value') 
              else (False, ["'%s' is not equal to 'value'" % b]))
    }
    ok, errors = validate_json(schema, {"name":"vsdalue"})
    assert not ok
    assert len(errors) == 1
    assert errors[0] == "'vsdalue' is not equal to 'value'"

def test_one_item_no_validator():
    schema = {
        "name" : "value"
    }
    ok, errors = validate_json(schema, {"name":"vsdalue"})
    assert not ok
    assert len(errors) == 1
    assert errors[0] == 'Expected schema item to be a callable got value'

def test_one_item_validator_returns_one_item():
    schema = {
        "name" : 
          lambda b: (True if (b == 'value') else False)
    }
    ok, errors = validate_json(schema, {"name":"vsdalue"})
    assert not ok
    assert len(errors) == 1
    assert errors[0] == 'Expected item validator to return a tuple got False'

def test_one_item_validator_returns_three_items():
    schema = {
        "name" : 
          lambda b: ((True, None, None) if (b == 'value') else (False, "asdf",
          "adfs"))
    }
    ok, errors = validate_json(schema, {"name":"vsdalue"})
    assert not ok
    assert len(errors) == 1
    assert errors[0] == "Expected item validator to return 2 items got (False, 'asdf', 'adfs')"

def test_list_one_item_valid():
    schema = [
      {
        "name" : vlib.value_checker("value")
      }
    ]
    ok, errors = validate_json(schema, [{"name":"value"}])
    assert ok
    assert len(errors) == 0

def test_list_three_items_valid():
    schema = [
      {
        "name" : vlib.value_checker("value")
      }
    ]
    ok, errors = validate_json(schema, [{"name":"value"}, {"name":"value"},
      {"name":"value"}])
    assert ok
    assert len(errors) == 0

def test_list_three_items_invalid():
    schema = [
      {
        "name" : vlib.value_checker("value")
      }
    ]
    ok, errors = validate_json(schema, [{"name":"vaque"}, {"name":"valqe"},
      {"name":"vqlue"}])
    assert not ok
    assert len(errors) == 3
    assert errors == ["'vaque' is not equal to 'value'", 
                      "'valqe' is not equal to 'value'", 
                      "'vqlue' is not equal to 'value'"]

def test_list_three_bare_items_valid():
    schema = [
        vlib.value_checker("value")
    ]
    ok, errors = validate_json(schema, ["value", "value", "value"])
    assert ok
    assert len(errors) == 0


def test_length_checker():
    schema = [
          vlib.length_checker(5)
    ]
    ok, errors = validate_json(schema, ["value", "value", "value"])
    assert ok
    assert len(errors) == 0

def test_type_checker():
    schema = [
          vlib.type_checker(basestring)
    ]
    ok, errors = validate_json(schema, ["value", "value", "value"])
    assert ok
    assert len(errors) == 0
 
def test_max_length_checker():
    schema = [
          vlib.max_length_checker(5)
    ]
    ok, errors = validate_json(schema, ["value", "value", "value"])
    assert ok
    assert len(errors) == 0

def test_max_length_checker_under():
    schema = [
          vlib.max_length_checker(5)
    ]
    ok, errors = validate_json(schema, ["valu"])
    assert ok
    assert len(errors) == 0

def test_max_length_checker_over():
    schema = [
          vlib.max_length_checker(5)
    ]
    ok, errors = validate_json(schema, ["values"])
    assert not ok
    assert len(errors) == 1
    assert errors == ["Sequence, 'values', greater than 5 items long"]

def test_min_length_checker():
    schema = [
          vlib.min_length_checker(5)
    ]
    ok, errors = validate_json(schema, ["value", "value", "value"])
    assert ok
    assert len(errors) == 0

def test_min_length_checker_under():
    schema = [
          vlib.min_length_checker(5)
    ]
    ok, errors = validate_json(schema, ["valu"])
    assert not ok
    assert len(errors) == 1
    assert errors == ["Sequence, 'valu', less than 5 items long"]

def test_min_length_checker_over():
    schema = [
          vlib.min_length_checker(5)
    ]
    ok, errors = validate_json(schema, ["values"])
    assert ok
    assert len(errors) == 0

def test_type_or_type_checker():
    schema = [
          vlib.type_checker(int) | vlib.type_checker(float)
    ]
    ok, errors = validate_json(schema, ["value", "value", "value"])
    assert not ok
    assert len(errors) == 6

def test_type_and_type_checker():
    schema = [
          vlib.type_checker(int) & vlib.type_checker(float)
    ]
    ok, errors = validate_json(schema, ["value", "value", "value"])
    assert not ok
    assert len(errors) == 6
    assert errors == [
        "Object, ''value'', not of type <type 'int'>", 
        "Object, ''value'', not of type <type 'float'>", 
        "Object, ''value'', not of type <type 'int'>", 
        "Object, ''value'', not of type <type 'float'>", 
        "Object, ''value'', not of type <type 'int'>", 
        "Object, ''value'', not of type <type 'float'>"]

def test_type_and_length_checker():
    schema = [
          vlib.type_checker(basestring) & vlib.length_checker(4)
    ]
    ok, errors = validate_json(schema, ["value"])
    assert not ok
    assert len(errors) == 1
    assert errors == ["Sequence, 'value', is not 4 items long"]

def test_type_or_length_checker():
    schema = [
          vlib.type_checker(basestring) | vlib.length_checker(4)
    ]
    ok, errors = validate_json(schema, ["value"])
    assert ok
    assert len(errors) == 0

def test_type_and_length_checker_both_true():
    schema = [
          vlib.type_checker(basestring) & vlib.length_checker(5)
    ]
    ok, errors = validate_json(schema, ["value"])
    assert ok
    assert len(errors) == 0