# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#

"""This module contains unit tests for the classes in the validators module."""

import glob
import os.path
import unittest

import common_unittest_utils
import common_util
import test_conf as conf
import validators

from common_unittest_utils import create_mocked_devices, parse_tests_data
from firmware_constants import AXIS, GV, PLATFORM, VAL
from firmware_log import MetricNameProps
from geometry.elements import Point
from touch_device import TouchDevice
from validators import (CountPacketsValidator,
                        CountTrackingIDValidator,
                        DrumrollValidator,
                        LinearityValidator,
                        NoGapValidator,
                        NoLevelJumpValidator,
                        NoReversedMotionValidator,
                        PhysicalClickValidator,
                        PinchValidator,
                        RangeValidator,
                        ReportRateValidator,
                        StationaryFingerValidator,
)


unittest_path_lumpy = os.path.join(os.getcwd(), 'tests/logs/lumpy')
mocked_device = create_mocked_devices()

# Make short aliases for supported platforms
alex = mocked_device[PLATFORM.ALEX]
lumpy = mocked_device[PLATFORM.LUMPY]
link = mocked_device[PLATFORM.LINK]
# Some tests do not care what device is used.
dontcare = 'dontcare'


class CountTrackingIDValidatorTest(unittest.TestCase):
    """Unit tests for CountTrackingIDValidator class."""

    def _test_count_tracking_id(self, filename, criteria, device):
        packets = parse_tests_data(filename)
        validator = CountTrackingIDValidator(criteria, device=device)
        vlog = validator.check(packets)
        return vlog.score

    def test_two_finger_id_change(self):
        """Two two fingers id change.

        Issue 7867: Cyapa : Two finger scroll, tracking ids change
        """
        filename = 'two_finger_id_change.dat'
        score = self._test_count_tracking_id(filename, '== 2', lumpy)
        self.assertTrue(score == 0)

    def test_one_finger_fast_swipe_id_split(self):
        """One finger fast swipe resulting in IDs split.

        Issue: 7869: Lumpy: Tracking ID reassigned during quick-2F-swipe
        """
        filename = 'one_finger_fast_swipe_id_split.dat'
        score = self._test_count_tracking_id(filename, '== 1', lumpy)
        self.assertTrue(score == 0)

    def test_two_fingers_fast_flick_id_split(self):
        """Two figners fast flick resulting in IDs split.

        Issue: 7869: Lumpy: Tracking ID reassigned during quick-2F-swipe
        """
        filename = 'two_finger_fast_flick_id_split.dat'
        score = self._test_count_tracking_id(filename, '== 2', lumpy)
        self.assertTrue(score == 0)


