#!/usr/bin/env vpython
# Copyright 2015 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.

# pylint: disable=protected-access

import unittest
from xml.etree import ElementTree

import emma_coverage_stats

import mock  # pylint: disable=import-error

EMPTY_COVERAGE_STATS_DICT = {
  'files': {},
  'patch': {
    'incremental': {
      'covered': 0, 'total': 0
    }
  }
}


class _EmmaHtmlParserTest(unittest.TestCase):
  """Tests for _EmmaHtmlParser.

  Uses modified EMMA report HTML that contains only the subset of tags needed
  for test verification.
  """

  def setUp(self):
    self.emma_dir = 'fake/dir/'
    self.parser = emma_coverage_stats._EmmaHtmlParser(self.emma_dir)
    self.simple_html = '<TR><TD CLASS="p">Test HTML</TD></TR>'
    self.index_html = (
      '<HTML>'
        '<BODY>'
          '<TABLE CLASS="hdft" CELLSPACING="0" WIDTH="100%">'
          '</TABLE>'
          '<TABLE CELLSPACING="0" WIDTH="100%">'
          '</TABLE>'
          '<TABLE CLASS="it" CELLSPACING="0">'
          '</TABLE>'
          '<TABLE CELLSPACING="0" WIDTH="100%">'
            '<TR>'
              '<TH CLASS="f">name</TH>'
              '<TH>class, %</TH>'
              '<TH>method, %</TH>'
              '<TH>block, %</TH>'
              '<TH>line, %</TH>'
            '</TR>'
            '<TR CLASS="o">'
              '<TD><A HREF="_files/0.html"'
              '>org.chromium.chrome.browser</A></TD>'
              '<TD CLASS="h">0%   (0/3)</TD>'
            '</TR>'
            '<TR>'
              '<TD><A HREF="_files/1.html"'
              '>org.chromium.chrome.browser.tabmodel</A></TD>'
              '<TD CLASS="h">0%   (0/8)</TD>'
            '</TR>'
          '</TABLE>'
          '<TABLE CLASS="hdft" CELLSPACING="0" WIDTH="100%">'
          '</TABLE>'
        '</BODY>'
      '</HTML>'
    )
    self.package_1_class_list_html = (
      '<HTML>'
        '<BODY>'
          '<TABLE CLASS="hdft" CELLSPACING="0" WIDTH="100%">'
          '</TABLE>'
          '<TABLE CELLSPACING="0" WIDTH="100%">'
          '</TABLE>'
          '<TABLE CELLSPACING="0" WIDTH="100%">'
            '<TR>'
              '<TH CLASS="f">name</TH>'
              '<TH>class, %</TH>'
              '<TH>method, %</TH>'
              '<TH>block, %</TH>'
              '<TH>line, %</TH>'
            '</TR>'
            '<TR CLASS="o">'
              '<TD><A HREF="1e.html">IntentHelper.java</A></TD>'
              '<TD CLASS="h">0%   (0/3)</TD>'
              '<TD CLASS="h">0%   (0/9)</TD>'
              '<TD CLASS="h">0%   (0/97)</TD>'
              '<TD CLASS="h">0%   (0/26)</TD>'
            '</TR>'
          '</TABLE>'
          '<TABLE CLASS="hdft" CELLSPACING="0" WIDTH="100%">'
          '</TABLE>'
        '</BODY>'
      '</HTML>'
    )
    self.package_2_class_list_html = (
      '<HTML>'
        '<BODY>'
          '<TABLE CLASS="hdft" CELLSPACING="0" WIDTH="100%">'
          '</TABLE>'
          '<TABLE CELLSPACING="0" WIDTH="100%">'
          '</TABLE>'
          '<TABLE CELLSPACING="0" WIDTH="100%">'
            '<TR>'
              '<TH CLASS="f">name</TH>'
              '<TH>class, %</TH>'
              '<TH>method, %</TH>'
              '<TH>block, %</TH>'
              '<TH>line, %</TH>'
            '</TR>'
            '<TR CLASS="o">'
              '<TD><A HREF="1f.html">ContentSetting.java</A></TD>'
              '<TD CLASS="h">0%   (0/1)</TD>'
            '</TR>'
            '<TR>'
              '<TD><A HREF="20.html">DevToolsServer.java</A></TD>'
            '</TR>'
            '<TR CLASS="o">'
              '<TD><A HREF="21.html">FileProviderHelper.java</A></TD>'
            '</TR>'
            '<TR>'
              '<TD><A HREF="22.html">ContextualMenuBar.java</A></TD>'
            '</TR>'
            '<TR CLASS="o">'
              '<TD><A HREF="23.html">AccessibilityUtil.java</A></TD>'
            '</TR>'
            '<TR>'
              '<TD><A HREF="24.html">NavigationPopup.java</A></TD>'
            '</TR>'
          '</TABLE>'
          '<TABLE CLASS="hdft" CELLSPACING="0" WIDTH="100%">'
          '</TABLE>'
        '</BODY>'
      '</HTML>'
    )
    self.partially_covered_tr_html = (
      '<TR CLASS="p">'
        '<TD CLASS="l" TITLE="78% line coverage (7 out of 9)">108</TD>'
        '<TD TITLE="78% line coverage (7 out of 9 instructions)">'
          'if (index &lt; 0 || index = mSelectors.size()) index = 0;</TD>'
      '</TR>'
    )
    self.covered_tr_html = (
      '<TR CLASS="c">'
        '<TD CLASS="l">110</TD>'
        '<TD>        if (mSelectors.get(index) != null) {</TD>'
      '</TR>'
    )
    self.not_executable_tr_html = (
      '<TR>'
        '<TD CLASS="l">109</TD>'
        '<TD> </TD>'
      '</TR>'
    )
    self.tr_with_extra_a_tag = (
      '<TR CLASS="z">'
        '<TD CLASS="l">'
          '<A name="1f">54</A>'
        '</TD>'
        '<TD>            }</TD>'
      '</TR>'
    )

  def testInit(self):
    emma_dir = self.emma_dir
    parser = emma_coverage_stats._EmmaHtmlParser(emma_dir)
    self.assertEqual(parser._base_dir, emma_dir)
    self.assertEqual(parser._emma_files_path, 'fake/dir/_files')
    self.assertEqual(parser._index_path, 'fake/dir/index.html')

  def testFindElements_basic(self):
    read_values = [self.simple_html]
    found, _ = MockOpenForFunction(self.parser._FindElements, read_values,
                                   file_path='fake', xpath_selector='.//TD')
    self.assertIs(type(found), list)
    self.assertIs(type(found[0]), ElementTree.Element)
    self.assertEqual(found[0].text, 'Test HTML')

  def testFindElements_multipleElements(self):
    multiple_trs = self.not_executable_tr_html + self.covered_tr_html
    read_values = ['<div>' + multiple_trs + '</div>']
    found, _ = MockOpenForFunction(self.parser._FindElements, read_values,
                                   file_path='fake', xpath_selector='.//TR')
    self.assertEquals(2, len(found))

  def testFindElements_noMatch(self):
    read_values = [self.simple_html]
    found, _ = MockOpenForFunction(self.parser._FindElements, read_values,
                                   file_path='fake', xpath_selector='.//TR')
    self.assertEqual(found, [])

  def testFindElements_badFilePath(self):
    with self.assertRaises(IOError):
      with mock.patch('os.path.exists', return_value=False):
        self.parser._FindElements('fake', xpath_selector='//tr')

  def testGetPackageNameToEmmaFileDict_basic(self):
    expected_dict = {
      'org.chromium.chrome.browser.AccessibilityUtil.java':
      'fake/dir/_files/23.html',
      'org.chromium.chrome.browser.ContextualMenuBar.java':
      'fake/dir/_files/22.html',
      'org.chromium.chrome.browser.tabmodel.IntentHelper.java':
      'fake/dir/_files/1e.html',
      'org.chromium.chrome.browser.ContentSetting.java':
      'fake/dir/_files/1f.html',
      'org.chromium.chrome.browser.DevToolsServer.java':
      'fake/dir/_files/20.html',
      'org.chromium.chrome.browser.NavigationPopup.java':
      'fake/dir/_files/24.html',
      'org.chromium.chrome.browser.FileProviderHelper.java':
      'fake/dir/_files/21.html'}

    read_values = [self.index_html, self.package_1_class_list_html,
                   self.package_2_class_list_html]
    return_dict, mock_open = MockOpenForFunction(
        self.parser.GetPackageNameToEmmaFileDict, read_values)

    self.assertDictEqual(return_dict, expected_dict)
    self.assertEqual(mock_open.call_count, 3)
    calls = [mock.call('fake/dir/index.html'),
             mock.call('fake/dir/_files/1.html'),
             mock.call('fake/dir/_files/0.html')]
    mock_open.assert_has_calls(calls)

  def testGetPackageNameToEmmaFileDict_noPackageElements(self):
    self.parser._FindElements = mock.Mock(return_value=[])
    return_dict = self.parser.GetPackageNameToEmmaFileDict()
    self.assertDictEqual({}, return_dict)

  def testGetLineCoverage_status_basic(self):
    line_coverage = self.GetLineCoverageWithFakeElements([self.covered_tr_html])
    self.assertEqual(line_coverage[0].covered_status,
                     emma_coverage_stats.COVERED)

  def testGetLineCoverage_status_statusMissing(self):
    line_coverage = self.GetLineCoverageWithFakeElements(
        [self.not_executable_tr_html])
    self.assertEqual(line_coverage[0].covered_status,
                     emma_coverage_stats.NOT_EXECUTABLE)

  def testGetLineCoverage_fractionalCoverage_basic(self):
    line_coverage = self.GetLineCoverageWithFakeElements([self.covered_tr_html])
    self.assertEqual(line_coverage[0].fractional_line_coverage, 1.0)

  def testGetLineCoverage_fractionalCoverage_partial(self):
    line_coverage = self.GetLineCoverageWithFakeElements(
        [self.partially_covered_tr_html])
    self.assertEqual(line_coverage[0].fractional_line_coverage, 0.78)

  def testGetLineCoverage_lineno_basic(self):
    line_coverage = self.GetLineCoverageWithFakeElements([self.covered_tr_html])
    self.assertEqual(line_coverage[0].lineno, 110)

  def testGetLineCoverage_lineno_withAlternativeHtml(self):
    line_coverage = self.GetLineCoverageWithFakeElements(
        [self.tr_with_extra_a_tag])
    self.assertEqual(line_coverage[0].lineno, 54)

  def testGetLineCoverage_source(self):
    self.parser._FindElements = mock.Mock(
        return_value=[ElementTree.fromstring(self.covered_tr_html)])
    line_coverage = self.parser.GetLineCoverage('fake_path')
    self.assertEqual(line_coverage[0].source,
                     '        if (mSelectors.get(index) != null) {')

  def testGetLineCoverage_multipleElements(self):
    line_coverage = self.GetLineCoverageWithFakeElements(
        [self.covered_tr_html, self.partially_covered_tr_html,
         self.tr_with_extra_a_tag])
    self.assertEqual(len(line_coverage), 3)

  def GetLineCoverageWithFakeElements(self, html_elements):
    """Wraps GetLineCoverage so mock HTML can easily be used.

    Args:
      html_elements: List of strings each representing an HTML element.

    Returns:
      A list of LineCoverage objects.
    """
    elements = [ElementTree.fromstring(string) for string in html_elements]
    with mock.patch('emma_coverage_stats._EmmaHtmlParser._FindElements',
                    return_value=elements):
      return self.parser.GetLineCoverage('fake_path')


