Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import { generateExamplesFromJsonSchema } from './exampleGeneration';
const modelWithNoExamples: JSONSchema7 = require('../../__fixtures__/models/model-with-no-examples.json');

describe('generateExamplesFromJsonSchema', () => {
afterEach(() => {
jest.restoreAllMocks();
});

it('returns error message when example generation fails ', () => {
const errorMessage = 'This is a mocked Error message';
jest.spyOn(Sampler, 'sample').mockImplementation(() => {
Expand All @@ -15,4 +19,196 @@ describe('generateExamplesFromJsonSchema', () => {
const example = generateExamplesFromJsonSchema(modelWithNoExamples);
expect(example).toEqual([{ label: '', data: `Example cannot be created for this schema\nError: ${errorMessage}` }]);
});

it('generates example from schema with examples array', () => {
const schema: JSONSchema7 = {
type: 'object',
properties: {
name: { type: 'string' },
},
examples: [{ name: 'Alice' }, { name: 'Bob' }],
};

jest.spyOn(Sampler, 'sample').mockReturnValue({ name: 'generated' });

const result = generateExamplesFromJsonSchema(schema);

expect(result).toHaveLength(2);
expect(result[0].label).toBe('default');
expect(JSON.parse(result[0].data)).toEqual({ name: 'generated' });
expect(result[1].label).toBe('example-1');
expect(JSON.parse(result[1].data)).toEqual({ name: 'generated' });
});

it('generates example from schema with x-examples', () => {
const schema: JSONSchema7 & { 'x-examples'?: unknown } = {
type: 'object',
properties: {
code: { type: 'string' },
message: { type: 'string' },
},
'x-examples': {
'Example 1': {
value: {
code: 'error',
message: 'Something bad happened!',
},
},
},
};

jest.spyOn(Sampler, 'sample').mockReturnValue({ code: 'generated', message: 'generated' });

const result = generateExamplesFromJsonSchema(schema);

expect(result).toHaveLength(1);
expect(result[0].label).toBe('default');
});

it('returns x-examples early when x-stoplight is present', () => {
const schema: JSONSchema7 & { 'x-examples'?: unknown; 'x-stoplight'?: unknown } = {
type: 'object',
properties: {
code: { type: 'string' },
},
'x-stoplight': { id: 'test' },
'x-examples': {
'My Example': {
value: {
code: 'test-code',
},
},
},
};

const sampleSpy = jest.spyOn(Sampler, 'sample');

const result = generateExamplesFromJsonSchema(schema);

expect(sampleSpy).not.toHaveBeenCalled();
expect(result).toHaveLength(1);
expect(result[0].label).toBe('My Example');
expect(JSON.parse(result[0].data)).toEqual({ code: 'test-code' });
});

it('returns examples array early when x-stoplight is present', () => {
const schema: JSONSchema7 & { 'x-stoplight'?: unknown } = {
type: 'object',
properties: {
name: { type: 'string' },
},
examples: [{ name: 'Alice' }],
'x-stoplight': { id: 'test' },
};

const sampleSpy = jest.spyOn(Sampler, 'sample');

const result = generateExamplesFromJsonSchema(schema);

expect(sampleSpy).not.toHaveBeenCalled();
expect(result).toHaveLength(1);
expect(result[0].label).toBe('default');
expect(JSON.parse(result[0].data)).toEqual({ name: 'Alice' });
});

it('generates a default example when schema has no examples', () => {
jest.spyOn(Sampler, 'sample').mockReturnValue({ code: 'string' });

const result = generateExamplesFromJsonSchema(modelWithNoExamples);

expect(result).toHaveLength(1);
expect(result[0].label).toBe('default');
expect(JSON.parse(result[0].data)).toEqual({ code: 'string' });
});

it('returns empty data when Sampler.sample returns null and no examples exist', () => {
jest.spyOn(Sampler, 'sample').mockReturnValue(null);

const schema: JSONSchema7 = {
type: 'object',
};

const result = generateExamplesFromJsonSchema(schema);

expect(result).toEqual([{ label: 'default', data: '' }]);
});

it('handles x-examples without value wrapper', () => {
const schema: JSONSchema7 & { 'x-examples'?: unknown } = {
type: 'object',
properties: {
code: { type: 'string' },
},
'x-examples': {
'Direct Example': {
code: 'direct-value',
extra: 'field',
},
},
};

jest.spyOn(Sampler, 'sample').mockReturnValue({ code: 'generated' });

const result = generateExamplesFromJsonSchema(schema);

expect(result).toHaveLength(1);
expect(result[0].label).toBe('default');
});

it('skips non-object entries in x-examples', () => {
const schema: JSONSchema7 & { 'x-examples'?: unknown; 'x-stoplight'?: unknown } = {
type: 'object',
properties: {
code: { type: 'string' },
},
'x-stoplight': { id: 'test' },
'x-examples': {
'Valid Example': {
value: { code: 'valid' },
},
'Invalid Example': 'not-an-object',
'Another Invalid': 42,
},
};

const result = generateExamplesFromJsonSchema(schema);

expect(result).toHaveLength(1);
expect(result[0].label).toBe('Valid Example');
});

it('labels multiple examples in the examples array correctly', () => {
const schema: JSONSchema7 & { 'x-stoplight'?: unknown } = {
type: 'object',
properties: {
name: { type: 'string' },
},
examples: [{ name: 'First' }, { name: 'Second' }, { name: 'Third' }],
'x-stoplight': { id: 'test' },
};

const result = generateExamplesFromJsonSchema(schema);

expect(result).toHaveLength(3);
expect(result[0].label).toBe('default');
expect(result[1].label).toBe('example-1');
expect(result[2].label).toBe('example-2');
});

it('restores original examples on schema after sampling', () => {
const originalExamples = [{ name: 'Alice' }, { name: 'Bob' }];
const schema: JSONSchema7 = {
type: 'object',
properties: {
name: { type: 'string' },
},
examples: [...originalExamples],
};

jest.spyOn(Sampler, 'sample').mockReturnValue({ name: 'generated' });

generateExamplesFromJsonSchema(schema);

expect(schema.examples).toEqual(originalExamples);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -82,24 +82,39 @@ export const generateExamplesFromJsonSchema = (schema: JSONSchema7 & { 'x-exampl
}
}

if (examples.length) {
if (examples.length && 'x-stoplight' in schema) {
return examples;
}

try {
let originalExamples = [];
if (Array.isArray(schema?.examples)) {
originalExamples = JSON.parse(JSON.stringify(schema.examples));
delete schema.examples;
}
const generated = Sampler.sample(schema, {
maxSampleDepth: 4,
ticks: 6000,
});

return generated !== null
? [
{
label: 'default',
data: safeStringify(generated, undefined, 2) ?? '',
},
]
: [{ label: 'default', data: '' }];
let updatedExamples: Example[] =
generated !== null
? [
{
label: 'default',
data: safeStringify(generated, undefined, 2) ?? '',
},
]
: [{ label: 'default', data: '' }];
if (originalExamples.length) {
schema.examples = originalExamples;
examples.forEach(item => {
item.data = updatedExamples[0].data;
});
return examples;
} else {
return updatedExamples;
}
} catch (e) {
return [{ label: '', data: `Example cannot be created for this schema\n${e}` }];
}
Expand Down