# 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 BaseValidatorTest(unittest.TestCase):
    """A base class for all ValidatorTest classes."""

    def setUp(self, show_spec_v2_flag=False):
        """Set up mocked devices for various test boards.

        @param show_spec_v2_flag: this flag indicates if we are using spec v2.
        """
        validators.set_show_spec_v2(show_spec_v2_flag)

    def tearDown(self):
        """Reset the show_spec_v2 so that other unit tests for spec v1 could be
        conducted as uaual.
        """
        validators.set_show_spec_v2(False)


class CountTrackingIDValidatorTest(BaseValidatorTest):
    """Unit tests for CountTrackingIDValidator class."""

    def setUp(self):
        super(CountTrackingIDValidatorTest, self).setUp()

    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(BaseValidatorTest):
    """Unit tests for DrumrollValidator class."""

    def setUp(self):
        super(DrumrollValidatorTest, self).setUp()
        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(BaseValidatorTest):
    """Unit tests for LinearityValidator class."""

    def setUp(self):
        super(LinearityValidatorTest, self).setUp()
        self.criteria = conf.linearity_criteria
        validators.show_new_spec = False

    def _test_linearity_criteria(self, criteria_str, fingers, device):
        filename = '2f_scroll_diagonal.dat'
        direction = GV.DIAGONAL
        packets = parse_tests_data(filename)
        scores = {}
        for finger in fingers:
            validator = LinearityValidator(criteria_str, device=device,
                                           finger=finger)
            scores[finger] = validator.check(packets, direction).score
        return scores

    def test_linearity_criteria0(self):
        """The scores are 0s due to strict criteria."""
        criteria_str = '<= 0.01, ~ +0.01'
        scores = self._test_linearity_criteria(criteria_str, (0, 1), alex)
        self.assertTrue(scores[0] == 0)
        self.assertTrue(scores[1] == 0)

    def test_linearity_criteria1(self):
        """The validator gets score betwee 0 and 1."""
        criteria_str = '<= 0.01, ~ +3.0'
        scores = self._test_linearity_criteria(criteria_str, (0, 1), alex)
        self.assertTrue(scores[0] > 0 and scores[0] < 1)
        self.assertTrue(scores[1] > 0 and scores[1] < 1)

    def test_linearity_criteria2(self):
        """The validator gets score of 1 due to very relaxed criteria."""
        criteria_str = '<= 10, ~ +10'
        scores = self._test_linearity_criteria(criteria_str, (0, 1), alex)
        self.assertTrue(scores[0] == 1)
        self.assertTrue(scores[1] == 1)

    def _test_linearity_validator(self, filename, criteria, fingers, device,
                                  direction):
        packets = parse_tests_data(filename)
        scores = {}
        if isinstance(fingers, int):
            fingers = (fingers,)
        for finger in fingers:
            validator = LinearityValidator(criteria, device=device,
                                           finger=finger)
            scores[finger] = validator.check(packets, direction).score
        return scores

    def test_two_finger_jagged_lines(self):
        """Test two-finger jagged lines."""
        filename = 'two_finger_tracking.diagonal.slow.dat'
        scores = self._test_linearity_validator(filename, self.criteria, (0, 1),
                                                lumpy, GV.DIAGONAL)
        self.assertTrue(scores[0] < 0.7)
        self.assertTrue(scores[1] < 0.7)

    def test_stationary_finger_fat_finger_wobble(self):
        """Test fat finger horizontal move with a stationary resting finger
        results in a wobble.

        Issue 7551: Fat finger horizontal move with a stationary resting
        finger results in a wobble.
        """
        filename = 'stationary_finger_fat_finger_wobble.dat'
        scores = self._test_linearity_validator(filename, self.criteria, 1,
                                                lumpy, GV.HORIZONTAL)
        self.assertTrue(scores[1] <= 0.1)

    def test_thumb_edge(self):
        """Test thumb edge wobble.

        Issue 7554: thumb edge behavior.
        """
        filename = 'thumb_edge_wobble.dat'
        scores = self._test_linearity_validator(filename, self.criteria, 0,
                                                lumpy, GV.HORIZONTAL)
        self.assertTrue(scores[0] < 0.5)

    def test_two_close_fingers_merging_changed_ids_gaps(self):
        """Test close finger merging - causes id changes

        Issue 7555: close finger merging - causes id changes.
        """
        filename = 'two_close_fingers_merging_changed_ids_gaps.dat'
        scores = self._test_linearity_validator(filename, self.criteria, 0,
                                                lumpy, GV.VERTICAL)
        self.assertTrue(scores[0] < 0.3)

    def test_jagged_two_finger_scroll(self):
        """Test jagged two finger scroll.

        Issue 7650: Cyapa : poor two fat fingers horizontal scroll performance -
        jagged lines
        """
        filename = 'jagged_two_finger_scroll_horizontal.dat'
        scores = self._test_linearity_validator(filename, self.criteria, (0, 1),
                                                lumpy, GV.HORIZONTAL)
        self.assertTrue(scores[0] < 0.3)
        self.assertTrue(scores[1] < 0.3)

    def test_first_point_jump(self):
        """Test the first point jump

        At finger 0, the positions of (x, y) looks like
            x: 208, 241, 242, 245, 246, ...
            y: 551, 594, 595, 597, 598, ...
        Note that the the first y position is a jump.
        """
        filename = 'two_finger_tracking.bottom_left_to_top_right.slow.dat'
        scores = self._test_linearity_validator(filename, self.criteria, 0,
                                                lumpy, GV.DIAGONAL)
        self.assertTrue(scores[0] < 0.3)

    def test_simple_linear_regression0(self):
        validator = LinearityValidator('<= 0.2, ~ +0.3', device=lumpy, finger=0)
        validator.init_check()
        # A perfect line from bottom left to top right
        list_x = [1, 2, 3, 4, 5, 6, 7, 8]
        list_y = [20, 40, 60, 80, 100, 120, 140, 160]
        spmse = validator._simple_linear_regression(list_x, list_y)
        self.assertEqual(spmse, 0)

    def test_simple_linear_regression1(self):
        validator = LinearityValidator('<= 0.2, ~ +0.3', device=lumpy, finger=0)
        validator.init_check()
        # Another perfect line from top left to bottom right
        list_x = [1, 2, 3, 4, 5, 6, 7, 8]
        list_y = [160, 140, 120, 100, 80, 60, 40, 20]
        spmse = validator._simple_linear_regression(list_x, list_y)
        self.assertEqual(spmse, 0)

    def test_simple_linear_regression2(self):
        validator = LinearityValidator('<= 0.2, ~ +0.3', device=lumpy, finger=0)
        validator.init_check()
        # An outlier in y axis
        list_x = [1, 2, 3, 4, 5, 6, 7, 8]
        list_y = [20, 40, 60, 70, 100, 120, 140, 160]
        spmse = validator._simple_linear_regression(list_x, list_y)
        self.assertTrue(spmse > 0)

    def test_simple_linear_regression3(self):
        validator = LinearityValidator('<= 0.2, ~ +0.3', device=lumpy, finger=0)
        validator.init_check()
        # Repeated values in x axis
        list_x = [1, 2, 2, 4, 5, 6, 7, 8]
        list_y = [20, 40, 60, 80, 100, 120, 140, 160]
        spmse = validator._simple_linear_regression(list_x, list_y)
        self.assertTrue(spmse > 0)