class DrumrollValidatorTest(unittest.TestCase):
    """Unit tests for DrumrollValidator class."""

    def setUp(self):
        self.criteria = conf.drumroll_criteria

    def _test_drumroll(self, filename, criteria, device):
        packets = parse_tests_data(filename)
        validator = DrumrollValidator(criteria, device=device)
        vlog = validator.check(packets)
        return vlog.score

    def _get_drumroll_metrics(self, filename, criteria, device):
        packets = parse_tests_data(filename, gesture_dir=unittest_path_lumpy)
        validator = DrumrollValidator(criteria, device=device)
        metrics = validator.check(packets).metrics
        return metrics

    def test_drumroll_lumpy(self):
        """Should catch the drumroll on lumpy.

        Issue 7809: Lumpy: Drumroll bug in firmware
        Max distance: 52.02 px
        """
        filename = 'drumroll_lumpy.dat'
        score = self._test_drumroll(filename, self.criteria, lumpy)
        self.assertTrue(score == 0)

    def test_drumroll_lumpy_1(self):
        """Should catch the drumroll on lumpy.

        Issue 7809: Lumpy: Drumroll bug in firmware
        Max distance: 43.57 px
        """
        filename = 'drumroll_lumpy_1.dat'
        score = self._test_drumroll(filename, self.criteria, lumpy)
        self.assertTrue(score <= 0.15)

    def test_no_drumroll_link(self):
        """Should pass (score == 1) when there is no drumroll.

        Issue 7809: Lumpy: Drumroll bug in firmware
        Max distance: 2.92 px
        """
        filename = 'no_drumroll_link.dat'
        score = self._test_drumroll(filename, self.criteria, link)
        self.assertTrue(score == 1)

    def test_drumroll_metrics(self):
        """Test the drumroll metrics."""
        expected_max_values = {
            '20130506_030025-fw_11.27-robot_sim/'
            'drumroll.fast-lumpy-fw_11.27-manual-20130528_044804.dat':
            2.29402908535,

            '20130506_030025-fw_11.27-robot_sim/'
            'drumroll.fast-lumpy-fw_11.27-manual-20130528_044820.dat':
            0.719567771497,

            '20130506_031746-fw_11.27-robot_sim/'
            'drumroll.fast-lumpy-fw_11.27-manual-20130528_044728.dat':
            0.833491481592,

            '20130506_032458-fw_11.23-robot_sim/'
            'drumroll.fast-lumpy-fw_11.23-manual-20130528_044856.dat':
            1.18368539364,

            '20130506_032458-fw_11.23-robot_sim/'
            'drumroll.fast-lumpy-fw_11.23-manual-20130528_044907.dat':
            0.851161282019,

            '20130506_032659-fw_11.23-robot_sim/'
            'drumroll.fast-lumpy-fw_11.23-manual-20130528_044933.dat':
            2.64245519251,

            '20130506_032659-fw_11.23-robot_sim/'
            'drumroll.fast-lumpy-fw_11.23-manual-20130528_044947.dat':
            0.910624022916,
        }
        criteria = self.criteria
        for filename, expected_max_value in expected_max_values.items():
            metrics = self._get_drumroll_metrics(filename, criteria, lumpy)
            actual_max_value = max([m.value for m in metrics])
            self.assertAlmostEqual(expected_max_value, actual_max_value)


class LinearityValidatorTest(unittest.TestCase):
    """Unit tests for LinearityValidator class."""

    def setUp(self):
        self.validator = LinearityValidator(conf.linearity_criteria,
                                            device=lumpy, finger=0)
        self.validator.init_check()

    def test_simple_linear_regression0(self):
        """A perfect y-t line from bottom left to top right"""
        list_y = [20, 40, 60, 80, 100, 120, 140, 160]
        list_t = [i * 0.1 for i in range(len(list_y))]
        (max_err_px, rms_err_px) = self.validator._calc_errors_single_axis(
                list_t, list_y)
        self.assertAlmostEqual(max_err_px, 0)
        self.assertAlmostEqual(rms_err_px, 0)

    def test_simple_linear_regression0b(self):
        """An imperfect y-t line from bottom left to top right with
        the first and the last entries as outliers.

        In this test case:
          begin segment = [1,]
          end segment = [188, 190]
          middle segment = [20, 40, 60, 80, 100, 120, 140, 160]

          the simple linear regression line is calculated based on the
          middle segment, and is
            y = 20 * t
          the error = [1, 0, 0, 0, 0, 0, 0, 0, 0, 8, 10]
        """
        list_y = [1, 20, 40, 60, 80, 100, 120, 140, 160, 188, 190]
        list_t = range(len(list_y))

        expected_errs_dict = {
            VAL.WHOLE: [1, 0, 0, 0, 0, 0, 0, 0, 0, 8, 10],
            VAL.BEGIN: [1, ],
            VAL.END: [8, 10],
            VAL.BOTH_ENDS: [1, 8, 10],
        }

        for segment_flag, expected_errs in expected_errs_dict.items():
            self.validator._segments= segment_flag
            (max_err, rms_err) = self.validator._calc_errors_single_axis(list_t,
                                                                         list_y)
            expected_max_err = max(expected_errs)
            expected_rms_err = (sum([i ** 2 for i in expected_errs]) /
                                len(expected_errs)) ** 0.5
            self.assertAlmostEqual(max_err, expected_max_err)
            self.assertAlmostEqual(rms_err, expected_rms_err)

    def test_log_details_and_metrics(self):
        """Test the axes in _log_details_and_metrics"""
        # gesture_dir: tests/data/linearity
        gesture_dir = 'linearity'
        filenames_axes = {
            'two_finger_tracking.right_to_left.slow-lumpy-fw_11.27-robot-'
                '20130227_204458.dat': [AXIS.X],
            'one_finger_to_edge.center_to_top.slow-lumpy-fw_11.27-robot-'
                '20130227_203228.dat': [AXIS.Y],
            'two_finger_tracking.bottom_left_to_top_right.normal-lumpy-'
                'fw_11.27-robot-20130227_204902.dat': [AXIS.X, AXIS.Y],
        }
        for filename, expected_axes in filenames_axes.items():
            packets = parse_tests_data(filename, gesture_dir=gesture_dir)
            # get the direction of the gesture
            direction = [filename.split('-')[0].split('.')[1]]
            self.validator.check(packets, direction)
            actual_axes = sorted(self.validator.list_coords.keys())
            self.assertEqual(actual_axes, expected_axes)

    def _test_simple_linear_regression1(self):
        """A y-t line taken from a real example.

        Refer to the "Numerical example" in the wiki page:
            http://en.wikipedia.org/wiki/Simple_linear_regression
        """
        list_t = [1.47, 1.50, 1.52, 1.55, 1.57, 1.60, 1.63, 1.65, 1.68, 1.70,
                  1.73, 1.75, 1.78, 1.80, 1.83]
        list_y = [52.21, 53.12, 54.48, 55.84, 57.20, 58.57, 59.93, 61.29,
                  63.11, 64.47, 66.28, 68.10, 69.92, 72.19, 74.46]
        expected_max_err = 1.3938545467809007
        expected_rms_err = 0.70666155991311708
        (max_err, rms_err) = self.validator._calc_errors_single_axis(
                list_t, list_y)
        self.assertAlmostEqual(max_err, expected_max_err)
        self.assertAlmostEqual(rms_err, expected_rms_err)


