From: Jackson Ray Hamilton Date: Tue, 5 May 2015 10:22:14 +0000 (-0700) Subject: Reimplement coverage reporter in elisp. X-Git-Url: https://code.delx.au/gnu-emacs-elpa/commitdiff_plain/dbddc452d9fa2345659d54f1df571cdc4c7fb1d4 Reimplement coverage reporter in elisp. --- diff --git a/test/context-coloring-coverage.el b/test/context-coloring-coverage.el index 0383ac421..2fe8fa905 100644 --- a/test/context-coloring-coverage.el +++ b/test/context-coloring-coverage.el @@ -25,6 +25,7 @@ ;;; Code: +(require 'json) (require 'undercover) @@ -50,8 +51,67 @@ (concat context-coloring-coverage-output-directory context-coloring-coverage-output-file-prefix ".txt")) -(defconst context-coloring-coverage-parser - (concat "node " (context-coloring-coverage-resolve-path "./parse-coverage.js"))) +(defun context-coloring-coverage-join (strings delimiter) + "Join a list of STRINGS with the string DELIMITER." + (mapconcat 'identity strings delimiter)) + +(defun context-coloring-coverage-percentage (dividend divisor) + "Get the percentage of DIVIDEND / DIVISOR with precision 2." + (let ((percentage (/ (float (round (* (/ (float dividend) divisor) 10000))) 100))) + (number-to-string + (cond + ((= (mod percentage 1) 0) + ;; Get an integer because we don't like dangling zeros. + (round percentage)) + (t + percentage))))) + +(defun context-coloring-coverage-format-source-file (source-file) + "Generate a report for SOURCE-FILE's line coverage." + (let* ((source-lines (split-string (cdr (assq 'source source-file)) "\n")) + (coverage (cdr (assq 'coverage source-file))) + (results (list "Hits | Source" + (context-coloring-coverage-join (make-vector 80 "-") ""))) + (lines-hit 0) + (lines-hittable 0) + hits + source-line) + (while coverage + (setq hits (car coverage)) + (setq coverage (cdr coverage)) + (setq source-line (car source-lines)) + (setq source-lines (cdr source-lines)) + (when (not (null hits)) + (setq lines-hittable (+ lines-hittable 1)) + (when (> hits 0) + (setq lines-hit (+ lines-hit 1)))) + (setq results + (append results + (list (format + "%-5s %s %s" + (if hits hits "N/A") + (if (and hits (= hits 0)) "~" "|") + source-line))))) + (setq results + (append results + (list + "" + (format + "Lines: %s / %s" + lines-hit + lines-hittable) + (format + "Coverage: %s%%" + (context-coloring-coverage-percentage lines-hit lines-hittable))))) + (context-coloring-coverage-join results "\n"))) + +(defun context-coloring-coverage-format (coverage-data) + "Generate reports for all files in COVERAGE-DATA." + (context-coloring-coverage-join + (mapcar + 'context-coloring-coverage-format-source-file + (cdr (assq 'source_files coverage-data))) + "\n")) (defun context-coloring-coverage-local-init () "Initialize test coverage for local viewing." @@ -63,13 +123,23 @@ (add-hook 'kill-emacs-hook (lambda () - (let* ((output-buffer (get-buffer-create "*parsed coverage*"))) - (call-process-shell-command - context-coloring-coverage-parser - context-coloring-coverage-output-file - output-buffer) - (with-current-buffer output-buffer - (princ (buffer-substring-no-properties (point-min) (point-max))) + (let (original-json-array-type + coverage-data + report) + (with-temp-buffer + (insert-file-contents-literally context-coloring-coverage-output-file) + (setq original-json-array-type json-array-type) + (setq json-array-type 'list) + (setq coverage-data + (json-read-from-string + (buffer-substring-no-properties (point-min) (point-max)))) + (setq json-array-type original-json-array-type) + (setq report + (context-coloring-coverage-format coverage-data)) + (setq report (concat report "\n"))) + (princ report) + (with-temp-buffer + (insert report) (write-file context-coloring-coverage-report-file)))) t) (require 'context-coloring)) diff --git a/test/parse-coverage.js b/test/parse-coverage.js deleted file mode 100755 index e65eab0c1..000000000 --- a/test/parse-coverage.js +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env node - -// Copyright (C) 2014-2015 Free Software Foundation, Inc. - -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -'use strict'; - -var padRight = function (value, padding) { - return value + new Array(Math.max(0, padding - String(value).length) + 1).join(' '); -}; - -var formatSourceFile = function (sourceFile) { - var sourceLines = sourceFile.source.split('\n'); - var results = [ - padRight('Hits', 5) + ' | Source', - new Array(80 + 1).join('-') - ]; - var linesHit = 0; - var linesHittable = 0; - results = results.concat(sourceFile.coverage.map(function (hits, index) { - var hitsValue = hits === null ? 'N/A' : hits; - var column = hits === 0 ? '~' : '|'; - if (hits > 0) { - linesHit += 1; - } - if (hits !== null) { - linesHittable += 1; - } - return padRight(hitsValue, 5) + ' ' + column + ' ' + sourceLines[index]; - })); - results = results.concat([ - '', - 'Lines: ' + linesHit + ' / ' + linesHittable, - 'Coverage: ' + (Math.round(linesHit / linesHittable * 10000) / 100) + '%' - ]); - return results.join('\n'); -}; - -var format = function (json) { - return json.source_files.map(formatSourceFile).join('\n'); -}; - -var read = function () { - var whole = ''; - - process.stdin.setEncoding('utf8'); - - process.stdin.on('readable', function () { - var chunk = process.stdin.read(); - if (chunk !== null) { - whole += chunk; - } - }); - - process.stdin.on('end', function () { - console.log(format(JSON.parse(whole))); - }); -}; - -read();