class LinearityValidator2Test(BaseValidatorTest):
    """Unit tests for LinearityValidator2 class."""

    def setUp(self):
        super(LinearityValidator2Test, self).setUp(show_spec_v2_flag=True)
        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(BaseValidatorTest):
    """Unit tests for NoGapValidator class."""
    GAPS_SUBDIR = 'gaps'

    def setUp(self):
        super(NoGapValidatorTest, self).setUp()
        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(BaseValidatorTest):
    """Unit tests for PhysicalClickValidator class."""

    def setUp(self):
        super(PhysicalClickValidatorTest, self).setUp()
        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(BaseValidatorTest):
    """Unit tests for RangeValidator class."""

    def setUp(self):
        super(RangeValidatorTest, self).setUp()
        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(BaseValidatorTest):
    """Unit tests for StationaryFingerValidator class."""

    def setUp(self):
        super(StationaryFingerValidatorTest, self).setUp(show_spec_v2_flag=True)
        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(BaseValidatorTest):
    """Unit tests for NoLevelJumpValidator class."""

    def setUp(self):
        super(NoLevelJumpValidatorTest, self).setUp()
        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(BaseValidatorTest):
    """Unit tests for ReportRateValidator class."""
    def setUp(self):
        super(ReportRateValidatorTest, self).setUp()
        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()