class NoGapValidatorTest(unittest.TestCase):
    """Unit tests for NoGapValidator class."""
    GAPS_SUBDIR = 'gaps'

    def setUp(self):
        self.criteria = conf.no_gap_criteria

    def _test_no_gap(self, filename, criteria, device, slot):
        file_subpath = os.path.join(self.GAPS_SUBDIR, filename)
        packets = parse_tests_data(file_subpath)
        validator = NoGapValidator(criteria, device=device, slot=slot)
        vlog = validator.check(packets)
        return vlog.score

    def test_two_finger_scroll_gaps(self):
        """Test that there are gaps in the two finger scroll gesture.

        Issue 7552: Cyapa : two finger scroll motion produces gaps in tracking
        """
        filename = 'two_finger_gaps.horizontal.dat'
        score0 = self._test_no_gap(filename, self.criteria, lumpy, 0)
        score1 = self._test_no_gap(filename, self.criteria, lumpy, 1)
        self.assertTrue(score0 <= 0.1)
        self.assertTrue(score1 <= 0.1)

    def test_gap_new_finger_arriving_or_departing(self):
        """Test gap when new finger arriving or departing.

        Issue: 8005: Cyapa : gaps appear when new finger arrives or departs
        """
        filename = 'gap_new_finger_arriving_or_departing.dat'
        score = self._test_no_gap(filename, self.criteria, lumpy, 0)
        self.assertTrue(score <= 0.3)

    def test_one_stationary_finger_2nd_finger_moving_gaps(self):
        """Test one stationary finger resulting in 2nd finger moving gaps."""
        filename = 'one_stationary_finger_2nd_finger_moving_gaps.dat'
        score = self._test_no_gap(filename, self.criteria, lumpy, 1)
        self.assertTrue(score <= 0.1)

    def test_resting_finger_2nd_finger_moving_gaps(self):
        """Test resting finger resulting in 2nd finger moving gaps.

        Issue 7648: Cyapa : Resting finger plus one finger move generates a gap
        """
        filename = 'resting_finger_2nd_finger_moving_gaps.dat'
        score = self._test_no_gap(filename, self.criteria, lumpy, 1)
        self.assertTrue(score <= 0.3)


