Bamieh/reflow

View on GitHub
packages/reflow-core/src/_generate-matrix.ts

Summary

Maintainability
B
4 hrs
Test Coverage
import {
  ReflowConfig,
  Title,
} from './'

import {getLocator} from './locate'
import {runInSandbox} from './sandbox';

enum ReflowType {
  Suite,
  Subflow,
  Hook,
  Fork,
}

type MatrixEntries = MatrixEntry<any>[]

interface MatrixEntry<ReflowType> {
  type: ReflowType,
  name: string,
  resolve: any,
  evaluated?: any,
}
// import * as util from 'util';

export
const createMatrixGenerator = async function(reflowConfig: ReflowConfig) {
  const {
    // flowPaths,
    hooks,
    suites,
    subflows,
    locateStrategy = 'require',
    strategyOptions,
  } = reflowConfig;

  // const flowLocator = await getLocator('require', { filePaths: flowPaths });
  const subflowLocator = await getLocator('require', { glob: subflows });
  const hookLocator = await getLocator('require', { glob: hooks });
  const suiteLocator = await getLocator(locateStrategy, {...strategyOptions, glob: suites });

  const createReflowContext = () => {
    const matrix:MatrixEntries = [];
    const reflowContext = {
      matrix,
      flow(title: Title, flowDetails: any) {
        reflowContext.matrix = flowDetails();
      },
      subflow(title: Title, subflowDetails: any) {
        reflowContext.matrix = subflowDetails().suites;
      },
      getSuite(title: Title): MatrixEntry<ReflowType.Suite> {
        return {
          name: title,
          type: ReflowType.Suite,
          resolve: suiteLocator.locate(title),
        };
      },
      getSubflow(title: Title): MatrixEntry<ReflowType.Subflow> {
        const resolve = subflowLocator.locate(title);
        return {
          name: title,
          type: ReflowType.Subflow,
          resolve,
        };
      },
      getHook(title: Title): MatrixEntry<ReflowType.Hook> {
        return {
          name: title,
          type: ReflowType.Hook,
          resolve: hookLocator.locate(title),
        }
      },
      fork(entries: MatrixEntry<ReflowType>[]): MatrixEntry<any>[] {
        return entries
      },
    };
    return reflowContext
  }

  async function generateMatrix(filePath: string): Promise<MatrixEntries> {
    const reflowContext = createReflowContext()
    await runInSandbox(filePath, reflowContext)
    const evaluatedMatrix:MatrixEntries = reflowContext.matrix;

    const results = evaluatedMatrix.map((entry: MatrixEntry<any>) => {
      if(entry.type === ReflowType.Subflow) {
        return generateMatrix(entry.resolve)
      }
      if(Array.isArray(entry)) {
        return entry.map(forkEntry => generateMatrix(forkEntry.resolve))
      }
      return Promise.resolve([entry])
    });

    const finalResult = await Promise.all([...results])
    return finalResult.map((result: any) => {
      if(result.length === 1) return result[0];
      return result;
    })

    return finalResult[0]
  }
  return generateMatrix
}