def test_quality(self):
        """
        Test basic scenarios, including special characters that would appear in JavaScript and mixed quotation marks
        """

        # Patch the output of `jshint`
        return_string = '\n' + dedent("""
                ../test_file.js: line 3, col 9, Missing "use strict" statement.
                ../test_file.js: line 10, col 17, '$hi' is defined but never used.
            """).strip() + '\n'
        self.subproc_mock.communicate.return_value = (
            (return_string.encode('utf-8'), b''))
        self._mock_communicate.return_value = self.subproc_mock

        # Parse the report
        quality = JsHintQualityReporter('jshint', [])

        # Expect that the name is set
        self.assertEqual(quality.name(), 'jshint')

        # Measured_lines is undefined for
        # a quality reporter since all lines are measured
        self.assertEqual(quality.measured_lines('../blah.js'), None)

        # Expect that we get the right violations
        expected_violations = [
            Violation(3, 'Missing "use strict" statement.'),
            Violation(10, "'$hi' is defined but never used."),
        ]

        self.assertEqual(expected_violations, quality.violations('../test_file.js'))
    def test_quality_pregenerated_report(self):

        # When the user provides us with a pre-generated jshint report
        # then use that instead of calling jshint directly.
        jshint_reports = [
            BytesIO(('\n' + dedent("""
                path/to/file.js: line 3, col 9, Missing "use strict" statement.
                path/to/file.js: line 10, col 130, Line is too long.
                another/file.js: line 1, col 1, 'require' is not defined.
            """).strip() + '\n').encode('utf-8')),

            BytesIO(('\n' + dedent(u"""
                path/to/file.js: line 12, col 14, \u9134\u1912
                path/to/file.js: line 10, col 17, '$hi' is defined but never used.
            """).strip() + '\n').encode('utf-8')),
        ]

        # Parse the report
        quality = JsHintQualityReporter('jshint', jshint_reports)

        # Measured_lines is undefined for
        # a quality reporter since all lines are measured
        self.assertEqual(quality.measured_lines('path/to/file.js'), None)

        # Expect that we get the right violations
        expected_violations = [
            Violation(3, u'Missing "use strict" statement.'),
            Violation(10, u"Line is too long."),
            Violation(10, u"'$hi' is defined but never used."),
            Violation(12, u"\u9134\u1912")
        ]

        # We're not guaranteed that the violations are returned
        # in any particular order.
        actual_violations = quality.violations('path/to/file.js')

        self.assertEqual(len(actual_violations), len(expected_violations))
        for expected in expected_violations:
            self.assertIn(expected, actual_violations)