docusaurus-plugin-generate-schema-docs 1.8.4 → 1.8.5
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 +10 -0
- package/__tests__/__fixtures__/validateSchemas/schema-with-not-anyof-multi.json +12 -0
- package/__tests__/__fixtures__/validateSchemas/schema-with-not-anyof.json +30 -0
- package/__tests__/__fixtures__/validateSchemas/schema-with-not-edge-cases.json +24 -0
- package/__tests__/__fixtures__/validateSchemas/schema-with-not-non-object.json +15 -0
- package/__tests__/generateEventDocs.anchor.test.js +1 -1
- package/__tests__/generateEventDocs.nested.test.js +1 -1
- package/__tests__/generateEventDocs.partials.test.js +1 -1
- package/__tests__/generateEventDocs.test.js +506 -1
- package/__tests__/generateEventDocs.versioned.test.js +1 -1
- package/__tests__/helpers/buildExampleFromSchema.test.js +240 -0
- package/__tests__/helpers/constraintSchemaPaths.test.js +208 -0
- package/__tests__/helpers/continuingLinesStyle.test.js +492 -0
- package/__tests__/helpers/exampleModel.test.js +209 -0
- package/__tests__/helpers/file-system.test.js +73 -1
- package/__tests__/helpers/getConstraints.test.js +27 -0
- package/__tests__/helpers/mergeSchema.test.js +94 -0
- package/__tests__/helpers/processSchema.test.js +291 -1
- package/__tests__/helpers/schema-doc-template.test.js +54 -0
- package/__tests__/helpers/schema-processing.test.js +122 -2
- package/__tests__/helpers/schemaToExamples.test.js +1007 -0
- package/__tests__/helpers/schemaToTableData.mutations.test.js +970 -0
- package/__tests__/helpers/schemaToTableData.test.js +157 -0
- package/__tests__/helpers/snippetTargets.test.js +432 -0
- package/__tests__/helpers/trackingTargets.test.js +319 -0
- package/__tests__/helpers/validator.test.js +385 -1
- package/__tests__/index.test.js +436 -0
- package/__tests__/syncGtm.test.js +139 -3
- package/__tests__/update-schema-ids.test.js +70 -1
- package/__tests__/validateSchemas-integration.test.js +2 -2
- package/__tests__/validateSchemas.test.js +142 -1
- package/generateEventDocs.js +21 -1
- package/helpers/constraintSchemaPaths.js +10 -14
- package/helpers/schemaToTableData.js +538 -492
- package/helpers/trackingTargets.js +26 -3
- package/helpers/validator.js +18 -4
- package/index.js +1 -2
- package/package.json +1 -1
- package/scripts/sync-gtm.js +25 -7
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getBracketPosition,
|
|
3
|
+
getBracketColor,
|
|
4
|
+
getBracketLinesStyle,
|
|
5
|
+
mergeBackgroundStyles,
|
|
6
|
+
getContinuingLinesStyle,
|
|
7
|
+
} from '../../helpers/continuingLinesStyle';
|
|
8
|
+
|
|
9
|
+
describe('getBracketPosition', () => {
|
|
10
|
+
it('returns 0.5 for bracketIndex 0', () => {
|
|
11
|
+
expect(getBracketPosition(0)).toBe(0.5);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('returns 0.75 for bracketIndex 1', () => {
|
|
15
|
+
expect(getBracketPosition(1)).toBe(0.75);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('returns 1.0 for bracketIndex 2', () => {
|
|
19
|
+
expect(getBracketPosition(2)).toBe(1.0);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('returns 1.25 for bracketIndex 3', () => {
|
|
23
|
+
expect(getBracketPosition(3)).toBe(1.25);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('increases position with each index (uses addition not subtraction)', () => {
|
|
27
|
+
expect(getBracketPosition(1)).toBeGreaterThan(getBracketPosition(0));
|
|
28
|
+
expect(getBracketPosition(2)).toBeGreaterThan(getBracketPosition(1));
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('uses multiplication not division for step size', () => {
|
|
32
|
+
const step = getBracketPosition(1) - getBracketPosition(0);
|
|
33
|
+
expect(step).toBe(0.25);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
describe('getBracketColor', () => {
|
|
38
|
+
it('returns the first color for index 0', () => {
|
|
39
|
+
expect(getBracketColor(0)).toBe('var(--ifm-color-info)');
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('returns the second color for index 1', () => {
|
|
43
|
+
expect(getBracketColor(1)).toBe('var(--ifm-color-warning)');
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('returns the third color for index 2', () => {
|
|
47
|
+
expect(getBracketColor(2)).toBe('var(--ifm-color-success)');
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('wraps around using modulo — index 3 returns first color again', () => {
|
|
51
|
+
expect(getBracketColor(3)).toBe(getBracketColor(0));
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('wraps around using modulo — index 4 returns second color again', () => {
|
|
55
|
+
expect(getBracketColor(4)).toBe(getBracketColor(1));
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('uses modulo not multiplication (does not go out of array bounds)', () => {
|
|
59
|
+
expect(() => getBracketColor(10)).not.toThrow();
|
|
60
|
+
expect(getBracketColor(10)).toBeDefined();
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
describe('getBracketLinesStyle', () => {
|
|
65
|
+
it('returns empty object for empty groupBrackets', () => {
|
|
66
|
+
expect(getBracketLinesStyle([])).toEqual({});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('returns empty object when groupBrackets defaults to empty', () => {
|
|
70
|
+
expect(getBracketLinesStyle()).toEqual({});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('returns style object with all background properties for a single bracket', () => {
|
|
74
|
+
const result = getBracketLinesStyle([{ level: 0, bracketIndex: 0 }]);
|
|
75
|
+
expect(result).toHaveProperty('backgroundImage');
|
|
76
|
+
expect(result).toHaveProperty('backgroundSize');
|
|
77
|
+
expect(result).toHaveProperty('backgroundPosition');
|
|
78
|
+
expect(result).toHaveProperty('backgroundRepeat', 'no-repeat');
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('produces exactly one gradient for a bracket with no caps', () => {
|
|
82
|
+
const result = getBracketLinesStyle([{ level: 0, bracketIndex: 0 }], {});
|
|
83
|
+
const gradientCount = (
|
|
84
|
+
result.backgroundImage.match(/linear-gradient/g) || []
|
|
85
|
+
).length;
|
|
86
|
+
expect(gradientCount).toBe(1);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('produces two gradients for a bracket with starting cap', () => {
|
|
90
|
+
const bracket = { level: 0, bracketIndex: 0 };
|
|
91
|
+
const result = getBracketLinesStyle([bracket], {
|
|
92
|
+
starting: [bracket],
|
|
93
|
+
});
|
|
94
|
+
const gradientCount =
|
|
95
|
+
result.backgroundImage.split('), linear-gradient').length;
|
|
96
|
+
expect(gradientCount).toBe(2);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('produces two gradients for a bracket with ending cap', () => {
|
|
100
|
+
const bracket = { level: 0, bracketIndex: 0 };
|
|
101
|
+
const result = getBracketLinesStyle([bracket], {
|
|
102
|
+
ending: [bracket],
|
|
103
|
+
});
|
|
104
|
+
const gradientCount =
|
|
105
|
+
result.backgroundImage.split('), linear-gradient').length;
|
|
106
|
+
expect(gradientCount).toBe(2);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('produces three gradients for a bracket with both starting and ending caps', () => {
|
|
110
|
+
const bracket = { level: 0, bracketIndex: 0 };
|
|
111
|
+
const result = getBracketLinesStyle([bracket], {
|
|
112
|
+
starting: [bracket],
|
|
113
|
+
ending: [bracket],
|
|
114
|
+
});
|
|
115
|
+
const gradientCount =
|
|
116
|
+
result.backgroundImage.split('), linear-gradient').length;
|
|
117
|
+
expect(gradientCount).toBe(3);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('includes the bracket color in the gradient', () => {
|
|
121
|
+
const result = getBracketLinesStyle([{ level: 0, bracketIndex: 0 }]);
|
|
122
|
+
expect(result.backgroundImage).toContain('var(--ifm-color-info)');
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('uses bracketIndex 1 color for bracketIndex 1', () => {
|
|
126
|
+
const result = getBracketLinesStyle([{ level: 0, bracketIndex: 1 }]);
|
|
127
|
+
expect(result.backgroundImage).toContain('var(--ifm-color-warning)');
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it('positions the line at the correct rem offset', () => {
|
|
131
|
+
const result = getBracketLinesStyle([{ level: 0, bracketIndex: 0 }]);
|
|
132
|
+
expect(result.backgroundPosition).toContain('right 0.5rem');
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('positions bracketIndex 1 further right than bracketIndex 0', () => {
|
|
136
|
+
const result0 = getBracketLinesStyle([{ level: 0, bracketIndex: 0 }]);
|
|
137
|
+
const result1 = getBracketLinesStyle([{ level: 0, bracketIndex: 1 }]);
|
|
138
|
+
expect(result1.backgroundPosition).toContain('right 0.75rem');
|
|
139
|
+
expect(result0.backgroundPosition).toContain('right 0.5rem');
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it('produces a full-height line (100%) when no caps', () => {
|
|
143
|
+
const result = getBracketLinesStyle([{ level: 0, bracketIndex: 0 }]);
|
|
144
|
+
expect(result.backgroundSize).toContain('1px calc(100% - 0px)');
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('shortens line height when starting cap is present (inset from top)', () => {
|
|
148
|
+
const bracket = { level: 0, bracketIndex: 0 };
|
|
149
|
+
const result = getBracketLinesStyle([bracket], { starting: [bracket] });
|
|
150
|
+
// CAP_INSET is 6, so top inset = 6, bottom = 0 → calc(100% - 6px)
|
|
151
|
+
expect(result.backgroundSize).toContain('1px calc(100% - 6px)');
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('shortens line height when ending cap is present (inset from bottom)', () => {
|
|
155
|
+
const bracket = { level: 0, bracketIndex: 0 };
|
|
156
|
+
const result = getBracketLinesStyle([bracket], { ending: [bracket] });
|
|
157
|
+
expect(result.backgroundSize).toContain('1px calc(100% - 6px)');
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it('shortens line height by 12px when both caps are present', () => {
|
|
161
|
+
const bracket = { level: 0, bracketIndex: 0 };
|
|
162
|
+
const result = getBracketLinesStyle([bracket], {
|
|
163
|
+
starting: [bracket],
|
|
164
|
+
ending: [bracket],
|
|
165
|
+
});
|
|
166
|
+
expect(result.backgroundSize).toContain('1px calc(100% - 12px)');
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it('cap size uses CAP_WIDTH (10px) not some other value', () => {
|
|
170
|
+
const bracket = { level: 0, bracketIndex: 0 };
|
|
171
|
+
const result = getBracketLinesStyle([bracket], { starting: [bracket] });
|
|
172
|
+
// The cap entry is "10px 1px"
|
|
173
|
+
expect(result.backgroundSize).toContain('10px 1px');
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it('starting cap is positioned at top CAP_INSET (6px)', () => {
|
|
177
|
+
const bracket = { level: 0, bracketIndex: 0 };
|
|
178
|
+
const result = getBracketLinesStyle([bracket], { starting: [bracket] });
|
|
179
|
+
expect(result.backgroundPosition).toContain('top 6px');
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it('ending cap is positioned at bottom CAP_INSET (6px)', () => {
|
|
183
|
+
const bracket = { level: 0, bracketIndex: 0 };
|
|
184
|
+
const result = getBracketLinesStyle([bracket], { ending: [bracket] });
|
|
185
|
+
expect(result.backgroundPosition).toContain('bottom 6px');
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it('matches cap key by level:bracketIndex — a different bracket does not get a cap', () => {
|
|
189
|
+
const bracket = { level: 0, bracketIndex: 0 };
|
|
190
|
+
const otherBracket = { level: 1, bracketIndex: 0 };
|
|
191
|
+
const result = getBracketLinesStyle([bracket], {
|
|
192
|
+
starting: [otherBracket],
|
|
193
|
+
});
|
|
194
|
+
// No cap → full height line
|
|
195
|
+
expect(result.backgroundSize).toContain('1px calc(100% - 0px)');
|
|
196
|
+
// Only one gradient (no cap added)
|
|
197
|
+
expect(result.backgroundImage.split('), linear-gradient').length).toBe(1);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it('handles multiple brackets, producing one gradient entry per bracket', () => {
|
|
201
|
+
const brackets = [
|
|
202
|
+
{ level: 0, bracketIndex: 0 },
|
|
203
|
+
{ level: 1, bracketIndex: 1 },
|
|
204
|
+
];
|
|
205
|
+
const result = getBracketLinesStyle(brackets);
|
|
206
|
+
// 2 brackets × 1 gradient each = 2 gradients
|
|
207
|
+
expect(result.backgroundImage.split('), linear-gradient').length).toBe(2);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
it('uses the correct cap offset formula: (CAP_WIDTH - 1) / 2 = 4.5px', () => {
|
|
211
|
+
const bracket = { level: 0, bracketIndex: 0 };
|
|
212
|
+
const result = getBracketLinesStyle([bracket], { starting: [bracket] });
|
|
213
|
+
// capOffset = (10 - 1) / 2 = 4.5
|
|
214
|
+
expect(result.backgroundPosition).toContain('calc(0.5rem - 4.5px)');
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it('ending cap also uses the correct cap offset formula: (CAP_WIDTH - 1) / 2 = 4.5px', () => {
|
|
218
|
+
const bracket = { level: 0, bracketIndex: 0 };
|
|
219
|
+
const result = getBracketLinesStyle([bracket], { ending: [bracket] });
|
|
220
|
+
// capOffset = (10 - 1) / 2 = 4.5, not (10 - 1) * 2 = 18, not (10 + 1) / 2 = 5.5
|
|
221
|
+
expect(result.backgroundPosition).toContain('calc(0.5rem - 4.5px)');
|
|
222
|
+
expect(result.backgroundPosition).not.toContain('calc(0.5rem - 18px)');
|
|
223
|
+
expect(result.backgroundPosition).not.toContain('calc(0.5rem - 5.5px)');
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
it('ending cap size is 10px 1px (not empty)', () => {
|
|
227
|
+
const bracket = { level: 0, bracketIndex: 0 };
|
|
228
|
+
const result = getBracketLinesStyle([bracket], { ending: [bracket] });
|
|
229
|
+
expect(result.backgroundSize).toContain('10px 1px');
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
it('joins gradients with ", " separator (not empty string)', () => {
|
|
233
|
+
const brackets = [
|
|
234
|
+
{ level: 0, bracketIndex: 0 },
|
|
235
|
+
{ level: 1, bracketIndex: 1 },
|
|
236
|
+
];
|
|
237
|
+
const result = getBracketLinesStyle(brackets);
|
|
238
|
+
// With 2 brackets there should be a comma-space separator between gradients
|
|
239
|
+
expect(result.backgroundImage).toContain('), linear-gradient(');
|
|
240
|
+
expect(result.backgroundSize).toContain(', ');
|
|
241
|
+
expect(result.backgroundPosition).toContain(', ');
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
it('initializes internal arrays as empty (not pre-populated)', () => {
|
|
245
|
+
// A single bracket with no caps should produce exactly 1 gradient entry
|
|
246
|
+
const bracket = { level: 0, bracketIndex: 0 };
|
|
247
|
+
const result = getBracketLinesStyle([bracket]);
|
|
248
|
+
// If arrays were initialized with ["Stryker was here"], we'd see extra content
|
|
249
|
+
expect(result.backgroundImage).toBe(
|
|
250
|
+
'linear-gradient(var(--ifm-color-info), var(--ifm-color-info))',
|
|
251
|
+
);
|
|
252
|
+
expect(result.backgroundSize).toBe('1px calc(100% - 0px)');
|
|
253
|
+
expect(result.backgroundPosition).toBe('right 0.5rem top 0px');
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
it('starting/ending key sets start empty (caps only match explicitly listed brackets)', () => {
|
|
257
|
+
// Providing no caps at all — the bracket should have no caps applied
|
|
258
|
+
const bracket = { level: 0, bracketIndex: 0 };
|
|
259
|
+
const result = getBracketLinesStyle([bracket], {});
|
|
260
|
+
// If startingKeys/endingKeys were pre-filled, the bracket might match a cap
|
|
261
|
+
expect(result.backgroundSize).toBe('1px calc(100% - 0px)');
|
|
262
|
+
// Only 1 gradient (no cap gradients)
|
|
263
|
+
expect(result.backgroundImage.split('linear-gradient').length - 1).toBe(1);
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
describe('mergeBackgroundStyles', () => {
|
|
268
|
+
const styleA = {
|
|
269
|
+
backgroundImage: 'linear-gradient(red, red)',
|
|
270
|
+
backgroundSize: '1px 100%',
|
|
271
|
+
backgroundPosition: '1rem top',
|
|
272
|
+
backgroundRepeat: 'no-repeat',
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
const styleB = {
|
|
276
|
+
backgroundImage: 'linear-gradient(blue, blue)',
|
|
277
|
+
backgroundSize: '2px 100%',
|
|
278
|
+
backgroundPosition: '2rem top',
|
|
279
|
+
backgroundRepeat: 'no-repeat',
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
it('returns style1 when style2 has no backgroundImage', () => {
|
|
283
|
+
expect(mergeBackgroundStyles(styleA, {})).toEqual(styleA);
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
it('returns style2 spread over style1 when style1 has no backgroundImage', () => {
|
|
287
|
+
const result = mergeBackgroundStyles({}, styleB);
|
|
288
|
+
expect(result).toMatchObject(styleB);
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
it('preserves style1 properties when style1 has no backgroundImage', () => {
|
|
292
|
+
const style1WithExtra = { paddingLeft: '1rem' };
|
|
293
|
+
const result = mergeBackgroundStyles(style1WithExtra, styleB);
|
|
294
|
+
expect(result.paddingLeft).toBe('1rem');
|
|
295
|
+
expect(result.backgroundImage).toBe(styleB.backgroundImage);
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
it('merges backgroundImage from both styles', () => {
|
|
299
|
+
const result = mergeBackgroundStyles(styleA, styleB);
|
|
300
|
+
expect(result.backgroundImage).toBe(
|
|
301
|
+
`${styleA.backgroundImage}, ${styleB.backgroundImage}`,
|
|
302
|
+
);
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
it('merges backgroundSize from both styles', () => {
|
|
306
|
+
const result = mergeBackgroundStyles(styleA, styleB);
|
|
307
|
+
expect(result.backgroundSize).toBe(
|
|
308
|
+
`${styleA.backgroundSize}, ${styleB.backgroundSize}`,
|
|
309
|
+
);
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
it('merges backgroundPosition from both styles', () => {
|
|
313
|
+
const result = mergeBackgroundStyles(styleA, styleB);
|
|
314
|
+
expect(result.backgroundPosition).toBe(
|
|
315
|
+
`${styleA.backgroundPosition}, ${styleB.backgroundPosition}`,
|
|
316
|
+
);
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
it('sets backgroundRepeat to no-repeat in merged result', () => {
|
|
320
|
+
const result = mergeBackgroundStyles(styleA, styleB);
|
|
321
|
+
expect(result.backgroundRepeat).toBe('no-repeat');
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
it('preserves other style1 properties in the merged result', () => {
|
|
325
|
+
const extended = { ...styleA, paddingLeft: '1rem' };
|
|
326
|
+
const result = mergeBackgroundStyles(extended, styleB);
|
|
327
|
+
expect(result.paddingLeft).toBe('1rem');
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
it('order matters — style1 backgroundImage comes first', () => {
|
|
331
|
+
const result = mergeBackgroundStyles(styleA, styleB);
|
|
332
|
+
expect(result.backgroundImage.startsWith(styleA.backgroundImage)).toBe(
|
|
333
|
+
true,
|
|
334
|
+
);
|
|
335
|
+
});
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
describe('getContinuingLinesStyle', () => {
|
|
339
|
+
it('returns just paddingLeft when no continuingLevels and level 0', () => {
|
|
340
|
+
expect(getContinuingLinesStyle([], 0)).toEqual({ paddingLeft: '0.5rem' });
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
it('returns just paddingLeft when no continuingLevels and level > 0', () => {
|
|
344
|
+
// level 1 → paddingLeft = 1*1.25 + 0.5 = 1.75rem
|
|
345
|
+
// level > 0 draws parent line only if not already in continuingLevels
|
|
346
|
+
// continuingLevels is empty so parent line IS drawn → not just paddingLeft
|
|
347
|
+
const result = getContinuingLinesStyle([], 1);
|
|
348
|
+
expect(result.paddingLeft).toBe('1.75rem');
|
|
349
|
+
expect(result.backgroundImage).toBeDefined();
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
it('returns paddingLeft only when level is 0 with no continuingLevels', () => {
|
|
353
|
+
const result = getContinuingLinesStyle([], 0);
|
|
354
|
+
expect(Object.keys(result)).toEqual(['paddingLeft']);
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
it('calculates paddingLeft correctly for level 0: 0*1.25+0.5 = 0.5rem', () => {
|
|
358
|
+
expect(getContinuingLinesStyle([], 0).paddingLeft).toBe('0.5rem');
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
it('calculates paddingLeft correctly for level 1: 1*1.25+0.5 = 1.75rem', () => {
|
|
362
|
+
expect(getContinuingLinesStyle([], 1).paddingLeft).toBe('1.75rem');
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
it('calculates paddingLeft correctly for level 2: 2*1.25+0.5 = 3rem', () => {
|
|
366
|
+
expect(getContinuingLinesStyle([], 2).paddingLeft).toBe('3rem');
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
it('uses multiplication not division in paddingLeft formula', () => {
|
|
370
|
+
// if it were division: 2/1.25+0.5 = 2.1rem, multiplication gives 3rem
|
|
371
|
+
expect(getContinuingLinesStyle([], 2).paddingLeft).toBe('3rem');
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
it('adds background styles when continuingLevels is non-empty', () => {
|
|
375
|
+
const result = getContinuingLinesStyle([0], 1);
|
|
376
|
+
expect(result).toHaveProperty('backgroundImage');
|
|
377
|
+
expect(result).toHaveProperty('backgroundSize');
|
|
378
|
+
expect(result).toHaveProperty('backgroundPosition');
|
|
379
|
+
expect(result).toHaveProperty('backgroundRepeat', 'no-repeat');
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
it('draws one gradient per continuing level', () => {
|
|
383
|
+
const result = getContinuingLinesStyle([0, 1], 3);
|
|
384
|
+
// 2 continuing levels + 1 parent line (level 2, not in continuingLevels) = 3 gradients
|
|
385
|
+
const gradientCount =
|
|
386
|
+
result.backgroundImage.split('), linear-gradient').length;
|
|
387
|
+
expect(gradientCount).toBe(3);
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
it('does not add parent line when level is 0', () => {
|
|
391
|
+
const result = getContinuingLinesStyle([0], 0);
|
|
392
|
+
// Only 1 continuing level, no parent line (level 0 has no parent)
|
|
393
|
+
const gradientCount =
|
|
394
|
+
result.backgroundImage.split('), linear-gradient').length;
|
|
395
|
+
expect(gradientCount).toBe(1);
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
it('adds parent line when level > 0 and parent not in continuingLevels', () => {
|
|
399
|
+
const result = getContinuingLinesStyle([], 1);
|
|
400
|
+
// 0 continuing + 1 parent = 1 gradient total
|
|
401
|
+
const gradientCount =
|
|
402
|
+
result.backgroundImage.split('), linear-gradient').length;
|
|
403
|
+
expect(gradientCount).toBe(1);
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
it('does not add duplicate parent line when parent already in continuingLevels', () => {
|
|
407
|
+
// level=1, so parent is level=0; continuingLevels includes 0 already
|
|
408
|
+
const result = getContinuingLinesStyle([0], 1);
|
|
409
|
+
// 1 continuing level (0) + no extra parent line = 1 gradient
|
|
410
|
+
const gradientCount =
|
|
411
|
+
result.backgroundImage.split('), linear-gradient').length;
|
|
412
|
+
expect(gradientCount).toBe(1);
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
it('uses level - 1 not level for parent position calculation', () => {
|
|
416
|
+
const resultL1 = getContinuingLinesStyle([], 1);
|
|
417
|
+
const resultL2 = getContinuingLinesStyle([], 2);
|
|
418
|
+
// level 1 → parent at level 0 → pos = 0*1.25+0.5 = 0.5rem
|
|
419
|
+
// level 2 → parent at level 1 → pos = 1*1.25+0.5 = 1.75rem
|
|
420
|
+
expect(resultL1.backgroundPosition).toContain('0.5rem');
|
|
421
|
+
expect(resultL2.backgroundPosition).toContain('1.75rem');
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
it('positions each continuing level correctly', () => {
|
|
425
|
+
const result = getContinuingLinesStyle([0], 2);
|
|
426
|
+
// level 0 position: 0*1.25+0.5 = 0.5rem
|
|
427
|
+
expect(result.backgroundPosition).toContain('0.5rem');
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
it('uses 100% height for all gradient lines', () => {
|
|
431
|
+
const result = getContinuingLinesStyle([0], 2);
|
|
432
|
+
expect(result.backgroundSize).toContain('1px 100%');
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
it('uses the table border color CSS variable', () => {
|
|
436
|
+
const result = getContinuingLinesStyle([0], 2);
|
|
437
|
+
expect(result.backgroundImage).toContain('var(--ifm-table-border-color)');
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
it('defaults continuingLevels to [] when not provided', () => {
|
|
441
|
+
expect(() => getContinuingLinesStyle()).not.toThrow();
|
|
442
|
+
expect(getContinuingLinesStyle()).toEqual({ paddingLeft: '0.5rem' });
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
it('defaults level to 0 when not provided', () => {
|
|
446
|
+
expect(getContinuingLinesStyle([])).toEqual({ paddingLeft: '0.5rem' });
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
it('level comparison is strictly > 0, not >= 0', () => {
|
|
450
|
+
// level 0: no parent line added
|
|
451
|
+
const atZero = getContinuingLinesStyle([], 0);
|
|
452
|
+
expect(Object.keys(atZero)).toEqual(['paddingLeft']);
|
|
453
|
+
|
|
454
|
+
// level 1: parent line added
|
|
455
|
+
const atOne = getContinuingLinesStyle([], 1);
|
|
456
|
+
expect(atOne).toHaveProperty('backgroundImage');
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
it('internal gradient arrays start empty (single level produces exactly one entry)', () => {
|
|
460
|
+
const result = getContinuingLinesStyle([0], 0);
|
|
461
|
+
// If arrays were initialized with ["Stryker was here"], we'd see extra/wrong content
|
|
462
|
+
expect(result.backgroundImage).toBe(
|
|
463
|
+
'linear-gradient(var(--ifm-table-border-color), var(--ifm-table-border-color))',
|
|
464
|
+
);
|
|
465
|
+
expect(result.backgroundSize).toBe('1px 100%');
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
it('continuing level size is exactly "1px 100%" (not empty string)', () => {
|
|
469
|
+
const result = getContinuingLinesStyle([0], 0);
|
|
470
|
+
expect(result.backgroundSize).toBe('1px 100%');
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
it('parent line size is exactly "1px 100%" (not empty string)', () => {
|
|
474
|
+
// level=2, empty continuingLevels → only parent line at level 1
|
|
475
|
+
const result = getContinuingLinesStyle([], 2);
|
|
476
|
+
expect(result.backgroundSize).toBe('1px 100%');
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
it('joins multiple entries with ", " separator in getContinuingLinesStyle', () => {
|
|
480
|
+
const result = getContinuingLinesStyle([0, 1], 3);
|
|
481
|
+
// 3 gradients: levels 0, 1, and parent at level 2
|
|
482
|
+
expect(result.backgroundImage).toContain('), linear-gradient(');
|
|
483
|
+
expect(result.backgroundSize).toContain(', ');
|
|
484
|
+
expect(result.backgroundPosition).toContain(', ');
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
it('allSizes array starts empty (not pre-populated)', () => {
|
|
488
|
+
const result = getContinuingLinesStyle([0], 0);
|
|
489
|
+
// Only one size entry for one continuing level
|
|
490
|
+
expect(result.backgroundSize.split(', ').length).toBe(1);
|
|
491
|
+
});
|
|
492
|
+
});
|