#!/usr/bin/python

"""
Copyright 2014 Google Inc.

Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.

Test imagepairset.py
"""

# System-level imports
import unittest

# Local imports
import column
import imagepair
import imagepairset


BASE_URL_1 = 'http://base/url/1'
BASE_URL_2 = 'http://base/url/2'
DIFF_BASE_URL = 'http://diff/base/url'
IMAGEPAIR_1_AS_DICT = {
    imagepair.KEY__IMAGEPAIRS__EXTRACOLUMNS: {
        'builder': 'MyBuilder',
        'test': 'test1',
    },
    imagepair.KEY__IMAGEPAIRS__IMAGE_A_URL: 'test1/1111.png',
    imagepair.KEY__IMAGEPAIRS__IMAGE_B_URL: 'test1/1111.png',
    imagepair.KEY__IMAGEPAIRS__IS_DIFFERENT: False,
}
IMAGEPAIR_2_AS_DICT = {
    imagepair.KEY__IMAGEPAIRS__DIFFERENCES: {
        'maxDiffPerChannel': [1, 2, 3],
        'numDifferingPixels': 111,
        'percentDifferingPixels': 22.222,
    },
    imagepair.KEY__IMAGEPAIRS__EXTRACOLUMNS: {
        'builder': 'MyBuilder',
        'test': 'test2',
    },
    imagepair.KEY__IMAGEPAIRS__IMAGE_A_URL: 'test2/2222.png',
    imagepair.KEY__IMAGEPAIRS__IMAGE_B_URL: 'test2/22223.png',
    imagepair.KEY__IMAGEPAIRS__IS_DIFFERENT: True,
}
IMAGEPAIR_3_AS_DICT = {
    imagepair.KEY__IMAGEPAIRS__DIFFERENCES: {
        'maxDiffPerChannel': [4, 5, 6],
        'numDifferingPixels': 111,
        'percentDifferingPixels': 44.444,
    },
    imagepair.KEY__IMAGEPAIRS__EXPECTATIONS: {
        'bugs': [1001, 1002],
        'ignoreFailure': True,
    },
    imagepair.KEY__IMAGEPAIRS__EXTRACOLUMNS: {
        'builder': 'MyBuilder',
        'test': 'test3',
    },
    imagepair.KEY__IMAGEPAIRS__IMAGE_A_URL: 'test3/3333.png',
    imagepair.KEY__IMAGEPAIRS__IMAGE_B_URL: 'test3/33334.png',
    imagepair.KEY__IMAGEPAIRS__IS_DIFFERENT: True,
}
SET_A_DESCRIPTION = 'expectations'
SET_B_DESCRIPTION = 'actuals'


