#!/usr/bin/env python

import unittest
import collect_idls_into_json
import utilities

from blink_idl_parser import parse_file, BlinkIDLParser

_FILE = 'Source/bindings/scripts/testdata/test_filepath.txt'
_KEY_SET = set(['Operations', 'Name', 'FilePath', 'Inherit', 'Consts', 'ExtAttributes', 'Attributes'])
_PARTIAL = {'Node': {'Operations': [], 'Name': 'Node', 'FilePath': 'Source/core/timing/WorkerGlobalScopePerformance.idl', 'Inherit': [], 'Consts': [], 'ExtAttributes': [], 'Attributes': [{'Static': False, 'Readonly': True, 'Type': 'WorkerPerformance', 'Name': 'performance', 'ExtAttributes': []}]}}


class TestFunctions(unittest.TestCase):
    def setUp(self):
        parser = BlinkIDLParser()
        path = utilities.read_file_to_list(_FILE)[0]
        definitions = parse_file(parser, path)
        self.definition = definitions.GetChildren()[0]

    def test_get_definitions(self):
        pathfile = utilities.read_file_to_list(_FILE)
        for actual in collect_idls_into_json.get_definitions(pathfile):
            self.assertEqual(actual.GetName(), self.definition.GetName())

    def test_is_non_partial(self):
        if self.definition.GetClass() == 'Interface' and not self.definition.GetProperty('Partial'):
            self.assertTrue(collect_idls_into_json.is_non_partial(self.definition))
        else:
            self.assertFalse(collect_idls_into_json.is_non_partial(self.definition))

    def test_is_partial(self):
        if self.definition.GetClass() == 'Interface' and self.definition.GetProperty('Partial'):
            self.assertTrue(collect_idls_into_json.is_partial(self.definition))
        else:
            self.assertFalse(collect_idls_into_json.is_partial(self.definition))

    def test_get_filepaths(self):
        filepath = collect_idls_into_json.get_filepath(self.definition)
        self.assertTrue(filepath.startswith('Source'))
        self.assertTrue(filepath.endswith('.idl'))

    def test_const_node_to_dict(self):
        const_member = set(['Name', 'Type', 'Value', 'ExtAttributes'])
        for const in collect_idls_into_json.get_const_node_list(self.definition):
            if const:
                self.assertEqual(const.GetClass(), 'Const')
                self.assertEqual(collect_idls_into_json.get_const_type(const), 'unsigned short')
                self.assertEqual(collect_idls_into_json.get_const_value(const), '1')
                self.assertTrue(const_member.issuperset(collect_idls_into_json.const_node_to_dict(const).keys()))
            else:
                self.assertEqual(const, None)

    def test_attribute_node_to_dict(self):
        attribute_member = set(['Name', 'Type', 'ExtAttributes', 'Readonly', 'Static'])
        for attribute in collect_idls_into_json.get_attribute_node_list(self.definition):
            if attribute:
                self.assertEqual(attribute.GetClass(), 'Attribute')
                self.assertEqual(attribute.GetName(), 'parentNode')
                self.assertEqual(collect_idls_into_json.get_attribute_type(attribute), 'Node')
                self.assertTrue(attribute_member.issuperset(collect_idls_into_json.attribute_node_to_dict(attribute).keys()))
            else:
                self.assertEqual(attribute, None)

    def test_operation_node_to_dict(self):
        operate_member = set(['Static', 'ExtAttributes', 'Type', 'Name', 'Arguments'])
        argument_member = set(['Name', 'Type'])
        for operation in collect_idls_into_json.get_operation_node_list(self.definition):
            if operation:
                self.assertEqual(operation.GetClass(), 'Operation')
                self.assertEqual(operation.GetName(), 'appendChild')
                self.assertEqual(collect_idls_into_json.get_operation_type(operation), 'Node')
                self.assertTrue(operate_member.issuperset(collect_idls_into_json.operation_node_to_dict(operation).keys()))
                for argument in collect_idls_into_json.get_argument_node_list(operation):
                    if argument:
                        self.assertEqual(argument.GetClass(), 'Argument')
                        self.assertEqual(argument.GetName(), 'newChild')
                        self.assertEqual(collect_idls_into_json.get_argument_type(argument), 'Node')
                        self.assertTrue(argument_member.issuperset(collect_idls_into_json.argument_node_to_dict(argument).keys()))
                    else:
                        self.assertEqual(argument, None)
            else:
                self.assertEqual(operation, None)

    def test_extattribute_node_to_dict(self):
        for extattr in collect_idls_into_json.get_extattribute_node_list(self.definition):
            if extattr:
                self.assertEqual(extattr.GetClass(), 'ExtAttribute')
                self.assertEqual(extattr.GetName(), 'CustomToV8')
                self.assertEqual(collect_idls_into_json.extattr_node_to_dict(extattr).keys(), ['Name'])
                self.assertEqual(collect_idls_into_json.extattr_node_to_dict(extattr).values(), ['CustomToV8'])
            else:
                self.assertEqual(extattr, None)

    def test_inherit_node_to_dict(self):
        inherit = collect_idls_into_json.inherit_node_to_dict(self.definition)
        if inherit:
            self.assertEqual(inherit.keys(), ['Parent'])
            self.assertEqual(inherit.values(), ['EventTarget'])
        else:
            self.assertEqual(inherit, [])

    def test_interface_node_to_dict(self):
        self.assertTrue(_KEY_SET.issuperset(collect_idls_into_json.interface_node_to_dict(self.definition)))

    def test_merge_partial_dicts(self):
        key_name = self.definition.GetName()
        self.assertEqual(collect_idls_into_json.merge_partial_dicts({key_name: collect_idls_into_json.interface_node_to_dict(self.definition)}, _PARTIAL)[key_name]['Partial_FilePaths'], ['Source/core/timing/WorkerGlobalScopePerformance.idl'])


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