Skip to content

Commit

Permalink
feat: adds updateCodeBlock
Browse files Browse the repository at this point in the history
  • Loading branch information
Ken Howard committed Nov 21, 2018
1 parent 663a386 commit 0865240
Show file tree
Hide file tree
Showing 13 changed files with 175 additions and 21 deletions.
11 changes: 11 additions & 0 deletions __mocks__/@octokit/rest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,17 @@ const gistsResponse = (): Promise<any> =>
});

const mockedGists = {
edit: jest.fn((options) =>
Promise.resolve({
data: {
...gistsResponseData[0],
files: {
...gistsResponseData[0].files,
...options.files
}
}
})
),
get: jest.fn((options) =>
Promise.resolve({ data: { ...gistsResponseData[0], id: options.gist_id } })
),
Expand Down
5 changes: 4 additions & 1 deletion __mocks__/path.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// tslint:disable:no-any no-unsafe-any
module.exports = {
join: jest.fn((...paths) => ['var', 'T', 'tmp', ...paths].join('/'))
dirname: jest.fn((input) => input),
join: jest.fn((...paths) => ['var', 'T', 'tmp', ...paths].join('/')),
sep: '/'
};
2 changes: 1 addition & 1 deletion __mocks__/tmp.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// tslint:disable:no-any ban no-magic-numbers
// tslint:disable:no-any ban no-magic-numbers no-unsafe-any
const randomString = (): string =>
Math.random()
.toString(36)
Expand Down
26 changes: 24 additions & 2 deletions src/commands/__tests__/gists.commands.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
// tslint:disable:no-any no-unsafe-any no-magic-numbers
import { window } from 'vscode';

import { openCodeBlock } from '../gists.commands';
import { TMP_DIRECTORY_PREFIX } from '../../constants';
import { gists } from '../../gists/gists-service';
import { openCodeBlock, updateCodeBlock } from '../gists.commands';

let editSpy: jest.SpyInstance;

describe('Gists Commands Tests', () => {
beforeEach(() => {
jest.restoreAllMocks();
editSpy = jest.spyOn(gists, 'update');
});
afterEach(() => {
editSpy.mockRestore();
});
describe('#openCodeBlock', () => {
test('it opens the quickpick pane', async () => {
Expand All @@ -26,4 +33,19 @@ describe('Gists Commands Tests', () => {
expect(secondGist.label).toBe('1. gist two');
});
});
describe('#updateCodeBlock', () => {
test('should save', async () => {
expect.assertions(2);

await updateCodeBlock({
fileName: `${TMP_DIRECTORY_PREFIX}_123456789abcdefg_random_string/test-file-name.md`,
getText: jest.fn(() => 'test-file-content')
});

expect(editSpy.mock.calls[0][0].gist_id).toBe('123456789abcdefg');
expect(editSpy.mock.calls[0][0].files).toStrictEqual({
'test-file-name.md': 'test-file-content'
});
});
});
});
38 changes: 34 additions & 4 deletions src/commands/gists.commands.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { commands, window, workspace } from 'vscode';

import { getGist, getGists } from '../gists';
import { getGist, getGists, updateGist } from '../gists';
import { logger } from '../logger';
import { filesSync } from '../utils';
import { extractTextDocumentDetails, filesSync } from '../utils';

const _formatGistsForQuickPick = (gists: Gist[]): QuickPickGist[] =>
gists.map((item, i, j) => ({
Expand Down Expand Up @@ -33,7 +33,13 @@ const _openDocument = (file: string): Thenable<void> =>
.then(window.showTextDocument)
.then(() => commands.executeCommand('workbench.action.keepEditor'));

// TODO: Move _notify to utils
const _notify = (friendly: string, message: string): void => {
window.showInformationMessage(`GIST: ${friendly}> ${message}"`);
};

const openCodeBlock = async (): Promise<void> => {
let gistName = '';
try {
logger.info('User Activated "openCodeBlock"');

Expand All @@ -50,6 +56,7 @@ const openCodeBlock = async (): Promise<void> => {

return;
}
gistName = `"${selected.block.name}"`;
logger.info(`User Selected Gist: "${selected.label}"`);

const codeBlock = await _getGist(selected.block.id);
Expand All @@ -62,8 +69,31 @@ const openCodeBlock = async (): Promise<void> => {
}
} catch (err) {
const error: Error = err as Error;
logger.error(error && error.message);
logger.error(`openCodeBlock > ${error && error.message}`);
if (error && error.message === 'Not Found') {
_notify(`Could Not Open Gist ${gistName}>`, error.message);
}
}
};

const updateCodeBlock = async (doc: GistTextDocument): Promise<void> => {
let file = '';
try {
const { id, filename, content } = extractTextDocumentDetails(doc);
file = `"${filename}" `;
if (id) {
logger.info(`Saving "${filename}"`);
await updateGist(id, filename, content);
} else {
logger.info(`"${filename}" Not a Gist`);
}
} catch (err) {
const error: Error = err as Error;
logger.error(`updateCodeBlock > ${error && error.message}`);
if (error && error.message === 'Not Found') {
_notify(`Could Not Save ${file}`, error.message);
}
}
};

export { openCodeBlock };
export { openCodeBlock, updateCodeBlock };
4 changes: 3 additions & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as vscode from 'vscode';

import { openCodeBlock } from './commands';
import { openCodeBlock, updateCodeBlock } from './commands';
import { Levels, logger } from './logger';

export function activate(_: vscode.ExtensionContext): void {
Expand All @@ -9,6 +9,8 @@ export function activate(_: vscode.ExtensionContext): void {

logger.debug('extension activated');
vscode.commands.registerCommand('extension.openCodeBlock', openCodeBlock);
vscode.workspace.onDidSaveTextDocument(updateCodeBlock);

vscode.commands.registerCommand(
'extension.openFavoriteCodeBlock',
(): void => {
Expand Down
2 changes: 1 addition & 1 deletion src/gists/__tests__/api.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// tslint:disable:no-any no-magic-numbers
// tslint:disable:no-any no-magic-numbers no-unsafe-any
import { getGists } from '../api';

describe('Gists API Tests', () => {
Expand Down
8 changes: 4 additions & 4 deletions src/gists/__tests__/gists-service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,21 @@ describe('GistService tests', () => {
});
});
});
describe('#getAll', () => {
describe('#list', () => {
test('should have getAll function', (done) => {
expect.assertions(1);

testGists.getAll().then((response: any) => {
testGists.list().then((response: any) => {
expect(response.data[0].description).toBe('gist one');
done();
});
});
});
describe('#getStarred', () => {
describe('#listStarred', () => {
test('should have getAll function', (done) => {
expect.assertions(1);

testGists.getStarred().then((response: any) => {
testGists.listStarred().then((response: any) => {
expect(response.data[0].description).toBe('gist one');
done();
});
Expand Down
55 changes: 50 additions & 5 deletions src/gists/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,18 @@ interface GistResponse {

type GistsResponse = GistResponse[];

// tslint:disable:no-any
const prepareError = (err: Error): Error => {
const httpError: Error = JSON.parse(err.message) as Error;

if (err instanceof Object && err.message && httpError.message) {
return new Error(httpError.message);
}

return err;
};
// tslint:enable:no-any

const formatGist = (gist: GistResponse): Gist => ({
createdAt: new Intl.DateTimeFormat(env.language, {
day: 'numeric',
Expand Down Expand Up @@ -55,12 +67,17 @@ export const getGist = async (id: string): Promise<Gist | void> => {
const results = await gists.get({ gist_id: id });

if (!results || !results.data) {
throw new Error('Gist Not Found');
throw new Error('Not Found');
}

return formatGist(results.data);
} catch (err) {
logger.error(err && err.message);
const error: Error = prepareError(err as Error);
const { message } = error;
if (message === 'Not Found') {
throw error;
}
logger.error(error && error.message);
}
};

Expand All @@ -69,18 +86,46 @@ export const getGist = async (id: string): Promise<Gist | void> => {
*/
export const getGists = async (starred = false): Promise<Gist[] | void> => {
try {
const results = await gists[starred ? 'getStarred' : 'getAll']({
const results = await gists[starred ? 'listStarred' : 'list']({
per_page: GISTS_PER_PAGE
});

if (!results || !results.data) {
throw new Error('No Gists Found');
throw new Error('Not Found');
}

// TODO: Octokit type definitions need updating.
// tslint:disable-next-line:no-any
return formatGists(results.data as any);
} catch (err) {
logger.error(err && err.message);
const error: Error = prepareError(err as Error);
const { message } = error;
if (message === 'Not Found') {
throw error;
}
logger.error(error && error.message);
}
};

export const updateGist = async (
id: string,
filename: string,
content: string
): Promise<Gist | void> => {
try {
const results = await gists.update({
files: { [filename]: content },
gist_id: id
});

return formatGist(results.data);
} catch (err) {
const error: Error = prepareError(err as Error);

const { message } = error;
if (message === 'Not Found') {
throw error;
}
logger.error(error && error.message);
}
};
10 changes: 8 additions & 2 deletions src/gists/gists-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ class GistsService {
return this.octokit.gists.get({ ...params });
}

public getAll(
public list(
params?: Octokit.GistsGetAllParams
): Response<Octokit.GistsGetAllResponseItem[]> {
return this.octokit.gists.getAll({ ...params });
}

public getStarred(
public listStarred(
params?: Octokit.GistsGetStarredParams
): Response<Octokit.GistsGetStarredResponseItem[]> {
return this.octokit.gists.getStarred({ ...params });
Expand All @@ -43,6 +43,12 @@ class GistsService {
this.options = options || this.options;
this.octokit = new Octokit(this.options);
}

public update(
params: Octokit.GistsEditParams
): Response<Octokit.GistsEditResponse> {
return this.octokit.gists.edit(params);
}
}

export const gists = GistsService.getInstance();
4 changes: 4 additions & 0 deletions src/typings/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ interface Gist {
updatedAt: string;
}

interface GistTextDocument {
fileName: string;
getText(): string;
}
interface QuickPickGist {
block: Gist;
/**
Expand Down
18 changes: 18 additions & 0 deletions src/utils/__tests__/file.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// tslint:disable:no-any no-magic-numbers no-unsafe-any
import { filesSync, fileSync } from '..';
import { extractTextDocumentDetails } from '../file';

jest.mock('path');
jest.mock('fs');
Expand Down Expand Up @@ -31,4 +32,21 @@ describe('File Tests', () => {
expect(filePath[2]).toContain('test-3-filename.md');
});
});
describe('#extractTextDocumentDetails', () => {
test('should get document details', () => {
const getText = jest.fn(() => 'mocked-content');
const result = extractTextDocumentDetails({
fileName:
'/var/folders/T/vscode_gist_1111_random_string/mocked-text-document.md',
getText
} as any);
expect(result).toStrictEqual({
content: 'mocked-content',
filename: 'mocked-text-document.md',
id: '1111',
path:
'/var/folders/T/vscode_gist_1111_random_string/mocked-text-document.md'
});
});
});
});
13 changes: 13 additions & 0 deletions src/utils/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,16 @@ export const filesSync = (

return filePaths;
};

export const extractTextDocumentDetails = (
doc: GistTextDocument
): { content: string; filename: string; id: string; path: string } => {
const sep = path.sep === '\\' ? '\\\\' : path.sep;
const regexp = new RegExp(
`.*${TMP_DIRECTORY_PREFIX}_([^_]*)_[^${sep}]*${sep}(.*)`
);
const [fullPath, id, filename] = doc.fileName.match(regexp) || ['', '', ''];
const content = doc.getText();

return { content, filename, id, path: path.dirname(fullPath) };
};

0 comments on commit 0865240

Please sign in to comment.