gurkencheck 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +115 -3
- package/dist/exit-codes.d.ts +10 -0
- package/dist/exit-codes.d.ts.map +1 -0
- package/dist/exit-codes.js +10 -0
- package/dist/exit-codes.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +12 -6
- package/dist/main.js.map +1 -1
- package/dist/stats/collect.d.ts +23 -0
- package/dist/stats/collect.d.ts.map +1 -0
- package/dist/stats/collect.js +219 -0
- package/dist/stats/collect.js.map +1 -0
- package/dist/stats/command.d.ts +3 -0
- package/dist/stats/command.d.ts.map +1 -0
- package/dist/stats/command.js +113 -0
- package/dist/stats/command.js.map +1 -0
- package/dist/stats/format/index.d.ts +25 -0
- package/dist/stats/format/index.d.ts.map +1 -0
- package/dist/stats/format/index.js +25 -0
- package/dist/stats/format/index.js.map +1 -0
- package/dist/stats/format/json.d.ts +10 -0
- package/dist/stats/format/json.d.ts.map +1 -0
- package/dist/stats/format/json.js +5 -0
- package/dist/stats/format/json.js.map +1 -0
- package/dist/stats/format/markdown.d.ts +8 -0
- package/dist/stats/format/markdown.d.ts.map +1 -0
- package/dist/stats/format/markdown.js +123 -0
- package/dist/stats/format/markdown.js.map +1 -0
- package/dist/stats/format/shared.d.ts +34 -0
- package/dist/stats/format/shared.d.ts.map +1 -0
- package/dist/stats/format/shared.js +37 -0
- package/dist/stats/format/shared.js.map +1 -0
- package/dist/stats/format/text.d.ts +5 -0
- package/dist/stats/format/text.d.ts.map +1 -0
- package/dist/stats/format/text.js +175 -0
- package/dist/stats/format/text.js.map +1 -0
- package/dist/stats/index.d.ts +21 -0
- package/dist/stats/index.d.ts.map +1 -0
- package/dist/stats/index.js +17 -0
- package/dist/stats/index.js.map +1 -0
- package/dist/stats/normalise.d.ts +38 -0
- package/dist/stats/normalise.d.ts.map +1 -0
- package/dist/stats/normalise.js +65 -0
- package/dist/stats/normalise.js.map +1 -0
- package/dist/stats/similar.d.ts +61 -0
- package/dist/stats/similar.d.ts.map +1 -0
- package/dist/stats/similar.js +173 -0
- package/dist/stats/similar.js.map +1 -0
- package/dist/stats/types.d.ts +159 -0
- package/dist/stats/types.d.ts.map +1 -0
- package/dist/stats/types.js +10 -0
- package/dist/stats/types.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.js","sourceRoot":"","sources":["../../../src/stats/format/text.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Statistics: what is in a set of feature files, rather than what is wrong
|
|
3
|
+
* with them.
|
|
4
|
+
*
|
|
5
|
+
* ```ts
|
|
6
|
+
* import {collectStatistics, readAndParseFile, toText} from 'gurkencheck';
|
|
7
|
+
*
|
|
8
|
+
* const parsed = await Promise.all(files.map((file) => readAndParseFile(file)));
|
|
9
|
+
* console.log(toText(collectStatistics(parsed), {top: 10}));
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
export { collectStatistics, distribution } from './collect.ts';
|
|
13
|
+
export type { CollectOptions } from './collect.ts';
|
|
14
|
+
export { DEFAULT_SIMILARITY, boundedEditDistance, groupSimilar } from './similar.ts';
|
|
15
|
+
export type { SimilarityOptions } from './similar.ts';
|
|
16
|
+
export { NUMBER_MARKER, PLACEHOLDER_MARKER, STRING_MARKER, countWords, normaliseStepText, } from './normalise.ts';
|
|
17
|
+
export { DEFAULT_STATS_FORMAT, DEFAULT_TOP, STATS_FORMATTERS, getStatsFormatter, toJson as statisticsToJson, toMarkdown, toText, } from './format/index.ts';
|
|
18
|
+
export type { StatsFormatOptions, StatsFormatter } from './format/index.ts';
|
|
19
|
+
export { runStats, statsUsage } from './command.ts';
|
|
20
|
+
export type * from './types.ts';
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/stats/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAC,iBAAiB,EAAE,YAAY,EAAC,MAAM,cAAc,CAAC;AAC7D,YAAY,EAAC,cAAc,EAAC,MAAM,cAAc,CAAC;AACjD,OAAO,EAAC,kBAAkB,EAAE,mBAAmB,EAAE,YAAY,EAAC,MAAM,cAAc,CAAC;AACnF,YAAY,EAAC,iBAAiB,EAAC,MAAM,cAAc,CAAC;AACpD,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,UAAU,EACV,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,oBAAoB,EACpB,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,MAAM,IAAI,gBAAgB,EAC1B,UAAU,EACV,MAAM,GACP,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAC,kBAAkB,EAAE,cAAc,EAAC,MAAM,mBAAmB,CAAC;AAC1E,OAAO,EAAC,QAAQ,EAAE,UAAU,EAAC,MAAM,cAAc,CAAC;AAClD,mBAAmB,YAAY,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Statistics: what is in a set of feature files, rather than what is wrong
|
|
3
|
+
* with them.
|
|
4
|
+
*
|
|
5
|
+
* ```ts
|
|
6
|
+
* import {collectStatistics, readAndParseFile, toText} from 'gurkencheck';
|
|
7
|
+
*
|
|
8
|
+
* const parsed = await Promise.all(files.map((file) => readAndParseFile(file)));
|
|
9
|
+
* console.log(toText(collectStatistics(parsed), {top: 10}));
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
export { collectStatistics, distribution } from './collect.js';
|
|
13
|
+
export { DEFAULT_SIMILARITY, boundedEditDistance, groupSimilar } from './similar.js';
|
|
14
|
+
export { NUMBER_MARKER, PLACEHOLDER_MARKER, STRING_MARKER, countWords, normaliseStepText, } from './normalise.js';
|
|
15
|
+
export { DEFAULT_STATS_FORMAT, DEFAULT_TOP, STATS_FORMATTERS, getStatsFormatter, toJson as statisticsToJson, toMarkdown, toText, } from './format/index.js';
|
|
16
|
+
export { runStats, statsUsage } from './command.js';
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/stats/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAC,iBAAiB,EAAE,YAAY,EAAC,MAAM,cAAc,CAAC;AAE7D,OAAO,EAAC,kBAAkB,EAAE,mBAAmB,EAAE,YAAY,EAAC,MAAM,cAAc,CAAC;AAEnF,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,UAAU,EACV,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,oBAAoB,EACpB,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,MAAM,IAAI,gBAAgB,EAC1B,UAAU,EACV,MAAM,GACP,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAC,QAAQ,EAAE,UAAU,EAAC,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deciding when two steps are the same step.
|
|
3
|
+
*
|
|
4
|
+
* `I have 3 items in my cart` and `I have 7 items in my cart` are one step
|
|
5
|
+
* behind one step definition, and counting them as two would make every
|
|
6
|
+
* measure of reuse meaningless. So the parts a step definition captures as
|
|
7
|
+
* arguments - numbers, quoted strings, Scenario Outline placeholders - are
|
|
8
|
+
* replaced by a marker before two steps are compared.
|
|
9
|
+
*
|
|
10
|
+
* The keyword is not part of the text: the Gherkin parser hands it over
|
|
11
|
+
* separately, and `Given I am logged in` and `And I am logged in` are the
|
|
12
|
+
* same step written in two places.
|
|
13
|
+
*
|
|
14
|
+
* Each kind of argument keeps a marker of its own, so a placeholder and a
|
|
15
|
+
* value written in its place stay apart: `I have <count> items` does not
|
|
16
|
+
* become `I have 0 items`. That understates reuse a little in an outline
|
|
17
|
+
* heavy suite, and it is the trade worth making, because the normalised text
|
|
18
|
+
* is what the report shows a reader - and a `0` in a step that has no number
|
|
19
|
+
* in it would be a lie about the file. The two are put back together by the
|
|
20
|
+
* near-duplicate report in `similar.ts`, which is a couple of edits apart.
|
|
21
|
+
*/
|
|
22
|
+
/** Stands in for a Scenario Outline placeholder, whatever it was called. */
|
|
23
|
+
export declare const PLACEHOLDER_MARKER = "<>";
|
|
24
|
+
/** Stands in for a double quoted string, whatever it contained. */
|
|
25
|
+
export declare const STRING_MARKER = "\"\"";
|
|
26
|
+
/** Stands in for a number, whatever its value. */
|
|
27
|
+
export declare const NUMBER_MARKER = "0";
|
|
28
|
+
/**
|
|
29
|
+
* The form of a step text used to decide whether two steps are the same one.
|
|
30
|
+
*
|
|
31
|
+
* Single quotes are deliberately left alone: `the user's cart is 'empty'` has
|
|
32
|
+
* three of them, and a rule masking whatever sits between a pair would eat
|
|
33
|
+
* half the sentence. Cucumber's own expressions quote with `"` anyway.
|
|
34
|
+
*/
|
|
35
|
+
export declare function normaliseStepText(text: string): string;
|
|
36
|
+
/** How many words a step is made of, counted before normalisation. */
|
|
37
|
+
export declare function countWords(text: string): number;
|
|
38
|
+
//# sourceMappingURL=normalise.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalise.d.ts","sourceRoot":"","sources":["../../src/stats/normalise.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,4EAA4E;AAC5E,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAEvC,mEAAmE;AACnE,eAAO,MAAM,aAAa,SAAO,CAAC;AAElC,kDAAkD;AAClD,eAAO,MAAM,aAAa,MAAM,CAAC;AAiBjC;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAatD;AAED,sEAAsE;AACtE,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG/C"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deciding when two steps are the same step.
|
|
3
|
+
*
|
|
4
|
+
* `I have 3 items in my cart` and `I have 7 items in my cart` are one step
|
|
5
|
+
* behind one step definition, and counting them as two would make every
|
|
6
|
+
* measure of reuse meaningless. So the parts a step definition captures as
|
|
7
|
+
* arguments - numbers, quoted strings, Scenario Outline placeholders - are
|
|
8
|
+
* replaced by a marker before two steps are compared.
|
|
9
|
+
*
|
|
10
|
+
* The keyword is not part of the text: the Gherkin parser hands it over
|
|
11
|
+
* separately, and `Given I am logged in` and `And I am logged in` are the
|
|
12
|
+
* same step written in two places.
|
|
13
|
+
*
|
|
14
|
+
* Each kind of argument keeps a marker of its own, so a placeholder and a
|
|
15
|
+
* value written in its place stay apart: `I have <count> items` does not
|
|
16
|
+
* become `I have 0 items`. That understates reuse a little in an outline
|
|
17
|
+
* heavy suite, and it is the trade worth making, because the normalised text
|
|
18
|
+
* is what the report shows a reader - and a `0` in a step that has no number
|
|
19
|
+
* in it would be a lie about the file. The two are put back together by the
|
|
20
|
+
* near-duplicate report in `similar.ts`, which is a couple of edits apart.
|
|
21
|
+
*/
|
|
22
|
+
/** Stands in for a Scenario Outline placeholder, whatever it was called. */
|
|
23
|
+
export const PLACEHOLDER_MARKER = '<>';
|
|
24
|
+
/** Stands in for a double quoted string, whatever it contained. */
|
|
25
|
+
export const STRING_MARKER = '""';
|
|
26
|
+
/** Stands in for a number, whatever its value. */
|
|
27
|
+
export const NUMBER_MARKER = '0';
|
|
28
|
+
const PLACEHOLDER = /<[^<>]*>/gu;
|
|
29
|
+
const QUOTED = /"[^"]*"/gu;
|
|
30
|
+
/**
|
|
31
|
+
* A whole number or decimal standing on its own. The word boundaries keep
|
|
32
|
+
* `1st` and `v2` intact, where the digits are part of a name rather than a
|
|
33
|
+
* value a step definition would capture.
|
|
34
|
+
*/
|
|
35
|
+
const NUMBER = /\b\d+(?:[.,]\d+)*\b/gu;
|
|
36
|
+
const WHITESPACE = /\s+/gu;
|
|
37
|
+
/** A full stop or exclamation mark at the end, which changes nothing. */
|
|
38
|
+
const TRAILING_PUNCTUATION = /[\s.!]*[.!]$/u;
|
|
39
|
+
/**
|
|
40
|
+
* The form of a step text used to decide whether two steps are the same one.
|
|
41
|
+
*
|
|
42
|
+
* Single quotes are deliberately left alone: `the user's cart is 'empty'` has
|
|
43
|
+
* three of them, and a rule masking whatever sits between a pair would eat
|
|
44
|
+
* half the sentence. Cucumber's own expressions quote with `"` anyway.
|
|
45
|
+
*/
|
|
46
|
+
export function normaliseStepText(text) {
|
|
47
|
+
return text
|
|
48
|
+
.replace(PLACEHOLDER, PLACEHOLDER_MARKER)
|
|
49
|
+
.replace(QUOTED, STRING_MARKER)
|
|
50
|
+
.replace(NUMBER, NUMBER_MARKER)
|
|
51
|
+
.toLowerCase()
|
|
52
|
+
.replace(WHITESPACE, ' ')
|
|
53
|
+
.trim()
|
|
54
|
+
// Whatever sat in front of the full stop goes with it: `I own it .` and
|
|
55
|
+
// `I own it` are one step, and a step text ending in a space is not one
|
|
56
|
+
// anybody would recognise in the report.
|
|
57
|
+
.replace(TRAILING_PUNCTUATION, '')
|
|
58
|
+
.trim();
|
|
59
|
+
}
|
|
60
|
+
/** How many words a step is made of, counted before normalisation. */
|
|
61
|
+
export function countWords(text) {
|
|
62
|
+
const trimmed = text.trim();
|
|
63
|
+
return trimmed === '' ? 0 : trimmed.split(WHITESPACE).length;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=normalise.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalise.js","sourceRoot":"","sources":["../../src/stats/normalise.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,4EAA4E;AAC5E,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEvC,mEAAmE;AACnE,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC;AAElC,kDAAkD;AAClD,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,CAAC;AAEjC,MAAM,WAAW,GAAG,YAAY,CAAC;AACjC,MAAM,MAAM,GAAG,WAAW,CAAC;AAE3B;;;;GAIG;AACH,MAAM,MAAM,GAAG,uBAAuB,CAAC;AAEvC,MAAM,UAAU,GAAG,OAAO,CAAC;AAE3B,yEAAyE;AACzE,MAAM,oBAAoB,GAAG,eAAe,CAAC;AAE7C;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,IAAI;SACR,OAAO,CAAC,WAAW,EAAE,kBAAkB,CAAC;SACxC,OAAO,CAAC,MAAM,EAAE,aAAa,CAAC;SAC9B,OAAO,CAAC,MAAM,EAAE,aAAa,CAAC;SAC9B,WAAW,EAAE;SACb,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC;SACxB,IAAI,EAAE;QACP,wEAAwE;QACxE,wEAAwE;QACxE,yCAAyC;SACxC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC;SACjC,IAAI,EAAE,CAAC;AACZ,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,OAAO,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC;AAC/D,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finding steps that are nearly, but not quite, the same step.
|
|
3
|
+
*
|
|
4
|
+
* `I am logged in` and `I'm logged in` are one behaviour written twice, and
|
|
5
|
+
* they cost two step definitions. Normalisation cannot join them - they
|
|
6
|
+
* really are different sentences - so they are grouped by how many single
|
|
7
|
+
* character edits it takes to turn one into the other.
|
|
8
|
+
*
|
|
9
|
+
* Edit distance is quadratic in the number of distinct steps, which on a
|
|
10
|
+
* large suite is millions of comparisons, so two cheap tests run first. Both
|
|
11
|
+
* are lower bounds on the distance, never overestimates, so a pair they
|
|
12
|
+
* reject could not have been close enough anyway:
|
|
13
|
+
*
|
|
14
|
+
* - two strings are at least as far apart as their lengths differ;
|
|
15
|
+
* - every edit changes the tally of characters by at most two, so half the
|
|
16
|
+
* difference between two tallies is a floor on the distance as well.
|
|
17
|
+
*/
|
|
18
|
+
/** How alike two steps have to be before they are reported together. */
|
|
19
|
+
export interface SimilarityOptions {
|
|
20
|
+
/**
|
|
21
|
+
* `1 - distance / length`, against the longer of the two steps. At 0.85 a
|
|
22
|
+
* forty character step may differ by six edits.
|
|
23
|
+
*/
|
|
24
|
+
ratio: number;
|
|
25
|
+
/**
|
|
26
|
+
* Steps shorter than this are left out. `I wait` and `I wait 0` are two
|
|
27
|
+
* edits apart, and at that length almost everything looks like everything.
|
|
28
|
+
*/
|
|
29
|
+
minLength: number;
|
|
30
|
+
/**
|
|
31
|
+
* Edits never allowed beyond, however long the steps are.
|
|
32
|
+
*
|
|
33
|
+
* The ratio on its own lets a long step drift a long way: six edits turn
|
|
34
|
+
* `the customer opens the order in bulk` into `the customer opens the cart
|
|
35
|
+
* in bulk`, which is a different step rather than the same one spelled two
|
|
36
|
+
* ways. What this report is for is the small differences - an apostrophe, a
|
|
37
|
+
* plural, a missing article - and three edits covers those.
|
|
38
|
+
*
|
|
39
|
+
* It is also what keeps the search quick: with a low cap two steps have to
|
|
40
|
+
* be within a few characters in length before they are compared at all.
|
|
41
|
+
*/
|
|
42
|
+
maxEdits: number;
|
|
43
|
+
}
|
|
44
|
+
export declare const DEFAULT_SIMILARITY: SimilarityOptions;
|
|
45
|
+
/**
|
|
46
|
+
* The Levenshtein distance between two strings, giving up as soon as it is
|
|
47
|
+
* certain to exceed `limit` and returning `limit + 1` in that case.
|
|
48
|
+
*
|
|
49
|
+
* Every value in a row of the table is a lower bound on everything below it,
|
|
50
|
+
* so once the whole row is past the limit there is no way back.
|
|
51
|
+
*/
|
|
52
|
+
export declare function boundedEditDistance(left: string, right: string, limit: number): number;
|
|
53
|
+
/**
|
|
54
|
+
* Groups entries whose text is close enough to be the same step written two
|
|
55
|
+
* ways. Entries that are close to nothing are left out, so every group
|
|
56
|
+
* returned has at least two members, in the order they were given in.
|
|
57
|
+
*/
|
|
58
|
+
export declare function groupSimilar<T extends {
|
|
59
|
+
text: string;
|
|
60
|
+
}>(entries: readonly T[], options?: SimilarityOptions): T[][];
|
|
61
|
+
//# sourceMappingURL=similar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"similar.d.ts","sourceRoot":"","sources":["../../src/stats/similar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,wEAAwE;AACxE,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;;;;;;OAWG;IACH,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,kBAAkB,EAAE,iBAA4D,CAAC;AAwC9F;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAsCtF;AAgCD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS;IAAC,IAAI,EAAE,MAAM,CAAA;CAAC,EACnD,OAAO,EAAE,SAAS,CAAC,EAAE,EACrB,OAAO,GAAE,iBAAsC,GAC9C,CAAC,EAAE,EAAE,CAsDP"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finding steps that are nearly, but not quite, the same step.
|
|
3
|
+
*
|
|
4
|
+
* `I am logged in` and `I'm logged in` are one behaviour written twice, and
|
|
5
|
+
* they cost two step definitions. Normalisation cannot join them - they
|
|
6
|
+
* really are different sentences - so they are grouped by how many single
|
|
7
|
+
* character edits it takes to turn one into the other.
|
|
8
|
+
*
|
|
9
|
+
* Edit distance is quadratic in the number of distinct steps, which on a
|
|
10
|
+
* large suite is millions of comparisons, so two cheap tests run first. Both
|
|
11
|
+
* are lower bounds on the distance, never overestimates, so a pair they
|
|
12
|
+
* reject could not have been close enough anyway:
|
|
13
|
+
*
|
|
14
|
+
* - two strings are at least as far apart as their lengths differ;
|
|
15
|
+
* - every edit changes the tally of characters by at most two, so half the
|
|
16
|
+
* difference between two tallies is a floor on the distance as well.
|
|
17
|
+
*/
|
|
18
|
+
export const DEFAULT_SIMILARITY = { ratio: 0.85, minLength: 8, maxEdits: 3 };
|
|
19
|
+
/** How many buckets the character tally uses. */
|
|
20
|
+
const TALLY_SIZE = 32;
|
|
21
|
+
/**
|
|
22
|
+
* A rough tally of the characters in a string.
|
|
23
|
+
*
|
|
24
|
+
* Characters share buckets, which can only make two tallies look more alike
|
|
25
|
+
* than they are - and since the tally is used to rule pairs out, looking more
|
|
26
|
+
* alike is the safe direction to be wrong in.
|
|
27
|
+
*/
|
|
28
|
+
function tally(text) {
|
|
29
|
+
const counts = new Array(TALLY_SIZE).fill(0);
|
|
30
|
+
for (let index = 0; index < text.length; index++) {
|
|
31
|
+
const bucket = text.charCodeAt(index) % TALLY_SIZE;
|
|
32
|
+
counts[bucket] = (counts[bucket] ?? 0) + 1;
|
|
33
|
+
}
|
|
34
|
+
return counts;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* True when two tallies are far enough apart that no run of `limit` edits
|
|
38
|
+
* could join the strings behind them.
|
|
39
|
+
*
|
|
40
|
+
* This is the test almost every pair fails, so it stops as soon as the answer
|
|
41
|
+
* is settled rather than finishing the count.
|
|
42
|
+
*/
|
|
43
|
+
function tallyRulesOut(left, right, limit) {
|
|
44
|
+
const budget = limit * 2;
|
|
45
|
+
let sum = 0;
|
|
46
|
+
for (let bucket = 0; bucket < TALLY_SIZE; bucket++) {
|
|
47
|
+
sum += Math.abs((left[bucket] ?? 0) - (right[bucket] ?? 0));
|
|
48
|
+
if (sum > budget) {
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The Levenshtein distance between two strings, giving up as soon as it is
|
|
56
|
+
* certain to exceed `limit` and returning `limit + 1` in that case.
|
|
57
|
+
*
|
|
58
|
+
* Every value in a row of the table is a lower bound on everything below it,
|
|
59
|
+
* so once the whole row is past the limit there is no way back.
|
|
60
|
+
*/
|
|
61
|
+
export function boundedEditDistance(left, right, limit) {
|
|
62
|
+
if (left === right) {
|
|
63
|
+
return 0;
|
|
64
|
+
}
|
|
65
|
+
if (Math.abs(left.length - right.length) > limit) {
|
|
66
|
+
return limit + 1;
|
|
67
|
+
}
|
|
68
|
+
const width = right.length;
|
|
69
|
+
let previous = Array.from({ length: width + 1 }, (_, index) => index);
|
|
70
|
+
let current = new Array(width + 1).fill(0);
|
|
71
|
+
for (let row = 1; row <= left.length; row++) {
|
|
72
|
+
current[0] = row;
|
|
73
|
+
let rowMinimum = row;
|
|
74
|
+
const leftCharacter = left.charCodeAt(row - 1);
|
|
75
|
+
for (let column = 1; column <= width; column++) {
|
|
76
|
+
const substitution = (previous[column - 1] ?? 0) + (leftCharacter === right.charCodeAt(column - 1) ? 0 : 1);
|
|
77
|
+
const deletion = (previous[column] ?? 0) + 1;
|
|
78
|
+
const insertion = (current[column - 1] ?? 0) + 1;
|
|
79
|
+
const best = Math.min(substitution, deletion, insertion);
|
|
80
|
+
current[column] = best;
|
|
81
|
+
if (best < rowMinimum) {
|
|
82
|
+
rowMinimum = best;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (rowMinimum > limit) {
|
|
86
|
+
return limit + 1;
|
|
87
|
+
}
|
|
88
|
+
const finished = previous;
|
|
89
|
+
previous = current;
|
|
90
|
+
current = finished;
|
|
91
|
+
}
|
|
92
|
+
return previous[width] ?? limit + 1;
|
|
93
|
+
}
|
|
94
|
+
/** Disjoint sets, used to join pairs of close steps into groups. */
|
|
95
|
+
function makeSets(size) {
|
|
96
|
+
const parent = Array.from({ length: size }, (_, index) => index);
|
|
97
|
+
function find(item) {
|
|
98
|
+
let root = item;
|
|
99
|
+
while ((parent[root] ?? root) !== root) {
|
|
100
|
+
root = parent[root] ?? root;
|
|
101
|
+
}
|
|
102
|
+
let walk = item;
|
|
103
|
+
while ((parent[walk] ?? walk) !== root) {
|
|
104
|
+
const next = parent[walk] ?? walk;
|
|
105
|
+
parent[walk] = root;
|
|
106
|
+
walk = next;
|
|
107
|
+
}
|
|
108
|
+
return root;
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
find,
|
|
112
|
+
union(a, b) {
|
|
113
|
+
const rootA = find(a);
|
|
114
|
+
const rootB = find(b);
|
|
115
|
+
if (rootA !== rootB) {
|
|
116
|
+
parent[rootB] = rootA;
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Groups entries whose text is close enough to be the same step written two
|
|
123
|
+
* ways. Entries that are close to nothing are left out, so every group
|
|
124
|
+
* returned has at least two members, in the order they were given in.
|
|
125
|
+
*/
|
|
126
|
+
export function groupSimilar(entries, options = DEFAULT_SIMILARITY) {
|
|
127
|
+
// Sorting by length lets the search stop early: once two steps are too
|
|
128
|
+
// different in length, every step after this one is longer still.
|
|
129
|
+
const candidates = entries
|
|
130
|
+
.map((entry, index) => ({ index, text: entry.text, tally: tally(entry.text) }))
|
|
131
|
+
.filter((candidate) => candidate.text.length >= options.minLength)
|
|
132
|
+
.sort((a, b) => a.text.length - b.text.length);
|
|
133
|
+
const sets = makeSets(entries.length);
|
|
134
|
+
let joined = false;
|
|
135
|
+
for (let i = 0; i < candidates.length; i++) {
|
|
136
|
+
const left = candidates[i];
|
|
137
|
+
for (let j = i + 1; j < candidates.length; j++) {
|
|
138
|
+
const right = candidates[j];
|
|
139
|
+
const limit = Math.min(options.maxEdits, Math.floor((1 - options.ratio) * right.text.length));
|
|
140
|
+
// Sorted by length, so once a step is too much longer than this one,
|
|
141
|
+
// every step after it is longer still.
|
|
142
|
+
if (right.text.length - left.text.length > limit) {
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
if (limit < 1 || tallyRulesOut(left.tally, right.tally, limit)) {
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
if (boundedEditDistance(left.text, right.text, limit) <= limit) {
|
|
149
|
+
sets.union(left.index, right.index);
|
|
150
|
+
joined = true;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (!joined) {
|
|
155
|
+
return [];
|
|
156
|
+
}
|
|
157
|
+
const groups = new Map();
|
|
158
|
+
for (const candidate of candidates) {
|
|
159
|
+
const root = sets.find(candidate.index);
|
|
160
|
+
const member = { index: candidate.index, entry: entries[candidate.index] };
|
|
161
|
+
const group = groups.get(root);
|
|
162
|
+
if (group === undefined) {
|
|
163
|
+
groups.set(root, [member]);
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
group.push(member);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return [...groups.values()]
|
|
170
|
+
.filter((group) => group.length > 1)
|
|
171
|
+
.map((group) => group.sort((a, b) => a.index - b.index).map((member) => member.entry));
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=similar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"similar.js","sourceRoot":"","sources":["../../src/stats/similar.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shape of a statistics run.
|
|
3
|
+
*
|
|
4
|
+
* Everything here is complete: no list is cut short, no number is rounded to
|
|
5
|
+
* fit a screen. Trimming is the formatters' job, so that the JSON output is a
|
|
6
|
+
* full dataset - one a later run can be compared against - while the text
|
|
7
|
+
* report stays short enough to read.
|
|
8
|
+
*/
|
|
9
|
+
/** A summary of a set of counts, for numbers whose average hides the shape. */
|
|
10
|
+
export interface Distribution {
|
|
11
|
+
/** How many values went into the summary. */
|
|
12
|
+
count: number;
|
|
13
|
+
min: number;
|
|
14
|
+
median: number;
|
|
15
|
+
/** The value nine tenths of the set are at or below. */
|
|
16
|
+
p90: number;
|
|
17
|
+
max: number;
|
|
18
|
+
mean: number;
|
|
19
|
+
}
|
|
20
|
+
/** One scenario, named well enough to go and find it. */
|
|
21
|
+
export interface ScenarioRef {
|
|
22
|
+
name: string;
|
|
23
|
+
file: string;
|
|
24
|
+
line: number;
|
|
25
|
+
/** Steps written in the scenario itself, Background steps excluded. */
|
|
26
|
+
steps: number;
|
|
27
|
+
}
|
|
28
|
+
/** One entry of the step vocabulary: a normalised step and where it is used. */
|
|
29
|
+
export interface StepEntry {
|
|
30
|
+
/** The step text after normalisation - what makes two steps "the same". */
|
|
31
|
+
text: string;
|
|
32
|
+
/** How many written steps normalise to this text. */
|
|
33
|
+
count: number;
|
|
34
|
+
/** The step text as somebody actually wrote it, the first time it appears. */
|
|
35
|
+
example: string;
|
|
36
|
+
/** Where that first sighting is. */
|
|
37
|
+
file: string;
|
|
38
|
+
line: number;
|
|
39
|
+
}
|
|
40
|
+
/** Normalised steps that differ only slightly from each other. */
|
|
41
|
+
export interface SimilarGroup {
|
|
42
|
+
/** The steps in the group, most used first. */
|
|
43
|
+
members: StepEntry[];
|
|
44
|
+
/** Written steps covered by the whole group. */
|
|
45
|
+
total: number;
|
|
46
|
+
}
|
|
47
|
+
/** How often a tag is written. */
|
|
48
|
+
export interface TagEntry {
|
|
49
|
+
name: string;
|
|
50
|
+
count: number;
|
|
51
|
+
}
|
|
52
|
+
/** A file the Gherkin parser refused, and so could not be counted. */
|
|
53
|
+
export interface UnreadableFile {
|
|
54
|
+
file: string;
|
|
55
|
+
/** The parser's complaint, or the rule name it maps onto. */
|
|
56
|
+
reason: string;
|
|
57
|
+
line: number;
|
|
58
|
+
}
|
|
59
|
+
/** How many files were written in each Gherkin dialect. */
|
|
60
|
+
export interface LanguageEntry {
|
|
61
|
+
/** The Gherkin language code, such as `en` or `de`. */
|
|
62
|
+
code: string;
|
|
63
|
+
files: number;
|
|
64
|
+
}
|
|
65
|
+
/** What is in the feature files, counted. */
|
|
66
|
+
export interface Inventory {
|
|
67
|
+
features: number;
|
|
68
|
+
rules: number;
|
|
69
|
+
backgrounds: number;
|
|
70
|
+
/** Scenarios that are not Scenario Outlines. */
|
|
71
|
+
scenarios: number;
|
|
72
|
+
scenarioOutlines: number;
|
|
73
|
+
examplesTables: number;
|
|
74
|
+
/** Body rows across every Examples table; header rows are not counted. */
|
|
75
|
+
examplesRows: number;
|
|
76
|
+
/** Steps as written, Background steps included. */
|
|
77
|
+
steps: number;
|
|
78
|
+
dataTables: number;
|
|
79
|
+
docStrings: number;
|
|
80
|
+
}
|
|
81
|
+
/** How the steps of the suite divide between Given, When and Then. */
|
|
82
|
+
export interface KeywordMix {
|
|
83
|
+
given: number;
|
|
84
|
+
when: number;
|
|
85
|
+
then: number;
|
|
86
|
+
/**
|
|
87
|
+
* Steps whose keyword resolves to nothing: an `And` or `But` written before
|
|
88
|
+
* anything for it to carry on from.
|
|
89
|
+
*/
|
|
90
|
+
other: number;
|
|
91
|
+
}
|
|
92
|
+
/** What the steps of the suite look like taken together. */
|
|
93
|
+
export interface StepStats {
|
|
94
|
+
/** Steps as written, Background steps included. */
|
|
95
|
+
total: number;
|
|
96
|
+
/** Distinct steps after normalisation. */
|
|
97
|
+
unique: number;
|
|
98
|
+
/**
|
|
99
|
+
* `unique / total`. Low means the team shares a vocabulary; high means
|
|
100
|
+
* everybody invents their own phrasing, and the step definitions rot.
|
|
101
|
+
*/
|
|
102
|
+
uniqueRatio: number;
|
|
103
|
+
/** Distinct steps written exactly once - usually accidental one-offs. */
|
|
104
|
+
usedOnce: number;
|
|
105
|
+
/** Every distinct step, most used first. */
|
|
106
|
+
vocabulary: StepEntry[];
|
|
107
|
+
/** Steps that are nearly, but not quite, each other. */
|
|
108
|
+
similar: SimilarGroup[];
|
|
109
|
+
/** Given/When/Then mix, with `And` and `But` resolved to what they follow. */
|
|
110
|
+
keywords: KeywordMix;
|
|
111
|
+
/** Words per step, as a proxy for how detailed the steps have become. */
|
|
112
|
+
wordsPerStep: Distribution;
|
|
113
|
+
}
|
|
114
|
+
/** What the scenarios of the suite look like taken together. */
|
|
115
|
+
export interface ScenarioStats {
|
|
116
|
+
/**
|
|
117
|
+
* The number of test cases: one per Scenario, and one per row of every
|
|
118
|
+
* Examples table. This is the number that predicts how long a suite takes
|
|
119
|
+
* to run, and almost nobody's mental count of it is right.
|
|
120
|
+
*/
|
|
121
|
+
effective: number;
|
|
122
|
+
/** Steps per scenario, Background steps excluded. */
|
|
123
|
+
stepsPerScenario: Distribution;
|
|
124
|
+
/** Every scenario, longest first. */
|
|
125
|
+
largest: ScenarioRef[];
|
|
126
|
+
}
|
|
127
|
+
/** What the tags of the suite look like taken together. */
|
|
128
|
+
export interface TagStats {
|
|
129
|
+
/** Tags as written, counting a tag once for every node carrying it. */
|
|
130
|
+
total: number;
|
|
131
|
+
unique: number;
|
|
132
|
+
/** Every distinct tag, most used first. */
|
|
133
|
+
vocabulary: TagEntry[];
|
|
134
|
+
/** Tags written exactly once - very often a typo of one written often. */
|
|
135
|
+
usedOnce: string[];
|
|
136
|
+
/**
|
|
137
|
+
* Scenarios carrying no tag of their own and inheriting none, and so
|
|
138
|
+
* reachable by no tag expression.
|
|
139
|
+
*/
|
|
140
|
+
untaggedScenarios: number;
|
|
141
|
+
}
|
|
142
|
+
/** Everything one statistics run found. */
|
|
143
|
+
export interface Statistics {
|
|
144
|
+
files: {
|
|
145
|
+
/** Files the search matched. */
|
|
146
|
+
total: number;
|
|
147
|
+
/** Files the parser accepted, and so the ones every other number is from. */
|
|
148
|
+
parsed: number;
|
|
149
|
+
/** Files the parser refused. Nothing in them is counted. */
|
|
150
|
+
unreadable: UnreadableFile[];
|
|
151
|
+
};
|
|
152
|
+
inventory: Inventory;
|
|
153
|
+
scenarios: ScenarioStats;
|
|
154
|
+
steps: StepStats;
|
|
155
|
+
tags: TagStats;
|
|
156
|
+
/** Dialects in use, most common first. A single stray entry is a bug. */
|
|
157
|
+
languages: LanguageEntry[];
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/stats/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shape of a statistics run.
|
|
3
|
+
*
|
|
4
|
+
* Everything here is complete: no list is cut short, no number is rounded to
|
|
5
|
+
* fit a screen. Trimming is the formatters' job, so that the JSON output is a
|
|
6
|
+
* full dataset - one a later run can be compared against - while the text
|
|
7
|
+
* report stays short enough to read.
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/stats/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|