Skip to content

Commit

Permalink
chore(oas-to-snippet): mock out httpsnippet-client-api behaviors (#961
Browse files Browse the repository at this point in the history
)

## 🧰 Changes

Both `oas-to-snippet` and
[httpsnippet-client-api](https://npm.im/httpsnippet-client-api)
depending on `oas` has always made it difficult to do breaking releases
of `oas` because after publishing `oas`, which automatically bumps
`oas-to-snippet`, I then need to bump `httpsnippet-client-api` and
_then_ pull that back into `oas-to-snippet`.

Nuts to all that. Since we are only loading it in tests to test out
behavior for [api](https://npm.im/api) code snippets we can instead just
mock out plugin examples and test around that.
  • Loading branch information
erunion authored Mar 6, 2025
1 parent f369a88 commit ce82e89
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 56 deletions.
36 changes: 0 additions & 36 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion packages/oas-to-snippet/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@
"@types/har-format": "^1.2.14",
"@types/node": "^22.7.6",
"har-examples": "file:../har-examples",
"httpsnippet-client-api": "^7.0.0-beta.4",
"oas": "file:../oas",
"typescript": "^5.2.2",
"vitest": "^3.0.5"
Expand Down
67 changes: 67 additions & 0 deletions packages/oas-to-snippet/test/__fixtures__/plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/**
* This is a plugin that lightly mimics the behavior of `httpsnippet-client-api` and is used to
* test behaviors related to surfacing snippets from it over stock `node` options.
*
* Why not just use `httpsnippet-client-api`? Because it depends on `oas` we end up with a bit of
* a circular dependency where if we make breaking changes to `oas`, which would update
* `oas-to-snippet` we then need to update `httpsnippet-client-api` to match. If we don't do this
* then the `httpsnippet-client-api` and `oas` dependencies within `oas-to-snippet` get into a
* weird state within NPM where there become conflicts and NPM is unable to load the right one.
*
*/
import type { Client, ClientPlugin } from '@readme/httpsnippet/targets';
import type { OASDocument } from 'oas/types';

import { CodeBuilder } from '@readme/httpsnippet/helpers/code-builder';

interface APIOptions {
api?: {
definition: OASDocument;

/**
* The string to identify this SDK as. This is used in the `import sdk from '<identifier>'`
* sample as well as the the variable name we attach the SDK to.
*
* @example `@api/developers`
*/
identifier?: string;

/**
* The URI that is used to download this API definition from `npx api install`.
*
* @example `@developers/v2.0#17273l2glm9fq4l5`
*/
registryURI: string;
};
escapeBrackets?: boolean;
indent?: string | false;
}

const client: Client<APIOptions> = {
info: {
key: 'api',
title: 'API',
link: 'https://npm.im/api',
description: 'Automatic SDK generation from an OpenAPI definition.',
extname: '.js',
installation: 'npx api install "{packageName}"',
},
convert: (request, options) => {
const { blank, push, join } = new CodeBuilder({ indent: options?.indent || ' ' });

push("console.log('example `api` plugin code snippet.')");
if (options?.api?.identifier) {
push(`const ${options.api.identifier} = 'example variable name';`);
}
blank();

return join();
},
};

const plugin: ClientPlugin<APIOptions> = {
target: 'node',
client,
};

export default plugin;
27 changes: 27 additions & 0 deletions packages/oas-to-snippet/test/__fixtures__/pluginFailure.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { Client, ClientPlugin } from '@readme/httpsnippet/targets';

interface APIOptions {
escapeBrackets?: boolean;
indent?: string | false;
}

const client: Client<APIOptions> = {
info: {
key: 'api',
title: 'API',
link: 'https://npm.im/api',
description: 'Automatic SDK generation from an OpenAPI definition.',
extname: '.js',
installation: 'npx api install "{packageName}"',
},
convert: () => {
throw new Error('This plugin is expected to fail.');
},
};

const plugin: ClientPlugin<APIOptions> = {
target: 'node',
client,
};

export default plugin;
15 changes: 5 additions & 10 deletions packages/oas-to-snippet/test/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -487,23 +487,18 @@ fetch(url, options)
exports[`oas-to-snippet > supported languages > node > targets > api > should support custom variable names 1`] = `
{
"code": "import developers from '@api/developers';
developers.loginUser({username: 'woof', password: 'barkbarkbark'})
.then(({ data }) => console.log(data))
.catch(err => console.error(err));",
"code": "console.log('example \`api\` plugin code snippet.')
const developers = 'example variable name';
",
"highlightMode": "javascript",
"install": "npx api install "@developers/v2.0#17273l2glm9fq4l5"",
}
`;
exports[`oas-to-snippet > supported languages > node > targets > api > should support snippet generation 1`] = `
{
"code": "import developers from '@api/developers';
developers.loginUser({username: 'woof', password: 'barkbarkbark'})
.then(({ data }) => console.log(data))
.catch(err => console.error(err));",
"code": "console.log('example \`api\` plugin code snippet.')
",
"highlightMode": "javascript",
"install": "npx api install "@developers/v2.0#17273l2glm9fq4l5"",
}
Expand Down
13 changes: 7 additions & 6 deletions packages/oas-to-snippet/test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import type { HarRequest } from '@readme/httpsnippet';
import fileUploads from '@readme/oas-examples/3.0/json/file-uploads.json';
import petstoreOas from '@readme/oas-examples/3.0/json/petstore.json';
import harExamples from 'har-examples';
import httpsnippetClientAPIPlugin from 'httpsnippet-client-api';
import Oas from 'oas';
import { PROXY_ENABLED } from 'oas/extensions';
import { describe, beforeEach, it, expect } from 'vitest';
Expand All @@ -16,6 +15,8 @@ import owlbertShrub from './__datasets__/owlbert-shrub.dataurl.json';
import owlbert from './__datasets__/owlbert.dataurl.json';
import queryEncodedHAR from './__datasets__/query-encoded.har.json';
import multipartFormDataOneOfRequestBody from './__datasets__/quirks/multipart-oneOf-requestbody.json';
import examplePlugin from './__fixtures__/plugin.js';
import examplePluginFailure from './__fixtures__/pluginFailure.js';

const petstore = Oas.init(petstoreOas);

Expand Down Expand Up @@ -425,10 +426,10 @@ formData.append('filename', await new Response(fs.createReadStream('owlbert-shru

describe('supported languages', () => {
const supportedLanguages = getSupportedLanguages({
plugins: [httpsnippetClientAPIPlugin],
plugins: [examplePlugin],
});

describe.each(Object.keys(supportedLanguages))('%s', (lang: keyof SupportedLanguages) => {
describe.each(Object.keys(supportedLanguages) as (keyof SupportedLanguages)[])('%s', lang => {
const targets = Object.keys(supportedLanguages[lang].httpsnippet.targets);

it('should have a language definition', () => {
Expand Down Expand Up @@ -477,7 +478,7 @@ formData.append('filename', await new Response(fs.createReadStream('owlbert-shru
registryIdentifier: OAS_REGISTRY_IDENTIFIER,
// variableName: 'developers',
},
plugins: [httpsnippetClientAPIPlugin],
plugins: [examplePlugin],
},
);

Expand All @@ -499,7 +500,7 @@ formData.append('filename', await new Response(fs.createReadStream('owlbert-shru
registryIdentifier: OAS_REGISTRY_IDENTIFIER,
variableName: 'developers',
},
plugins: [httpsnippetClientAPIPlugin],
plugins: [examplePlugin],
},
);

Expand All @@ -518,7 +519,7 @@ formData.append('filename', await new Response(fs.createReadStream('owlbert-shru
openapi: {
registryIdentifier: OAS_REGISTRY_IDENTIFIER,
},
plugins: [httpsnippetClientAPIPlugin],
plugins: [examplePluginFailure],
});

expect(snippet.code).toContain('fetch');
Expand Down
7 changes: 4 additions & 3 deletions packages/oas-to-snippet/test/languages.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import httpsnippetClientAPIPlugin from 'httpsnippet-client-api';
import { describe, it, expect } from 'vitest';

import { getSupportedLanguages, getClientInstallationInstructions } from '../src/languages.js';

import examplePlugin from './__fixtures__/plugin.js';

describe('#getSupportedLanguages', () => {
it('should retrieve our default supported languages', () => {
const languages = getSupportedLanguages();
Expand All @@ -14,7 +15,7 @@ describe('#getSupportedLanguages', () => {

it('should support external plugins', () => {
const languages = getSupportedLanguages({
plugins: [httpsnippetClientAPIPlugin],
plugins: [examplePlugin],
});

expect(languages.node.httpsnippet.targets.api).toStrictEqual({
Expand All @@ -41,7 +42,7 @@ describe('#getClientInstallationInstructions', () => {

it('should retrieve a templated `api` install command if the `api` plugin is loaded', () => {
const languages = getSupportedLanguages({
plugins: [httpsnippetClientAPIPlugin],
plugins: [examplePlugin],
});

expect(getClientInstallationInstructions(languages, ['node', 'api'], '@developers/v2.0#17273l2glm9fq4l5')).toBe(
Expand Down

0 comments on commit ce82e89

Please sign in to comment.