Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

quickpickle

Package Overview
Dependencies
Maintainers
0
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

quickpickle - npm Package Compare versions

Comparing version 1.2.2 to 1.2.3

22

dist/index.d.ts
import { Plugin } from 'vite';
import { BeforeAll, applyBeforeAllHooks, Before, applyBeforeHooks, AfterAll, applyAfterAllHooks, After, applyAfterHooks, BeforeStep, applyBeforeStepHooks, AfterStep, applyAfterStepHooks } from './hooks';
import { explodeTags, tagsMatch } from './render';
import { DataTable } from '@cucumber/cucumber';

@@ -7,2 +8,3 @@ import { DocString } from './models/DocString';

export { DocString, DataTable };
export { explodeTags, tagsMatch };
export { BeforeAll, Before, AfterAll, After, BeforeStep, AfterStep };

@@ -14,5 +16,5 @@ export { applyBeforeAllHooks, applyBeforeHooks, applyAfterAllHooks, applyAfterHooks, applyBeforeStepHooks, applyAfterStepHooks, };

export declare const qp: (step: string, state: any, line: number, data?: any) => Promise<any>;
export type QuickPickleConfig<T = {
export type QuickPickleConfigSetting<T = {
[key: string]: any;
}> = {
}> = Partial<{
todoTags: string | string[];

@@ -24,8 +26,18 @@ skipTags: string | string[];

explodeTags: string | string[] | string[][];
worldConfig: T;
worldConfig: Partial<T>;
}>;
export type QuickPickleConfig<T = {
[key: string]: any;
}> = {
todoTags: string[];
skipTags: string[];
failTags: string[];
concurrentTags: string[];
sequentialTags: string[];
explodeTags: string[][];
worldConfig: Partial<T>;
};
export declare const defaultConfig: QuickPickleConfig;
export declare function normalizeTags(tags?: string | string[] | undefined): string[];
export declare function explodeTags(explodeTags: string[][], testTags: string[]): string[][];
export declare const quickpickle: (conf?: Partial<QuickPickleConfig>) => Plugin;
export declare const quickpickle: (conf?: Partial<QuickPickleConfigSetting>) => Plugin;
export default quickpickle;
import { ExpressionFactory, ParameterTypeRegistry } from '@cucumber/cucumber-expressions';
import { isFunction, isString, isObject, concat, intersection, fromPairs, pick, get } from 'lodash-es';
import { isFunction, isString, isObject, concat, intersection, fromPairs, pick, defaultsDeep, get } from 'lodash-es';
import parse from '@cucumber/tag-expressions';
import * as Gherkin from '@cucumber/gherkin';
import * as Messages from '@cucumber/messages';
import { DataTable } from '@cucumber/cucumber';
export { DataTable } from '@cucumber/cucumber';
import * as Gherkin from '@cucumber/gherkin';
import * as Messages from '@cucumber/messages';

@@ -227,11 +227,12 @@ const steps = [];

tags = [...tags, ...child.scenario.tags.map(t => t.name)];
let todo = (intersection(config.todoTags, tags).length > 0) ? '.todo' : '';
let skip = (intersection(config.skipTags, tags).length > 0) ? '.skip' : '';
let fails = (intersection(config.failTags, tags).length > 0) ? '.fails' : '';
let concurrent = (intersection(config.concurrentTags, tags).length > 0) ? '.concurrent' : '';
let sequential = (intersection(config.sequentialTags, tags).length > 0) ? '.sequential' : '';
let todo = tagsMatch(config.todoTags, tags) ? '.todo' : '';
let skip = tagsMatch(config.skipTags, tags) ? '.skip' : '';
let fails = tagsMatch(config.failTags, tags) ? '.fails' : '';
let sequential = tagsMatch(config.sequentialTags, tags) ? '.sequential' : '';
let concurrent = (!sequential && tagsMatch(config.concurrentTags, tags)) ? '.concurrent' : '';
let attrs = todo + skip + fails + concurrent + sequential;
// Deal with exploding tags
let taglists = explodeTags(config.explodeTags, tags);
return taglists.map(tags => {
let isExploded = taglists.length > 1 ? true : false;
return taglists.map((tags, explodedIdx) => {
// For Scenario Outlines with examples

@@ -259,3 +260,3 @@ if (child.scenario.examples?.[0]?.tableHeader && child.scenario.examples?.[0]?.tableBody) {

text = replaceParamNames(text, true);
return `${sp} await qp(\`${text}\`, state, ${step.location.line});`;
return `${sp} await qp(\`${text}\`, state, ${step.location.line}${isExploded ? '.' + explodedIdx : ''});`;
}).join('\n')}

@@ -270,3 +271,3 @@ ${sp} await afterScenario(state);

${sp} let state = await ${initFn}(context, '${q(child.scenario.name)}', ['${tags.join("', '") || ''}']);
${renderSteps(child.scenario.steps, config, sp + ' ')}
${renderSteps(child.scenario.steps, config, sp + ' ', isExploded ? `.${explodedIdx}` : '')}
${sp} await afterScenario(state);

@@ -277,3 +278,3 @@ ${sp}});

}
function renderSteps(steps, config, sp = ' ') {
function renderSteps(steps, config, sp = ' ', explodedText = '') {
return steps.map(step => {

@@ -284,12 +285,87 @@ if (step.dataTable) {

}));
return `${sp}await qp('${q(step.text)}', state, ${step.location.line}, ${data});`;
return `${sp}await qp('${q(step.text)}', state, ${step.location.line}${explodedText}, ${data});`;
}
else if (step.docString) {
let data = JSON.stringify(pick(step.docString, ['content', 'mediaType']));
return `${sp}await qp('${q(step.text)}', state, ${step.location.line}, ${data});`;
return `${sp}await qp('${q(step.text)}', state, ${step.location.line}${explodedText}, ${data});`;
}
return `${sp}await qp('${q(step.text)}', state, ${step.location.line});`;
return `${sp}await qp('${q(step.text)}', state, ${step.location.line}${explodedText});`;
}).join('\n');
}
/**
* Escapes quotation marks in a string for the purposes of this rendering function.
* @param t string
* @returns string
*/
const q = (t) => (t.replace(/'/g, "\\'"));
/**
* Creates a 2d array of all possible combinations of the items in the input array
* @param arr Array
* @returns A 2d array of all possible combinations of the items in the input array
*/
function explodeArray(arr) {
if (arr.length === 0)
return [[]];
const [first, ...rest] = arr;
const subCombinations = explodeArray(rest);
return first.flatMap(item => subCombinations.map(subCombo => [item, ...subCombo]));
}
/**
* This function "explodes" any tags in the "explodeTags" setting and returns all possible
* combinations of all the tags. The theory is that it allows you to write one Scenario that
* runs multiple times in different ways; e.g. with and without JS or in different browsers.
*
* To take this case as an example, if the explodeTags are:
* ```
* [
* ['nojs', 'js'],
* ['firefox', 'chromium', 'webkit'],
* ]
* ```
*
* And the testTags are:
* ```
* ['nojs', 'js', 'snapshot']
* ```
*
* Then the function will return:
* ```
* [
* ['nojs', 'snapshot'],
* ['js', 'snapshot'],
* ]
* ```
*
* In that case, the test will be run twice.
*
* @param explodeTags the 2d array of tags that should be exploded
* @param testTags the tags to test against
* @returns a 2d array of all possible combinations of tags
*/
function explodeTags(explodeTags, testTags) {
if (!explodeTags.length)
return [testTags];
let tagsToTest = [...testTags];
// gather a 2d array of items that are shared between tags and each array in explodeTags
// and then remove those items from the tags array
const sharedTags = explodeTags.map(tagList => {
let items = tagList.filter(tag => tagsToTest.includes(tag));
if (items.length)
items.forEach(item => tagsToTest.splice(tagsToTest.indexOf(item), 1));
return items;
});
// then, build a 2d array of all possible combinations of the shared tags
let combined = explodeArray(sharedTags);
// finally, return the list
return combined.length ? combined.map(arr => [...tagsToTest, ...arr]) : [testTags];
}
/**
*
* @param confTags string[]
* @param testTags string[]
* @returns boolean
*/
function tagsMatch(confTags, testTags) {
return intersection(confTags.map(t => t.toLowerCase()), testTags.map(t => t.toLowerCase()))?.length ? true : false;
}

@@ -325,2 +401,5 @@ class DocString extends String {

async init() { }
tagsMatch(tags) {
return tagsMatch(tags, this.info.tags);
}
}

@@ -402,26 +481,2 @@ let worldConstructor = QuickPickleWorld;

}
function explodeArray(arr) {
if (arr.length === 0)
return [[]];
const [first, ...rest] = arr;
const subCombinations = explodeArray(rest);
return first.flatMap(item => subCombinations.map(subCombo => [item, ...subCombo]));
}
function explodeTags(explodeTags, testTags) {
if (!explodeTags.length)
return [testTags];
let tagsToTest = [...testTags];
// gather a 3d array of items that are shared between tags and each array in explodeTags
// and then remove those items from the tags array
const sharedTags = explodeTags.map(tagList => {
let items = tagList.filter(tag => tagsToTest.includes(tag));
if (items.length)
items.forEach(item => tagsToTest.splice(tagsToTest.indexOf(item), 1));
return items;
});
// then, build a 3d array of all possible combinations of the remaining tags
let combined = explodeArray(sharedTags);
// finally, return the list
return combined.length ? combined.map(arr => [...tagsToTest, ...arr]) : [testTags];
}
const quickpickle = (conf = {}) => {

@@ -433,3 +488,3 @@ let config;

configResolved(resolvedConfig) {
config = Object.assign({}, defaultConfig, passedConfig, get(resolvedConfig, 'quickpickle') || {}, get(resolvedConfig, 'test.quickpickle') || {});
config = defaultsDeep(get(resolvedConfig, 'test.quickpickle') || {}, get(resolvedConfig, 'quickpickle') || {}, passedConfig, defaultConfig);
config.todoTags = normalizeTags(config.todoTags);

@@ -453,3 +508,3 @@ config.skipTags = normalizeTags(config.skipTags);

export { After, AfterAll, AfterStep, Before, BeforeAll, BeforeStep, DocString, Given, QuickPickleWorld, Then, When, applyAfterAllHooks, applyAfterHooks, applyAfterStepHooks, applyBeforeAllHooks, applyBeforeHooks, applyBeforeStepHooks, quickpickle as default, defaultConfig, explodeTags, getWorldConstructor, normalizeTags, qp, quickpickle, setWorldConstructor };
export { After, AfterAll, AfterStep, Before, BeforeAll, BeforeStep, DocString, Given, QuickPickleWorld, Then, When, applyAfterAllHooks, applyAfterHooks, applyAfterStepHooks, applyBeforeAllHooks, applyBeforeHooks, applyBeforeStepHooks, quickpickle as default, defaultConfig, explodeTags, getWorldConstructor, normalizeTags, qp, quickpickle, setWorldConstructor, tagsMatch };
//# sourceMappingURL=index.esm.js.map

@@ -5,1 +5,41 @@ import type { Feature } from "@cucumber/messages";

export declare function renderFeature(feature: Feature, config: QuickPickleConfig): string;
/**
* This function "explodes" any tags in the "explodeTags" setting and returns all possible
* combinations of all the tags. The theory is that it allows you to write one Scenario that
* runs multiple times in different ways; e.g. with and without JS or in different browsers.
*
* To take this case as an example, if the explodeTags are:
* ```
* [
* ['nojs', 'js'],
* ['firefox', 'chromium', 'webkit'],
* ]
* ```
*
* And the testTags are:
* ```
* ['nojs', 'js', 'snapshot']
* ```
*
* Then the function will return:
* ```
* [
* ['nojs', 'snapshot'],
* ['js', 'snapshot'],
* ]
* ```
*
* In that case, the test will be run twice.
*
* @param explodeTags the 2d array of tags that should be exploded
* @param testTags the tags to test against
* @returns a 2d array of all possible combinations of tags
*/
export declare function explodeTags(explodeTags: string[][], testTags: string[]): string[][];
/**
*
* @param confTags string[]
* @param testTags string[]
* @returns boolean
*/
export declare function tagsMatch(confTags: string[], testTags: string[]): boolean;

@@ -16,2 +16,3 @@ import type { TestContext } from 'vitest';

init: () => Promise<void>;
tagsMatch(tags: string[]): boolean;
}

@@ -24,2 +25,3 @@ export declare class QuickPickleWorld implements QuickPickleWorldInterface {

init(): Promise<void>;
tagsMatch(tags: string[]): boolean;
}

@@ -26,0 +28,0 @@ export type WorldConstructor = new (context: TestContext, info?: QuickPickleWorldInterface['info'], worldConfig?: any) => QuickPickleWorldInterface;

{
"name": "quickpickle",
"version": "1.2.2",
"version": "1.2.3",
"description": "Plugin for Vitest to run tests written in Gherkin Syntax.",

@@ -5,0 +5,0 @@ "keywords": [

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc