docusaurus-plugin-generate-schema-docs 1.6.0 → 1.7.0

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.
Files changed (30) hide show
  1. package/__tests__/__fixtures__/static/schemas/battle-test-event.json +771 -0
  2. package/__tests__/__fixtures__/static/schemas/conditional-event.json +52 -0
  3. package/__tests__/__fixtures__/static/schemas/nested-conditional-event.json +50 -0
  4. package/__tests__/components/ConditionalRows.test.js +150 -0
  5. package/__tests__/components/ConnectorLines.visualRegression.test.js +93 -0
  6. package/__tests__/components/FoldableRows.test.js +7 -4
  7. package/__tests__/components/SchemaRows.test.js +31 -0
  8. package/__tests__/components/__snapshots__/ConnectorLines.visualRegression.test.js.snap +7 -0
  9. package/__tests__/generateEventDocs.partials.test.js +134 -0
  10. package/__tests__/helpers/buildExampleFromSchema.test.js +49 -0
  11. package/__tests__/helpers/schemaToExamples.test.js +75 -0
  12. package/__tests__/helpers/schemaToTableData.battleTest.test.js +704 -0
  13. package/__tests__/helpers/schemaToTableData.hierarchicalLines.test.js +190 -7
  14. package/__tests__/helpers/schemaToTableData.test.js +263 -2
  15. package/__tests__/helpers/validator.test.js +6 -6
  16. package/components/ConditionalRows.js +156 -0
  17. package/components/FoldableRows.js +88 -61
  18. package/components/PropertiesTable.js +1 -1
  19. package/components/PropertyRow.js +24 -8
  20. package/components/SchemaRows.css +115 -0
  21. package/components/SchemaRows.js +31 -4
  22. package/generateEventDocs.js +41 -34
  23. package/helpers/buildExampleFromSchema.js +11 -0
  24. package/helpers/continuingLinesStyle.js +169 -0
  25. package/helpers/schema-doc-template.js +2 -5
  26. package/helpers/schemaToExamples.js +75 -2
  27. package/helpers/schemaToTableData.js +252 -26
  28. package/helpers/update-schema-ids.js +3 -3
  29. package/helpers/validator.js +7 -19
  30. package/package.json +1 -1
@@ -0,0 +1,52 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://tracking-docs-demo.buchert.digital/schemas/events/conditional-event.json",
4
+ "title": "Conditional Event",
5
+ "description": "An event with conditional properties based on country.",
6
+ "type": "object",
7
+ "properties": {
8
+ "event": {
9
+ "type": "string",
10
+ "const": "form_submit"
11
+ },
12
+ "country": {
13
+ "type": "string",
14
+ "description": "The user's country.",
15
+ "enum": ["US", "CA"],
16
+ "examples": ["US"]
17
+ }
18
+ },
19
+ "required": ["event", "country"],
20
+ "if": {
21
+ "properties": {
22
+ "country": { "const": "US" }
23
+ },
24
+ "required": ["country"]
25
+ },
26
+ "then": {
27
+ "properties": {
28
+ "postal_code": {
29
+ "type": "string",
30
+ "description": "US ZIP code format.",
31
+ "pattern": "[0-9]{5}",
32
+ "examples": ["90210"]
33
+ },
34
+ "state": {
35
+ "type": "string",
36
+ "description": "US state abbreviation.",
37
+ "examples": ["CA"]
38
+ }
39
+ },
40
+ "required": ["postal_code"]
41
+ },
42
+ "else": {
43
+ "properties": {
44
+ "postal_code": {
45
+ "type": "string",
46
+ "description": "Canadian postal code format.",
47
+ "pattern": "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]",
48
+ "examples": ["K1A 0B1"]
49
+ }
50
+ }
51
+ }
52
+ }
@@ -0,0 +1,50 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://tracking-docs-demo.buchert.digital/schemas/events/nested-conditional-event.json",
4
+ "title": "Nested Conditional Event",
5
+ "description": "An event with conditional properties nested inside a property.",
6
+ "type": "object",
7
+ "properties": {
8
+ "event": {
9
+ "type": "string",
10
+ "const": "order_placed"
11
+ },
12
+ "shipping": {
13
+ "type": "object",
14
+ "description": "Shipping details.",
15
+ "properties": {
16
+ "method": {
17
+ "type": "string",
18
+ "description": "The shipping method.",
19
+ "examples": ["express"]
20
+ }
21
+ },
22
+ "required": ["method"],
23
+ "if": {
24
+ "properties": {
25
+ "method": { "const": "express" }
26
+ },
27
+ "required": ["method"]
28
+ },
29
+ "then": {
30
+ "properties": {
31
+ "priority_level": {
32
+ "type": "string",
33
+ "description": "Express priority level.",
34
+ "examples": ["high"]
35
+ }
36
+ }
37
+ },
38
+ "else": {
39
+ "properties": {
40
+ "estimated_days": {
41
+ "type": "integer",
42
+ "description": "Estimated delivery days.",
43
+ "examples": [5]
44
+ }
45
+ }
46
+ }
47
+ }
48
+ },
49
+ "required": ["event", "shipping"]
50
+ }
@@ -0,0 +1,150 @@
1
+ import '@testing-library/jest-dom';
2
+ import React from 'react';
3
+ import { render, screen, fireEvent } from '@testing-library/react';
4
+ import ConditionalRows from '../../components/ConditionalRows';
5
+
6
+ jest.mock('../../components/SchemaRows', () => {
7
+ const MockSchemaRows = (props) => (
8
+ <tr data-testid="schema-rows">
9
+ <td>{JSON.stringify(props.tableData)}</td>
10
+ </tr>
11
+ );
12
+ MockSchemaRows.displayName = 'MockSchemaRows';
13
+ return MockSchemaRows;
14
+ });
15
+
16
+ describe('ConditionalRows', () => {
17
+ const conditionalRow = {
18
+ type: 'conditional',
19
+ path: ['if/then/else'],
20
+ level: 0,
21
+ continuingLevels: [],
22
+ condition: {
23
+ title: 'If',
24
+ description: 'When country is US',
25
+ rows: [{ name: 'country', isCondition: true }],
26
+ },
27
+ branches: [
28
+ {
29
+ title: 'Then',
30
+ description: 'US-specific fields',
31
+ rows: [{ name: 'postal_code' }],
32
+ },
33
+ {
34
+ title: 'Else',
35
+ description: 'Non-US fields',
36
+ rows: [{ name: 'province' }],
37
+ },
38
+ ],
39
+ };
40
+
41
+ it('renders condition (if) rows always visible', () => {
42
+ render(
43
+ <table>
44
+ <tbody>
45
+ <ConditionalRows row={conditionalRow} />
46
+ </tbody>
47
+ </table>,
48
+ );
49
+
50
+ expect(screen.getByText('If')).toBeInTheDocument();
51
+ expect(
52
+ screen.getByText(
53
+ JSON.stringify([{ name: 'country', isCondition: true }]),
54
+ ),
55
+ ).toBeInTheDocument();
56
+ });
57
+
58
+ it('shows Then branch by default', () => {
59
+ render(
60
+ <table>
61
+ <tbody>
62
+ <ConditionalRows row={conditionalRow} />
63
+ </tbody>
64
+ </table>,
65
+ );
66
+
67
+ expect(
68
+ screen.getByText(JSON.stringify([{ name: 'postal_code' }])),
69
+ ).toBeInTheDocument();
70
+ expect(
71
+ screen.queryByText(JSON.stringify([{ name: 'province' }])),
72
+ ).not.toBeInTheDocument();
73
+ });
74
+
75
+ it('switches to Else branch when clicked', () => {
76
+ render(
77
+ <table>
78
+ <tbody>
79
+ <ConditionalRows row={conditionalRow} />
80
+ </tbody>
81
+ </table>,
82
+ );
83
+
84
+ // Click the Else toggle
85
+ fireEvent.click(screen.getByText('Else'));
86
+
87
+ // Now Else should be visible and Then should be hidden
88
+ expect(
89
+ screen.queryByText(JSON.stringify([{ name: 'postal_code' }])),
90
+ ).not.toBeInTheDocument();
91
+ expect(
92
+ screen.getByText(JSON.stringify([{ name: 'province' }])),
93
+ ).toBeInTheDocument();
94
+ });
95
+
96
+ it('renders condition description when present', () => {
97
+ render(
98
+ <table>
99
+ <tbody>
100
+ <ConditionalRows row={conditionalRow} />
101
+ </tbody>
102
+ </table>,
103
+ );
104
+
105
+ expect(screen.getByText('When country is US')).toBeInTheDocument();
106
+ });
107
+
108
+ it('applies correct indentation for nested levels', () => {
109
+ const nestedRow = {
110
+ ...conditionalRow,
111
+ level: 2,
112
+ continuingLevels: [0],
113
+ };
114
+
115
+ const { container } = render(
116
+ <table>
117
+ <tbody>
118
+ <ConditionalRows row={nestedRow} />
119
+ </tbody>
120
+ </table>,
121
+ );
122
+
123
+ const cells = container.querySelectorAll('td[colspan="5"]');
124
+ // level 2: 2 * 1.25 + 0.5 = 3rem
125
+ cells.forEach((cell) => {
126
+ expect(cell.style.paddingLeft).toBe('3rem');
127
+ });
128
+ });
129
+
130
+ it('handles conditional with only Then branch (no Else)', () => {
131
+ const rowWithoutElse = {
132
+ ...conditionalRow,
133
+ branches: [conditionalRow.branches[0]],
134
+ };
135
+
136
+ render(
137
+ <table>
138
+ <tbody>
139
+ <ConditionalRows row={rowWithoutElse} />
140
+ </tbody>
141
+ </table>,
142
+ );
143
+
144
+ expect(screen.getByText('Then')).toBeInTheDocument();
145
+ expect(screen.queryByText('Else')).not.toBeInTheDocument();
146
+ expect(
147
+ screen.getByText(JSON.stringify([{ name: 'postal_code' }])),
148
+ ).toBeInTheDocument();
149
+ });
150
+ });
@@ -0,0 +1,93 @@
1
+ import '@testing-library/jest-dom';
2
+ import React from 'react';
3
+ import { fireEvent, render, screen } from '@testing-library/react';
4
+ import FoldableRows from '../../components/FoldableRows';
5
+ import ConditionalRows from '../../components/ConditionalRows';
6
+ import { schemaToTableData } from '../../helpers/schemaToTableData';
7
+ import battleTestSchema from '../__fixtures__/static/schemas/battle-test-event.json';
8
+
9
+ const renderInTable = (ui) =>
10
+ render(
11
+ <table>
12
+ <tbody>{ui}</tbody>
13
+ </table>,
14
+ );
15
+
16
+ const getPropertyCellByName = (container, name) => {
17
+ const strongEls = Array.from(
18
+ container.querySelectorAll('span.property-name > strong'),
19
+ );
20
+ const strong = strongEls.find((el) => el.textContent === name);
21
+ return strong?.closest('td');
22
+ };
23
+
24
+ describe('connector lines visual regressions', () => {
25
+ const rows = schemaToTableData(battleTestSchema);
26
+
27
+ it('keeps user_id option row open when user conditional follows', () => {
28
+ const userIdChoice = rows.find(
29
+ (row) => row.type === 'choice' && row.name === 'user_id',
30
+ );
31
+
32
+ const { container } = renderInTable(<FoldableRows row={userIdChoice} />);
33
+ fireEvent.click(screen.getByText('Integer ID'));
34
+
35
+ const userIdCell = getPropertyCellByName(container, 'user_id');
36
+ expect(userIdCell).toBeInTheDocument();
37
+ expect(userIdCell).not.toHaveClass('is-last');
38
+ expect(userIdCell.outerHTML).toMatchSnapshot();
39
+ });
40
+
41
+ it('keeps wallet_provider option row open when wallet_email follows', () => {
42
+ const paymentChoice = rows.find(
43
+ (row) =>
44
+ row.type === 'choice' &&
45
+ row.path[0] === 'payment' &&
46
+ row.choiceType === 'anyOf',
47
+ );
48
+ const digitalWallet = paymentChoice.options.find(
49
+ (option) => option.title === 'Digital Wallet',
50
+ );
51
+ const walletProviderChoice = digitalWallet.rows.find(
52
+ (row) => row.type === 'choice' && row.name === 'wallet_provider',
53
+ );
54
+
55
+ const { container } = renderInTable(
56
+ <FoldableRows row={walletProviderChoice} />,
57
+ );
58
+ fireEvent.click(screen.getByText('Custom Provider'));
59
+
60
+ const walletProviderCell = getPropertyCellByName(
61
+ container,
62
+ 'wallet_provider',
63
+ );
64
+ expect(walletProviderCell).toBeInTheDocument();
65
+ expect(walletProviderCell).not.toHaveClass('is-last');
66
+ expect(walletProviderCell.outerHTML).toMatchSnapshot();
67
+ });
68
+
69
+ it('keeps cvv row open when payment choice has following options', () => {
70
+ const paymentChoice = rows.find(
71
+ (row) =>
72
+ row.type === 'choice' &&
73
+ row.path[0] === 'payment' &&
74
+ row.choiceType === 'anyOf',
75
+ );
76
+ const creditCard = paymentChoice.options.find(
77
+ (option) => option.title === 'Credit Card',
78
+ );
79
+ const cardConditional = creditCard.rows.find(
80
+ (row) => row.type === 'conditional',
81
+ );
82
+
83
+ const { container } = renderInTable(
84
+ <ConditionalRows row={cardConditional} />,
85
+ );
86
+ fireEvent.click(screen.getByText('Else'));
87
+
88
+ const cvvCell = getPropertyCellByName(container, 'cvv');
89
+ expect(cvvCell).toBeInTheDocument();
90
+ expect(cvvCell).not.toHaveClass('is-last');
91
+ expect(cvvCell.outerHTML).toMatchSnapshot();
92
+ });
93
+ });
@@ -233,7 +233,7 @@ describe('FoldableRows', () => {
233
233
  });
