polymer-cli
Version:
A commandline tool for Polymer projects
208 lines (185 loc) • 6.64 kB
text/typescript
/*
* Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at
* http://polymer.github.io/LICENSE.txt The complete set of authors may be found
* at http://polymer.github.io/AUTHORS.txt The complete set of contributors may
* be found at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by
* Google as part of the polymer project is also subject to an additional IP
* rights grant found at http://polymer.github.io/PATENTS.txt
*/
import {assert, use} from 'chai';
import * as fs from 'fs-extra';
import * as path from 'path';
import * as sinon from 'sinon';
import {PassThrough} from 'stream';
import * as tempMod from 'temp';
import chaiSubset = require('chai-subset');
import {Github, GithubResponseError} from '../../../github/github';
import {invertPromise, fixtureDir} from '../../util';
use(chaiSubset);
const temp = tempMod.track();
suite('github/github', () => {
suite('tokenFromFile()', () => {
test.skip(
'returns a token from file if that file exists',
() => {
// not currently in use, add tests if put back into use
});
test.skip(
'returns null if token file cannot be read',
() => {
// not currently in use, add tests if put back into use
});
});
suite('extractReleaseTarball()', () => {
test('extracts a tarball from a github tarball url', async () => {
const tarballUrl = 'http://foo.com/bar.tar';
let requestedUrl;
const mockRequestApi = (options: {url: string}) => {
requestedUrl = options.url;
return fs.createReadStream(
path.join(fixtureDir, 'github-test-data/test_tarball.tgz'));
};
const github = new Github({
owner: 'TEST_OWNER',
repo: 'TEST_REPO',
// tslint:disable-next-line: no-any
requestApi: mockRequestApi as any,
});
const tmpDir = temp.mkdirSync();
await github.extractReleaseTarball(tarballUrl, tmpDir);
assert.equal(requestedUrl, tarballUrl);
assert.deepEqual(fs.readdirSync(tmpDir), ['file1.txt']);
});
test('rejects when Github returns a 404 response status code', async () => {
const mockRequestApi = () => {
const readStream = new PassThrough();
setTimeout(() => {
readStream.emit('response', {
statusCode: 404,
statusMessage: 'TEST MESSAGE - 404',
});
}, 10);
return readStream;
};
const github = new Github({
owner: 'TEST_OWNER',
repo: 'TEST_REPO',
// tslint:disable-next-line: no-any
requestApi: mockRequestApi as any,
});
const tmpDir = temp.mkdirSync();
const err = await invertPromise(
github.extractReleaseTarball('http://foo.com/bar.tar', tmpDir));
assert.instanceOf(err, GithubResponseError);
assert.equal(
err!.message,
'404 fetching http://foo.com/bar.tar - TEST MESSAGE - 404');
});
});
suite('removeUnwantedFiles()', () => {
function makeDirStruct(files: string[]) {
const tmpDir = temp.mkdirSync();
files.forEach((file) => {
const nodes = file.split('/');
let tmpPath = tmpDir;
nodes.forEach((node, index) => {
tmpPath = path.join(tmpPath, node);
if (fs.existsSync(tmpPath)) {
return;
}
if (index === nodes.length - 1) {
fs.writeFileSync(tmpPath, '');
} else {
fs.mkdirSync(tmpPath);
}
});
});
return tmpDir;
}
test('removes correct files', () => {
const tmpDir = makeDirStruct([
'.gitattributes',
'.github/CONTRIBUTING',
'.gitignore',
'.travis.yml',
'README',
'src/base.js',
]);
const github = new Github({
owner: 'TEST_OWNER',
repo: 'TEST_REPO',
});
github.removeUnwantedFiles(tmpDir);
assert.deepEqual(fs.readdirSync(tmpDir), ['.gitignore', 'README', 'src']);
assert.deepEqual(fs.readdirSync(path.join(tmpDir, 'src')), ['base.js']);
});
});
suite('getSemverRelease()', () => {
let listReleasesStub: sinon.SinonStub;
let github: Github;
const basicReleasesResponse = {
data: [
{tag_name: 'v1.0.0'},
{tag_name: 'v1.1.0'},
{tag_name: 'v1.2.1'},
{tag_name: 'v2.0.0'},
{tag_name: 'v2.0.0-pre.1'},
{tag_name: 'v2.0.1'},
{tag_name: 'v2.1.0'},
{tag_name: 'TAG_NAME_WITHOUT_VERSION'},
]
};
setup(() => {
listReleasesStub = sinon.stub();
github = new Github({
owner: 'TEST_OWNER',
repo: 'TEST_REPO',
githubApi: {
repos: {
listReleases: listReleasesStub,
},
},
// tslint:disable-next-line: no-any
} as any);
});
test('calls the github API with correct params', async () => {
listReleasesStub.returns(Promise.resolve(basicReleasesResponse));
await github.getSemverRelease('*');
assert.isOk(listReleasesStub.calledWithExactly({
owner: 'TEST_OWNER',
repo: 'TEST_REPO',
per_page: 100,
}));
});
let testName =
'resolves with latest semver release that matches the range: *';
test(testName, async () => {
listReleasesStub.returns(Promise.resolve(basicReleasesResponse));
const release = await github.getSemverRelease('*');
assert.containSubset(release, {name: 'v2.1.0'});
});
testName =
'resolves with latest semver release that matches the range: ^v1.0.0';
test(testName, async () => {
listReleasesStub.returns(Promise.resolve(basicReleasesResponse));
const release = await github.getSemverRelease('^v1.0.0');
assert.containSubset(release, {name: 'v1.2.1'});
});
testName =
'resolves with latest semver release that matches the range: ^v2.0.0';
test(testName, async () => {
listReleasesStub.returns(Promise.resolve(basicReleasesResponse));
const release = await github.getSemverRelease('^v2.0.0');
assert.containSubset(release, {name: 'v2.1.0'});
});
testName = 'rejects with an error if no matching releases are found';
test(testName, async () => {
listReleasesStub.returns(Promise.resolve(basicReleasesResponse));
const err = await invertPromise(github.getSemverRelease('^v3.0.0'));
assert.equal(
err!.message,
'TEST_OWNER/TEST_REPO has no releases matching ^v3.0.0.');
});
});
});