Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit a0d6fa1

Browse files
daveweijDave-Weijtuncb
authored
Issue #25: Do not sort intermediate uses sections (#37)
* Only consider uses sections that follow and implementation, interface or program definition. * Allow for comment blocks before uses section. * fix spaces * add more specific tests for matching only whole 'uses' keyword * switch to ES2022 * fix tests: * close opened editors * run each test sequentially as we are interacting with the "active" editor of vscode * fix test * remove uses keyword in the comment, there is a bug affecting the process. * update version --------- Co-authored-by: Dave.Weij <Dave.Weij@bentley.com> Co-authored-by: Tunç Bahçecioğlu <tunc.bahcecioglu@gmail.com>
1 parent 5eb523f commit a0d6fa1

File tree

7 files changed

+194
-60
lines changed

7 files changed

+194
-60
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "pascal-uses-formatter",
33
"displayName": "pascal-uses-formatter",
44
"description": "sorts the uses section in pascal files",
5-
"version": "0.3.2",
5+
"version": "0.3.3",
66
"publisher": "tuncb",
77
"repository": "https://github.com/tuncb/delphi-uses-formatter",
88
"license": "Apache-2.0",

src/test/suite/extension.test.ts

+13-11
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,29 @@
1-
import { assert } from 'chai';
1+
import { assert, expect } from 'chai';
22
import { before } from 'mocha';
33
import * as path from 'path';
44
import * as vscode from 'vscode';
55
import glob = require('glob');
66

77
const findCorrectFileName = (originalFileName: string) => {
88
const originalPos = originalFileName.lastIndexOf('.original');
9-
return `${originalFileName.substr(0, originalPos)}.correct.test.pas`;
9+
return `${originalFileName.substring(0, originalPos)}.correct.test.pas`;
1010
};
1111

1212
interface ITestPairDoc {
1313
originalDoc: vscode.TextDocument;
1414
correctDoc: vscode.TextDocument;
1515
}
1616

17-
const openTextDocument = async (fileName: string): Promise<vscode.TextDocument> => {
18-
return Promise.resolve(vscode.workspace.openTextDocument(fileName));
19-
};
20-
2117
const openTestPair = async (originalFileName: string, correctFileName: string): Promise<ITestPairDoc> => {
22-
const originalDoc = await openTextDocument(originalFileName);
23-
const correctDoc = await openTextDocument(correctFileName);
18+
const originalDoc = await vscode.workspace.openTextDocument(originalFileName);
19+
const correctDoc = await vscode.workspace.openTextDocument(correctFileName);
2420

25-
return {originalDoc, correctDoc};
21+
return { originalDoc, correctDoc };
2622
};
2723

2824
const testFile = async (originalFileName: string): Promise<void> => {
2925
const correctFileName = findCorrectFileName(originalFileName);
26+
console.log(originalFileName, correctFileName);
3027
const testPair = await openTestPair(originalFileName, correctFileName);
3128
await vscode.window.showTextDocument(testPair.originalDoc);
3229

@@ -39,7 +36,10 @@ const testFile = async (originalFileName: string): Promise<void> => {
3936
const changedText = testPair.originalDoc.getText();
4037
const correctDoc = testPair.correctDoc.getText();
4138

42-
assert.ok(correctDoc === changedText);
39+
expect(changedText).to.equal(correctDoc);
40+
41+
await vscode.commands.executeCommand('workbench.action.revertAndCloseActiveEditor');
42+
await vscode.commands.executeCommand('workbench.action.closeAllEditors');
4343
};
4444

4545
suite('Extension Test Suite', () => {
@@ -50,6 +50,8 @@ suite('Extension Test Suite', () => {
5050
test('Conversion tests', async () => {
5151
const fileGlob = path.resolve(__dirname, '../../../testExamples', '*.original.test.pas');
5252
const files = glob.sync(fileGlob);
53-
return Promise.all(files.map(testFile));
53+
for (const file of files) {
54+
await testFile(file);
55+
}
5456
});
5557
});

src/test/suite/usesFormatter.test.ts

+26-7
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { formatText, ITextSection } from '../../usesFormatter';
22

33
var expect = require('chai').expect;
4-
var {describe, it} = require('mocha');
4+
var { describe, it } = require('mocha');
55

66
interface ITestInput {
77
text: string;
@@ -22,7 +22,7 @@ const sampleTexts: TestSample[] = [
2222
output: [
2323
{
2424
startOffset: 0,
25-
endOffset:22,
25+
endOffset: 22,
2626
value: "uses\n a,\n b,\n c,\n d,\n e,\n f;"
2727
}
2828
],
@@ -35,26 +35,45 @@ const sampleTexts: TestSample[] = [
3535
output: [
3636
{
3737
startOffset: 0,
38-
endOffset:22,
38+
endOffset: 22,
3939
value: "uses\n c,\n f,\n a,\n b,\n d,\n e;"
4040
}
4141
],
4242
},
43+
{
44+
input: {
45+
text: "}uses d, c, b, e, f, a;",
46+
configurableSortingArray: ["c", "f"]
47+
},
48+
output: [
49+
{
50+
startOffset: 1,
51+
endOffset: 23,
52+
value: "uses\n c,\n f,\n a,\n b,\n d,\n e;"
53+
}
54+
],
55+
},
56+
{
57+
input: {
58+
text: "kuses d, c, b, e, f, a;",
59+
configurableSortingArray: ["c", "f"]
60+
},
61+
output: [],
62+
},
4363

4464
];
4565

46-
const test = (sample: TestSample): void =>
47-
{
66+
const test = (sample: TestSample): void => {
4867
const separator = " ";
4968
const lineEnd = "\n";
5069

5170
const replaces = formatText(sample.input.text, separator, lineEnd, sample.input.configurableSortingArray);
5271
expect(replaces).to.eql(sample.output);
5372
};
5473

55-
describe('UsesFormatter', function() {
74+
describe('UsesFormatter', function () {
5675
describe('formatText', function () {
57-
it('Expect correct replaceText for provided samples', function() {
76+
it('Expect correct replaceText for provided samples', function () {
5877
sampleTexts.forEach(test);
5978
});
6079
});

src/usesFormatter.ts

+19-20
Original file line numberDiff line numberDiff line change
@@ -4,42 +4,41 @@ export interface ITextSection {
44
value: string;
55
}
66

7-
const findUsesSections = (text: string): ITextSection[] => {
8-
const regex = /uses[\s\w.,]+;/g;
7+
const findUsesSections = (text: string): ITextSection[] => {
8+
const regex = /(?:^|[\s}])(uses[\s\w.,]+;)/gid;
99
const results: ITextSection[] = [];
1010
let match = null;
1111
while ((match = regex.exec(text)) !== null) {
1212
results.push({
13-
startOffset: match.index,
13+
startOffset: match.index + match[0].length - match[1].length,
1414
endOffset: match.index + match[0].length,
15-
value: match[0]
15+
value: match[1]
1616
});
1717
}
1818
return results;
1919
};
2020

21-
const parseUnits = (text:string): string[] => {
21+
const parseUnits = (text: string): string[] => {
2222
return text
2323
.substring(4, text.length - 1)
24-
.replace(/(\r\n\t|\n|\r\t|\s)/gm,"")
24+
.replace(/(\r\n\t|\n|\r\t|\s)/gm, "")
2525
.split(',');
2626
};
2727

28-
function formatUsesSection(units: string[], separator: string, lineEnd: string, configurableSortingArray: string[]): string
29-
{
28+
function formatUsesSection(units: string[], separator: string, lineEnd: string, configurableSortingArray: string[]): string {
3029
const sortFun = (a: string, b: string) => {
31-
for(let namespace of configurableSortingArray){
32-
let normalizedNamespace = namespace.toLowerCase();
33-
let normalizedA = a.trim().toLocaleLowerCase();
34-
let normalizedB = b.trim().toLocaleLowerCase();
35-
if(normalizedA.startsWith(normalizedNamespace) && !normalizedB.startsWith(normalizedNamespace)){
36-
return -1;
37-
}
38-
else if(!normalizedA.startsWith(normalizedNamespace) && normalizedB.startsWith(normalizedNamespace)){
39-
return 1;
40-
}
30+
for (let namespace of configurableSortingArray) {
31+
let normalizedNamespace = namespace.toLowerCase();
32+
let normalizedA = a.trim().toLocaleLowerCase();
33+
let normalizedB = b.trim().toLocaleLowerCase();
34+
if (normalizedA.startsWith(normalizedNamespace) && !normalizedB.startsWith(normalizedNamespace)) {
35+
return -1;
36+
}
37+
else if (!normalizedA.startsWith(normalizedNamespace) && normalizedB.startsWith(normalizedNamespace)) {
38+
return 1;
39+
}
4140
}
42-
return a.localeCompare(b, undefined, {sensitivity: 'base'});
41+
return a.localeCompare(b, undefined, { sensitivity: 'base' });
4342
};
4443

4544
const formattedUnits = units.sort(sortFun).join(`,${lineEnd}${separator}`);
@@ -51,7 +50,7 @@ export function formatText(text: string, separator: string, lineEnd: string, con
5150
return {
5251
startOffset: section.startOffset,
5352
endOffset: section.endOffset,
54-
value: formatUsesSection(parseUnits(section.value), separator, lineEnd, configurableSortingArray)
53+
value: formatUsesSection(parseUnits(section.value), separator, lineEnd, configurableSortingArray)
5554
};
5655
});
5756
}

testExamples/ex2.correct.test.pas

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
unit ex2;
2+
3+
interface
4+
5+
uses
6+
b,
7+
c,
8+
f,
9+
f,
10+
g,
11+
h,
12+
k,
13+
l,
14+
t,
15+
u,
16+
y;
17+
18+
// will not be sorted due to extra k in front
19+
implementation
20+
kuses
21+
b,
22+
c,
23+
f,
24+
f,
25+
z,
26+
g,
27+
h,
28+
k,
29+
l,
30+
t,
31+
u,
32+
y;
33+
34+
{ Will be sorted, uses is preceded by comment block or compiler directive
35+
}uses
36+
Generics.Collections.patched,
37+
MemoryGuard,
38+
Optional,
39+
ProjectDB.DelphiFacade.FacadeManagedDataView,
40+
ProjectDB.DelphiFacade.FacadeManagedDataViewFactory,
41+
ProjectDB.DelphiFacade.FMDMeshEntityComponentData,
42+
ProjectDB.DelphiFacade.FMDMeshEntityResultData,
43+
ProjectDB.DelphiFacade.FMDNodeCoordinates,
44+
ProjectDB.DelphiFacade.FMOMesh,
45+
ProjectDB.DelphiFacade.FMOMeshEntity,
46+
ProjectDB.DelphiFacade.FMOMeshEntityPhasesState,
47+
ProjectDB.DelphiFacade.FMOPhase,
48+
ProjectDB.DelphiFacade.FMOStep,
49+
System.SysUtils,
50+
Xvtkwc.DataArray,
51+
Xvtkwc.Definitions,
52+
Xvtkwc.DllLoader,
53+
Xvtkwc.Piece,
54+
Xvtkwc.PvdItem,
55+
Xvtkwc.Writer;
56+
57+
end.

testExamples/ex2.original.test.pas

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
unit ex2;
2+
3+
interface
4+
5+
uses
6+
b,
7+
c,
8+
f,
9+
f,
10+
g,
11+
h,
12+
k,
13+
l,
14+
t,
15+
u,
16+
y;
17+
18+
// will not be sorted due to extra k in front
19+
implementation
20+
kuses
21+
b,
22+
c,
23+
f,
24+
f,
25+
z,
26+
g,
27+
h,
28+
k,
29+
l,
30+
t,
31+
u,
32+
y;
33+
34+
{ Will be sorted, uses is preceded by comment block or compiler directive
35+
}uses
36+
ProjectDB.DelphiFacade.FMDMeshEntityResultData,
37+
ProjectDB.DelphiFacade.FMDNodeCoordinates,
38+
ProjectDB.DelphiFacade.FMOMesh,
39+
ProjectDB.DelphiFacade.FMOMeshEntity,
40+
ProjectDB.DelphiFacade.FMOMeshEntityPhasesState,
41+
ProjectDB.DelphiFacade.FMOPhase,
42+
ProjectDB.DelphiFacade.FMOStep,
43+
ProjectDB.DelphiFacade.FacadeManagedDataView,
44+
ProjectDB.DelphiFacade.FacadeManagedDataViewFactory,
45+
System.SysUtils,
46+
Xvtkwc.DataArray,
47+
Xvtkwc.Definitions,
48+
Xvtkwc.DllLoader,
49+
Generics.Collections.patched,
50+
MemoryGuard,
51+
Optional,
52+
ProjectDB.DelphiFacade.FMDMeshEntityComponentData,
53+
Xvtkwc.Piece,
54+
Xvtkwc.PvdItem,
55+
Xvtkwc.Writer;
56+
57+
end.

tsconfig.json

+21-21
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
{
2-
"compilerOptions": {
3-
"module": "commonjs",
4-
"target": "es6",
5-
"outDir": "out",
6-
"lib": [
7-
"es6"
8-
],
9-
"sourceMap": true,
10-
"rootDir": "src",
11-
/* Strict Type-Checking Option */
12-
"strict": true, /* enable all strict type-checking options */
13-
/* Additional Checks */
14-
"noUnusedLocals": true /* Report errors on unused locals. */
15-
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
16-
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
17-
// "noUnusedParameters": true, /* Report errors on unused parameters. */
18-
},
19-
"exclude": [
20-
"node_modules",
21-
".vscode-test"
22-
]
2+
"compilerOptions": {
3+
"module": "commonjs",
4+
"target": "ES2022",
5+
"outDir": "out",
6+
"lib": [
7+
"ES2022"
8+
],
9+
"sourceMap": true,
10+
"rootDir": "src",
11+
/* Strict Type-Checking Option */
12+
"strict": true, /* enable all strict type-checking options */
13+
/* Additional Checks */
14+
"noUnusedLocals": true /* Report errors on unused locals. */
15+
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
16+
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
17+
// "noUnusedParameters": true, /* Report errors on unused parameters. */
18+
},
19+
"exclude": [
20+
"node_modules",
21+
".vscode-test"
22+
]
2323
}

0 commit comments

Comments
 (0)