234
234
  });
235
235
 
236
- it('has no background-image for root level choices with no continuing levels', () => {
236
+ it('has a bracket gradient for root level choices with no continuing levels', () => {
237
237
  const rootLevelRow = {
238
238
  type: 'choice',
239
239
  choiceType: 'oneOf',
@@ -241,6 +241,7 @@ describe('FoldableRows', () => {
241
241
  level: 0,
242
242
  description: 'Root level choice',
243
243
  continuingLevels: [],
244
+ groupBrackets: [],
244
245
  options: [
245
246
  {
246
247
  title: 'Option A',
@@ -257,9 +258,10 @@ describe('FoldableRows', () => {
257
258
  </table>,
258
259
  );
259
260
 
261
+ // Root-level choice rows get a bracket gradient even without tree-line continuing levels
260
262
  const cells = container.querySelectorAll('td[colspan="5"]');
261
263
  cells.forEach((cell) => {
262
- expect(cell.style.backgroundImage).toBe('');
264
+ expect(cell.style.backgroundImage).toContain('linear-gradient');
263
265
  });
264
266
  });
265
267
 
@@ -290,9 +292,10 @@ describe('FoldableRows', () => {
290
292
  const cells = container.querySelectorAll('td[colspan="5"]');
291
293
  cells.forEach((cell) => {
292
294
  const bgImage = cell.style.backgroundImage;
293
- // Should have multiple gradients (one for each continuing level + parent)
295
+ // colSpan=5 rows only have bracket lines (right side), not tree lines (left side).
296
+ // Should have exactly 1 bracket gradient.
294
297
  const gradientCount = (bgImage.match(/linear-gradient/g) || []).length;
295
- expect(gradientCount).toBeGreaterThanOrEqual(2);
298
+ expect(gradientCount).toBeGreaterThanOrEqual(1);
296
299
  });
297
300
  });
298
301
 
@@ -24,6 +24,16 @@ jest.mock('../../components/FoldableRows', () => {
24
24
  return MockFoldableRows;
25
25
  });
26
26
 
27
+ jest.mock('../../components/ConditionalRows', () => {
28
+ const MockConditionalRows = (props) => (
29
+ <tr>
30
+ <td>Mocked ConditionalRows: {props.row.condition.title}</td>
31
+ </tr>
32
+ );
33
+ MockConditionalRows.displayName = 'MockConditionalRows';
34
+ return MockConditionalRows;
35
+ });
36
+
27
37
  describe('SchemaRows', () => {
28
38
  it('renders a PropertyRow for each property type item in tableData', () => {
29
39
  const tableData = [
@@ -107,4 +117,25 @@ describe('SchemaRows', () => {
107
117
  expect(getByText('Mocked FoldableRows: anyOf')).toBeInTheDocument();
108
118
  expect(getByText('Mocked PropertyRow: prop2')).toBeInTheDocument();
109
119
  });
120
+
121
+ it('renders a ConditionalRows for conditional type items in tableData', () => {
122
+ const tableData = [
123
+ {
124
+ type: 'conditional',
125
+ path: ['if/then/else'],
126
+ condition: { title: 'If', rows: [] },
127
+ branches: [],
128
+ },
129
+ ];
130
+
131
+ const { getByText } = render(
132
+ <table>
133
+ <tbody>
134
+ <SchemaRows tableData={tableData} />
135
+ </tbody>
136
+ </table>,
137
+ );
138
+
139
+ expect(getByText('Mocked ConditionalRows: If')).toBeInTheDocument();
140
+ });
110
141
  });
@@ -0,0 +1,7 @@
1
+ // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
2
+
3
+ exports[`connector lines visual regressions keeps cvv row open when payment choice has following options 1`] = `"<td rowspan="1" style="padding-left: 1.75rem;" class="level-1"><span class="property-name"><strong>cvv</strong></span></td>"`;
4
+
5
+ exports[`connector lines visual regressions keeps user_id option row open when user conditional follows 1`] = `"<td rowspan="1" style="padding-left: 1.75rem;" class="level-1"><span class="property-name"><strong>user_id</strong></span></td>"`;
6
+
7
+ exports[`connector lines visual regressions keeps wallet_provider option row open when wallet_email follows 1`] = `"<td rowspan="2" style="padding-left: 1.75rem;" class="level-1"><span class="property-name"><strong>wallet_provider</strong></span></td>"`;
@@ -0,0 +1,134 @@
1
+ /**
2
+ * @jest-environment node
3
+ *
4
+ * Tests that top and bottom partials are correctly injected into generated MDX
5
+ * when matching partial files exist in the partials directory, and that the
6
+ * generated import paths use the event name (not the component prefix).
7
+ */
8
+
9
+ import generateEventDocs from '../generateEventDocs';
10
+ import fs from 'fs';
11
+ import path from 'path';
12
+
13
+ jest.mock('fs', () => {
14
+ const memfs = require('memfs');
15
+ return memfs;
16
+ });
17
+
18
+ describe('generateEventDocs (partials)', () => {
19
+ const fixturesDir = path.resolve(__dirname, '__fixtures__');
20
+ const options = {
21
+ organizationName: 'test-org',
22
+ projectName: 'test-project',
23
+ siteDir: fixturesDir,
24
+ url: 'https://tracking-docs-demo.buchert.digital',
25
+ };
26
+ const outputDir = path.join(fixturesDir, 'docs');
27
+ const partialsDir = path.join(outputDir, 'partials');
28
+
29
+ beforeEach(() => {
30
+ fs.vol.reset();
31
+ const realFs = jest.requireActual('fs');
32
+
33
+ function readDirRecursive(dir) {
34
+ const files = realFs.readdirSync(dir, { withFileTypes: true });
35
+ for (const file of files) {
36
+ const filePath = path.join(dir, file.name);
37
+ if (file.isDirectory()) {
38
+ fs.vol.mkdirSync(filePath, { recursive: true });
39
+ readDirRecursive(filePath);
40
+ } else {
41
+ fs.vol.writeFileSync(filePath, realFs.readFileSync(filePath));
42
+ }
43
+ }
44
+ }
45
+ readDirRecursive(fixturesDir);
46
+ });
47
+
48
+ it('injects top partial when _<eventName>.mdx exists in partials dir', async () => {
49
+ console.log = jest.fn();
50
+ fs.vol.mkdirSync(partialsDir, { recursive: true });
51
+ fs.vol.writeFileSync(
52
+ path.join(partialsDir, '_add-to-cart-event.mdx'),
53
+ '## Top content',
54
+ );
55
+
56
+ await generateEventDocs(options);
57
+
58
+ const output = fs.readFileSync(
59
+ path.join(outputDir, 'add-to-cart-event.mdx'),
60
+ 'utf-8',
61
+ );
62
+
63
+ expect(output).toContain(
64
+ "import TopPartial from '@site/docs/partials/_add-to-cart-event.mdx'",
65
+ );
66
+ expect(output).toContain('<TopPartial />');
67
+ expect(output).not.toContain('_Top.mdx');
68
+ });
69
+
70
+ it('injects bottom partial when _<eventName>_bottom.mdx exists in partials dir', async () => {
71
+ console.log = jest.fn();
72
+ fs.vol.mkdirSync(partialsDir, { recursive: true });
73
+ fs.vol.writeFileSync(
74
+ path.join(partialsDir, '_add-to-cart-event_bottom.mdx'),
75
+ '## Bottom content',
76
+ );
77
+
78
+ await generateEventDocs(options);
79
+
80
+ const output = fs.readFileSync(
81
+ path.join(outputDir, 'add-to-cart-event.mdx'),
82
+ 'utf-8',
83
+ );
84
+
85
+ expect(output).toContain(
86
+ "import BottomPartial from '@site/docs/partials/_add-to-cart-event_bottom.mdx'",
87
+ );
88
+ expect(output).toContain('<BottomPartial />');
89
+ expect(output).not.toContain('_Bottom.mdx');
90
+ });
91
+
92
+ it('injects both top and bottom partials when both exist', async () => {
93
+ console.log = jest.fn();
94
+ fs.vol.mkdirSync(partialsDir, { recursive: true });
95
+ fs.vol.writeFileSync(
96
+ path.join(partialsDir, '_add-to-cart-event.mdx'),
97
+ '## Top content',
98
+ );
99
+ fs.vol.writeFileSync(
100
+ path.join(partialsDir, '_add-to-cart-event_bottom.mdx'),
101
+ '## Bottom content',
102
+ );
103
+
104
+ await generateEventDocs(options);
105
+
106
+ const output = fs.readFileSync(
107
+ path.join(outputDir, 'add-to-cart-event.mdx'),
108
+ 'utf-8',
109
+ );
110
+
111
+ expect(output).toContain(
112
+ "import TopPartial from '@site/docs/partials/_add-to-cart-event.mdx'",
113
+ );
114
+ expect(output).toContain('<TopPartial />');
115
+ expect(output).toContain(
116
+ "import BottomPartial from '@site/docs/partials/_add-to-cart-event_bottom.mdx'",
117
+ );
118
+ expect(output).toContain('<BottomPartial />');
119
+ });
120
+
121
+ it('omits partial imports when no partial files exist', async () => {
122
+ console.log = jest.fn();
123
+
124
+ await generateEventDocs(options);
125
+
126
+ const output = fs.readFileSync(
127
+ path.join(outputDir, 'add-to-cart-event.mdx'),
128
+ 'utf-8',
129
+ );
130
+
131
+ expect(output).not.toContain('TopPartial');
132
+ expect(output).not.toContain('BottomPartial');
133
+ });
134
+ });
@@ -185,4 +185,53 @@ describe('buildExampleFromSchema', () => {
185
185
  },
186
186
  });
187
187
  });
188
+
189
+ it('should handle if/then/else by defaulting to then branch', () => {
190
+ const schema = {
191
+ type: 'object',
192
+ properties: {
193
+ event: { type: 'string', examples: ['form_submit'] },
194
+ },
195
+ if: { properties: { event: { const: 'form_submit' } } },
196
+ then: {
197
+ properties: {
198
+ form_name: { type: 'string', examples: ['contact'] },
199
+ },
200
+ },
201
+ else: {
202
+ properties: {
203
+ error_code: { type: 'integer', examples: [404] },
204
+ },
205
+ },
206
+ };
207
+
208
+ const example = buildExampleFromSchema(schema);
209
+ expect(example).toHaveProperty('event', 'form_submit');
210
+ expect(example).toHaveProperty('form_name', 'contact');
211
+ expect(example).not.toHaveProperty('error_code');
212
+ });
213
+
214
+ it('should handle nested if/then/else inside a property', () => {
215
+ const schema = {
216
+ type: 'object',
217
+ properties: {
218
+ shipping: {
219
+ type: 'object',
220
+ properties: {
221
+ method: { type: 'string', examples: ['express'] },
222
+ },
223
+ if: { properties: { method: { const: 'express' } } },
224
+ then: {
225
+ properties: {
226
+ priority: { type: 'string', examples: ['high'] },
227
+ },
228
+ },
229
+ },
230
+ },
231
+ };
232
+
233
+ const example = buildExampleFromSchema(schema);
234
+ expect(example.shipping).toHaveProperty('method', 'express');
235
+ expect(example.shipping).toHaveProperty('priority', 'high');
236
+ });
188
237
  });