class _EmmaCoverageStatsTest(unittest.TestCase):
  """Tests for _EmmaCoverageStats."""

  def setUp(self):
    self.good_source_to_emma = {
      '/path/to/1/File1.java': '/emma/1.html',
      '/path/2/File2.java': '/emma/2.html',
      '/path/2/File3.java': '/emma/3.html'
    }
    self.line_coverage = [
        emma_coverage_stats.LineCoverage(
            1, '', emma_coverage_stats.COVERED, 1.0),
        emma_coverage_stats.LineCoverage(
            2, '', emma_coverage_stats.COVERED, 1.0),
        emma_coverage_stats.LineCoverage(
            3, '', emma_coverage_stats.NOT_EXECUTABLE, 1.0),
        emma_coverage_stats.LineCoverage(
            4, '', emma_coverage_stats.NOT_COVERED, 1.0),
        emma_coverage_stats.LineCoverage(
            5, '', emma_coverage_stats.PARTIALLY_COVERED, 0.85),
        emma_coverage_stats.LineCoverage(
            6, '', emma_coverage_stats.PARTIALLY_COVERED, 0.20)
    ]
    self.lines_for_coverage = [1, 3, 5, 6]
    with mock.patch('emma_coverage_stats._EmmaHtmlParser._FindElements',
                    return_value=[]):
      self.simple_coverage = emma_coverage_stats._EmmaCoverageStats(
          'fake_dir', {})

  def testInit(self):
    coverage_stats = self.simple_coverage
    self.assertIsInstance(coverage_stats._emma_parser,
                          emma_coverage_stats._EmmaHtmlParser)
    self.assertIsInstance(coverage_stats._source_to_emma, dict)

  def testNeedsCoverage_withExistingJavaFile(self):
    test_file = '/path/to/file/File.java'
    with mock.patch('os.path.exists', return_value=True):
      self.assertTrue(
          emma_coverage_stats._EmmaCoverageStats.NeedsCoverage(test_file))

  def testNeedsCoverage_withNonJavaFile(self):
    test_file = '/path/to/file/File.c'
    with mock.patch('os.path.exists', return_value=True):
      self.assertFalse(
          emma_coverage_stats._EmmaCoverageStats.NeedsCoverage(test_file))

  def testNeedsCoverage_fileDoesNotExist(self):
    test_file = '/path/to/file/File.java'
    with mock.patch('os.path.exists', return_value=False):
      self.assertFalse(
          emma_coverage_stats._EmmaCoverageStats.NeedsCoverage(test_file))

  def testGetPackageNameFromFile_basic(self):
    test_file_text = """// Test Copyright
    package org.chromium.chrome.browser;
    import android.graphics.RectF;"""
    result_package, _ = MockOpenForFunction(
        emma_coverage_stats._EmmaCoverageStats.GetPackageNameFromFile,
        [test_file_text], file_path='/path/to/file/File.java')
    self.assertEqual(result_package, 'org.chromium.chrome.browser.File.java')

  def testGetPackageNameFromFile_noPackageStatement(self):
    result_package, _ = MockOpenForFunction(
        emma_coverage_stats._EmmaCoverageStats.GetPackageNameFromFile,
        ['not a package statement'], file_path='/path/to/file/File.java')
    self.assertIsNone(result_package)

  def testGetSummaryStatsForLines_basic(self):
    covered, total = self.simple_coverage.GetSummaryStatsForLines(
        self.line_coverage)
    self.assertEqual(covered, 3.05)
    self.assertEqual(total, 5)

  def testGetSourceFileToEmmaFileDict(self):
    package_names = {
      '/path/to/1/File1.java': 'org.fake.one.File1.java',
      '/path/2/File2.java': 'org.fake.File2.java',
      '/path/2/File3.java': 'org.fake.File3.java'
    }
    package_to_emma = {
      'org.fake.one.File1.java': '/emma/1.html',
      'org.fake.File2.java': '/emma/2.html',
      'org.fake.File3.java': '/emma/3.html'
    }
    with mock.patch('os.path.exists', return_value=True):
      coverage_stats = self.simple_coverage
      coverage_stats._emma_parser.GetPackageNameToEmmaFileDict = mock.MagicMock(
          return_value=package_to_emma)
      coverage_stats.GetPackageNameFromFile = lambda x: package_names[x]
      result_dict = coverage_stats._GetSourceFileToEmmaFileDict(
          package_names.keys())
    self.assertDictEqual(result_dict, self.good_source_to_emma)

  def testGetCoverageDictForFile(self):
    line_coverage = self.line_coverage
    self.simple_coverage._emma_parser.GetLineCoverage = lambda x: line_coverage
    self.simple_coverage._source_to_emma = {'/fake/src': 'fake/emma'}
    lines = self.lines_for_coverage
    expected_dict = {
      'absolute': {
        'covered': 3.05,
        'total': 5
      },
      'incremental': {
        'covered': 2.05,
        'total': 3
      },
      'source': [
        {
          'line': line_coverage[0].source,
          'coverage': line_coverage[0].covered_status,
          'changed': True,
          'fractional_coverage': line_coverage[0].fractional_line_coverage,
        },
        {
          'line': line_coverage[1].source,
          'coverage': line_coverage[1].covered_status,
          'changed': False,
          'fractional_coverage': line_coverage[1].fractional_line_coverage,
        },
        {
          'line': line_coverage[2].source,
          'coverage': line_coverage[2].covered_status,
          'changed': True,
          'fractional_coverage': line_coverage[2].fractional_line_coverage,
        },
        {
          'line': line_coverage[3].source,
          'coverage': line_coverage[3].covered_status,
          'changed': False,
          'fractional_coverage': line_coverage[3].fractional_line_coverage,
        },
        {
          'line': line_coverage[4].source,
          'coverage': line_coverage[4].covered_status,
          'changed': True,
          'fractional_coverage': line_coverage[4].fractional_line_coverage,
        },
        {
          'line': line_coverage[5].source,
          'coverage': line_coverage[5].covered_status,
          'changed': True,
          'fractional_coverage': line_coverage[5].fractional_line_coverage,
        }
      ]
    }
    result_dict = self.simple_coverage.GetCoverageDictForFile(
        '/fake/src', lines)
    self.assertDictEqual(result_dict, expected_dict)

  def testGetCoverageDictForFile_emptyCoverage(self):
    expected_dict = {
      'absolute': {'covered': 0, 'total': 0},
      'incremental': {'covered': 0, 'total': 0},
      'source': []
    }
    self.simple_coverage._emma_parser.GetLineCoverage = lambda x: []
    self.simple_coverage._source_to_emma = {'fake_dir': 'fake/emma'}
    result_dict = self.simple_coverage.GetCoverageDictForFile('fake_dir', {})
    self.assertDictEqual(result_dict, expected_dict)

  def testGetCoverageDictForFile_missingCoverage(self):
    self.simple_coverage._source_to_emma = {}
    result_dict = self.simple_coverage.GetCoverageDictForFile('fake_file', {})
    self.assertIsNone(result_dict)

  def testGetCoverageDict_basic(self):
    files_for_coverage = {
      '/path/to/1/File1.java': [1, 3, 4],
      '/path/2/File2.java': [1, 2]
    }
    self.simple_coverage._source_to_emma = {
      '/path/to/1/File1.java': 'emma_1',
      '/path/2/File2.java': 'emma_2'
    }
    coverage_info = {
      'emma_1': [
        emma_coverage_stats.LineCoverage(
            1, '', emma_coverage_stats.COVERED, 1.0),
        emma_coverage_stats.LineCoverage(
            2, '', emma_coverage_stats.PARTIALLY_COVERED, 0.5),
        emma_coverage_stats.LineCoverage(
            3, '', emma_coverage_stats.NOT_EXECUTABLE, 1.0),
        emma_coverage_stats.LineCoverage(
            4, '', emma_coverage_stats.COVERED, 1.0)
      ],
      'emma_2': [
        emma_coverage_stats.LineCoverage(
            1, '', emma_coverage_stats.NOT_COVERED, 1.0),
        emma_coverage_stats.LineCoverage(
            2, '', emma_coverage_stats.COVERED, 1.0)
      ]
    }
    expected_dict = {
      'files': {
        '/path/2/File2.java': {
          'absolute': {'covered': 1, 'total': 2},
          'incremental': {'covered': 1, 'total': 2},
          'source': [{'changed': True, 'coverage': 0,
                      'line': '', 'fractional_coverage': 1.0},
                     {'changed': True, 'coverage': 1,
                      'line': '', 'fractional_coverage': 1.0}]
        },
        '/path/to/1/File1.java': {
          'absolute': {'covered': 2.5, 'total': 3},
          'incremental': {'covered': 2, 'total': 2},
          'source': [{'changed': True, 'coverage': 1,
                      'line': '', 'fractional_coverage': 1.0},
                     {'changed': False, 'coverage': 2,
                      'line': '', 'fractional_coverage': 0.5},
                     {'changed': True, 'coverage': -1,
                      'line': '', 'fractional_coverage': 1.0},
                     {'changed': True, 'coverage': 1,
                      'line': '', 'fractional_coverage': 1.0}]
        }
      },
      'patch': {'incremental': {'covered': 3, 'total': 4}}
    }
    # Return the relevant coverage info for each file.
    self.simple_coverage._emma_parser.GetLineCoverage = (
        lambda x: coverage_info[x])
    result_dict = self.simple_coverage.GetCoverageDict(files_for_coverage)
    self.assertDictEqual(result_dict, expected_dict)

  def testGetCoverageDict_noCoverage(self):
    result_dict = self.simple_coverage.GetCoverageDict({})
    self.assertDictEqual(result_dict, EMPTY_COVERAGE_STATS_DICT)


class EmmaCoverageStatsGenerateCoverageReport(unittest.TestCase):
  """Tests for GenerateCoverageReport."""

  def testGenerateCoverageReport_missingJsonFile(self):
    with self.assertRaises(IOError):
      with mock.patch('os.path.exists', return_value=False):
        emma_coverage_stats.GenerateCoverageReport('', '', '')

  def testGenerateCoverageReport_invalidJsonFile(self):
    with self.assertRaises(ValueError):
      with mock.patch('os.path.exists', return_value=True):
        MockOpenForFunction(emma_coverage_stats.GenerateCoverageReport, [''],
                            line_coverage_file='', out_file_path='',
                            coverage_dir='')


def MockOpenForFunction(func, side_effects, **kwargs):
  """Allows easy mock open and read for callables that open multiple files.

  Will mock the python open function in a way such that each time read() is
  called on an open file, the next element in |side_effects| is returned. This
  makes it easier to test functions that call open() multiple times.

  Args:
    func: The callable to invoke once mock files are setup.
    side_effects: A list of return values for each file to return once read.
      Length of list should be equal to the number calls to open in |func|.
    **kwargs: Keyword arguments to be passed to |func|.

  Returns:
    A tuple containing the return value of |func| and the MagicMock object used
      to mock all calls to open respectively.
  """
  mock_open = mock.mock_open()
  mock_open.side_effect = [mock.mock_open(read_data=side_effect).return_value
                           for side_effect in side_effects]
  with mock.patch('__builtin__.open', mock_open):
    return func(**kwargs), mock_open


if __name__ == '__main__':
  # Suppress logging messages.
  unittest.main(buffer=True)