class PhysicalClickValidatorTest(unittest.TestCase):
    """Unit tests for PhysicalClickValidator class."""

    def setUp(self):
        self.device = lumpy
        self.criteria = '== 1'
        self.mnprops = MetricNameProps()

    def _test_physical_clicks(self, gesture_dir, files, expected_score):
        gesture_path = os.path.join(unittest_path_lumpy, gesture_dir)
        for filename, fingers in files.items():
            packets = parse_tests_data(os.path.join(gesture_path, filename))
            validator = PhysicalClickValidator(self.criteria,
                                               fingers=fingers,
                                               device=self.device)
            vlog = validator.check(packets)
            actual_score = vlog.score
            self.assertTrue(actual_score == expected_score)

    def test_physical_clicks_success(self):
        """All physcial click files in the gesture_dir should pass."""
        gesture_dir = '20130506_030025-fw_11.27-robot_sim'
        gesture_path = os.path.join(unittest_path_lumpy, gesture_dir)

        # Get all 1f physical click files.
        file_prefix = 'one_finger_physical_click'
        fingers = 1
        files1 = [(filepath, fingers) for filepath in glob.glob(
            os.path.join(gesture_path, file_prefix + '*.dat'))]

        # Get all 2f physical click files.
        file_prefix = 'two_fingers_physical_click'
        fingers = 2
        files2 = [(filepath, fingers) for filepath in glob.glob(
            os.path.join(gesture_path, file_prefix + '*.dat'))]

        # files is a dictionary of {filename: fingers}
        files = dict(files1 + files2)
        expected_score = 1.0
        self._test_physical_clicks(gesture_dir, files, expected_score)

    def test_physical_clicks_failure(self):
        """All physcial click files specified below should fail."""
        gesture_dir = '20130506_032458-fw_11.23-robot_sim'
        # files is a dictionary of {filename: fingers}
        files = {
            'one_finger_physical_click.bottom_side-lumpy-fw_11.23-complete-'
                '20130614_065744.dat': 1,
            'one_finger_physical_click.center-lumpy-fw_11.23-complete-'
                '20130614_065727.dat': 1,
            'two_fingers_physical_click-lumpy-fw_11.23-complete-'
                '20130614_065757.dat': 2,
        }
        expected_score = 0.0
        self._test_physical_clicks(gesture_dir, files, expected_score)

    def test_physical_clicks_by_finger_IDs(self):
        """Test that some physical clicks may come with or without correct
        finger IDs.
        """
        # files is a dictionary of {
        #     filename: (number_fingers, (actual clicks, expected clicks))}
        files = {
                # An incorrect case with 1 finger: the event sequence comprises
                #   Event: ABS_MT_TRACKING_ID, value 284
                #   Event: ABS_MT_TRACKING_ID, value -1
                #   Event: BTN_LEFT, value 1
                #   Event: BTN_LEFT, value 0
                # In this case, the BTN_LEFT occurs when there is no finger.
                '1f_click_incorrect_behind_tid.dat': (1, (0, 1)),

                # A correct case with 1 finger: the event sequence comprises
                #   Event: ABS_MT_TRACKING_ID, value 284
                #   Event: BTN_LEFT, value 1
                #   Event: ABS_MT_TRACKING_ID, value -1
                #   Event: BTN_LEFT, value 0
                # In this case, the BTN_LEFT occurs when there is no finger.
                '1f_click.dat': (1, (1, 1)),

                # An incorrect case with 2 fingers: the event sequence comprises
                #   Event: ABS_MT_TRACKING_ID, value 18
                #   Event: BTN_LEFT, value 1
                #   Event: BTN_LEFT, value 0
                #   Event: ABS_MT_TRACKING_ID, value 19
                #   Event: ABS_MT_TRACKING_ID, value -1
                #   Event: ABS_MT_TRACKING_ID, value -1
                # In this case, the BTN_LEFT occurs when there is only 1 finger.
                '2f_clicks_incorrect_before_2nd_tid.dat': (2, (0, 1)),

                # An incorrect case with 2 fingers: the event sequence comprises
                #   Event: ABS_MT_TRACKING_ID, value 18
                #   Event: ABS_MT_TRACKING_ID, value 19
                #   Event: ABS_MT_TRACKING_ID, value -1
                #   Event: ABS_MT_TRACKING_ID, value -1
                #   Event: BTN_LEFT, value 1
                #   Event: BTN_LEFT, value 0
                # In this case, the BTN_LEFT occurs when there is only 1 finger.
                '2f_clicks_incorrect_behind_2_tids.dat': (2, (0, 1)),

                # A correct case with 2 fingers: the event sequence comprises
                #   Event: ABS_MT_TRACKING_ID, value 18
                #   Event: ABS_MT_TRACKING_ID, value 19
                #   Event: BTN_LEFT, value 1
                #   Event: ABS_MT_TRACKING_ID, value -1
                #   Event: ABS_MT_TRACKING_ID, value -1
                #   Event: BTN_LEFT, value 0
                # In this case, the BTN_LEFT occurs when there is only 1 finger.
                '2f_clicks.dat': (2, (1, 1)),
        }
        for filename, (fingers, expected_value) in files.items():
            packets = parse_tests_data(filename)
            validator = PhysicalClickValidator(self.criteria, fingers=fingers,
                                               device=dontcare)
            vlog = validator.check(packets)
            metric_name = self.mnprops.CLICK_CHECK_TIDS.format(fingers)
            for metric in vlog.metrics:
                if metric.name == metric_name:
                    self.assertEqual(metric.value, expected_value)


