Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

todos #1

Open
tunnckoCore opened this issue Oct 26, 2016 · 3 comments
Open

todos #1

tunnckoCore opened this issue Oct 26, 2016 · 3 comments

Comments

@tunnckoCore
Copy link
Owner

tunnckoCore commented Oct 26, 2016

  • fix sharing context (need add options argument hybridables/try-catch-core#4 and add options argument hybridables/try-catch-callback#1)
  • add hideSkip to defaults
  • (?) implement .only tests (or remove .todo, .skip)
  • externalize reporter to https://github.com/tunnckoCore/gruu-reporter
  • externalize "is callback called" thing (utils.updateTest) to separate package
  • update arr-includes to returns find index and true if it is 0
  • (?) implement .cb for callbacks, force test() to be "returning a value and accepting ctx argument" (aka promises, stream, pure sync, async/await, child processes, observables
  • spec reporter
  • rename to asia? what will be the diffs? meaning... it is pretty stable now and absolutely needed - should we add more things and rely to minibase for example?
  • for above: i believe asia will be something similar, but more open new things and this to stay as small as possible and backward compatible with assertit/mukla (not so much, but the arguments at least)
  • update async-simple-iterator (needs minibase be finished, in turn it needs minibase-tests finished)
  • after above: finish async-control (rename it to async-base?) it also should be using minibase
@tunnckoCore
Copy link
Owner Author

tunnckoCore commented Mar 9, 2017

v1

index.js

'use strict'

const arrayify = require('arrify')
const pReflect = require('p-reflect')
const pFinally = require('p-finally')
const getFnName = require('get-fn-name')
const pMapSeries = require('p-map-series')
const pMap = require('p-map')
const mitt = require('./mitt')

const pTry = (fn, args) => () => new Promise((resolve) => {
  resolve(fn.apply(null, arrayify(args)))
})

module.exports = (options) => {
  const { emit, on, off } = mitt()

  const app = {
    on,
    off,
    emit,
    tests: [],
    stats: {
      pass: 0,
      fail: 0,
      count: 0,
      anonymous: 0
    },
    options: Object.assign({
      showStack: false,
      serial: false,
      settle: true
    }, options),

    add: (title, fn, opts) => {
      if (typeof fn === 'object') {
        opts = fn
        fn = title
        title = null
      }
      if (typeof title === 'function') {
        fn = title
        title = null
      }
      if (typeof fn !== 'function') {
        throw new TypeError('.add: expect `fn` to be a function')
      }

      title = typeof title === 'string' ? title : getFnName(fn)
      if (title === null) {
        app.stats.anonymous++
      }

      app.stats.count++

      const test = {
        title,
        index: app.tests.length,
        fn: pTry(fn, app.options.args),
        options: Object.assign(app.options, opts)
      }

      app.tests.push(test)
      return app
    },

    run: (opts) => {
      app.options = Object.assign({}, options, opts)
      app.emit('header', app)

      function mapper (test, index) {
        app.emit('beforeEach', app, test)

        function pNotify (result) {
          test = Object.assign({}, test, result)
          app.emit('afterEach', app, test)

          if (test.isRejected) {
            app.stats.fail++
            app.emit('fail', app, test)
          } else {
            app.stats.pass++
            app.emit('pass', app, test)
          }

          if (test.isRejected && app.options.settle === false) {
            throw test.reason
          } else {
            return test
          }
        }

        return pReflect(test.fn()).then(pNotify)
      }

      const flow = app.options.serial === true ? pMapSeries : pMap
      const promise = flow(app.tests, mapper, app.options)

      return pFinally(promise, () => app.emit('footer', app))
    }
  }

  return app
}

example

var delay = require('delay')
var gruu = require('./index')
const app = gruu({ args: require('assert'), serial: true })
const test = app.add

// var test = require('tape')

test('foo bar baz', function b (t) {
  t.strictEqual(13, 1)
  // t.end()
})

test('quxie setty', function a (t) {
  return delay(400).then(() => {
    t.strictEqual(222, 222)
    // t.end()
  })
})

test('zeta gama', function s (t) {
  t.strictEqual(3, 3)
  // t.end()
})

// test('hiahahah zeah', (t) => delay(220).then(() => t.ok(123)))
test('hiahahah zeah', async function c (t) {
  await delay(220).then(() => {
    // fo
  })
  t.fail(123)
  // t.end()
})

test('hi22222ahahah zeah', function x (t) {
  t.strictEqual(3332333, 333333)
  // t.end()
})

@tunnckoCore
Copy link
Owner Author

tunnckoCore commented Mar 13, 2017

the final working update with lastest each-promise changes. Mostly node 0.10 should work.

/*!
 * gruu2 <https://github.com/tunnckoCore/gruu2>
 *
 * Copyright (c) Charlike Mike Reagent <@tunnckoCore> (https://i.am.charlike.online)
 * Released under the MIT license.
 */

'use strict'

var flow = require('each-promise')
var extend = require('extend-shallow')
var getName = require('get-fn-name')
var redolent = require('redolent')
var assert = require('assert')
var dush = require('dush')

module.exports = function gruu2 (options) {
  var ret = dush().use(function _plugin (app) {
    app = extend(app, {
      tests: [],
      titles: [],
      stats: {
        pass: 0,
        fail: 0,
        count: 0,
        anonymous: 0
      },
      options: extend({
        detailed: true,
        serial: false,
        settle: true,
        args: assert
      }, options),

      add: function add (title, fn) {
        if (typeof title === 'function') {
          fn = title
          title = null
        }
        if (typeof fn !== 'function') {
          var err = new TypeError('.add: expect `fn` to be a function')
          app.emit('error', err)
          return app
        }

        title = typeof title === 'string' ? title : getName(fn)
        if (title === null) {
          app.stats.anonymous++
        }

        app.stats.count++
        app.titles.push(title)
        app.tests.push(redolent(fn, app.options))
        return app
      },

      run: function run (options) {
        app.options = extend({}, app.options, options)
        var reporter = typeof app.options.reporter === 'function'
          ? app.options.reporter
          : function noopPluginReporter () {}

        app.use(reporter)

        function makeTest (item) {
          return {
            title: app.titles[item.index],
            index: item.index + 1,
            value: item.value
          }
        }

        return flow.each(app.tests, {
          start: function start () {
            app.emit('start', app)
          },

          beforeEach: function beforeEach (item) {
            var test = makeTest(item)
            app.emit('beforeEach', app, test)
          },

          afterEach: function afterEach (item) {
            var test = extend(makeTest(item), reflect(item))
            app.emit('afterEach', app, test)

            if (test.isRejected) {
              app.stats.fail++
              app.emit('fail', app, test)
            } else {
              app.stats.pass++
              app.emit('pass', app, test)
            }

            if (test.isRejected && app.options.settle === false) {
              throw test.reason
            } else {
              return test
            }

          },
          finish: function finish () {
            app.emit('finish', app)
          }
        })
      }
    })

    return app
  })

  return ret
}

function reflect (item) {
  if (item.reason) {
    return {
      isRejected: true,
      isFulfilled: false,
      reason: item.reason
    }
  }

  return {
    isRejected: false,
    isFulfilled: true,
    value: item.value
  }
}

as about the reporter... Need update again on the stacktrace-metadata and some sane yaml error output

var delay = require('delay')
var gruu = require('./index')

var rimraf = require('rimraf') // for testing stack traces


var app = gruu({
  reporter: reporter,
  showStack: false,
  settle: false,
  detailed: false,
})

app.add('foo bar baz', function b (t) {
  t.strictEqual(11, 11)
})

app.add('quxie setty', function aaaa (t) {
  // fsdf // work
  // rimraf.sync(44444444)      // work
  // require('/home/charlike/apps/alwa')(555555) // work
  return delay(400).then(() => {
    // require('/home/charlike/apps/alwa')(555555) // work
    // console.log('actual')
    // rimraf.sync(44444444)      // work
    // dasdasd                    // work
    t.strictEqual(222, 222)
    // t.strictEqual(23322, 222)  // work
  })
})

app.add('zeta gama', function s (t) {
  t.strictEqual(44, 3)
})

app.run().then(
  () => console.log('done'),
  (er) => console.log('err', er)
)

function reporter (app) {
  app.on('start', () => {
    console.log('TAP version 13')
  })
  app.on('pass', (app, test) => {
    console.log('# :)', test.title)
    console.log('ok', test.index, '-', test.title)
  })
  app.on('fail', (app, test) => {
    var err = metadata(test.reason, app.options)
    console.log('# :(', test.title)
    console.log('not ok', test.index, '-', test.title)
    console.log('  ---')
    yamlEncode(err)
    console.log('  ...')

    if (app.options.settle === false) {
      app.emit('finish', app)
      process.exit(1)
    }
  })
  app.on('finish', (app) => {
    console.log('')
    console.log(`1..${app.stats.count}`)
    console.log('# tests', app.stats.count)
    console.log('# pass ', app.stats.pass)

    if (app.stats.fail) {
      console.log('# fail ', app.stats.fail)
      console.log('')
      process.exit(1)
    } else {
      console.log('')
      console.log('# ok')
      process.exit(0)
    }
  })
}

var hasOwn = function hasOwn (self, key) {
  return Object.prototype.hasOwnProperty.call(self, key)
}
var metadata = require('/home/charlike/apps/foo')

function yamlEncode (err) {
  delete err.generatedMessage

  console.log('  name:', err.name)

  if (err.message.length) {
    console.log('  message:', err.message)
  }
  if (hasOwn(err, 'actual') && hasOwn(err, 'expected')) {
    console.log('  expected:', err.expected)
    console.log('  actual:', err.actual)
  }
  if (hasOwn(err, 'operator') && err.message.indexOf(err.operator) === -1) {
    console.log('  operator:', err.operator)
  }
  if (app.options.detailed) {
    console.log('  line:', err.line)
    console.log('  column:', err.column)
    console.log('  filename:', err.filename)
  }

  var sites = err.stack.split('\n').map(function (line) {
    return line.trim()
  })

  // need latest updates in `stacktrace-metadata`
  if (err.at) {
    console.log('  at:', err.at)
  }

  if (app.options.showStack) {
    console.log('  stack:')
    sites.slice(1).forEach(function (line) {
      console.log('   ', line)
    })
  }
}

@tunnckoCore
Copy link
Owner Author

Note in the reporter that we should manually call finish and process.exit(1) from the fail event if settle: false.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant