@likec4/core 0.6.1 → 0.6.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@likec4/core",
3
- "version": "0.6.1",
3
+ "version": "0.6.3",
4
4
  "license": "MIT",
5
5
  "bugs": "https://github.com/likec4/likec4/issues",
6
6
  "homepage": "https://like-c4.dev",
@@ -14,8 +14,8 @@
14
14
  "directory": "packages/core"
15
15
  },
16
16
  "scripts": {
17
- "compile": "",
18
- "release:build": "tsc -p tsconfig.esm.json",
17
+ "compile": "tsc --emitDeclarationOnly",
18
+ "build:release": "tsc -p tsconfig.esm.json",
19
19
  "build": "tsc",
20
20
  "dev": "tsc --watch",
21
21
  "lint": "run -T eslint src/ --fix",
@@ -1,173 +0,0 @@
1
- import { ModelIndex } from '../model-index';
2
- import type { ElementKind, ElementView, Fqn, RelationID } from '../types';
3
- /**
4
- ┌──────────────────────────────────────────────────┐
5
- │ cloud │
6
- │ ┌───────────────────────────────────────────┐ │
7
- │ │ frontend │ │
8
- ┏━━━━━━━━━━┓ │ │ ┏━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━━┓ │ │ ┏━━━━━━━━━━━┓
9
- ┃ ┃ │ │ ┃ ┃ ┃ ┃ │ │ ┃ ┃
10
- ┃ customer ┃──┼──┼──▶┃ dashboard ┃ ┃ adminpanel ┃◀───┼───┼───┃ support ┃
11
- ┃ ┃ │ │ ┃ ┃ ┃ ┃ │ │ ┃ ┃
12
- ┗━━━━━━━━━━┛ │ │ ┗━━━━━━┳━━━━━━┛ ┗━━━━━━━━┳━━━━━━━┛ │ │ ┗━━━━━━━━━━━┛
13
- │ └──────────┼───────────────────┼────────────┘ │
14
- │ ├───────────────────┘ │
15
- │ │ │
16
- │ ┌──────────┼────────────────────────────────┐ │
17
- │ │ ▼ backend │ │
18
- │ │ ┏━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━┓ │ │
19
- │ │ ┃ ┃ ┃ ┃ │ │
20
- │ │ ┃ graphlql ┃──────▶┃ storage ┃ │ │
21
- │ │ ┃ ┃ ┃ ┃ │ │
22
- │ │ ┗━━━━━━━━━━━━━┛ ┗━━━━━━┳━━━━━━┛ │ │
23
- │ └────────────────────────────────┼──────────┘ │
24
- └───────────────────────────────────┼──────────────┘
25
-
26
- ┌─────────┼─────────┐
27
- │ amazon │ │
28
- │ ▼ │
29
- │ ┏━━━━━━━━━━━━━━┓ │
30
- │ ┃ ┃ │
31
- │ ┃ s3 ┃ │
32
- │ ┃ ┃ │
33
- │ ┗━━━━━━━━━━━━━━┛ │
34
- └───────────────────┘
35
-
36
- specification {
37
- element actor
38
- element system
39
- element component
40
- }
41
-
42
- model {
43
-
44
- actor customer
45
- actor support
46
-
47
- system cloud {
48
- component backend {
49
- component graphql
50
- component storage
51
-
52
- graphql -> storage
53
- }
54
-
55
- component frontend {
56
- component dashboard {
57
- -> graphql
58
- }
59
- component adminPanel {
60
- -> graphql
61
- }
62
- }
63
- }
64
-
65
- customer -> dashboard
66
- support -> adminPanel
67
-
68
- system amazon {
69
- component s3
70
-
71
- cloud.backend.storage -> s3
72
- }
73
-
74
- }
75
-
76
- */
77
- export declare const fakeElements: {
78
- amazon: {
79
- id: Fqn;
80
- kind: ElementKind;
81
- title: string;
82
- };
83
- cloud: {
84
- id: Fqn;
85
- kind: ElementKind;
86
- title: string;
87
- };
88
- customer: {
89
- id: Fqn;
90
- kind: ElementKind;
91
- title: string;
92
- };
93
- support: {
94
- id: Fqn;
95
- kind: ElementKind;
96
- title: string;
97
- };
98
- 'amazon.s3': {
99
- id: Fqn;
100
- kind: ElementKind;
101
- title: string;
102
- };
103
- 'cloud.backend': {
104
- id: Fqn;
105
- kind: ElementKind;
106
- title: string;
107
- };
108
- 'cloud.frontend': {
109
- id: Fqn;
110
- kind: ElementKind;
111
- title: string;
112
- };
113
- 'cloud.backend.graphql': {
114
- id: Fqn;
115
- kind: ElementKind;
116
- title: string;
117
- };
118
- 'cloud.backend.storage': {
119
- id: Fqn;
120
- kind: ElementKind;
121
- title: string;
122
- };
123
- 'cloud.frontend.adminPanel': {
124
- id: Fqn;
125
- kind: ElementKind;
126
- title: string;
127
- };
128
- 'cloud.frontend.dashboard': {
129
- id: Fqn;
130
- kind: ElementKind;
131
- title: string;
132
- };
133
- };
134
- export declare const fakeRelations: {
135
- 'customer:cloud.frontend.dashboard': {
136
- id: RelationID;
137
- source: Fqn;
138
- target: Fqn;
139
- title: string;
140
- };
141
- 'support:cloud.frontend.adminPanel': {
142
- id: RelationID;
143
- source: Fqn;
144
- target: Fqn;
145
- title: string;
146
- };
147
- 'cloud.backend.storage:amazon.s3': {
148
- id: RelationID;
149
- source: Fqn;
150
- target: Fqn;
151
- title: string;
152
- };
153
- 'cloud.backend.graphql:cloud.backend.storage': {
154
- id: RelationID;
155
- source: Fqn;
156
- target: Fqn;
157
- title: string;
158
- };
159
- 'cloud.frontend.dashboard:cloud.backend.graphql': {
160
- id: RelationID;
161
- source: Fqn;
162
- target: Fqn;
163
- title: string;
164
- };
165
- 'cloud.frontend.adminPanel:cloud.backend.graphql': {
166
- id: RelationID;
167
- source: Fqn;
168
- target: Fqn;
169
- title: string;
170
- };
171
- };
172
- export declare const fakeElementView: ElementView;
173
- export declare const fakeModel: () => ModelIndex;
@@ -1,188 +0,0 @@
1
- import { ModelIndex } from '../model-index';
2
- /**
3
- ┌──────────────────────────────────────────────────┐
4
- │ cloud │
5
- │ ┌───────────────────────────────────────────┐ │
6
- │ │ frontend │ │
7
- ┏━━━━━━━━━━┓ │ │ ┏━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━━┓ │ │ ┏━━━━━━━━━━━┓
8
- ┃ ┃ │ │ ┃ ┃ ┃ ┃ │ │ ┃ ┃
9
- ┃ customer ┃──┼──┼──▶┃ dashboard ┃ ┃ adminpanel ┃◀───┼───┼───┃ support ┃
10
- ┃ ┃ │ │ ┃ ┃ ┃ ┃ │ │ ┃ ┃
11
- ┗━━━━━━━━━━┛ │ │ ┗━━━━━━┳━━━━━━┛ ┗━━━━━━━━┳━━━━━━━┛ │ │ ┗━━━━━━━━━━━┛
12
- │ └──────────┼───────────────────┼────────────┘ │
13
- │ ├───────────────────┘ │
14
- │ │ │
15
- │ ┌──────────┼────────────────────────────────┐ │
16
- │ │ ▼ backend │ │
17
- │ │ ┏━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━┓ │ │
18
- │ │ ┃ ┃ ┃ ┃ │ │
19
- │ │ ┃ graphlql ┃──────▶┃ storage ┃ │ │
20
- │ │ ┃ ┃ ┃ ┃ │ │
21
- │ │ ┗━━━━━━━━━━━━━┛ ┗━━━━━━┳━━━━━━┛ │ │
22
- │ └────────────────────────────────┼──────────┘ │
23
- └───────────────────────────────────┼──────────────┘
24
-
25
- ┌─────────┼─────────┐
26
- │ amazon │ │
27
- │ ▼ │
28
- │ ┏━━━━━━━━━━━━━━┓ │
29
- │ ┃ ┃ │
30
- │ ┃ s3 ┃ │
31
- │ ┃ ┃ │
32
- │ ┗━━━━━━━━━━━━━━┛ │
33
- └───────────────────┘
34
-
35
- specification {
36
- element actor
37
- element system
38
- element component
39
- }
40
-
41
- model {
42
-
43
- actor customer
44
- actor support
45
-
46
- system cloud {
47
- component backend {
48
- component graphql
49
- component storage
50
-
51
- graphql -> storage
52
- }
53
-
54
- component frontend {
55
- component dashboard {
56
- -> graphql
57
- }
58
- component adminPanel {
59
- -> graphql
60
- }
61
- }
62
- }
63
-
64
- customer -> dashboard
65
- support -> adminPanel
66
-
67
- system amazon {
68
- component s3
69
-
70
- cloud.backend.storage -> s3
71
- }
72
-
73
- }
74
-
75
- */
76
- export const fakeElements = {
77
- amazon: {
78
- id: 'amazon',
79
- kind: 'system',
80
- title: 'amazon'
81
- },
82
- cloud: {
83
- id: 'cloud',
84
- kind: 'system',
85
- title: 'cloud'
86
- },
87
- customer: {
88
- id: 'customer',
89
- kind: 'actor',
90
- title: 'customer'
91
- },
92
- support: {
93
- id: 'support',
94
- kind: 'actor',
95
- title: 'support'
96
- },
97
- 'amazon.s3': {
98
- id: 'amazon.s3',
99
- kind: 'component',
100
- title: 's3'
101
- },
102
- 'cloud.backend': {
103
- id: 'cloud.backend',
104
- kind: 'component',
105
- title: 'backend'
106
- },
107
- 'cloud.frontend': {
108
- id: 'cloud.frontend',
109
- kind: 'component',
110
- title: 'frontend'
111
- },
112
- 'cloud.backend.graphql': {
113
- id: 'cloud.backend.graphql',
114
- kind: 'component',
115
- title: 'graphql'
116
- },
117
- 'cloud.backend.storage': {
118
- id: 'cloud.backend.storage',
119
- kind: 'component',
120
- title: 'storage'
121
- },
122
- 'cloud.frontend.adminPanel': {
123
- id: 'cloud.frontend.adminPanel',
124
- kind: 'component',
125
- title: 'adminPanel'
126
- },
127
- 'cloud.frontend.dashboard': {
128
- id: 'cloud.frontend.dashboard',
129
- kind: 'component',
130
- title: 'dashboard'
131
- }
132
- };
133
- export const fakeRelations = {
134
- 'customer:cloud.frontend.dashboard': {
135
- id: 'customer:cloud.frontend.dashboard',
136
- source: 'customer',
137
- target: 'cloud.frontend.dashboard',
138
- title: ''
139
- },
140
- 'support:cloud.frontend.adminPanel': {
141
- id: 'support:cloud.frontend.adminPanel',
142
- source: 'support',
143
- target: 'cloud.frontend.adminPanel',
144
- title: ''
145
- },
146
- 'cloud.backend.storage:amazon.s3': {
147
- id: 'cloud.backend.storage:amazon.s3',
148
- source: 'cloud.backend.storage',
149
- target: 'amazon.s3',
150
- title: ''
151
- },
152
- 'cloud.backend.graphql:cloud.backend.storage': {
153
- id: 'cloud.backend.graphql:cloud.backend.storage',
154
- source: 'cloud.backend.graphql',
155
- target: 'cloud.backend.storage',
156
- title: ''
157
- },
158
- 'cloud.frontend.dashboard:cloud.backend.graphql': {
159
- id: 'cloud.frontend.dashboard:cloud.backend.graphql',
160
- source: 'cloud.frontend.dashboard',
161
- target: 'cloud.backend.graphql',
162
- title: ''
163
- },
164
- 'cloud.frontend.adminPanel:cloud.backend.graphql': {
165
- id: 'cloud.frontend.adminPanel:cloud.backend.graphql',
166
- source: 'cloud.frontend.adminPanel',
167
- target: 'cloud.backend.graphql',
168
- title: ''
169
- }
170
- };
171
- export const fakeElementView = {
172
- id: 'fakeView',
173
- title: '',
174
- viewOf: 'cloud',
175
- rules: [
176
- {
177
- isInclude: true,
178
- exprs: [{ wildcard: true }]
179
- }
180
- ]
181
- };
182
- export const fakeModel = () => ModelIndex.from({
183
- elements: fakeElements,
184
- relations: fakeRelations,
185
- views: {
186
- [fakeElementView.id]: fakeElementView
187
- }
188
- });
@@ -1 +0,0 @@
1
- export * from './data';
@@ -1 +0,0 @@
1
- export * from './data';
@@ -1 +0,0 @@
1
- export {};
@@ -1,175 +0,0 @@
1
- import { expect, test } from 'vitest';
2
- import { fakeModel } from '../__test__';
3
- import { computeElementView } from './compute.element-view';
4
- test('index view', () => {
5
- const { nodes, edges } = computeElementView({
6
- id: 'index',
7
- title: '',
8
- rules: [
9
- {
10
- isInclude: true,
11
- exprs: [
12
- {
13
- wildcard: true
14
- }
15
- ]
16
- }
17
- ]
18
- }, fakeModel());
19
- expect(nodes.map(n => n.id)).toEqual(['support', 'customer', 'cloud', 'amazon']);
20
- expect(edges.map(e => e.id)).toEqual(['support:cloud', 'customer:cloud', 'cloud:amazon']);
21
- });
22
- test('view of cloud', () => {
23
- const view = computeElementView({
24
- id: 'cloud',
25
- title: '',
26
- viewOf: 'cloud',
27
- rules: [
28
- {
29
- isInclude: true,
30
- exprs: [
31
- {
32
- wildcard: true
33
- }
34
- ]
35
- }
36
- ]
37
- }, fakeModel());
38
- const { nodes, edges } = view;
39
- expect(nodes.map(n => n.id)).toEqual([
40
- 'support',
41
- 'customer',
42
- 'cloud',
43
- 'cloud.frontend',
44
- 'cloud.backend',
45
- 'amazon'
46
- ]);
47
- expect(edges.map(e => e.id)).toEqual([
48
- 'cloud.frontend:cloud.backend',
49
- 'cloud.backend:amazon',
50
- 'support:cloud.frontend',
51
- 'customer:cloud.frontend'
52
- ]);
53
- expect(view).toMatchSnapshot();
54
- });
55
- test('view with 3 levels', () => {
56
- const view = computeElementView({
57
- id: 'cloud3levels',
58
- title: '',
59
- viewOf: 'cloud',
60
- rules: [
61
- {
62
- isInclude: true,
63
- exprs: [
64
- // include *
65
- { wildcard: true },
66
- // include cloud.frontend.*
67
- { element: 'cloud.frontend', isDescedants: true },
68
- // include cloud.backend.*
69
- { element: 'cloud.backend', isDescedants: true }
70
- ]
71
- },
72
- {
73
- isInclude: false,
74
- exprs: [
75
- // exclude cloud.frontend
76
- { element: 'cloud.frontend', isDescedants: false }
77
- ]
78
- }
79
- ]
80
- }, fakeModel());
81
- expect(view.nodes.map(n => n.id)).toEqual([
82
- 'support',
83
- 'customer',
84
- 'cloud',
85
- 'cloud.frontend.dashboard',
86
- 'cloud.frontend.adminPanel',
87
- 'cloud.backend',
88
- 'cloud.backend.graphql',
89
- 'cloud.backend.storage',
90
- 'amazon'
91
- ]);
92
- expect(view).toMatchSnapshot();
93
- });
94
- test('view of amazon', () => {
95
- const { nodes, edges } = computeElementView({
96
- id: 'amazon',
97
- title: '',
98
- viewOf: 'amazon',
99
- rules: [
100
- {
101
- isInclude: true,
102
- exprs: [
103
- // include *
104
- { wildcard: true },
105
- // include cloud
106
- { element: 'cloud', isDescedants: false },
107
- // include cloud.* -> amazon
108
- {
109
- source: { element: 'cloud', isDescedants: true },
110
- target: { element: 'amazon', isDescedants: false }
111
- }
112
- ]
113
- }
114
- ]
115
- }, fakeModel());
116
- expect(nodes.map(n => n.id)).toEqual(['cloud', 'cloud.backend', 'amazon', 'amazon.s3']);
117
- expect(edges.map(e => e.id)).toEqual(['cloud.backend:amazon.s3']);
118
- });
119
- test('index view with applied styles', () => {
120
- const { nodes } = computeElementView({
121
- id: 'index',
122
- rules: [
123
- {
124
- isInclude: true,
125
- exprs: [{ wildcard: true }, { element: 'cloud.backend', isDescedants: false }]
126
- },
127
- // all elements
128
- // color: secondary
129
- {
130
- targets: [{ wildcard: true }],
131
- style: {
132
- color: 'secondary',
133
- shape: 'storage'
134
- }
135
- },
136
- // cloud
137
- // color: muted
138
- {
139
- targets: [{ element: 'cloud', isDescedants: false }],
140
- style: {
141
- color: 'muted'
142
- }
143
- },
144
- // cloud.*
145
- // shape: browser
146
- {
147
- targets: [{ element: 'cloud', isDescedants: true }],
148
- style: {
149
- shape: 'browser'
150
- }
151
- }
152
- ]
153
- }, fakeModel());
154
- const amazon = nodes.find(n => n.id === 'amazon');
155
- const customer = nodes.find(n => n.id === 'customer');
156
- const cloud = nodes.find(n => n.id === 'cloud');
157
- const backend = nodes.find(n => n.id === 'cloud.backend');
158
- expect(amazon).toMatchObject({
159
- color: 'secondary',
160
- shape: 'storage'
161
- });
162
- expect(customer).toMatchObject({
163
- color: 'secondary',
164
- shape: 'storage'
165
- });
166
- expect(cloud).toMatchObject({
167
- color: 'muted',
168
- shape: 'storage'
169
- });
170
- expect(backend).toMatchObject({
171
- parent: 'cloud',
172
- color: 'secondary',
173
- shape: 'browser'
174
- });
175
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,267 +0,0 @@
1
- import { Graph, alg } from '@dagrejs/graphlib';
2
- import { indexBy, pluck, toPairs } from 'rambdax';
3
- import { describe, expect, it } from 'vitest';
4
- import { commonAncestor, parentFqn } from '../../utils';
5
- import { sortNodes } from './sortNodes';
6
- describe('sortNodes', () => {
7
- it('should do topological sort', () => {
8
- const g = new Graph({
9
- compound: true,
10
- directed: true,
11
- multigraph: false
12
- });
13
- g.setNode('customer');
14
- g.setNode('cloud');
15
- g.setNode('cloud.frontend');
16
- g.setEdge('cloud', 'cloud.frontend');
17
- g.setNode('cloud.backend');
18
- g.setEdge('cloud', 'cloud.backend');
19
- g.setNode('cloud.backend.graphql');
20
- g.setEdge('cloud.backend', 'cloud.backend.graphql');
21
- g.setNode('cloud.backend.storage');
22
- g.setEdge('cloud.backend', 'cloud.backend.storage');
23
- g.setEdge('cloud.backend.graphql', 'cloud.backend.storage');
24
- g.setEdge('cloud.frontend', 'cloud.backend.graphql');
25
- g.setEdge('cloud.frontend', 'cloud.backend');
26
- g.setEdge('customer', 'cloud.frontend');
27
- g.setEdge('customer', 'cloud');
28
- expect(alg.topsort(g)).toEqual([
29
- 'customer',
30
- 'cloud',
31
- 'cloud.frontend',
32
- 'cloud.backend',
33
- 'cloud.backend.graphql',
34
- 'cloud.backend.storage'
35
- ]);
36
- });
37
- const testnodes = (_nodes, _edges = []) => {
38
- const nodesreg = indexBy(n => n.id, _nodes.map(nd => ({
39
- parent: null,
40
- children: [],
41
- ...nd
42
- })));
43
- const edges = _edges.map(([source, target]) => {
44
- let parent = commonAncestor(source, target);
45
- while (parent) {
46
- if (parent in nodesreg) {
47
- break;
48
- }
49
- parent = parentFqn(parent);
50
- }
51
- return {
52
- parent,
53
- source,
54
- target
55
- };
56
- });
57
- return sortNodes(new Map(toPairs(nodesreg)), edges);
58
- };
59
- const expectSorting = (_nodes, _edges = []) => expect(testnodes(_nodes, _edges).map(n => n.id));
60
- describe('two nodes inside', () => {
61
- const nodes = [
62
- {
63
- id: 'cloud'
64
- },
65
- {
66
- id: 'customer'
67
- },
68
- {
69
- id: 'cloud.backend',
70
- parent: 'cloud'
71
- },
72
- {
73
- id: 'cloud.frontend',
74
- parent: 'cloud'
75
- }
76
- ];
77
- it('should sort hierarchically, if no edges', () => {
78
- expectSorting(nodes).toEqual(['customer', 'cloud', 'cloud.backend', 'cloud.frontend']);
79
- });
80
- it('should sort nested nodes using edges', () => {
81
- expectSorting(nodes, [['cloud.frontend', 'cloud.backend']]).toEqual([
82
- 'customer',
83
- 'cloud',
84
- 'cloud.frontend',
85
- 'cloud.backend'
86
- ]);
87
- });
88
- it('should sort nodes using edges', () => {
89
- expectSorting(nodes, [
90
- ['customer', 'cloud.frontend'],
91
- ['cloud.frontend', 'cloud.backend']
92
- ]).toEqual(['customer', 'cloud', 'cloud.frontend', 'cloud.backend']);
93
- });
94
- });
95
- describe('three nodes inside', () => {
96
- const nodes = [
97
- {
98
- id: 'cloud'
99
- },
100
- {
101
- id: 'customer'
102
- },
103
- {
104
- id: 'amazon'
105
- },
106
- {
107
- id: 'cloud.db',
108
- parent: 'cloud'
109
- },
110
- {
111
- id: 'cloud.backend',
112
- parent: 'cloud'
113
- },
114
- {
115
- id: 'cloud.frontend',
116
- parent: 'cloud'
117
- }
118
- ];
119
- it('should sort hierarchically if no edges and source order', () => {
120
- const sorted = testnodes(nodes);
121
- expect(pluck('id', sorted)).toEqual([
122
- 'customer',
123
- 'amazon',
124
- 'cloud',
125
- 'cloud.db',
126
- 'cloud.backend',
127
- 'cloud.frontend'
128
- ]);
129
- const cloud = sorted[2];
130
- expect(cloud).toMatchObject({
131
- id: 'cloud',
132
- parent: null,
133
- children: ['cloud.db', 'cloud.backend', 'cloud.frontend']
134
- });
135
- });
136
- it('should sort nested nodes using edges', () => {
137
- const sorted = testnodes(nodes, [
138
- ['cloud.frontend', 'cloud.backend'],
139
- ['cloud.backend', 'cloud.db']
140
- ]);
141
- expect(pluck('id', sorted)).toEqual([
142
- 'customer',
143
- 'amazon',
144
- 'cloud',
145
- 'cloud.frontend',
146
- 'cloud.backend',
147
- 'cloud.db'
148
- ]);
149
- const cloud = sorted[2];
150
- expect(cloud).toMatchObject({
151
- id: 'cloud',
152
- parent: null,
153
- children: ['cloud.frontend', 'cloud.backend', 'cloud.db']
154
- });
155
- });
156
- it('should sort nodes using edges', () => {
157
- expectSorting(nodes, [
158
- ['customer', 'cloud.frontend'],
159
- ['cloud.frontend', 'cloud.backend'],
160
- ['cloud.backend', 'cloud.db'],
161
- ['cloud.db', 'amazon']
162
- ]).toEqual(['customer', 'cloud', 'cloud.frontend', 'cloud.backend', 'cloud.db', 'amazon']);
163
- });
164
- it('should sort nodes using edges and ignore cycles', () => {
165
- expectSorting(nodes, [
166
- ['customer', 'cloud.frontend'],
167
- ['cloud.frontend', 'cloud.backend'],
168
- ['cloud.backend', 'cloud.db'],
169
- ['cloud.db', 'amazon'],
170
- ['amazon', 'cloud.backend']
171
- ]).toEqual(['customer', 'cloud', 'cloud.frontend', 'cloud.backend', 'cloud.db', 'amazon']);
172
- });
173
- });
174
- describe('data from test model', () => {
175
- const nodes = [
176
- {
177
- id: 'amazon'
178
- },
179
- {
180
- id: 'cloud'
181
- },
182
- {
183
- id: 'customer'
184
- },
185
- {
186
- id: 'support'
187
- },
188
- {
189
- id: 'cloud.backend',
190
- parent: 'cloud'
191
- },
192
- {
193
- id: 'amazon.rds',
194
- parent: 'amazon'
195
- },
196
- {
197
- id: 'cloud.backend.graphql',
198
- parent: 'cloud.backend'
199
- },
200
- {
201
- id: 'cloud.backend.storage',
202
- parent: 'cloud.backend'
203
- },
204
- {
205
- id: 'cloud.frontend.adminPanel',
206
- parent: 'cloud'
207
- },
208
- {
209
- id: 'cloud.frontend.dashboard',
210
- parent: 'cloud'
211
- }
212
- ];
213
- it('should sort hierarchically, if no edges', () => {
214
- expectSorting(nodes).toEqual([
215
- 'customer',
216
- 'support',
217
- 'amazon',
218
- 'amazon.rds',
219
- 'cloud',
220
- 'cloud.backend',
221
- 'cloud.backend.graphql',
222
- 'cloud.backend.storage',
223
- 'cloud.frontend.adminPanel',
224
- 'cloud.frontend.dashboard'
225
- ]);
226
- });
227
- it('should sort using top level edges', () => {
228
- expectSorting(nodes, [
229
- ['amazon', 'support'],
230
- ['amazon', 'customer'],
231
- ['customer', 'support']
232
- ]).toEqual([
233
- 'amazon',
234
- 'customer',
235
- 'support',
236
- 'amazon.rds',
237
- 'cloud',
238
- 'cloud.backend',
239
- 'cloud.backend.graphql',
240
- 'cloud.backend.storage',
241
- 'cloud.frontend.adminPanel',
242
- 'cloud.frontend.dashboard'
243
- ]);
244
- });
245
- it('should sort using nested in/out edges', () => {
246
- expectSorting(nodes, [
247
- ['customer', 'cloud.frontend.dashboard'],
248
- ['support', 'cloud.frontend.adminPanel'],
249
- ['cloud.frontend.dashboard', 'cloud.backend.graphql'],
250
- ['cloud.frontend.adminPanel', 'cloud.backend.graphql'],
251
- ['cloud.backend.graphql', 'cloud.backend.storage'],
252
- ['cloud.backend.storage', 'amazon.rds']
253
- ]).toEqual([
254
- 'customer',
255
- 'support',
256
- 'cloud',
257
- 'cloud.frontend.dashboard',
258
- 'cloud.frontend.adminPanel',
259
- 'cloud.backend',
260
- 'cloud.backend.graphql',
261
- 'cloud.backend.storage',
262
- 'amazon',
263
- 'amazon.rds'
264
- ]);
265
- });
266
- });
267
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,47 +0,0 @@
1
- import { expect, describe, it } from 'vitest';
2
- import { commonAncestor, compareFqnHierarchically, isAncestor, parentFqn } from './fqn';
3
- describe('parentFqn', () => {
4
- it('should return null if no parent', () => {
5
- expect(parentFqn('a')).toBeNull();
6
- });
7
- it('should return parent', () => {
8
- expect(parentFqn('a.b')).toBe('a');
9
- expect(parentFqn('a.b.c')).toBe('a.b');
10
- });
11
- });
12
- describe('commonAncestor', () => {
13
- it('should return null if no common ancestor', () => {
14
- expect(commonAncestor('a', 'b')).toBeNull();
15
- expect(commonAncestor('a.b', 'c.d')).toBeNull();
16
- });
17
- it('should return common ancestor', () => {
18
- expect(commonAncestor('a.b', 'a.c')).toBe('a');
19
- expect(commonAncestor('a.b.c', 'a.b.e')).toBe('a.b');
20
- expect(commonAncestor('a.b.c.d.e', 'a.b.c.d')).toBe('a.b.c');
21
- });
22
- });
23
- describe('isAncestor', () => {
24
- it('should return true if ancestor', () => {
25
- expect(isAncestor('a', 'a.b')).toBe(true);
26
- expect(isAncestor('a.b', 'a.b.c')).toBe(true);
27
- });
28
- it('should return false if not ancestor', () => {
29
- expect(isAncestor('a', 'b')).toBe(false);
30
- expect(isAncestor('a.b', 'a')).toBe(false);
31
- expect(isAncestor('a.b', 'b.a')).toBe(false);
32
- });
33
- });
34
- describe('compareFqnHierarchically', () => {
35
- it('should compare hierarchically', () => {
36
- expect(['a', 'b', 'a.b', 'a.b.c', 'a.c.c'].sort(compareFqnHierarchically)).toEqual([
37
- 'a',
38
- 'b',
39
- 'a.b',
40
- 'a.b.c',
41
- 'a.c.c'
42
- ]);
43
- });
44
- it('should compare hierarchically 2', () => {
45
- expect(['aaa', 'aa', 'a', 'aaa.c', 'aa.b', 'a.b', 'a.c'].sort(compareFqnHierarchically)).toEqual(['a', 'aa', 'aaa', 'a.b', 'a.c', 'aa.b', 'aaa.c']);
46
- });
47
- });