icore 1.0.4 → 1.0.6
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/dist/argv.d.ts.map +1 -1
- package/dist/argv.js +72 -4
- package/dist/argv.js.map +1 -1
- package/dist/commands.d.ts +3 -3
- package/dist/commands.d.ts.map +1 -1
- package/dist/options.d.ts +4 -3
- package/dist/options.d.ts.map +1 -1
- package/dist/options.js +6 -3
- package/dist/options.js.map +1 -1
- package/package.json +1 -1
- package/readme.md +530 -47
- package/docs/api.md +0 -466
- package/docs/design.md +0 -80
- package/docs/examples.md +0 -100
- package/docs/git-flow.md +0 -188
- package/docs/policy/abstraction-policy.md +0 -198
- package/docs/policy/change-policy.md +0 -86
- package/docs/policy/comment-policy.md +0 -253
- package/docs/policy/decision-rule-policy.md +0 -41
- package/docs/policy/dependencies-policy.md +0 -49
- package/docs/policy/documentation-policy.md +0 -27
- package/docs/policy/index.md +0 -49
- package/docs/policy/naming-policy.md +0 -18
- package/docs/policy/non-functional-requirements.md +0 -31
- package/docs/policy/scripts-and-build-policy.md +0 -60
- package/docs/policy/testing-policy.md +0 -335
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
# Decision Rule
|
|
2
|
-
|
|
3
|
-
> Type: Policy. This document defines the baseline filter before any code change.
|
|
4
|
-
|
|
5
|
-
If the change is not required, do not make it.
|
|
6
|
-
|
|
7
|
-
If the change adds behavior, do not make it.
|
|
8
|
-
|
|
9
|
-
If the change removes behavior, do not make it.
|
|
10
|
-
|
|
11
|
-
If the change is made because "this is how it is usually done", do not make it.
|
|
12
|
-
|
|
13
|
-
If the change seems safe, do not make it.
|
|
14
|
-
|
|
15
|
-
If the change seems correct, do not make it.
|
|
16
|
-
|
|
17
|
-
If there is doubt, leave the code as it is.
|
|
18
|
-
|
|
19
|
-
Existing code is considered intentional.
|
|
20
|
-
|
|
21
|
-
## Practical Application
|
|
22
|
-
|
|
23
|
-
Before making a change, check the following in order:
|
|
24
|
-
|
|
25
|
-
1. Is the change directly required by the task?
|
|
26
|
-
2. Does it change behavior, pipeline, or project structure?
|
|
27
|
-
3. Can the task be solved with a smaller change?
|
|
28
|
-
4. Is the decision based on a heuristic instead of a requirement?
|
|
29
|
-
|
|
30
|
-
## Examples
|
|
31
|
-
|
|
32
|
-
Correct decision:
|
|
33
|
-
|
|
34
|
-
- fix a specific conditional branch when the task is about an incorrect calculation
|
|
35
|
-
- add a test for already required behavior
|
|
36
|
-
|
|
37
|
-
Incorrect decision:
|
|
38
|
-
|
|
39
|
-
- rewrite a module "while we are touching it"
|
|
40
|
-
- add artifact cleanup because it feels customary
|
|
41
|
-
- change the dependency graph for a subjective sense of order
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
# Dependencies Policy
|
|
2
|
-
|
|
3
|
-
> Type: Policy. This document defines criteria for choosing new libraries and signs of undesirable dependencies.
|
|
4
|
-
|
|
5
|
-
Only high-quality libraries are allowed.
|
|
6
|
-
|
|
7
|
-
A library must:
|
|
8
|
-
|
|
9
|
-
- solve a broad problem
|
|
10
|
-
- have a clear API
|
|
11
|
-
- be maintained
|
|
12
|
-
- provide architectural value
|
|
13
|
-
- be justified long term
|
|
14
|
-
|
|
15
|
-
Undesirable dependencies:
|
|
16
|
-
|
|
17
|
-
- a package for one function
|
|
18
|
-
- a package for deleting files
|
|
19
|
-
- a package for a small utility
|
|
20
|
-
- a package wrapper over a standard function
|
|
21
|
-
|
|
22
|
-
Bad example:
|
|
23
|
-
|
|
24
|
-
rimraf
|
|
25
|
-
|
|
26
|
-
Good example:
|
|
27
|
-
|
|
28
|
-
a general-purpose filesystem library
|
|
29
|
-
with a complete API
|
|
30
|
-
|
|
31
|
-
## Selection Examples
|
|
32
|
-
|
|
33
|
-
Allowed:
|
|
34
|
-
|
|
35
|
-
- add a library that covers a stable infrastructure task and is already needed in several places
|
|
36
|
-
- choose a dependency with a clear support model and understandable documentation
|
|
37
|
-
- prefer the standard library if it covers the task without architectural losses
|
|
38
|
-
|
|
39
|
-
Not allowed:
|
|
40
|
-
|
|
41
|
-
- add a package only for one call that would take a few lines of project code
|
|
42
|
-
- pull in a dependency for "prettier" syntax
|
|
43
|
-
- add a library if it duplicates a tool already used in the project
|
|
44
|
-
|
|
45
|
-
## Good Practices
|
|
46
|
-
|
|
47
|
-
- before adding a dependency, state which long-term task it solves
|
|
48
|
-
- check whether the task can be covered by existing project libraries
|
|
49
|
-
- evaluate not only API convenience but also the maintenance cost of the dependency
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
# Documentation Policy
|
|
2
|
-
|
|
3
|
-
> Type: Policy. This document defines rules for choosing the documentation source of truth and forbids duplicating code contracts in permanent reference pages.
|
|
4
|
-
|
|
5
|
-
## Purpose
|
|
6
|
-
|
|
7
|
-
Documentation must help find the current contract, not create a second source of truth next to the code.
|
|
8
|
-
|
|
9
|
-
If a contract is already expressed by a runtime mechanism, source file, config file, or tests, a Markdown document must link to that source and explain the working route instead of copying the full reference.
|
|
10
|
-
|
|
11
|
-
## README And Docs
|
|
12
|
-
|
|
13
|
-
README must remain a concise entry point to the project:
|
|
14
|
-
|
|
15
|
-
- installation;
|
|
16
|
-
- quick start;
|
|
17
|
-
- main links;
|
|
18
|
-
- important workflows.
|
|
19
|
-
|
|
20
|
-
Detailed rules and policies must live in `docs/`.
|
|
21
|
-
|
|
22
|
-
Navigation documents must help find the source of truth, not become a second README.
|
|
23
|
-
|
|
24
|
-
## Minimum Rule
|
|
25
|
-
|
|
26
|
-
Markdown must answer the question "where is the current contract and how should it
|
|
27
|
-
be used". The contract itself must live where it is verified by runtime or tests.
|
package/docs/policy/index.md
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
# Project Policies
|
|
2
|
-
|
|
3
|
-
> Type: Navigation. This document provides navigation for the policy section and defines the general purpose of the project change constraints.
|
|
4
|
-
|
|
5
|
-
This section contains project rules for changing Node.js/TypeScript codebases.
|
|
6
|
-
|
|
7
|
-
The policy set is intended to preserve:
|
|
8
|
-
|
|
9
|
-
- predictable project behavior;
|
|
10
|
-
- reproducible builds;
|
|
11
|
-
- public contract stability;
|
|
12
|
-
- absence of accidental changes;
|
|
13
|
-
- controlled code evolution.
|
|
14
|
-
|
|
15
|
-
These policies are mandatory for developers, reviewers, and agents making changes in the repository.
|
|
16
|
-
|
|
17
|
-
## Start Here
|
|
18
|
-
|
|
19
|
-
- [Decision Rule](./decision-rule-policy.md) - the meta-policy for choosing between acceptable options.
|
|
20
|
-
- [Change Policy](./change-policy.md) - the rule for the minimum sufficient change.
|
|
21
|
-
|
|
22
|
-
## When To Read This Section
|
|
23
|
-
|
|
24
|
-
- before starting code changes;
|
|
25
|
-
- during code review;
|
|
26
|
-
- when there is doubt whether a change is acceptable;
|
|
27
|
-
- when a change affects scripts, documentation, dependencies, or architecture;
|
|
28
|
-
- when public API, CLI behavior, build pipeline, or publish output changes.
|
|
29
|
-
|
|
30
|
-
## Full List
|
|
31
|
-
|
|
32
|
-
- [Decision Rule](./decision-rule-policy.md)
|
|
33
|
-
- [Change Policy](./change-policy.md)
|
|
34
|
-
- [Non-Functional Requirements](./non-functional-requirements.md)
|
|
35
|
-
- [Abstraction Policy](./abstraction-policy.md)
|
|
36
|
-
- [Naming Policy](./naming-policy.md)
|
|
37
|
-
- [Comment Policy](./comment-policy.md)
|
|
38
|
-
- [Testing Policy](./testing-policy.md)
|
|
39
|
-
- [Scripts and Build Policy](./scripts-and-build-policy.md)
|
|
40
|
-
- [Dependencies Policy](./dependencies-policy.md)
|
|
41
|
-
- [Documentation Policy](./documentation-policy.md)
|
|
42
|
-
|
|
43
|
-
## Short Route
|
|
44
|
-
|
|
45
|
-
When a change decision must be made quickly, it is enough to go through three documents:
|
|
46
|
-
|
|
47
|
-
1. [Decision Rule](./decision-rule-policy.md)
|
|
48
|
-
2. [Change Policy](./change-policy.md)
|
|
49
|
-
3. [Non-Functional Requirements](./non-functional-requirements.md)
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# Naming Policy
|
|
2
|
-
|
|
3
|
-
> Type: Policy. This document defines naming rules for code entities.
|
|
4
|
-
|
|
5
|
-
## Goal
|
|
6
|
-
|
|
7
|
-
Names in code must be consistent, predictable, and must not create false semantic signals.
|
|
8
|
-
|
|
9
|
-
Name notation must reflect the entity role, not the author's personal preference.
|
|
10
|
-
|
|
11
|
-
## Basic Naming Rules
|
|
12
|
-
|
|
13
|
-
TypeScript/JavaScript code uses the following rules:
|
|
14
|
-
|
|
15
|
-
- `camelCase` - variables, functions, values, exported const values;
|
|
16
|
-
- `PascalCase` - classes, types, interfaces, enums;
|
|
17
|
-
- `kebab-case` - runtime names and file names;
|
|
18
|
-
- `SCREAMING_SNAKE_CASE` / `ALL_CAPS` - forbidden for internal project identifiers.
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
# Non-Functional Requirements
|
|
2
|
-
|
|
3
|
-
> Type: Policy. This document defines the non-functional properties of the project that a working change must not violate.
|
|
4
|
-
|
|
5
|
-
Changes must not break:
|
|
6
|
-
|
|
7
|
-
- build reproducibility
|
|
8
|
-
- determinism
|
|
9
|
-
- portability
|
|
10
|
-
- CI
|
|
11
|
-
- runtime behavior
|
|
12
|
-
- file structure
|
|
13
|
-
- startup order
|
|
14
|
-
- architecture
|
|
15
|
-
- dependencies
|
|
16
|
-
|
|
17
|
-
Even if the code works,
|
|
18
|
-
a change is forbidden if it violates these properties.
|
|
19
|
-
|
|
20
|
-
## Risk Examples
|
|
21
|
-
|
|
22
|
-
- the build passes locally but depends on file ordering in a specific OS
|
|
23
|
-
- the code works but changes the location of output artifacts
|
|
24
|
-
- the change does not break logic but adds a dependency on shell-specific behavior
|
|
25
|
-
- tests pass but the component startup order becomes different
|
|
26
|
-
|
|
27
|
-
## Good Practices
|
|
28
|
-
|
|
29
|
-
- verify not only result correctness but also preservation of previous side effects
|
|
30
|
-
- avoid changes that bind the project to a specific execution environment
|
|
31
|
-
- separately evaluate the impact of a change on CI, file structure, and reproducibility
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
# Scripts And Build Policy
|
|
2
|
-
|
|
3
|
-
> Type: Policy. This document defines restrictions on changing scripts, build, and test pipeline.
|
|
4
|
-
|
|
5
|
-
## Purpose
|
|
6
|
-
|
|
7
|
-
Build, test, and run scripts are considered part of the runtime pipeline.
|
|
8
|
-
|
|
9
|
-
They must not be changed without clear necessity.
|
|
10
|
-
|
|
11
|
-
## Forbidden Changes
|
|
12
|
-
|
|
13
|
-
Forbidden without a direct requirement:
|
|
14
|
-
|
|
15
|
-
- add file deletion;
|
|
16
|
-
- add automatic build output cleanup;
|
|
17
|
-
- add a `clean` script for automatic cleanup before `build` or `test`;
|
|
18
|
-
- add shell-specific cleanup commands;
|
|
19
|
-
- add prebuild/postbuild hooks;
|
|
20
|
-
- add pretest/posttest hooks;
|
|
21
|
-
- change command order;
|
|
22
|
-
- add chained commands for convenience;
|
|
23
|
-
- replace portable runtime logic with shell commands.
|
|
24
|
-
|
|
25
|
-
Example of a correct minimal script:
|
|
26
|
-
|
|
27
|
-
```json
|
|
28
|
-
"build": "<project-build-command>"
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
Example of an incorrect change:
|
|
32
|
-
|
|
33
|
-
```json
|
|
34
|
-
"build": "rm -rf <build-output> && <project-build-command>"
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
If stale artifacts remain in build output after files are moved, they must be removed narrowly and explicitly as part of that specific operation, not by changing the project's permanent build/test pipeline.
|
|
38
|
-
|
|
39
|
-
File deletion is allowed only when the task explicitly requests it.
|
|
40
|
-
|
|
41
|
-
## Additional Examples
|
|
42
|
-
|
|
43
|
-
Allowed:
|
|
44
|
-
|
|
45
|
-
- leave the existing `build` unchanged and fix the cause of the error in code;
|
|
46
|
-
- add a new script only when the task directly requires a new entrypoint;
|
|
47
|
-
- change the implementation of the invoked file without changing the run scenario itself, if the task is about that file's behavior.
|
|
48
|
-
|
|
49
|
-
Not allowed:
|
|
50
|
-
|
|
51
|
-
- change the test script so that it runs additional unrelated checks;
|
|
52
|
-
- replace the existing build tool with another one without a direct task requirement;
|
|
53
|
-
- add cleanup of temporary directories "just in case";
|
|
54
|
-
- add automatic build output cleanup before `build` or `test`.
|
|
55
|
-
|
|
56
|
-
## Good Practices
|
|
57
|
-
|
|
58
|
-
- treat scripts as part of the project contract, not as an implementation detail;
|
|
59
|
-
- if the problem can be solved inside the code, do not move the solution into shell commands;
|
|
60
|
-
- before changing a script, check whether step order, side effects, and entrypoints change.
|
|
@@ -1,335 +0,0 @@
|
|
|
1
|
-
# Testing Policy
|
|
2
|
-
|
|
3
|
-
> Type: Policy. This document limits the addition of tests and test infrastructure.
|
|
4
|
-
|
|
5
|
-
## Purpose
|
|
6
|
-
|
|
7
|
-
Tests must protect production contracts, observable behavior, and boundary scenarios.
|
|
8
|
-
|
|
9
|
-
A test must not lock in accidental implementation, temporary code structure, or internal action order unless this is part of the public contract.
|
|
10
|
-
|
|
11
|
-
The main question a test must answer is:
|
|
12
|
-
|
|
13
|
-
> Which behavior or production risk is protected?
|
|
14
|
-
|
|
15
|
-
Not:
|
|
16
|
-
|
|
17
|
-
> Which lines of code were executed?
|
|
18
|
-
|
|
19
|
-
## How To Run Tests
|
|
20
|
-
|
|
21
|
-
Tests are written in TypeScript in `src/**/*.test.ts` or `src/**/*.spec.ts` and use standard Node.js modules:
|
|
22
|
-
|
|
23
|
-
- `node:test`;
|
|
24
|
-
- `node:assert`.
|
|
25
|
-
|
|
26
|
-
Before running tests after changes in `src`, rebuild the project:
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
npm run build
|
|
30
|
-
npm test
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## Test Requirements
|
|
34
|
-
|
|
35
|
-
Tests must be:
|
|
36
|
-
|
|
37
|
-
- isolated;
|
|
38
|
-
- deterministic;
|
|
39
|
-
- readable;
|
|
40
|
-
- minimal but sufficient;
|
|
41
|
-
- focused on one behavior;
|
|
42
|
-
- oriented toward observable result, not internal implementation.
|
|
43
|
-
|
|
44
|
-
One test must verify one behavior.
|
|
45
|
-
|
|
46
|
-
Multiple assertions in one test are allowed if they describe the same contract. If assertions verify different reasons for behavior changes, they must be split into separate tests.
|
|
47
|
-
|
|
48
|
-
## Test File Boundary
|
|
49
|
-
|
|
50
|
-
A test file must cover a specific production file, not a directory.
|
|
51
|
-
|
|
52
|
-
Mapping rule:
|
|
53
|
-
|
|
54
|
-
```text
|
|
55
|
-
src/bootstrap/help/renderer.ts -> src/bootstrap/help/renderer.test.ts
|
|
56
|
-
src/bootstrap/help/commands.ts -> src/bootstrap/help/commands.test.ts
|
|
57
|
-
src/bootstrap/help/help.ts -> src/bootstrap/help/help.test.ts
|
|
58
|
-
src/bootstrap/cli.ts -> src/bootstrap/cli.test.ts
|
|
59
|
-
src/bootstrap/config.ts -> src/bootstrap/config.spec.ts
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
Creating a test whose name looks like a test for a directory or barrel module is forbidden:
|
|
63
|
-
|
|
64
|
-
```text
|
|
65
|
-
src/bootstrap/help.test.ts # covers the help/ directory
|
|
66
|
-
src/bootstrap/help.spec.ts # covers the help/ directory
|
|
67
|
-
src/bootstrap/help/index.test.ts # covers a barrel-only index.ts
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
An exception is allowed only if the file is actually a runtime entrypoint
|
|
71
|
-
or a package entrypoint with its own behavior. In that case, the test must
|
|
72
|
-
verify the entrypoint behavior itself, not the internal files of the directory.
|
|
73
|
-
|
|
74
|
-
If `index.ts` contains only re-exports, a separate test for it is not needed.
|
|
75
|
-
Files that contain logic must be tested.
|
|
76
|
-
|
|
77
|
-
## Imports In Tests
|
|
78
|
-
|
|
79
|
-
Unit tests must import code from the specific file they verify.
|
|
80
|
-
|
|
81
|
-
Allowed:
|
|
82
|
-
|
|
83
|
-
```ts
|
|
84
|
-
import { renderCliHelp } from './renderer';
|
|
85
|
-
import { isHelpRequested } from './help'; // if there is a nearby help.ts file
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
Forbidden for a unit test of a specific file:
|
|
89
|
-
|
|
90
|
-
```ts
|
|
91
|
-
import { renderCliHelp } from './index';
|
|
92
|
-
import { renderCliHelp } from '../help';
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
The second example is forbidden if `../help` resolves to a directory or barrel,
|
|
96
|
-
not to a specific file.
|
|
97
|
-
|
|
98
|
-
An integration test may go through a public entrypoint if it verifies
|
|
99
|
-
observable entrypoint behavior: exit code, stdout/stderr, dispatch, wiring, or
|
|
100
|
-
public API contract.
|
|
101
|
-
|
|
102
|
-
## Isolation
|
|
103
|
-
|
|
104
|
-
A test must minimize dependence on:
|
|
105
|
-
|
|
106
|
-
- the real filesystem, unless filesystem behavior is being tested;
|
|
107
|
-
- network;
|
|
108
|
-
- current time;
|
|
109
|
-
- test execution order;
|
|
110
|
-
- external processes;
|
|
111
|
-
- global mutable state;
|
|
112
|
-
- stale build artifacts.
|
|
113
|
-
|
|
114
|
-
If dependence on an external resource is the essence of the test, it must be clearly visible from the test name, suite, or fixture.
|
|
115
|
-
|
|
116
|
-
## Test Data
|
|
117
|
-
|
|
118
|
-
Test data must be minimal but sufficient for the scenario.
|
|
119
|
-
|
|
120
|
-
There is no need to create a realistic dataset if one object with three fields is enough for the check.
|
|
121
|
-
|
|
122
|
-
Good:
|
|
123
|
-
|
|
124
|
-
```ts
|
|
125
|
-
test('returns undefined for an unknown path', () => {
|
|
126
|
-
const throttle = new Throttle({
|
|
127
|
-
KnownService: 100
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
assert.equal(
|
|
131
|
-
throttle.resolveLimit('/api.contract.v1.UnknownService/Get'),
|
|
132
|
-
undefined
|
|
133
|
-
);
|
|
134
|
-
});
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
Bad:
|
|
138
|
-
|
|
139
|
-
```ts
|
|
140
|
-
test('validates throttling', () => {
|
|
141
|
-
const throttle = new Throttle({
|
|
142
|
-
ExamplesService: 200,
|
|
143
|
-
DataService: 300,
|
|
144
|
-
OperationsService: 200,
|
|
145
|
-
SandboxService: 200,
|
|
146
|
-
UsersService: 100
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
assert.equal(
|
|
150
|
-
throttle.resolveLimit('/api.contract.v1.UnknownService/Get'),
|
|
151
|
-
undefined
|
|
152
|
-
);
|
|
153
|
-
});
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
Extra fields hide the reason for the test and increase maintenance cost.
|
|
157
|
-
|
|
158
|
-
## Test Suite Naming
|
|
159
|
-
|
|
160
|
-
Test names must describe the public API path and expected behavior.
|
|
161
|
-
|
|
162
|
-
Top-level `describe()` names the unit under test:
|
|
163
|
-
|
|
164
|
-
- `ClassName` for classes and runtime components;
|
|
165
|
-
- `functionName` for standalone exported functions;
|
|
166
|
-
- `objectName` for exported objects or namespaces;
|
|
167
|
-
- `module-name` only when several closely related exports are tested and there is no single primary subject.
|
|
168
|
-
|
|
169
|
-
Good:
|
|
170
|
-
|
|
171
|
-
```ts
|
|
172
|
-
describe('Throttle', () => {
|
|
173
|
-
// ...
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
describe('createSdkMetadata', () => {
|
|
177
|
-
// ...
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
describe('suite runner helpers', () => {
|
|
181
|
-
// ...
|
|
182
|
-
});
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
Bad:
|
|
186
|
-
|
|
187
|
-
```ts
|
|
188
|
-
describe('utils', () => {
|
|
189
|
-
// ...
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
describe('tests for sdk', () => {
|
|
193
|
-
// ...
|
|
194
|
-
});
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
## Nested Suite Naming
|
|
198
|
-
|
|
199
|
-
Nested `describe()` names a public member or operation:
|
|
200
|
-
|
|
201
|
-
- `constructor` for constructor behavior;
|
|
202
|
-
- `#methodName` for instance methods called as `instance.methodName()`;
|
|
203
|
-
- `.methodName` for static methods called as `ClassName.methodName()`;
|
|
204
|
-
- `.methodName` for exported object/namespace methods called as `objectName.methodName()`;
|
|
205
|
-
- `functionName` for standalone functions grouped under a module-level suite.
|
|
206
|
-
|
|
207
|
-
Examples:
|
|
208
|
-
|
|
209
|
-
```ts
|
|
210
|
-
describe('Throttle', () => {
|
|
211
|
-
describe('#resolveLimit', () => {
|
|
212
|
-
// ...
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
describe('#reduce', () => {
|
|
216
|
-
// ...
|
|
217
|
-
});
|
|
218
|
-
});
|
|
219
|
-
|
|
220
|
-
describe('suite runner helpers', () => {
|
|
221
|
-
describe('collectTestFiles', () => {
|
|
222
|
-
// ...
|
|
223
|
-
});
|
|
224
|
-
});
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
A parent suite must not contain sibling `describe()` blocks with the same name. If two blocks have the same name, they must be merged or named after different public scenarios.
|
|
228
|
-
|
|
229
|
-
## Test Case Naming
|
|
230
|
-
|
|
231
|
-
`test()` names only expected behavior.
|
|
232
|
-
|
|
233
|
-
The test name must not repeat the subject or method name if they are already stated in `describe()`.
|
|
234
|
-
|
|
235
|
-
Good:
|
|
236
|
-
|
|
237
|
-
```ts
|
|
238
|
-
describe('Throttle', () => {
|
|
239
|
-
describe('#resolveLimit', () => {
|
|
240
|
-
test('returns undefined for an unknown path', () => {
|
|
241
|
-
// ...
|
|
242
|
-
});
|
|
243
|
-
});
|
|
244
|
-
});
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
Bad:
|
|
248
|
-
|
|
249
|
-
```ts
|
|
250
|
-
describe('Throttle', () => {
|
|
251
|
-
describe('#resolveLimit', () => {
|
|
252
|
-
test('Throttle resolveLimit returns undefined for an unknown path', () => {
|
|
253
|
-
// ...
|
|
254
|
-
});
|
|
255
|
-
});
|
|
256
|
-
});
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
Repeating the subject makes the name noisy and worsens test output readability.
|
|
260
|
-
|
|
261
|
-
## Preferred Behavior Verbs
|
|
262
|
-
|
|
263
|
-
Preferred verbs for `test()`:
|
|
264
|
-
|
|
265
|
-
- `returns ...`;
|
|
266
|
-
- `throws ...`;
|
|
267
|
-
- `rejects ...`;
|
|
268
|
-
- `parses ...`;
|
|
269
|
-
- `formats ...`;
|
|
270
|
-
- `writes ...`;
|
|
271
|
-
- `reads ...`;
|
|
272
|
-
- `keeps ...`;
|
|
273
|
-
- `skips ...`;
|
|
274
|
-
- `uses ...`;
|
|
275
|
-
- `does not ...`;
|
|
276
|
-
- `handles ...`;
|
|
277
|
-
- `preserves ...`;
|
|
278
|
-
- `computes ...`;
|
|
279
|
-
- `maps ...`;
|
|
280
|
-
- `normalizes ...`;
|
|
281
|
-
- `ignores ...`.
|
|
282
|
-
|
|
283
|
-
Good:
|
|
284
|
-
|
|
285
|
-
```ts
|
|
286
|
-
test('throws for unknown unary limit path', async () => {
|
|
287
|
-
// ...
|
|
288
|
-
});
|
|
289
|
-
|
|
290
|
-
test('does not throttle response streams', async () => {
|
|
291
|
-
// ...
|
|
292
|
-
});
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
Bad:
|
|
296
|
-
|
|
297
|
-
```ts
|
|
298
|
-
test('works correctly', () => {
|
|
299
|
-
// ...
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
test('should process data', () => {
|
|
303
|
-
// ...
|
|
304
|
-
});
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
`should` is not technically forbidden, but the preferred style is a direct description of observable behavior without an extra modal word.
|
|
308
|
-
|
|
309
|
-
## Explicitness Over DRY
|
|
310
|
-
|
|
311
|
-
The drive toward DRY does not apply to tests.
|
|
312
|
-
|
|
313
|
-
Repetition in tests is allowed if it:
|
|
314
|
-
|
|
315
|
-
* keeps the scenario local;
|
|
316
|
-
* removes non-obvious setup;
|
|
317
|
-
* reduces the risk of mistakes in test infrastructure;
|
|
318
|
-
* allows the test case to be read without jumping to helpers.
|
|
319
|
-
|
|
320
|
-
A bad test is worse than no test: it creates false confidence and makes code harder to change.
|
|
321
|
-
|
|
322
|
-
## Generalization In Tests
|
|
323
|
-
|
|
324
|
-
Helpers in tests are almost always undesirable.
|
|
325
|
-
|
|
326
|
-
A helper is allowed only if it removes technical noise and does not hide the meaning of the scenario.
|
|
327
|
-
If a helper is more complex than the test itself, it must be removed.
|
|
328
|
-
If a large helper, fixture builder, or conditional test logic is needed for a check, this may signal that production code is poorly separated or that the test is at the wrong level.
|
|
329
|
-
A direct test with explicit data is preferable to abstract test infrastructure.
|
|
330
|
-
|
|
331
|
-
## Coverage Boundaries
|
|
332
|
-
|
|
333
|
-
There is no need to try to cover the entire public method or contract with one large test.
|
|
334
|
-
If composite behavior sections are already checked separately, an additional large test appears unnecessary.
|
|
335
|
-
It is allowed to leave some sections without direct coverage if they are already indirectly protected by other tests.
|