GithubHelp home page GithubHelp logo

tap-prettify's People

Contributors

toolness avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

tap-prettify's Issues

Show stderr by default

If stderr isn't shown and the tests throw an exception, it's possible for tap-prettify to simply display no output and exit. It also makes debugging tests harder--not only does console.log not display anything, but console.error doesn't either, as the user needs to explicitly enable stderr output to see it.

TypeError: c.stack.forEach is not a function

I'm redirecting the output from tape-run to tap-prettify. I inserted a console.info(c.stack).

$ gulp test | ./node_modules/tap-prettify/bin/tap-prettify.js -
โœ“ login|render|GET https://accounts.crystalcommerce.com/account.json|401|show logged-out
x account/login/login.tag|main

  SyntaxError: JSON Parse error: Unexpected identifier "undefined" failure

  Traceback (most recent call first):
c.stack { 'at parse ([native code])': '',
  'at http': '//localhost:52950/bundle.js?daec7d24:26718:9',
  'at baseFindIndex (http': '//localhost:52950/bundle.js?daec7d24:5902:20)',
  'at request (http': '//localhost:52950/bundle.js?daec7d24:26769:20)',
  'at bound (http': '//localhost:52950/bundle.js?daec7d24:24630:37)',
  'at run (http': '//localhost:52950/bundle.js?daec7d24:2446:19)',
  'at next (http': '//localhost:52950/bundle.js?daec7d24:24440:18)',
  'at drainQueue (http': '//localhost:52950/bundle.js?daec7d24:2417:41)' }
/home/phoenix/workspace/cc/frontend-components/node_modules/tap-prettify/index.js:92
                c.stack.forEach(function(line) {
                        ^
TypeError: c.stack.forEach is not a function
    at /home/phoenix/workspace/cc/frontend-components/node_modules/tap-prettify/index.js:92:25
    at Array.forEach (native)
    at TapConsumer.<anonymous> (/home/phoenix/workspace/cc/frontend-components/node_modules/tap-prettify/index.js:78:32)
    at emitOne (events.js:82:20)
    at TapConsumer.emit (events.js:169:7)
    at TapConsumer._parseLine (/home/phoenix/workspace/cc/frontend-components/node_modules/tap-prettify/node_modules/tap/lib/tap-consumer.js:133:20)
    at TapConsumer.write (/home/phoenix/workspace/cc/frontend-components/node_modules/tap-prettify/node_modules/tap/lib/tap-consumer.js:77:10)
    at Socket.ondata (_stream_readable.js:521:20)
    at emitOne (events.js:77:13)
    at Socket.emit (events.js:169:7)
stream.js:74
      throw er; // Unhandled stream error in pipe.
            ^
Error: write EPIPE
    at Object.exports._errnoException (util.js:812:11)
    at exports._exceptionWithHostPort (util.js:835:20)
    at WriteWrap.afterWrite (net.js:758:14)

Test skips and passes not output

A simple TAP stream like this:

TAP version 13
ok 1 - foo
ok 2 - bar # SKIP nope
not ok 3 - baz
1..3

Will not output the passes and skips when ran through tap-prettify -

The logic in index.js seems to read out the pass and skips as objects, but then not output them until a non-object line (such as a comment) is encountered. This is not per the spec.

The logic should be something along this:

const CHECKMARK = "\u2713";
const OK_FINISH_REGEXP = /^ok$/;
const FAIL_FINISH_REGEXP = /^fail[0-9\s]+$/;
const SKIP_FINISH_REGEXP = /^skip[0-9\s]+$/;
const CURRENT_TEST_START = {
  name: "",
  total: 0,
  skipped: false,
  failed: [],
  ok: []
};

var colors = require("colors");
var tap = require("tap");

function copy(obj) {
  return JSON.parse(JSON.stringify(obj));
}

function isUsefulLine(line, usefulSubstrings) {
  for (var i = 0; i < usefulSubstrings.length; i++) {
    if (line.indexOf(usefulSubstrings[i]) != -1)
      return true;
  }
  return false;
}

function prettifyTapOutput(options) {
  var tc = options.tapConsumer;
  var log = options.log || console.log.bind(console);
  var usefulTracebackSubstrings = options.usefulTracebackSubstrings || [];
  var debug = options.debug;
  var passed = 0;
  var failed = 0;
  var skipped = 0;
  var currentTest = copy(CURRENT_TEST_START);
  var lastOutput = null;

  tc.on("bailout", function(info) {
    log("BAILOUT".red, info);
    process.exit(1);
  });
  tc.on("data", function (c) {
    if (typeof(c) == "object") {
      if (debug)
        log("DEBUG object".magenta, JSON.stringify(c, null, 2).grey);
      currentTest.total++;

      if (currentTest.name != c.name) {
        currentTest = copy(CURRENT_TEST_START);
        currentTest.name = c.name;
      }

      if (c.ok) {
        if (c.skip) {
          currentTest.skipped = true;
          skipped++;
        } else {
          currentTest.ok.push(c);
          passed++;
        }
      } else {
        if (c.timedOut)
          log("TIMEOUT".red, c.name.trim());
        if (c.exit)
          process.exit(c.exit);
        currentTest.failed.push(c);
        failed++;
      }

      if (currentTest.name) {
        if (currentTest.failed.length) {
          log("x".red, currentTest.name.grey);
          log();
          currentTest.failed.forEach(function(c) {
            log("  " + c.name.trim(), "failure".grey);
            if ('found' in c && 'wanted' in c) {
              log("  found ".grey, JSON.stringify(c.found));
              log("  wanted".grey, JSON.stringify(c.wanted));
              if (c.diff) {
                log("  diff".grey);
                c.diff.split('\n').forEach(function(line) {
                  log("    " + line);
                });
              }
            }
            if (c.stack) {
              log("\n  Traceback (most recent call first):".grey);
              c.stack.forEach(function(line) {
                log("    " + (isUsefulLine(line, usefulTracebackSubstrings)
                              ? line.white
                              : line.grey));
              });
            } else if (c.file) {
              log("  @ ".grey + c.file + ":".grey + c.line);
            }
            log();
          });
        } else if (currentTest.skipped) {
          log("S".yellow, currentTest.name.grey);
        } else {
          log(CHECKMARK.green, currentTest.name.grey);
        }
      }

    } else {
      if (debug) log("DEBUG foo".magenta, c.grey);
      if (currentTest.total) {
        if (OK_FINISH_REGEXP.test(currentTest.name) ||
            FAIL_FINISH_REGEXP.test(currentTest.name) ||
            SKIP_FINISH_REGEXP.test(currentTest.name)) {
          if (currentTest.ok.length) {
            console.log("\nFinished testing ".grey +
                        currentTest.ok[0].name.trim() + ".\n".grey);
          }
        }
      }
    }
  });
  tc.on("end", function () {
    var total = passed + failed;
    var count = passed + "/" + total;
    log(passed == total ? count.green : count.red,
        "tests passed,".grey,
        (skipped ? skipped.toString().yellow : "none".grey),
        "skipped.".grey);
    process.exit(failed);
  });
}

module.exports = Object.create(tap);

module.exports.prettify = prettifyTapOutput;

// Exported for unit testing purposes only.
module.exports._isUsefulLine = isUsefulLine;

Accept piped inputs

It would be nice for the tap-prettify.js executable to accept & format piped TAP inputs.

Unable to install with yarn

In a brand new directory:

$ yarn add tap-prettify
yarn add v0.21.3
[1/4] ๐Ÿ”  Resolving packages...
warning tap-prettify > tap > glob > [email protected]: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue
[2/4] ๐Ÿšš  Fetching packages...
[3/4] ๐Ÿ”—  Linking dependencies...
error Couldn't find a package.json file in "/Users/jamesseppi/CODE/test-tap-prettify/node_modules/tap/node_modules/tap-consumer"
info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command.

not a stream :(

The big advantage for me with tape is that that I can use any executable enviroment and not some "helpful" runner like mocha, making transpilation and node harmony arguments really difficult to use. I'd love to use this, but there is no way to fit it into my environment now.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.