def test_collects_POST_coverage_info(self):

        # Start the page server
        server = SuitePageServer([self._mock_suite_desc('test-suite-0', '/root', ['src.js'])],
                                 mock.MagicMock(SuiteRenderer),
                                 jscover_path=self.JSCOVER_PATH)
        server.start()
        self.addCleanup(server.stop)

        # POST some coverage data to the src page
        # This test does NOT mock the CoverageData class created internally,
        # so we need to pass valid JSON data.
        # (Since CoverageData involves no network or file access, mocking
        # it is not worth the effort).
        coverage_data = {'/src.js': {'lineData': [1, 0, None, 2, 1, None, 0]}}

        requests.post(server.root_url() + "jscoverage-store/test-suite-0",
                      data=json.dumps(coverage_data),
                      timeout=0.1)

        # Get the results immediately from the server.
        # It's the server's responsibility to block until all results are received.
        result_data = server.all_coverage_data()

        # Check the result
        self.assertEqual(result_data.src_list(), ['/root/src.js'])
        self.assertEqual(result_data.line_dict_for_src('/root/src.js'),
                         {0: True, 1: False, 3: True, 4: True, 6: False})
    def test_timeout_if_missing_coverage(self):

        # Start the page server with multiple descriptions
        mock_desc_list = [self._mock_suite_desc('test-suite-0', '/root_1', ['src1.js', 'src2.js']),
                          self._mock_suite_desc('test-suite-1', '/root_2', ['src.js'])]

        server = SuitePageServer(mock_desc_list, mock.MagicMock(SuiteRenderer),
                                 jscover_path=self.JSCOVER_PATH)
        server.start()
        self.addCleanup(server.stop)

        # POST coverage data to one of the sources, but not the other
        coverage_data = {'/suite/test-suite-0/include/src1.js': {'lineData': [1]}}
        requests.post(server.root_url() + "jscoverage-store/test-suite-0",
                      data=json.dumps(coverage_data),
                      timeout=0.1)

        # Try to get the coverage data; expect it to timeout
        # We configured the timeout to be short in our setup method
        # so this should return quickly.
        with self.assertRaises(TimeoutError):
            server.all_coverage_data()
    def test_uncovered_src(self):

        # Create the source file -- we need to do this
        # CoverageData can determine the number of uncovered
        # lines (every line in the file)
        num_lines = 5
        with open('src.js', 'w') as src_file:
            contents = '\n'.join(['test line' for _ in range(num_lines)])
            src_file.write(contents)

        # Start the page server
        root_dir = self.temp_dir
        server = SuitePageServer([self._mock_suite_desc('test-suite-0', root_dir, ['src.js'])],
                                 mock.MagicMock(SuiteRenderer),
                                 jscover_path=self.JSCOVER_PATH)
        server.start()
        self.addCleanup(server.stop)

        # POST empty coverage data back to the server
        # Since no coverage information is reported, we expect
        # that the source file in the suite description is
        # reported as uncovered.
        coverage_data = {}

        requests.post(server.root_url() + "jscoverage-store/test-suite-0",
                      data=json.dumps(coverage_data),
                      timeout=0.1)

        # Get the results immediately from the server.
        # It's the server's responsibility to block until all results are received.
        result_data = server.all_coverage_data()

        # Check the result -- expect that the source file
        # is reported as completely uncovered
        full_src_path = os.path.join(root_dir, 'src.js')
        self.assertEqual(result_data.src_list(), [full_src_path])
        self.assertEqual(result_data.line_dict_for_src(full_src_path),
                         {line_num: False for line_num in range(num_lines)})