class RangeValidatorTest(unittest.TestCase):
    """Unit tests for RangeValidator class."""

    def setUp(self):
        self.device = lumpy

    def _test_range(self, filename, expected_short_of_range_px):
        filepath = os.path.join(unittest_path_lumpy, filename)
        packets = parse_tests_data(filepath)
        validator = RangeValidator(conf.range_criteria, device=self.device)

        # Extract the gesture variation from the filename
        variation = (filename.split('/')[-1].split('.')[1],)

        # Determine the axis based on the direction in the gesture variation
        axis = (self.device.axis_x if validator.is_horizontal(variation)
                else self.device.axis_y if validator.is_vertical(variation)
                else None)
        self.assertTrue(axis is not None)

        # Convert from pixels to mms.
        expected_short_of_range_mm = self.device.pixel_to_mm_single_axis(
                expected_short_of_range_px, axis)

        vlog = validator.check(packets, variation)

        # There is only one metric in the metrics list.
        self.assertEqual(len(vlog.metrics), 1)
        actual_short_of_range_mm = vlog.metrics[0].value
        self.assertEqual(actual_short_of_range_mm, expected_short_of_range_mm)

    def test_range(self):
        """All physical click files specified below should fail."""
        # files_px is a dictionary of {filename: short_of_range_px}
        files_px = {
            '20130506_030025-fw_11.27-robot_sim/'
            'one_finger_to_edge.center_to_left.slow-lumpy-fw_11.27-'
                'robot_sim-20130506_031554.dat': 0,

            '20130506_030025-fw_11.27-robot_sim/'
            'one_finger_to_edge.center_to_left.slow-lumpy-fw_11.27-'
                'robot_sim-20130506_031608.dat': 0,

            '20130506_032458-fw_11.23-robot_sim/'
            'one_finger_to_edge.center_to_left.slow-lumpy-fw_11.23-'
                'robot_sim-20130506_032538.dat': 1,

            '20130506_032458-fw_11.23-robot_sim/'
            'one_finger_to_edge.center_to_left.slow-lumpy-fw_11.23-'
                'robot_sim-20130506_032549.dat': 1,
        }

        for filename, short_of_range_px in files_px.items():
            self._test_range(filename, short_of_range_px)