class ImagePairSetTest(unittest.TestCase):

  def setUp(self):
    self.maxDiff = None  # do not truncate diffs when tests fail

  def shortDescription(self):
    """Tells unittest framework to not print docstrings for test cases."""
    return None

  def test_success(self):
    """Assembles some ImagePairs into an ImagePairSet, and validates results.
    """
    image_pairs = [
        MockImagePair(imageA_base_url=BASE_URL_1, imageB_base_url=BASE_URL_1,
                      dict_to_return=IMAGEPAIR_1_AS_DICT),
        MockImagePair(imageA_base_url=BASE_URL_1, imageB_base_url=BASE_URL_1,
                      dict_to_return=IMAGEPAIR_2_AS_DICT),
        MockImagePair(imageA_base_url=BASE_URL_1, imageB_base_url=BASE_URL_1,
                      dict_to_return=IMAGEPAIR_3_AS_DICT),
    ]
    expected_imageset_dict = {
        'extraColumnHeaders': {
            'builder': {
                'headerText': 'builder',
                'isFilterable': True,
                'isSortable': True,
                'useFreeformFilter': False,
                'valuesAndCounts': [('MyBuilder', 3)],
            },
            'test': {
                'headerText': 'which GM test',
                'headerUrl': 'http://learn/about/gm/tests',
                'isFilterable': True,
                'isSortable': False,
                'useFreeformFilter': False,
                'valuesAndCounts': [('test1', 1),
                                    ('test2', 1),
                                    ('test3', 1)],
            },
        },
        'extraColumnOrder': ['builder', 'test'],
        'imagePairs': [
            IMAGEPAIR_1_AS_DICT,
            IMAGEPAIR_2_AS_DICT,
            IMAGEPAIR_3_AS_DICT,
        ],
        'imageSets': {
            'imageA': {
                'baseUrl': BASE_URL_1,
                'description': SET_A_DESCRIPTION,
            },
            'imageB': {
                'baseUrl': BASE_URL_1,
                'description': SET_B_DESCRIPTION,
            },
            'diffs': {
                'baseUrl': DIFF_BASE_URL + '/diffs',
                'description': 'color difference per channel',
            },
            'whiteDiffs': {
                'baseUrl': DIFF_BASE_URL + '/whitediffs',
                'description': 'differing pixels in white',
            },
        },
    }

    image_pair_set = imagepairset.ImagePairSet(
        descriptions=(SET_A_DESCRIPTION, SET_B_DESCRIPTION),
        diff_base_url=DIFF_BASE_URL)
    for image_pair in image_pairs:
      image_pair_set.add_image_pair(image_pair)
    # The 'builder' column header uses the default settings,
    # but the 'test' column header has manual adjustments.
    image_pair_set.set_column_header_factory(
        'test',
        column.ColumnHeaderFactory(
            header_text='which GM test',
            header_url='http://learn/about/gm/tests',
            is_filterable=True,
            is_sortable=False))
    self.assertEqual(image_pair_set.as_dict(), expected_imageset_dict)

  def test_mismatched_base_url(self):
    """Confirms that mismatched base_urls will cause an exception."""
    image_pair_set = imagepairset.ImagePairSet(
        diff_base_url=DIFF_BASE_URL)
    image_pair_set.add_image_pair(
        MockImagePair(imageA_base_url=BASE_URL_1, imageB_base_url=BASE_URL_1,
                      dict_to_return=IMAGEPAIR_1_AS_DICT))
    image_pair_set.add_image_pair(
        MockImagePair(imageA_base_url=BASE_URL_1, imageB_base_url=BASE_URL_1,
                      dict_to_return=IMAGEPAIR_2_AS_DICT))
    with self.assertRaises(Exception):
      image_pair_set.add_image_pair(
          MockImagePair(imageA_base_url=BASE_URL_2, imageB_base_url=BASE_URL_2,
                        dict_to_return=IMAGEPAIR_3_AS_DICT))

  def test_missing_column_ids(self):
    """Confirms that passing truncated column_ids_in_order to as_dict()
    will cause an exception."""
    image_pair_set = imagepairset.ImagePairSet(
        diff_base_url=DIFF_BASE_URL)
    image_pair_set.add_image_pair(
        MockImagePair(imageA_base_url=BASE_URL_1, imageB_base_url=BASE_URL_1,
                      dict_to_return=IMAGEPAIR_1_AS_DICT))
    image_pair_set.add_image_pair(
        MockImagePair(imageA_base_url=BASE_URL_1, imageB_base_url=BASE_URL_1,
                      dict_to_return=IMAGEPAIR_2_AS_DICT))
    # Call as_dict() with default or reasonable column_ids_in_order.
    image_pair_set.as_dict()
    image_pair_set.as_dict(column_ids_in_order=['test', 'builder'])
    image_pair_set.as_dict(column_ids_in_order=['test', 'builder', 'extra'])
    # Call as_dict() with not enough column_ids.
    with self.assertRaises(Exception):
      image_pair_set.as_dict(column_ids_in_order=['builder'])


class MockImagePair(object):
  """Mock ImagePair object, which will return canned results."""
  def __init__(self, imageA_base_url, imageB_base_url, dict_to_return):
    """
    Args:
      base_url: base_url attribute for this object
      dict_to_return: dictionary to return from as_dict()
    """
    self.imageA_base_url = imageA_base_url
    self.imageB_base_url = imageB_base_url
    self.extra_columns_dict = dict_to_return.get(
        imagepair.KEY__IMAGEPAIRS__EXTRACOLUMNS, None)
    self._dict_to_return = dict_to_return

  def as_dict(self):
    return self._dict_to_return


def main():
  suite = unittest.TestLoader().loadTestsFromTestCase(ImagePairSetTest)
  unittest.TextTestRunner(verbosity=2).run(suite)


if __name__ == '__main__':
  main()
