Skip to content

Commit

Permalink
Merge pull request #24 from mapado/handle-long-name-and-description
Browse files Browse the repository at this point in the history
Handle printWidth for node name and description
  • Loading branch information
jdeniau authored Jul 5, 2024
2 parents 37ff243 + 9bf6f81 commit 99e9b7e
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 49 deletions.
6 changes: 2 additions & 4 deletions .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@ name: Node.js CI

on:
push:
branches: [ "main" ]
branches: ['main']
pull_request:
branches: [ "main" ]
branches: ['main']

jobs:
build:

runs-on: ubuntu-latest

strategy:
Expand All @@ -27,5 +26,4 @@ jobs:
node-version: ${{ matrix.node-version }}
cache: 'yarn'
- run: yarn install --frozen-lockfile
- run: yarn run build
- run: yarn test
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,4 +177,5 @@ yarn lint # the plugin is writter in TypeScript, this command will help you dete

### Test datas

Test datas can be found here : https://github.com/cucumber/gherkin-utils/tree/main/testdata
Test datas can be found here : https://github.com/cucumber/gherkin-utils/tree/c35857189c2da3a9b84796ad585d25e70f7bf3b8/testdata

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"build": "tsc",
"lint": "tsc --noEmit",
"example": "yarn build && prettier --plugin=dist/index.js tests/plugin/example.feature",
"test": "NODE_OPTIONS=--experimental-vm-modules jest",
"test": "yarn build && NODE_OPTIONS=--experimental-vm-modules jest",
"prepublishOnly": "yarn build"
},
"keywords": [
Expand Down
108 changes: 67 additions & 41 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ import {
TypedRuleChild,
isHasChildren,
isHasChild,
HasChild,
HasChildren,
GherkinNodeWithLocation,
isWithLocation,
} from './GherkinAST/index.js';
Expand All @@ -52,7 +50,7 @@ const DEFAULT_ESCAPE_BACKSLASH = false;
// taken from https://github.com/cucumber/gherkin-javascript/blob/e25a1be3b21133c7a92eb7735997c6e774406226/src/GherkinClassicTokenMatcher.ts#L11
const LANGUAGE_PATTERN = /^\s*#\s*language\s*:\s*([a-zA-Z\-_]+)\s*$/;

const { hardline, join, indent } = doc.builders;
const { hardline, join, indent, line, fill } = doc.builders;

const languages: SupportLanguage[] = [
{
Expand Down Expand Up @@ -205,9 +203,9 @@ const gherkinParser: Parser<GherkinNode> = {
return gherkinParser.locStart(node) + node.text.trim().length;
}

if (!(node instanceof TypedComment)) {
console.log({ method: 'locEnd', nodeName: node.constructor.name });
}
// if (!(node instanceof TypedComment)) {
// console.log({ method: 'locEnd', nodeName: node.constructor.name });
// }

if (node instanceof TypedFeature) {
return (
Expand Down Expand Up @@ -238,34 +236,28 @@ function printTags(
path: AstPath<TypedGherkinNode<GherkinNode & { tags: readonly TypedTag[] }>>,
node: GherkinNode & { tags: readonly TypedTag[] }
) {
// console.log(node);

return [
// @ts-expect-error TODO path should be recognized as an AstPath<GherkinNode & { tags: readonly TypedTag[] }>>
join(printHardline(), path.map(gherkinAstPrinter.print, 'tags')),
node.tags.length > 0 ? printHardline() : '',
];
}

function printDescription(
path: AstPath<TypedGherkinNode<GherkinNode & { description: string }>>,
node: GherkinNode & { description: string },
hardlineIfDescription: boolean
) {
// console.log(node);
function printNodeHeading(
node: GherkinNode & { keyword: string; name: string }
): Doc {
return `${node.keyword}: ${node.name}`;
}

function printDescription(
node: GherkinNode & { description: string; location: Location },
hardlineIfNoDescription: boolean
): Doc {
if (!node.description) {
return hardlineIfDescription ? printHardline() : '';
return hardlineIfNoDescription ? printHardline() : '';
}

return [
join(
printHardline(),
node.description.split('\n').map((s) => s.trim())
),
printHardline(),
printHardline(),
];
return [printTextBloc(node.description), printHardline()];
}

/**
Expand Down Expand Up @@ -306,8 +298,6 @@ function findNodeForCommentInAST(
}

return null;

return null;
}

function stepNeedsHardline(
Expand Down Expand Up @@ -344,6 +334,35 @@ function stepNeedsHardline(
);
}

function printTextBloc(text: string, doIndent: boolean = false) {
const filledHeading = fill(
text
// replace all line break by a hardline
.split('\n')
.map(
(
l: string
): Array<string | doc.builders.Line | doc.builders.Hardline> => {
const splittedLine: Array<string | doc.builders.Line> = l
.trim()
// replace all spaces by a line, that will break only if it overflow thanks to the `fill` method
.split(' ')
.map((l): Array<string | doc.builders.Line> => [l, line])
.flat();

return [...splittedLine, hardline];
}
)
.flat()
);

if (!doIndent) {
return filledHeading;
}

return indent(filledHeading);
}

const gherkinAstPrinter: Printer<TypedGherkinNode<GherkinNode>> = {
printComment: (path, options) => {
const node = path.getValue();
Expand Down Expand Up @@ -457,7 +476,7 @@ const gherkinAstPrinter: Printer<TypedGherkinNode<GherkinNode>> = {
print: (path, options, print) => {
const node = path.getValue();

// console.log({ node, isDocument: node instanceof TypedGherkinDocument });
// console.log(node);

if (node instanceof TypedGherkinDocument) {
// console.log(node)
Expand All @@ -478,11 +497,11 @@ const gherkinAstPrinter: Printer<TypedGherkinNode<GherkinNode>> = {
? ['# language: ' + node.language, printHardline()]
: '',
printTags(path, node),
`${node.keyword}: ${node.name}`,
printNodeHeading(node),

indent([
printHardline(),
printDescription(path, node, true),
printDescription(node, true),

// @ts-expect-error TODO path should be recognized as an AstPath<TypedFeature>
join(printTwoHardlines(), path.map(print, 'children')),
Expand All @@ -502,7 +521,6 @@ const gherkinAstPrinter: Printer<TypedGherkinNode<GherkinNode>> = {
// @ts-expect-error TODO path should be recognized as an AstPath<TypedFeatureChild>
return path.call(print, 'rule');
} else {
console.log(node);
throw new Error(
`unhandled case where ${
node instanceof TypedFeatureChild
Expand All @@ -516,24 +534,24 @@ const gherkinAstPrinter: Printer<TypedGherkinNode<GherkinNode>> = {
} else if (node instanceof TypedBackground) {
// console.log(node.steps);
return [
`${node.keyword}: ${node.name}`,
printNodeHeading(node),
node.description || node.steps.length > 0
? indent([
printHardline(),
printDescription(path, node, false),
printDescription(node, false),
// @ts-expect-error TODO path should be recognized as an AstPath<TypedBackground>
join(printHardline(), path.map(print, 'steps')),
path.map(print, 'steps'),
])
: '',
];
} else if (node instanceof TypedScenario) {
// console.log(node);
return [
printTags(path, node),
`${node.keyword}: ${node.name}`,
printNodeHeading(node),
indent([
printHardline(),
printDescription(path, node, false),
printDescription(node, false),

// @ts-expect-error TODO path should be recognized as an AstPath<TypedScenario>
join(printHardline(), path.map(print, 'steps')),
Expand Down Expand Up @@ -591,11 +609,11 @@ const gherkinAstPrinter: Printer<TypedGherkinNode<GherkinNode>> = {

return [
printTags(path, node),
`${node.keyword}: ${node.name}`,
printNodeHeading(node),

indent([
printHardline(),
printDescription(path, node, false),
printDescription(node, false),
join(
printHardline(),
[
Expand Down Expand Up @@ -636,22 +654,30 @@ const gherkinAstPrinter: Printer<TypedGherkinNode<GherkinNode>> = {
if (node instanceof TypedDocString) {
const { content, mediaType } = node;

return async (textToDoc): Promise<Doc|undefined> => {
let doc : doc.builders.Doc | null = null;
return async (textToDoc): Promise<Doc | undefined> => {
let doc: doc.builders.Doc | null = null;

if (mediaType) {
// try applying the prettier parser for the media type
doc = await textToDoc(content, { ...options, parser: mediaType }).catch(() => null);
doc = await textToDoc(content, {
...options,
parser: mediaType,
}).catch(() => null);

// if the parser failed for xml, try with the html parser
if (!doc && mediaType === 'xml') {
doc = await textToDoc(content, { ...options, parser: 'html' }).catch(() => null);
doc = await textToDoc(content, {
...options,
parser: 'html',
}).catch(() => null);
}
}

// try applying the json parser
if (!doc) {
doc = await textToDoc(content, { ...options, parser: 'json' }).catch(() => null);
doc = await textToDoc(content, { ...options, parser: 'json' }).catch(
() => null
);
}

if (doc) {
Expand Down
Loading

0 comments on commit 99e9b7e

Please sign in to comment.