'use strict'; const where = require('ramda/src/where'); const includes = require('ramda/src/includes'); const intersection = require('ramda/src/intersection'); const pipe = require('ramda/src/pipe'); const isEmpty = require('ramda/src/isEmpty'); const complement = require('ramda/src/complement'); const flip = require('ramda/src/flip'); const filter = require('ramda/src/filter'); const over = require('ramda/src/over'); const lensProp = require('ramda/src/lensProp'); const map = require('ramda/src/map'); const view = require('ramda/src/view'); const assoc = require('ramda/src/assoc'); const allPass = require('ramda/src/allPass'); const INTERFACES = { BDD: 'BDD', TDD: 'TDD', QUnit: 'QUnit' }; const TYPES = { suite: 'suite', testCase: 'testCase', hook: 'hook' }; const MODIFIERS = { skip: 'skip', only: 'only' }; const baseNames = [ { name: 'describe', interfaces: [ INTERFACES.BDD ], type: TYPES.suite }, { name: 'context', interfaces: [ INTERFACES.BDD ], type: TYPES.suite }, { name: 'suite', interfaces: [ INTERFACES.TDD, INTERFACES.QUnit ], type: TYPES.suite }, { name: 'it', interfaces: [ INTERFACES.BDD ], type: TYPES.testCase }, { name: 'specify', interfaces: [ INTERFACES.BDD ], type: TYPES.testCase }, { name: 'test', interfaces: [ INTERFACES.TDD, INTERFACES.QUnit ], type: TYPES.testCase }, { name: 'before', interfaces: [ INTERFACES.BDD, INTERFACES.QUnit ], type: TYPES.hook }, { name: 'after', interfaces: [ INTERFACES.BDD, INTERFACES.QUnit ], type: TYPES.hook }, { name: 'beforeEach', interfaces: [ INTERFACES.BDD, INTERFACES.QUnit ], type: TYPES.hook }, { name: 'afterEach', interfaces: [ INTERFACES.BDD, INTERFACES.QUnit ], type: TYPES.hook }, { name: 'suiteSetup', interfaces: [ INTERFACES.TDD ], type: TYPES.hook }, { name: 'suiteTeardown', interfaces: [ INTERFACES.TDD ], type: TYPES.hook }, { name: 'setup', interfaces: [ INTERFACES.TDD ], type: TYPES.hook }, { name: 'teardown', interfaces: [ INTERFACES.TDD ], type: TYPES.hook } ]; const includesSublist = (sublist) => pipe(intersection(sublist), complement(isEmpty)); const isIncludedIn = flip(includes); const hasMatchingType = (typesToMatch) => where({ type: isIncludedIn(typesToMatch) }); const hasMatchingInterfaces = (interfacesToMatch) => where({ interfaces: includesSublist(interfacesToMatch) }); const hasMatchingModifier = (modifierToMatch) => where({ modifier: isIncludedIn(modifierToMatch) }); const filterTestCasesAndSuites = filter(hasMatchingType([ TYPES.suite, TYPES.testCase ])); const nameLens = lensProp('name'); const mapNames = (fn) => map(over(nameLens, fn)); const extractNames = map(view(nameLens)); const addModifier = (modifier) => map(assoc('modifier', modifier)); function formatXVariant(name) { return `x${name}`; } function formatSkipVariant(name) { return `${name}.${MODIFIERS.skip}`; } function formatExclusiveVariant(name) { return `${name}.${MODIFIERS.only}`; } const buildXVariants = pipe( filterTestCasesAndSuites, filter(hasMatchingInterfaces([ INTERFACES.BDD ])), mapNames(formatXVariant), addModifier(MODIFIERS.skip) ); const buildSkipVariants = pipe( filterTestCasesAndSuites, mapNames(formatSkipVariant), addModifier(MODIFIERS.skip) ); const buildExclusiveVariants = pipe( filterTestCasesAndSuites, mapNames(formatExclusiveVariant), addModifier(MODIFIERS.only) ); function buildAllNames(additionalNames) { const names = addModifier(null)([ ...baseNames, ...additionalNames ]); return [ ...names, ...buildSkipVariants(names), ...buildXVariants(names), ...buildExclusiveVariants(names) ]; } function getNamesByType(type, filterOptions = {}) { const { modifiers = [], modifiersOnly = false, additionalCustomNames = [] } = filterOptions; const allNames = buildAllNames(additionalCustomNames); const predicates = [ hasMatchingType([ type ]), hasMatchingModifier([ ...modifiers, ...modifiersOnly ? [] : [ null ] ]) ]; const filteredNames = filter(allPass(predicates), allNames); return extractNames(filteredNames); } function getTestCaseNames(options) { return getNamesByType(TYPES.testCase, options); } function getSuiteNames(options) { return getNamesByType(TYPES.suite, options); } module.exports = { getTestCaseNames, getSuiteNames };