class StationaryFingerValidatorTest(unittest.TestCase):
    """Unit tests for StationaryFingerValidator class."""

    def setUp(self):
        self.criteria = conf.stationary_finger_criteria

    def _test_stationary_finger(self, filename, criteria, device):
        packets = parse_tests_data(filename)
        validator = StationaryFingerValidator(criteria, device=device)
        vlog = validator.check(packets)
        return vlog.score

    def test_stationary_finger_shift(self):
        """Test that the stationary shift due to 2nd finger tapping.

        Issue 7442: Cyapa : Second finger tap events influence stationary finger
        position
        """
        filename = 'stationary_finger_shift_with_2nd_finger_tap.dat'
        score = self._test_stationary_finger(filename, self.criteria, lumpy)
        self.assertTrue(score <= 0.1)

    def test_stationary_strongly_affected_by_2nd_moving_finger(self):
        """Test stationary finger strongly affected by 2nd moving finger with
        gaps.

        Issue 5812: [Cypress] reported positions of stationary finger strongly
        affected by nearby moving finger
        """
        filename = ('stationary_finger_strongly_affected_by_2nd_moving_finger_'
                    'with_gaps.dat')
        score = self._test_stationary_finger(filename, self.criteria, lumpy)
        self.assertTrue(score <= 0.1)


class NoLevelJumpValidatorTest(unittest.TestCase):
    """Unit tests for NoLevelJumpValidator class."""

    def setUp(self):
        self.criteria = conf.no_level_jump_criteria
        self.gesture_dir = 'drag_edge_thumb'

    def _get_score(self, filename, device):
        validator = NoLevelJumpValidator(self.criteria, device=device,
                                         slots=[0,])
        packets = parse_tests_data(filename, gesture_dir=self.gesture_dir)
        vlog = validator.check(packets)
        score = vlog.score
        return score

    def test_level_jumps(self):
        """Test files with level jumps."""
        filenames = [
            'drag_edge_thumb.horizontal.dat',
            'drag_edge_thumb.horizontal_2.dat',
            'drag_edge_thumb.horizontal_3.no_points.dat',
            'drag_edge_thumb.vertical.dat',
            'drag_edge_thumb.vertical_2.dat',
            'drag_edge_thumb.diagonal.dat',
        ]
        for filename in filenames:
            self.assertTrue(self._get_score(filename, lumpy) <= 0.6)

    def test_no_level_jumps(self):
        """Test files without level jumps."""
        filenames = [
            'drag_edge_thumb.horizontal.curvy.dat',
            'drag_edge_thumb.horizontal_2.curvy.dat',
            'drag_edge_thumb.vertical.curvy.dat',
            'drag_edge_thumb.vertical_2.curvy.dat',
        ]
        for filename in filenames:
            self.assertTrue(self._get_score(filename, lumpy) == 1.0)


