unional / ava-fixture

Fixture test for https://github.com/avajs/ava
MIT License
5 stars 1 forks source link

feat: add perCase() #12

Closed unional closed 7 years ago

unional commented 7 years ago

Continue discussion of #9

@flying-sheep lets continue the discussion here, as it is not about beforeEach anymore.

I have added you as a collaborator. Feel free to give it a try on creating this function.

Current proposal (pesudo code):

import ava from 'ava'
import { auto } from 'ava-fixture'

auto(ava, function* () => {
  yield {
    casePath: '',
    baselinePath?: '',
    resultPath?: ''
  }
}, 
(t, d) => {
   // do work
   return d.match()
})

// or
auto(ava, 
{ casesPath: '', baselinesPath: '', resultsPath: '' },
{ only: 'case-1', skip: [...], failing: [...] }, 
(t, d) => {
   // do work
   return d.match()
})

// or
auto(ava, 
// option
{ 
  casesPath: '', 
  baselinesPath: '',
  resultsPath: '',
  only?: 'case-1',
  skip?: [...],
  failing?: [...] }, 
(t, d) => {
   // do work
   return d.match()
})
unional commented 7 years ago

Actually, I still do not get what is the situation the current API can't cover:

import test from 'ava'
import fixture from './index'
import { resolve } from 'path'
import { readdirSync } from 'fs'

import { target } from './test-target'

const cwd = resolve(process.cwd(), 'fixtures/cases')
const ftest = fixture(test, 'fixtures/cases', 'fixtures/baselines', 'fixtures/results')

const dirs = readdirSync(cwd)

dirs.forEach(testcase => {
  ftest(testcase, (t, d) => {

    // target.run(..., from, to)
    target.run(..., d.casePath, d.resultPath)

    return d.match
  })
})

Seems like I still can't see what exactly you need to do in beforeEach(). Can you provide a concrete example?

flying-sheep commented 7 years ago

you’re right. maybe we should just wrap this in a convenience function similar to this one:

ftest.perCase([globPattern, ][titleTemplate, ]run)

i also propose to add d.caseName, i.e. just the file name part of d.casePath.

import fixture from 'ava-fixture'

const ftest = fixture(test, 'fixtures/cases', 'fixtures/baselines', 'fixtures/results')

ftest.perCase((t, d) => {
    // uses d.caseName as test title and readdirSync('fixtures/cases') as cases
    …
})

ftest.perCase('test-*', (t, d) => {
    // uses glob(path.join('fixtures/cases', 'test-*')) as cases
    …
})

ftest.perCase(d => toTitleCase(d.caseName), (t, d) => {
    // calls the function to get the test title
    …
})

ftest.perCase('*.test.js', 'transforms [caseName]', (t, d) => {
    // replaces [caseName] with d.caseName to get the test tile
    …
})

this signature is possible because globs must contain * and webpack-like chunk templates must contain [].

unional commented 7 years ago

Like that idea!

flying-sheep commented 7 years ago

perCase is just ad-hoc, idk if it’s the best name

unional commented 7 years ago

Among perCase, forEach, iterate, filter, each, I think perCase or each stands out most.

Other suggestions?

flying-sheep commented 7 years ago

no, i also like those two most. we could combine them into eachCase, but idk

unional commented 7 years ago

What do you think?

ftest.each((t, d) => {})
ftest.each(filter, (t,d) => {})
ftest.each.failing(filter, (t,d) => {})

filter: string /* glob */ | ((caseName: string) => boolean)
d: {
  caseName: string,
  casePath: string,
  baselinePath: string,
  resultPath: string,
  // this change can be added later.
  match('abs or relative glob to result', 'abs or relative glob to baseline'): Promise<void>
}
unional commented 7 years ago

Released 0.8.0.

It is also chainable. I didn't add all permutations. But it should be sufficient. 🌷

ftest.only.each.failling(), ftest.skip.each.failing() 🌷

unional commented 7 years ago

@flying-sheep , what you originally ask (per file) is actually supported too #19 🌷