#!/usr/bin/env python3
# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Unit tests for dependency_analysis.serialization."""

import unittest.mock

import class_dependency
import class_json_consts
import graph
import json_consts
import package_dependency
import package_json_consts
import serialization


class TestSerialization(unittest.TestCase):
    """Unit tests for various de/serialization functions."""
    CLASS_1 = 'p1.c1'
    CLASS_2 = 'p1.c2'
    CLASS_3 = 'p2.c3'
    BUILD_TARGET_1 = '//build/target:one'
    BUILD_TARGET_2 = '//build/target:two'
    CLASS_1_NESTED_1 = 'abc'
    CLASS_1_NESTED_2 = 'def'
    CLASS_2_NESTED_1 = 'ghi'

    # The lists in the following JSON are sorted,
    # since we sort lists when serializing (for easier testing).
    JSON_CLASS_GRAPH = {
        json_consts.NODES: [
            {
                json_consts.NAME: CLASS_1,
                json_consts.META: {
                    class_json_consts.PACKAGE:
                    'p1',
                    class_json_consts.CLASS:
                    'c1',
                    class_json_consts.BUILD_TARGETS: [BUILD_TARGET_1],
                    class_json_consts.NESTED_CLASSES:
                    [CLASS_1_NESTED_1, CLASS_1_NESTED_2],
                },
            },
            {
                json_consts.NAME: CLASS_2,
                json_consts.META: {
                    class_json_consts.PACKAGE: 'p1',
                    class_json_consts.CLASS: 'c2',
                    class_json_consts.BUILD_TARGETS: [],
                    class_json_consts.NESTED_CLASSES: [CLASS_2_NESTED_1],
                },
            },
            {
                json_consts.NAME: CLASS_3,
                json_consts.META: {
                    class_json_consts.PACKAGE:
                    'p2',
                    class_json_consts.CLASS:
                    'c3',
                    class_json_consts.BUILD_TARGETS:
                    [BUILD_TARGET_1, BUILD_TARGET_2],
                    class_json_consts.NESTED_CLASSES: [],
                },
            },
        ],
        json_consts.EDGES: [
            {
                json_consts.BEGIN: CLASS_1,
                json_consts.END: CLASS_2,
            },
            {
                json_consts.BEGIN: CLASS_1,
                json_consts.END: CLASS_3,
            },
            {
                json_consts.BEGIN: CLASS_2,
                json_consts.END: CLASS_3,
            },
        ],
    }

    JSON_PACKAGE_GRAPH = {
        json_consts.NODES: [
            {
                json_consts.NAME: 'p1',
                json_consts.META: {
                    package_json_consts.CLASSES: [CLASS_1, CLASS_2],
                },
            },
            {
                json_consts.NAME: 'p2',
                json_consts.META: {
                    package_json_consts.CLASSES: [CLASS_3],
                },
            },
        ],
        json_consts.EDGES: [
            {
                json_consts.BEGIN: 'p1',
                json_consts.END: 'p1',
                json_consts.META: {
                    package_json_consts.CLASS_EDGES: [
                        [CLASS_1, CLASS_2],
                    ],
                },
            },
            {
                json_consts.BEGIN: 'p1',
                json_consts.END: 'p2',
                json_consts.META: {
                    package_json_consts.CLASS_EDGES: [
                        [CLASS_1, CLASS_3],
                        [CLASS_2, CLASS_3],
                    ],
                },
            },
        ],
    }

    def test_class_serialization(self):
        """Tests JSON serialization of a class dependency graph."""
        test_graph = class_dependency.JavaClassDependencyGraph()
        test_graph.add_edge_if_new(self.CLASS_1, self.CLASS_2)
        test_graph.add_edge_if_new(self.CLASS_1, self.CLASS_3)
        test_graph.add_edge_if_new(self.CLASS_2, self.CLASS_3)
        test_graph.get_node_by_key(self.CLASS_1).add_nested_class(
            self.CLASS_1_NESTED_1)
        test_graph.get_node_by_key(self.CLASS_1).add_nested_class(
            self.CLASS_1_NESTED_2)
        test_graph.get_node_by_key(self.CLASS_2).add_nested_class(
            self.CLASS_2_NESTED_1)
        test_graph.get_node_by_key(self.CLASS_1).add_build_target(
            self.BUILD_TARGET_1)
        test_graph.get_node_by_key(self.CLASS_3).add_build_target(
            self.BUILD_TARGET_1)
        test_graph.get_node_by_key(self.CLASS_3).add_build_target(
            self.BUILD_TARGET_2)

        test_json_obj = serialization.create_json_obj_from_graph(test_graph)

        self.assertEqual(test_json_obj, self.JSON_CLASS_GRAPH)

    def test_package_serialization(self):
        """Tests JSON serialization of a package dependency graph."""
        class_graph = class_dependency.JavaClassDependencyGraph()
        class_graph.add_edge_if_new(self.CLASS_1, self.CLASS_2)
        class_graph.add_edge_if_new(self.CLASS_1, self.CLASS_3)
        class_graph.add_edge_if_new(self.CLASS_2, self.CLASS_3)
        class_graph.get_node_by_key(self.CLASS_1).add_nested_class(
            self.CLASS_1_NESTED_1)
        class_graph.get_node_by_key(self.CLASS_1).add_nested_class(
            self.CLASS_1_NESTED_2)
        class_graph.get_node_by_key(self.CLASS_2).add_nested_class(
            self.CLASS_2_NESTED_1)

        package_graph = package_dependency.JavaPackageDependencyGraph(
            class_graph)
        test_json_obj = serialization.create_json_obj_from_graph(package_graph)

        self.assertEqual(test_json_obj, self.JSON_PACKAGE_GRAPH)

    def test_class_deserialization(self):
        """Tests JSON deserialization of a class dependency graph.

        Since we only ever construct package graphs from class graphs
        (and that feature is tested elsewhere), we do not need to test
        deserialization of package dependency graphs as well.
        """
        test_graph = serialization.create_class_graph_from_json_obj(
            self.JSON_CLASS_GRAPH)

        node_1 = test_graph.get_node_by_key(self.CLASS_1)
        node_2 = test_graph.get_node_by_key(self.CLASS_2)
        node_3 = test_graph.get_node_by_key(self.CLASS_3)

        self.assertIsNotNone(node_1)
        self.assertIsNotNone(node_2)
        self.assertIsNotNone(node_3)
        self.assertEqual(node_1.nested_classes,
                         {self.CLASS_1_NESTED_1, self.CLASS_1_NESTED_2})
        self.assertEqual(node_2.nested_classes, {self.CLASS_2_NESTED_1})
        self.assertEqual(node_3.nested_classes, set())
        self.assertEqual(node_1.build_targets, {self.BUILD_TARGET_1})
        self.assertEqual(node_2.build_targets, set())
        self.assertEqual(node_3.build_targets,
                         {self.BUILD_TARGET_1, self.BUILD_TARGET_2})
        self.assertEqual(
            graph.sorted_edges_by_name(test_graph.edges),
            graph.sorted_edges_by_name([(node_1, node_2), (node_1, node_3),
                                        (node_2, node_3)]))


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