class ReportRateValidatorTest(unittest.TestCase):
    """Unit tests for ReportRateValidator class."""
    def setUp(self):
        self.criteria = '>= 60'

    def _get_score(self, filename, device):
        validator = ReportRateValidator(self.criteria, device=device,
                                        chop_off_pauses=False)
        packets = parse_tests_data(filename)
        vlog = validator.check(packets)
        score = vlog.score
        return score

    def test_report_rate_scores(self):
        """Test the score of the report rate."""
        filename = '2f_scroll_diagonal.dat'
        self.assertTrue(self._get_score(filename, device=lumpy) <= 0.5)

        filename = 'one_finger_with_slot_0.dat'
        self.assertTrue(self._get_score(filename, device=lumpy) >= 0.9)

        filename = 'two_close_fingers_merging_changed_ids_gaps.dat'
        self.assertTrue(self._get_score(filename, device=lumpy) <= 0.5)

    def test_report_rate_without_slot(self):
        """Test report rate without specifying any slot."""
        filename_report_rate_pair = [
            ('2f_scroll_diagonal.dat', 40.31),
            ('one_finger_with_slot_0.dat', 148.65),
            ('two_close_fingers_merging_changed_ids_gaps.dat', 53.12),
        ]
        for filename, expected_report_rate in filename_report_rate_pair:
            validator = ReportRateValidator(self.criteria, device=dontcare,
                                            chop_off_pauses=False)
            validator.check(parse_tests_data(filename))
            actual_report_rate = round(validator.report_rate, 2)
            self.assertAlmostEqual(actual_report_rate, expected_report_rate)

    def test_report_rate_with_slot(self):
        """Test report rate with slot=1"""
        # Compute actual_report_rate
        filename = ('stationary_finger_strongly_affected_by_2nd_moving_finger_'
                    'with_gaps.dat')
        validator = ReportRateValidator(self.criteria, device=dontcare,
                                        finger=1, chop_off_pauses=False)
        validator.check(parse_tests_data(filename))
        actual_report_rate = validator.report_rate
        # Compute expected_report_rate
        first_syn_time = 2597.682925
        last_syn_time = 2604.543335
        num_packets = 592 - 1
        expected_report_rate = num_packets / (last_syn_time - first_syn_time)
        self.assertAlmostEqual(actual_report_rate, expected_report_rate)

    def _test_report_rate_metrics(self, filename, expected_values):
        packets = parse_tests_data(filename)
        validator = ReportRateValidator(self.criteria, device=lumpy,
                                        chop_off_pauses=False)
        vlog = validator.check(packets)

        # Verify that there are 3 metrics
        number_metrics = 3
        self.assertEqual(len(vlog.metrics), number_metrics)

        # Verify the values of the 3 metrics.
        for i in range(number_metrics):
            actual_value = vlog.metrics[i].value
            if isinstance(actual_value, tuple):
                self.assertEqual(actual_value, expected_values[i])
            else:
                self.assertAlmostEqual(actual_value, expected_values[i])

    def test_report_rate_metrics(self):
        """Test the metrics of the report rates."""
        # files is a dictionary of
        #       {filename: ((# long_intervals, # all intervals),
        #                    ave_interval, max_interval)}
        files = {
            '2f_scroll_diagonal.dat':
                ((33, 33), 24.8057272727954, 26.26600000075996),
            'one_finger_with_slot_0.dat':
                ((1, 12), 6.727166666678386, 20.411999998032115),
            'two_close_fingers_merging_changed_ids_gaps.dat':
                ((13, 58), 18.82680942272318, 40.936946868896484),
        }

        for filename, values in files.items():
            self._test_report_rate_metrics(filename, values)

    def _test_chop_off_both_ends(self, xy_pairs, distance, expected_middle):
        """Verify if the actual middle is equal to the expected middle."""
        points = [Point(*xy) for xy in xy_pairs]
        validator = ReportRateValidator(self.criteria, device=dontcare)
        actual_middle = validator._chop_off_both_ends(points, distance)
        self.assertEqual(actual_middle, expected_middle)

    def test_chop_off_both_ends0(self):
        """Test chop_off_both_ends() with distinct distances."""
        xy_pairs = [
                # pauses
                (100, 20), (100, 21), (101, 22), (102, 24), (103, 26),
                # moving segment
                (120, 30), (122, 29), (123, 32), (123, 33), (126, 35),
                (126, 32), (142, 29), (148, 30), (159, 31), (162, 30),
                (170, 32), (183, 32), (194, 32), (205, 32), (208, 32),
                # pauses
                (230, 30), (231, 31), (232, 30), (231, 30), (230, 30),
        ]

        distance = 20
        expected_begin_index = 5
        expected_end_index = 19
        expected_middle = [expected_begin_index, expected_end_index]
        self._test_chop_off_both_ends(xy_pairs, distance, expected_middle)

        distance = 0
        expected_begin_index = 0
        expected_end_index = len(xy_pairs) - 1
        expected_middle = [expected_begin_index, expected_end_index]
        self._test_chop_off_both_ends(xy_pairs, distance, expected_middle)

    def test_chop_off_both_ends1(self):
        """Test chop_off_both_ends() with some corner cases"""
        distance = 20
        xy_pairs = [(120, 50), (120, 50)]
        expected_middle = None
        self._test_chop_off_both_ends(xy_pairs, distance, expected_middle)

        xy_pairs = [(120, 50), (150, 52), (200, 51)]
        expected_middle = [1, 1]
        self._test_chop_off_both_ends(xy_pairs, distance, expected_middle)

        xy_pairs = [(120, 50), (120, 51), (200, 52), (200, 51)]
        expected_middle = None
        self._test_chop_off_both_ends(xy_pairs, distance, expected_middle)


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