Skip to content

Commit 22448e7

Browse files
authored
Split out a "core" package candidate (#45)
1 parent 8590c2e commit 22448e7

17 files changed

+133
-102
lines changed

eslint.config.mjs

+61-41
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,74 @@
1-
import { fixupConfigRules, fixupPluginRules } from "@eslint/compat";
2-
import _import from "eslint-plugin-import";
3-
import simpleImportSort from "eslint-plugin-simple-import-sort";
4-
import n from "eslint-plugin-n";
5-
import typescriptEslint from "@typescript-eslint/eslint-plugin";
6-
import globals from "globals";
7-
import tsParser from "@typescript-eslint/parser";
8-
import path from "node:path";
9-
import { fileURLToPath } from "node:url";
10-
import js from "@eslint/js";
11-
import { FlatCompat } from "@eslint/eslintrc";
1+
import { fixupConfigRules, fixupPluginRules } from '@eslint/compat'
2+
import _import from 'eslint-plugin-import'
3+
import simpleImportSort from 'eslint-plugin-simple-import-sort'
4+
import n from 'eslint-plugin-n'
5+
import typescriptEslint from '@typescript-eslint/eslint-plugin'
6+
import globals from 'globals'
7+
import tsParser from '@typescript-eslint/parser'
8+
import path from 'node:path'
9+
import { fileURLToPath } from 'node:url'
10+
import js from '@eslint/js'
11+
import { FlatCompat } from '@eslint/eslintrc'
1212

13-
const __filename = fileURLToPath(import.meta.url);
14-
const __dirname = path.dirname(__filename);
13+
const __filename = fileURLToPath(import.meta.url)
14+
const __dirname = path.dirname(__filename)
1515
const compat = new FlatCompat({
16-
baseDirectory: __dirname,
17-
recommendedConfig: js.configs.recommended,
18-
allConfig: js.configs.all
19-
});
16+
baseDirectory: __dirname,
17+
recommendedConfig: js.configs.recommended,
18+
allConfig: js.configs.all,
19+
})
2020

21-
export default [...fixupConfigRules(compat.extends(
22-
"eslint:recommended",
23-
"plugin:import/typescript",
24-
"plugin:@typescript-eslint/eslint-recommended",
25-
"plugin:@typescript-eslint/recommended",
26-
)), {
21+
export default [
22+
...fixupConfigRules(
23+
compat.extends(
24+
'eslint:recommended',
25+
'plugin:import/typescript',
26+
'plugin:@typescript-eslint/eslint-recommended',
27+
'plugin:@typescript-eslint/recommended'
28+
)
29+
),
30+
{
2731
plugins: {
28-
import: fixupPluginRules(_import),
29-
"simple-import-sort": simpleImportSort,
30-
n,
31-
"@typescript-eslint": fixupPluginRules(typescriptEslint),
32+
import: fixupPluginRules(_import),
33+
'simple-import-sort': simpleImportSort,
34+
n,
35+
'@typescript-eslint': fixupPluginRules(typescriptEslint),
3236
},
3337

3438
languageOptions: {
35-
globals: {
36-
...globals.node,
37-
},
39+
globals: {
40+
...globals.node,
41+
},
3842

39-
parser: tsParser,
40-
ecmaVersion: 5,
41-
sourceType: "module",
43+
parser: tsParser,
44+
ecmaVersion: 5,
45+
sourceType: 'module',
4246

43-
parserOptions: {
44-
project: "tsconfig.json",
45-
},
47+
parserOptions: {
48+
project: 'tsconfig.json',
49+
},
4650
},
4751

4852
rules: {
49-
"import/no-cycle": "error",
50-
"n/no-extraneous-import": "error",
51-
"simple-import-sort/imports": "error",
52-
"simple-import-sort/exports": "error",
53+
'import/no-cycle': 'error',
54+
'n/no-extraneous-import': 'error',
55+
'simple-import-sort/imports': 'error',
56+
'simple-import-sort/exports': 'error',
57+
'import/no-relative-parent-imports': 'error',
5358
},
54-
}];
59+
},
60+
{
61+
files: ['src/core/**/*.ts'],
62+
63+
rules: {
64+
'no-restricted-imports': ['error', {
65+
patterns: [
66+
{
67+
group: ['../'],
68+
message: 'The core should be self-contained'
69+
}
70+
]
71+
}],
72+
},
73+
},
74+
]

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"docs": "typedoc",
2121
"exports:check": "api-extractor run --verbose",
2222
"exports:update": "api-extractor run --verbose --local",
23-
"fix": "eslint --max-warnings 0 src --fix src && prettier --write src test",
23+
"fix": "eslint --max-warnings 0 src --fix && prettier --write src test",
2424
"lint": "eslint --max-warnings 0 src && prettier --check src test",
2525
"test": "npm run test:unit && npm run test:integration",
2626
"test:integration": "tsc && mocha test/**/*.spec.ts",
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

src/runner/SupportCodeBuilder.spec.ts renamed to src/core/SupportCodeBuilder.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { SupportCodeBuilder } from './SupportCodeBuilder.js'
44

55
describe('SupportCodeBuilder', () => {
66
it('catches undefined parameter type errors and emits an appropriate message', () => {
7-
const builder = new SupportCodeBuilder()
7+
const builder = new SupportCodeBuilder(() => crypto.randomUUID())
88
builder.registerStep('a {thing} happens', () => {}, {})
99

1010
const library = builder.build()
@@ -18,7 +18,7 @@ describe('SupportCodeBuilder', () => {
1818
})
1919

2020
it('allows other errors from expression compilation to bubble', () => {
21-
const builder = new SupportCodeBuilder()
21+
const builder = new SupportCodeBuilder(() => crypto.randomUUID())
2222
// @ts-expect-error passing incorrect type to yield an error
2323
builder.registerStep(null, () => {}, {})
2424

src/runner/SupportCodeBuilder.ts renamed to src/core/SupportCodeBuilder.ts

+22-30
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,37 @@ import {
66
import { SourceReference } from '@cucumber/messages'
77
import parse from '@cucumber/tag-expressions'
88

9-
import { makeId } from '../makeId.js'
10-
import { HookFunction, HookOptions, ParameterTypeOptions, StepFunction } from '../types.js'
119
import {
1210
DefinedHook,
1311
DefinedParameterType,
1412
DefinedStep,
1513
SupportCodeLibrary,
1614
UndefinedParameterType,
1715
} from './SupportCodeLibrary.js'
16+
import { SupportCodeFunction } from './types.js'
1817

19-
interface RegisteredParameterType extends ParameterTypeOptions {
18+
interface RegisteredParameterType {
2019
id: string
20+
name: string
21+
regexp: RegExp | string | readonly RegExp[] | readonly string[]
22+
transformer?: (...match: string[]) => unknown
23+
useForSnippets?: boolean
24+
preferForRegexpMatch?: boolean
2125
sourceReference: SourceReference
2226
}
2327

24-
interface RegisteredHook extends HookOptions {
28+
interface RegisteredHook {
2529
id: string
26-
fn: HookFunction
30+
name?: string
31+
tagFilter?: string
32+
fn: SupportCodeFunction
2733
sourceReference: SourceReference
2834
}
2935

3036
interface RegisteredStep {
3137
id: string
3238
text: string
33-
fn: StepFunction
39+
fn: SupportCodeFunction
3440
sourceReference: SourceReference
3541
}
3642

@@ -42,53 +48,39 @@ export class SupportCodeBuilder {
4248
private readonly beforeHooks: Array<RegisteredHook> = []
4349
private readonly afterHooks: Array<RegisteredHook> = []
4450

45-
registerParameterType(
46-
options: ParameterTypeOptions,
47-
sourceReference: SourceReference
48-
): SupportCodeBuilder {
51+
constructor(private readonly newId: () => string) {}
52+
53+
registerParameterType(options: Omit<RegisteredParameterType, 'id'>): SupportCodeBuilder {
4954
this.parameterTypes.push({
50-
id: makeId(),
55+
id: this.newId(),
5156
...options,
52-
sourceReference,
5357
})
5458
return this
5559
}
5660

57-
registerBeforeHook(
58-
options: HookOptions,
59-
fn: HookFunction,
60-
sourceReference: SourceReference
61-
): SupportCodeBuilder {
61+
registerBeforeHook(options: Omit<RegisteredHook, 'id'>): SupportCodeBuilder {
6262
this.beforeHooks.push({
63-
id: makeId(),
63+
id: this.newId(),
6464
...options,
65-
fn,
66-
sourceReference,
6765
})
6866
return this
6967
}
7068

71-
registerAfterHook(
72-
options: HookOptions,
73-
fn: HookFunction,
74-
sourceReference: SourceReference
75-
): SupportCodeBuilder {
69+
registerAfterHook(options: Omit<RegisteredHook, 'id'>): SupportCodeBuilder {
7670
this.afterHooks.push({
77-
id: makeId(),
71+
id: this.newId(),
7872
...options,
79-
fn,
80-
sourceReference,
8173
})
8274
return this
8375
}
8476

8577
registerStep(
8678
text: string,
87-
fn: StepFunction,
79+
fn: SupportCodeFunction,
8880
sourceReference: SourceReference
8981
): SupportCodeBuilder {
9082
this.steps.push({
91-
id: makeId(),
83+
id: this.newId(),
9284
text,
9385
fn,
9486
sourceReference,

src/runner/SupportCodeLibrary.ts renamed to src/core/SupportCodeLibrary.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Argument, CucumberExpression } from '@cucumber/cucumber-expressions'
22
import { Envelope, HookType, SourceReference, StepDefinitionPatternType } from '@cucumber/messages'
33
import parse from '@cucumber/tag-expressions'
44

5-
import { HookFunction, StepFunction } from '../types.js'
5+
import { SupportCodeFunction } from './types.js'
66

77
export type UndefinedParameterType = {
88
name: string
@@ -23,15 +23,15 @@ export type DefinedHook = {
2323
name?: string
2424
rawTagExpression?: string
2525
tagExpression?: ReturnType<typeof parse>
26-
fn: HookFunction
26+
fn: SupportCodeFunction
2727
sourceReference: SourceReference
2828
}
2929

3030
export type DefinedStep = {
3131
id: string
3232
rawExpression: string
3333
expression: CucumberExpression
34-
fn: StepFunction
34+
fn: SupportCodeFunction
3535
sourceReference: SourceReference
3636
}
3737

@@ -63,7 +63,7 @@ export class SupportCodeLibrary {
6363
return results
6464
}
6565

66-
findAllBeforeHooksBy(tags: ReadonlyArray<string>) {
66+
findAllBeforeHooksBy(tags: ReadonlyArray<string>): ReadonlyArray<DefinedHook> {
6767
return this.beforeHooks.filter((def) => {
6868
if (def.tagExpression) {
6969
return def.tagExpression.evaluate(tags as string[])
@@ -72,7 +72,7 @@ export class SupportCodeLibrary {
7272
})
7373
}
7474

75-
findAllAfterHooksBy(tags: ReadonlyArray<string>) {
75+
findAllAfterHooksBy(tags: ReadonlyArray<string>): ReadonlyArray<DefinedHook> {
7676
return this.afterHooks.filter((def) => {
7777
if (def.tagExpression) {
7878
return def.tagExpression.evaluate(tags as string[])
File renamed without changes.

src/core/index.ts

Whitespace-only changes.

src/runner/makeTestPlan.ts renamed to src/core/makeTestPlan.ts

+19-14
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
import { Group as ExpressionsGroup } from '@cucumber/cucumber-expressions'
22
import { Envelope, Group as MessagesGroup, Pickle, TestCase, TestStep } from '@cucumber/messages'
33

4-
import { DataTable } from '../DataTable.js'
5-
import { makeId } from '../makeId.js'
6-
import { StepFunction } from '../types.js'
74
import { AmbiguousError } from './AmbiguousError.js'
5+
import { DataTable } from './DataTable.js'
86
import { SupportCodeLibrary } from './SupportCodeLibrary.js'
7+
import { SupportCodeFunction } from './types.js'
98
import { UndefinedError } from './UndefinedError.js'
109

1110
export type Runnable = {
12-
fn: StepFunction
13-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
14-
args: ReadonlyArray<any>
11+
fn: SupportCodeFunction
12+
args: ReadonlyArray<unknown>
1513
}
1614

1715
export interface AssembledTestPlan {
@@ -35,18 +33,19 @@ export interface AssembledStep {
3533
}
3634

3735
export function makeTestPlan(
36+
newId: () => string,
3837
pickles: ReadonlyArray<Pickle>,
3938
library: SupportCodeLibrary
4039
): AssembledTestPlan {
4140
return {
4241
testCases: pickles.map((pickle) => {
4342
return {
44-
id: makeId(),
43+
id: newId(),
4544
name: pickle.name,
4645
steps: [
47-
...fromBeforeHooks(pickle, library),
48-
...fromPickleSteps(pickle, library),
49-
...fromAfterHooks(pickle, library),
46+
...fromBeforeHooks(newId, pickle, library),
47+
...fromPickleSteps(newId, pickle, library),
48+
...fromAfterHooks(newId, pickle, library),
5049
],
5150
toMessage() {
5251
return {
@@ -64,12 +63,13 @@ export function makeTestPlan(
6463
}
6564

6665
function fromBeforeHooks(
66+
newId: () => string,
6767
pickle: Pickle,
6868
library: SupportCodeLibrary
6969
): ReadonlyArray<AssembledStep> {
7070
return library.findAllBeforeHooksBy(pickle.tags.map((tag) => tag.name)).map((def) => {
7171
return {
72-
id: makeId(),
72+
id: newId(),
7373
name: def.name ?? '',
7474
always: false,
7575
prepare() {
@@ -88,13 +88,17 @@ function fromBeforeHooks(
8888
})
8989
}
9090

91-
function fromAfterHooks(pickle: Pickle, library: SupportCodeLibrary): ReadonlyArray<AssembledStep> {
91+
function fromAfterHooks(
92+
newId: () => string,
93+
pickle: Pickle,
94+
library: SupportCodeLibrary
95+
): ReadonlyArray<AssembledStep> {
9296
return library
9397
.findAllAfterHooksBy(pickle.tags.map((tag) => tag.name))
9498
.toReversed()
9599
.map((def) => {
96100
return {
97-
id: makeId(),
101+
id: newId(),
98102
name: def.name ?? '',
99103
always: true,
100104
prepare() {
@@ -114,13 +118,14 @@ function fromAfterHooks(pickle: Pickle, library: SupportCodeLibrary): ReadonlyAr
114118
}
115119

116120
function fromPickleSteps(
121+
newId: () => string,
117122
pickle: Pickle,
118123
library: SupportCodeLibrary
119124
): ReadonlyArray<AssembledStep> {
120125
return pickle.steps.map((pickleStep) => {
121126
const matched = library.findAllStepsBy(pickleStep.text)
122127
return {
123-
id: makeId(),
128+
id: newId(),
124129
name: pickleStep.text,
125130
always: false,
126131
prepare() {

src/core/types.ts

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
2+
export type SupportCodeFunction = (...args: any[]) => any | Promise<any>

0 commit comments

Comments
 (0)