8000 feat(kernel): support `prePrecess(): { text, ast }` return value · textlint/textlint@16301d7 · GitHub
[go: up one dir, main page]

Skip to content

Commit 16301d7

Browse files
committed
feat(kernel): support prePrecess(): { text, ast } return value
- Add test for binary plugin that return dummy text and dummy ast instead of a single ast
1 parent db56bc4 commit 16301d7

File tree

8 files changed

+199
-6
lines changed

8 files changed

+199
-6
lines changed

packages/@textlint/kernel/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
"test": "mocha \"test/**/*.{js,ts}\""
3333
},
3434
"dependencies": {
35+
"@textlint/ast-tester": "^2.1.6",
3536
"@textlint/ast-node-types": "^4.2.5",
3637
"@textlint/ast-traverse": "^2.1.6",
3738
"@textlint/feature-flag": "^3.1.5",

packages/@textlint/kernel/src/descriptor/plugin-creator-helper.ts

Whitespace-only changes.

packages/@textlint/kernel/src/fixer/fixer-processor.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { TextlintKernelConstructorOptions } from "../textlint-kernel-interface";
1010
import MessageProcessManager from "../messages/MessageProcessManager";
1111
import { TextlintFilterRuleDescriptors, TextlintRuleDescriptors } from "../descriptor";
1212
import { TextlintSourceCodeImpl } from "../context/TextlintSourceCodeImpl";
13+
import { isTxtAST } from "@textlint/ast-tester";
1314

1415
const debug = require("debug")("textlint:fixer-processor");
1516

@@ -66,9 +67,13 @@ export default class FixerProcessor {
6667
const fixerProcessList = ruleDescriptors.fixableDescriptors.map(ruleDescriptor => {
6768
return (sourceText: string): Promise<string> => {
6869
// create new SourceCode object
70+
const preProcessResult = preProcess(sourceText, sourceCode.filePath);
71+
const isPluginReturnAnAST = isTxtAST(preProcessResult);
72+
const textForAST = isPluginReturnAnAST ? sourceText : preProcessResult.text;
73+
const ast = isPluginReturnAnAST ? preProcessResult : preProcessResult.ast;
6974
const newSourceCode = new TextlintSourceCodeImpl({
70-
text: sourceText,
71-
ast: preProcess(sourceText, sourceCode.filePath),
75+
text: textForAST,
76+
ast,
7277
filePath: resultFilePath,
7378
ext: sourceCode.ext
7479
});

packages/@textlint/kernel/src/textlint-kernel.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ import { TextlintKernelConstructorOptions, TextlintKernelOptions } from "./textl
1515
import { TextlintFixResult, TextlintResult } from "@textlint/types";
1616
import { TextlintKernelDescriptor } from "./descriptor";
1717
import { TextlintSourceCodeImpl } from "./context/TextlintSourceCodeImpl";
18+
import { isTxtAST } from "@textlint/ast-tester";
1819

1920
const debug = require("debug")("textlint:kernel");
21+
2022
/**
2123
* add fileName to trailing of error message
2224
* @param {string|undefined} fileName
@@ -138,9 +140,12 @@ export class TextlintKernel {
138140
typeof preProcess === "function" && typeof postProcess === "function",
139141
"processor should implements {preProcess, postProcess}"
140142
);
141-
const ast = preProcess(text, filePath);
143+
const preProcessResult = preProcess(text, filePath);
144+
const isPluginReturnAnAST = isTxtAST(preProcessResult);
145+
const textForAST = isPluginReturnAnAST ? text : preProcessResult.text;
146+
const ast = isPluginReturnAnAST ? preProcessResult : preProcessResult.ast;
142147
const sourceCode = new TextlintSourceCodeImpl({
143-
text,
148+
text: textForAST,
144149
ast,
145150
ext,
146151
filePath
@@ -191,9 +196,12 @@ export class TextlintKernel {
191196
typeof preProcess === "function" && typeof postProcess === "function",
192197
"processor should implements {preProcess, postProcess}"
193198
);
194-
const ast = preProcess(text, filePath);
199+
const preProcessResult = preProcess(text, filePath);
200+
const isPluginReturnAnAST = isTxtAST(preProcessResult);
201+
const textForAST = isPluginReturnAnAST ? text : preProcessResult.text;
202+
const ast = isPluginReturnAnAST ? preProcessResult : preProcessResult.ast;
195203
const sourceCode = new TextlintSourceCodeImpl({
196-
text,
204+
text: textForAST,
197205
ast,
198206
ext,
199207
filePath
Binary file not shown.
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// MIT © 2017 azu
2+
import { TextlintMessage } from "@textlint/kernel";
3+
import { TextlintPluginCreator, TextlintPluginProcessor } from "@textlint/types";
4+
5+
export interface BinaryPluginProcessorOptions {
6+
testOption: string;
7+
}
8+
9+
export interface CreateBinaryPluginOptions {
10+
extensions?: string[];
11+
pseudoText?: string;
12+
}
13+
14+
/**
15+
* Create Binary Plugin stub
16+
* It spy the assigned argument.
17+
* this plugin's preprocess return {text, ast}
18+
* https://github.com/textlint/textlint/issues/649
19+
*/
20+
export const createBinaryPluginStub = (options?: CreateBinaryPluginOptions) => {
21+
let assignedOptions: undefined | {};
22+
let processorArgs: {
23+
extension: string;
24+
};
25+
let preProcessArgs: {
26+
text: string;
27+
filePath: string;
28+
};
29+
let postProcessArgs: {
30+
messages: TextlintMessage[];
31+
filePath?: string;
32+
};
33+
return {
34+
getOptions() {
35+
return assignedOptions;
36+
},
37+
getProcessorArgs() {
38+
return processorArgs;
39+
},
40+
getPreProcessArgs() {
41+
return preProcessArgs;
42+
},
43+
getPostProcessArgs() {
44+
return postProcessArgs;
45+
},
46+
/**
47+
* Return plugin module
48+
*/
49+
get plugin(): TextlintPluginCreator {
50+
return {
51+
Processor: class MockBinaryPluginProcessor implements TextlintPluginProcessor {
52+
availableExtensions() {
53+
return (options && options.extensions) || [".out"];
54+
}
55+
56+
constructor(public options?: {}) {
57+
assignedOptions = options;
58+
}
59+
60+
processor(extension: string) {
61+
processorArgs = { extension };
62+
// use dummyText instead of binary
63+
// return { text, ast }
64+
return {
65+
preProcess(text: string, filePath: string) {
66+
preProcessArgs = { text, filePath };
67+
const dummyText = (options && options.pseudoText) || "this is binary";
68+
const ast = {
69+
type: "Document",
70+
raw: dummyText,
71+
range: [0, dummyText.length] as [number, number],
72+
loc: {
73+
start: {
74+
line: 1,
75+
column: 0
76+
},
77+
end: {
78+
line: 1,
79+
column: dummyText.length - 1
80+
}
81+
},
82+
children: [
83+
{
84+
type: "Str",
85+
value: dummyText,
86+
raw: dummyText,
87+
range: [0, dummyText.length] as [number, number],
88+
loc: {
89+
start: {
90+
line: 1,
91+
column: 0
92+
},
93+
end: {
94+
line: 1,
95+
column: dummyText.length - 1
96+
}
97+
}
98+
}
99+
]
100+
};
101+
return {
102+
text: dummyText,
103+
ast
104+
};
105+
},
106+
postProcess(messages: TextlintMessage[], filePath: string) {
107+
postProcessArgs = { messages, filePath };
108+
return {
109+
messages,
110+
filePath: filePath || "unknown"
111+
};
112+
}
113+
};
114+
}
115+
}
116+
};
117+
}
118+
};
119+
};

packages/@textlint/kernel/test/kernel-plugin-test.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,52 @@
11
import { createPluginStub } from "./helper/ExamplePlugin";
22
import { errorRule } from "./helper/ErrorRule";
33
import { TextlintKernel } from "../src";
4+
import * as path from "path";
45
import * as assert from "assert";
6+
import { createBinaryPluginStub } from "./helper/BinaryPlugin";
7+
import { TextlintRuleReporter } from "@textlint/types";
58

69
describe("kernel-plugin", () => {
10+
describe("binary plugin", () => {
11+
it("should get dummyText via context.getSource", () => {
12+
const kernel = new TextlintKernel();
13+
const expectedSourceText = "This is binary";
14+
const binaryFilePath = path.join(__dirname, "fixtures/binary/a.out");
15+
const { plugin } = createBinaryPluginStub({
16+
// return pseudoText instead of binary content as preProcess result
17+
pseudoText: expectedSourceText
18+
});
19+
let isStrCalled = false;
20+
const rule: TextlintRuleReporter = context => {
21+
const { Syntax, getSource, getFilePath } = context;
22+
return {
23+
[Syntax.Str](node) {
24+
const text = getSource(node);
25+
const marginText = getSource(node, -1, -1);
26+
assert.strictEqual(text, expectedSourceText);
27+
assert.strictEqual(marginText, expectedSourceText.slice(1, expectedSourceText.length - 1));
28+
const filePath = getFilePath();
29+
assert.strictEqual(filePath, binaryFilePath);
30+
isStrCalled = true;
31+
}
32+
};
33+
};
34+
const options = {
35+
filePath: binaryFilePath,
36+
ext: ".out",
37+
plugins: [{ pluginId: "binary", plugin: plugin }],
38+
rules: [
39+
{
40+
ruleId: "error",
41+
rule: rule
42+
}
43+
]
44+
};
45+
return kernel.lintText("text", options).then(_result => {
46+
assert.ok(isStrCalled);
47+
});
48+
});
49+
});
750
describe("#constructor", () => {
851
it("should receive {} by default", () => {
952
const kernel = new TextlintKernel();
@@ -81,6 +124,21 @@ describe("kernel-plugin", () => {
81124
assert.strictEqual(getPreProcessArgs().filePath, options.filePath);
82125
});
83126
});
127+
it("preProcess can return {text, ast}", () => {
128+
const kernel = new TextlintKernel();
129+
const { plugin, getPreProcessArgs } = createBinaryPluginStub();
130+
const options = {
131+
filePath: path.join(__dirname, "fixtures/binary/a.out"),
132+
ext: ".out",
133+
plugins: [{ pluginId: "example", plugin: plugin }],
134+
rules: [{ ruleId: "error", rule: errorRule }]
135+
};
136+
const text = "text";
137+
return kernel.lintText(text, options).then(_result => {
138+
assert.strictEqual(getPreProcessArgs().text, text);
139+
assert.strictEqual(getPreProcessArgs().filePath, options.filePath);
140+
});
141+
});
84142
});
85143
describe("#postProcess", () => {
86144
it("preProcess should be called with messages and filePath", () => {

packages/textlint/test/pluguins/fixtures/example-plugin.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ export class ExampleProcessor {
1414
return {
1515
type: "Document",
1616
children: [],
17+
value: "",
18+
raw: "",
1719
range: [0, 0],
1820
loc: {
1921
start: {

0 commit comments

Comments
 (0)
0